aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Kconfig1
-rw-r--r--drivers/message/fusion/lsi/mpi.h10
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h158
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt77
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h8
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h122
-rw-r--r--drivers/message/fusion/lsi/mpi_log_fc.h89
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h162
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h30
-rw-r--r--drivers/message/fusion/mptbase.c48
-rw-r--r--drivers/message/fusion/mptbase.h34
-rw-r--r--drivers/message/fusion/mptctl.c12
-rw-r--r--drivers/message/fusion/mptfc.c579
-rw-r--r--drivers/message/fusion/mptlan.c14
-rw-r--r--drivers/message/fusion/mptsas.c404
-rw-r--r--drivers/message/fusion/mptscsih.c34
-rw-r--r--drivers/message/fusion/mptspi.c26
17 files changed, 1558 insertions, 250 deletions
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index 1883d22cffeb..e67cf15e9c39 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -23,6 +23,7 @@ config FUSION_FC
23 tristate "Fusion MPT ScsiHost drivers for FC" 23 tristate "Fusion MPT ScsiHost drivers for FC"
24 depends on PCI && SCSI 24 depends on PCI && SCSI
25 select FUSION 25 select FUSION
26 select SCSI_FC_ATTRS
26 ---help--- 27 ---help---
27 SCSI HOST support for a Fiber Channel host adapters. 28 SCSI HOST support for a Fiber Channel host adapters.
28 29
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index b61e3d175070..02cdc840a06b 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -6,7 +6,7 @@
6 * Title: MPI Message independent structures and definitions 6 * Title: MPI Message independent structures and definitions
7 * Creation Date: July 27, 2000 7 * Creation Date: July 27, 2000
8 * 8 *
9 * mpi.h Version: 01.05.08 9 * mpi.h Version: 01.05.10
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -74,6 +74,8 @@
74 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and 74 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
75 * TargetAssistExtended requests. 75 * TargetAssistExtended requests.
76 * Added EEDP IOCStatus codes. 76 * Added EEDP IOCStatus codes.
77 * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
78 * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
77 * -------------------------------------------------------------------------- 79 * --------------------------------------------------------------------------
78 */ 80 */
79 81
@@ -104,7 +106,7 @@
104/* Note: The major versions of 0xe0 through 0xff are reserved */ 106/* Note: The major versions of 0xe0 through 0xff are reserved */
105 107
106/* versioning for this MPI header set */ 108/* versioning for this MPI header set */
107#define MPI_HEADER_VERSION_UNIT (0x0A) 109#define MPI_HEADER_VERSION_UNIT (0x0C)
108#define MPI_HEADER_VERSION_DEV (0x00) 110#define MPI_HEADER_VERSION_DEV (0x00)
109#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) 111#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
110#define MPI_HEADER_VERSION_UNIT_SHIFT (8) 112#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
@@ -711,6 +713,8 @@ typedef struct _MSG_DEFAULT_REPLY
711#define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D) 713#define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D)
712#define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E) 714#define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E)
713#define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F) 715#define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F)
716#define MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070)
717#define MPI_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071)
714 718
715/****************************************************************************/ 719/****************************************************************************/
716/* Additional FCP target values (obsolete) */ 720/* Additional FCP target values (obsolete) */
@@ -745,7 +749,7 @@ typedef struct _MSG_DEFAULT_REPLY
745#define MPI_IOCSTATUS_LAN_CANCELED (0x0087) 749#define MPI_IOCSTATUS_LAN_CANCELED (0x0087)
746 750
747/****************************************************************************/ 751/****************************************************************************/
748/* Serial Attached SCSI values */ 752/* Serial Attached SCSI values */
749/****************************************************************************/ 753/****************************************************************************/
750 754
751#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) 755#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index d8339896f734..b1becec27e1b 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -6,7 +6,7 @@
6 * Title: MPI Config message, structures, and Pages 6 * Title: MPI Config message, structures, and Pages
7 * Creation Date: July 27, 2000 7 * Creation Date: July 27, 2000
8 * 8 *
9 * mpi_cnfg.h Version: 01.05.09 9 * mpi_cnfg.h Version: 01.05.11
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -249,6 +249,23 @@
249 * Added OwnerDevHandle and Flags field to SAS PHY Page 0. 249 * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
250 * Added IOC GPIO Flags define to SAS Enclosure Page 0. 250 * Added IOC GPIO Flags define to SAS Enclosure Page 0.
251 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. 251 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
252 * 08-03-05 01.05.10 Removed ISDataScrubRate and ISResyncRate from
253 * Manufacturing Page 4.
254 * Added MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE bit.
255 * Added NumDevsPerEnclosure field to SAS IO Unit page 2.
256 * Added MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP
257 * define.
258 * Added EnclosureHandle field to SAS Expander page 0.
259 * Removed redundant NumTableEntriesProg field from SAS
260 * Expander Page 1.
261 * 08-30-05 01.05.11 Added DeviceID for FC949E and changed the DeviceID for
262 * SAS1078.
263 * Added more defines for Manufacturing Page 4 Flags field.
264 * Added more defines for IOCSettings and added
265 * ExpanderSpinup field to Bios Page 1.
266 * Added postpone SATA Init bit to SAS IO Unit Page 1
267 * ControlFlags.
268 * Changed LogEntry format for Log Page 0.
252 * -------------------------------------------------------------------------- 269 * --------------------------------------------------------------------------
253 */ 270 */
254 271
@@ -494,7 +511,7 @@ typedef struct _MSG_CONFIG_REPLY
494#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626) 511#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
495#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642) 512#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642)
496#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640) 513#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
497#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646) 514#define MPI_MANUFACTPAGE_DEVICEID_FC949E (0x0646)
498/* SCSI */ 515/* SCSI */
499#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) 516#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
500#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) 517#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
@@ -510,7 +527,7 @@ typedef struct _MSG_CONFIG_REPLY
510#define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A) 527#define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A)
511#define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054) 528#define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054)
512#define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058) 529#define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058)
513#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0060) 530#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0062)
514 531
515 532
516typedef struct _CONFIG_PAGE_MANUFACTURING_0 533typedef struct _CONFIG_PAGE_MANUFACTURING_0
@@ -602,9 +619,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
602 U32 IMVolumeSettings; /* 50h */ 619 U32 IMVolumeSettings; /* 50h */
603 U32 Reserved3; /* 54h */ 620 U32 Reserved3; /* 54h */
604 U32 Reserved4; /* 58h */ 621 U32 Reserved4; /* 58h */
605 U8 ISDataScrubRate; /* 5Ch */ 622 U32 Reserved5; /* 5Ch */
606 U8 ISResyncRate; /* 5Dh */
607 U16 Reserved5; /* 5Eh */
608 U8 IMEDataScrubRate; /* 60h */ 623 U8 IMEDataScrubRate; /* 60h */
609 U8 IMEResyncRate; /* 61h */ 624 U8 IMEResyncRate; /* 61h */
610 U16 Reserved6; /* 62h */ 625 U16 Reserved6; /* 62h */
@@ -616,9 +631,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
616} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, 631} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
617 ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; 632 ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
618 633
619#define MPI_MANUFACTURING4_PAGEVERSION (0x02) 634#define MPI_MANUFACTURING4_PAGEVERSION (0x03)
620 635
621/* defines for the Flags field */ 636/* defines for the Flags field */
637#define MPI_MANPAGE4_IME_DISABLE (0x20)
638#define MPI_MANPAGE4_IM_DISABLE (0x10)
639#define MPI_MANPAGE4_IS_DISABLE (0x08)
640#define MPI_MANPAGE4_IR_MODEPAGE8_DISABLE (0x04)
641#define MPI_MANPAGE4_IM_RESYNC_CACHE_ENABLE (0x02)
622#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) 642#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
623 643
624 644
@@ -669,7 +689,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
669} CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1, 689} CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
670 IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t; 690 IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
671 691
672#define MPI_IOUNITPAGE1_PAGEVERSION (0x01) 692#define MPI_IOUNITPAGE1_PAGEVERSION (0x02)
673 693
674/* IO Unit Page 1 Flags defines */ 694/* IO Unit Page 1 Flags defines */
675#define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000) 695#define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000)
@@ -681,7 +701,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
681#define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040) 701#define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040)
682#define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) 702#define MPI_IOUNITPAGE1_FORCE_32 (0x00000080)
683#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100) 703#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100)
684 704#define MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE (0x00000200)
685 705
686typedef struct _MPI_ADAPTER_INFO 706typedef struct _MPI_ADAPTER_INFO
687{ 707{
@@ -968,7 +988,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
968 U32 Reserved1; /* 0Ch */ 988 U32 Reserved1; /* 0Ch */
969 U32 DeviceSettings; /* 10h */ 989 U32 DeviceSettings; /* 10h */
970 U16 NumberOfDevices; /* 14h */ 990 U16 NumberOfDevices; /* 14h */
971 U16 Reserved2; /* 16h */ 991 U8 ExpanderSpinup; /* 16h */
992 U8 Reserved2; /* 17h */
972 U16 IOTimeoutBlockDevicesNonRM; /* 18h */ 993 U16 IOTimeoutBlockDevicesNonRM; /* 18h */
973 U16 IOTimeoutSequential; /* 1Ah */ 994 U16 IOTimeoutSequential; /* 1Ah */
974 U16 IOTimeoutOther; /* 1Ch */ 995 U16 IOTimeoutOther; /* 1Ch */
@@ -976,7 +997,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
976} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1, 997} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
977 BIOSPage1_t, MPI_POINTER pBIOSPage1_t; 998 BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
978 999
979#define MPI_BIOSPAGE1_PAGEVERSION (0x02) 1000#define MPI_BIOSPAGE1_PAGEVERSION (0x03)
980 1001
981/* values for the BiosOptions field */ 1002/* values for the BiosOptions field */
982#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400) 1003#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
@@ -985,8 +1006,15 @@ typedef struct _CONFIG_PAGE_BIOS_1
985#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) 1006#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
986 1007
987/* values for the IOCSettings field */ 1008/* values for the IOCSettings field */
1009#define MPI_BIOSPAGE1_IOCSET_MASK_INITIAL_SPINUP_DELAY (0x0F000000)
1010#define MPI_BIOSPAGE1_IOCSET_SHIFT_INITIAL_SPINUP_DELAY (24)
1011
988#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000) 1012#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000)
989#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20) 1013#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20)
1014
1015#define MPI_BIOSPAGE1_IOCSET_AUTO_PORT_ENABLE (0x00080000)
1016#define MPI_BIOSPAGE1_IOCSET_DIRECT_ATTACH_SPINUP_MODE (0x00040000)
1017
990#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) 1018#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
991#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) 1019#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
992#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) 1020#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
@@ -1016,6 +1044,11 @@ typedef struct _CONFIG_PAGE_BIOS_1
1016#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) 1044#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002)
1017#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) 1045#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001)
1018 1046
1047/* defines for the ExpanderSpinup field */
1048#define MPI_BIOSPAGE1_EXPSPINUP_MASK_MAX_TARGET (0xF0)
1049#define MPI_BIOSPAGE1_EXPSPINUP_SHIFT_MAX_TARGET (4)
1050#define MPI_BIOSPAGE1_EXPSPINUP_MASK_DELAY (0x0F)
1051
1019typedef struct _MPI_BOOT_DEVICE_ADAPTER_ORDER 1052typedef struct _MPI_BOOT_DEVICE_ADAPTER_ORDER
1020{ 1053{
1021 U32 Reserved1; /* 00h */ 1054 U32 Reserved1; /* 00h */
@@ -1233,13 +1266,13 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
1233 1266
1234#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8) 1267#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8)
1235#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \ 1268#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \
1236 ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MIN_SYNC_PERIOD) \ 1269 ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK) \
1237 >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \ 1270 >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \
1238 ) 1271 )
1239#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000) 1272#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
1240#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16) 1273#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16)
1241#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \ 1274#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \
1242 ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \ 1275 ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK) \
1243 >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \ 1276 >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \
1244 ) 1277 )
1245#define MPI_SCSIPORTPAGE0_CAP_IDP (0x08000000) 1278#define MPI_SCSIPORTPAGE0_CAP_IDP (0x08000000)
@@ -2370,47 +2403,48 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2370} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, 2403} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
2371 SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; 2404 SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
2372 2405
2373#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04) 2406#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05)
2374 2407
2375/* values for SAS IO Unit Page 1 ControlFlags */ 2408/* values for SAS IO Unit Page 1 ControlFlags */
2376#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) 2409#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
2377#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) 2410#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
2378#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) 2411#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
2379#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) 2412#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
2380#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800) 2413#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800)
2381 2414
2382#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600) 2415#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600)
2383#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) 2416#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
2384#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00) 2417#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
2385#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01) 2418#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
2386#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02) 2419#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
2387 2420
2388#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) 2421#define MPI_SAS_IOUNIT1_CONTROL_POSTPONE_SATA_INIT (0x0100)
2389#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) 2422#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
2390#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) 2423#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
2391#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010) 2424#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
2392#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008) 2425#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010)
2393#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004) 2426#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008)
2394#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) 2427#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004)
2395#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) 2428#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
2429#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
2396 2430
2397/* values for SAS IO Unit Page 1 PortFlags */ 2431/* values for SAS IO Unit Page 1 PortFlags */
2398#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) 2432#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
2399#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) 2433#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
2400#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) 2434#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
2401 2435
2402/* values for SAS IO Unit Page 0 PhyFlags */ 2436/* values for SAS IO Unit Page 0 PhyFlags */
2403#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04) 2437#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04)
2404#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02) 2438#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02)
2405#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01) 2439#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01)
2406 2440
2407/* values for SAS IO Unit Page 0 MaxMinLinkRate */ 2441/* values for SAS IO Unit Page 0 MaxMinLinkRate */
2408#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0) 2442#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0)
2409#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80) 2443#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80)
2410#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90) 2444#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90)
2411#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F) 2445#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F)
2412#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08) 2446#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08)
2413#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09) 2447#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09)
2414 2448
2415/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */ 2449/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
2416 2450
@@ -2418,16 +2452,18 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2418typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 2452typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
2419{ 2453{
2420 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ 2454 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
2421 U32 Reserved1; /* 08h */ 2455 U8 NumDevsPerEnclosure; /* 08h */
2456 U8 Reserved1; /* 09h */
2457 U16 Reserved2; /* 0Ah */
2422 U16 MaxPersistentIDs; /* 0Ch */ 2458 U16 MaxPersistentIDs; /* 0Ch */
2423 U16 NumPersistentIDsUsed; /* 0Eh */ 2459 U16 NumPersistentIDsUsed; /* 0Eh */
2424 U8 Status; /* 10h */ 2460 U8 Status; /* 10h */
2425 U8 Flags; /* 11h */ 2461 U8 Flags; /* 11h */
2426 U16 MaxNumPhysicalMappedIDs;/* 12h */ /* 12h */ 2462 U16 MaxNumPhysicalMappedIDs;/* 12h */
2427} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, 2463} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
2428 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; 2464 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
2429 2465
2430#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04) 2466#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x05)
2431 2467
2432/* values for SAS IO Unit Page 2 Status field */ 2468/* values for SAS IO Unit Page 2 Status field */
2433#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) 2469#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
@@ -2441,6 +2477,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
2441#define MPI_SAS_IOUNIT2_FLAGS_NO_PHYS_MAP (0x00) 2477#define MPI_SAS_IOUNIT2_FLAGS_NO_PHYS_MAP (0x00)
2442#define MPI_SAS_IOUNIT2_FLAGS_DIRECT_ATTACH_PHYS_MAP (0x01) 2478#define MPI_SAS_IOUNIT2_FLAGS_DIRECT_ATTACH_PHYS_MAP (0x01)
2443#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02) 2479#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02)
2480#define MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP (0x07)
2444 2481
2445#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10) 2482#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10)
2446#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20) 2483#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20)
@@ -2473,7 +2510,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
2473 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ 2510 CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
2474 U8 PhysicalPort; /* 08h */ 2511 U8 PhysicalPort; /* 08h */
2475 U8 Reserved1; /* 09h */ 2512 U8 Reserved1; /* 09h */
2476 U16 Reserved2; /* 0Ah */ 2513 U16 EnclosureHandle; /* 0Ah */
2477 U64 SASAddress; /* 0Ch */ 2514 U64 SASAddress; /* 0Ch */
2478 U32 DiscoveryStatus; /* 14h */ 2515 U32 DiscoveryStatus; /* 14h */
2479 U16 DevHandle; /* 18h */ 2516 U16 DevHandle; /* 18h */
@@ -2487,7 +2524,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
2487} CONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0, 2524} CONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
2488 SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t; 2525 SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
2489 2526
2490#define MPI_SASEXPANDER0_PAGEVERSION (0x02) 2527#define MPI_SASEXPANDER0_PAGEVERSION (0x03)
2491 2528
2492/* values for SAS Expander Page 0 DiscoveryStatus field */ 2529/* values for SAS Expander Page 0 DiscoveryStatus field */
2493#define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) 2530#define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001)
@@ -2527,9 +2564,9 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_1
2527 U8 NegotiatedLinkRate; /* 1Fh */ 2564 U8 NegotiatedLinkRate; /* 1Fh */
2528 U8 PhyIdentifier; /* 20h */ 2565 U8 PhyIdentifier; /* 20h */
2529 U8 AttachedPhyIdentifier; /* 21h */ 2566 U8 AttachedPhyIdentifier; /* 21h */
2530 U8 NumTableEntriesProg; /* 22h */ 2567 U8 Reserved3; /* 22h */
2531 U8 DiscoveryInfo; /* 23h */ 2568 U8 DiscoveryInfo; /* 23h */
2532 U32 Reserved3; /* 24h */ 2569 U32 Reserved4; /* 24h */
2533} CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1, 2570} CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1,
2534 SasExpanderPage1_t, MPI_POINTER pSasExpanderPage1_t; 2571 SasExpanderPage1_t, MPI_POINTER pSasExpanderPage1_t;
2535 2572
@@ -2766,16 +2803,15 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
2766#define MPI_LOG_0_NUM_LOG_ENTRIES (1) 2803#define MPI_LOG_0_NUM_LOG_ENTRIES (1)
2767#endif 2804#endif
2768 2805
2769#define MPI_LOG_0_LOG_DATA_LENGTH (20) 2806#define MPI_LOG_0_LOG_DATA_LENGTH (0x1C)
2770 2807
2771typedef struct _MPI_LOG_0_ENTRY 2808typedef struct _MPI_LOG_0_ENTRY
2772{ 2809{
2773 U64 WWID; /* 00h */ 2810 U32 TimeStamp; /* 00h */
2774 U32 TimeStamp; /* 08h */ 2811 U32 Reserved1; /* 04h */
2775 U32 Reserved1; /* 0Ch */ 2812 U16 LogSequence; /* 08h */
2776 U16 LogSequence; /* 10h */ 2813 U16 LogEntryQualifier; /* 0Ah */
2777 U16 LogEntryQualifier; /* 12h */ 2814 U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 0Ch */
2778 U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 14h */
2779} MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY, 2815} MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY,
2780 MpiLog0Entry_t, MPI_POINTER pMpiLog0Entry_t; 2816 MpiLog0Entry_t, MPI_POINTER pMpiLog0Entry_t;
2781 2817
@@ -2794,7 +2830,7 @@ typedef struct _CONFIG_PAGE_LOG_0
2794} CONFIG_PAGE_LOG_0, MPI_POINTER PTR_CONFIG_PAGE_LOG_0, 2830} CONFIG_PAGE_LOG_0, MPI_POINTER PTR_CONFIG_PAGE_LOG_0,
2795 LogPage0_t, MPI_POINTER pLogPage0_t; 2831 LogPage0_t, MPI_POINTER pLogPage0_t;
2796 2832
2797#define MPI_LOG_0_PAGEVERSION (0x00) 2833#define MPI_LOG_0_PAGEVERSION (0x01)
2798 2834
2799 2835
2800#endif 2836#endif
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index 1a30ef16adb4..4a5f8dd1d766 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -6,25 +6,25 @@
6 Copyright (c) 2000-2005 LSI Logic Corporation. 6 Copyright (c) 2000-2005 LSI Logic Corporation.
7 7
8 --------------------------------------- 8 ---------------------------------------
9 Header Set Release Version: 01.05.10 9 Header Set Release Version: 01.05.12
10 Header Set Release Date: 03-11-05 10 Header Set Release Date: 08-30-05
11 --------------------------------------- 11 ---------------------------------------
12 12
13 Filename Current version Prior version 13 Filename Current version Prior version
14 ---------- --------------- ------------- 14 ---------- --------------- -------------
15 mpi.h 01.05.08 01.05.07 15 mpi.h 01.05.10 01.05.09
16 mpi_ioc.h 01.05.09 01.05.08 16 mpi_ioc.h 01.05.10 01.05.09
17 mpi_cnfg.h 01.05.09 01.05.08 17 mpi_cnfg.h 01.05.11 01.05.10
18 mpi_init.h 01.05.05 01.05.04 18 mpi_init.h 01.05.06 01.05.06
19 mpi_targ.h 01.05.05 01.05.04 19 mpi_targ.h 01.05.05 01.05.05
20 mpi_fc.h 01.05.01 01.05.01 20 mpi_fc.h 01.05.01 01.05.01
21 mpi_lan.h 01.05.01 01.05.01 21 mpi_lan.h 01.05.01 01.05.01
22 mpi_raid.h 01.05.02 01.05.02 22 mpi_raid.h 01.05.02 01.05.02
23 mpi_tool.h 01.05.03 01.05.03 23 mpi_tool.h 01.05.03 01.05.03
24 mpi_inb.h 01.05.01 01.05.01 24 mpi_inb.h 01.05.01 01.05.01
25 mpi_sas.h 01.05.01 01.05.01 25 mpi_sas.h 01.05.02 01.05.01
26 mpi_type.h 01.05.01 01.05.01 26 mpi_type.h 01.05.02 01.05.01
27 mpi_history.txt 01.05.09 01.05.09 27 mpi_history.txt 01.05.12 01.05.11
28 28
29 29
30 * Date Version Description 30 * Date Version Description
@@ -91,6 +91,8 @@ mpi.h
91 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and 91 * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
92 * TargetAssistExtended requests. 92 * TargetAssistExtended requests.
93 * Added EEDP IOCStatus codes. 93 * Added EEDP IOCStatus codes.
94 * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
95 * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
94 * -------------------------------------------------------------------------- 96 * --------------------------------------------------------------------------
95 97
96mpi_ioc.h 98mpi_ioc.h
@@ -164,6 +166,10 @@ mpi_ioc.h
164 * Removed IOCFacts Reply EEDP Capability bit. 166 * Removed IOCFacts Reply EEDP Capability bit.
165 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. 167 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
166 * Added Max SATA Targets to SAS Discovery Error event. 168 * Added Max SATA Targets to SAS Discovery Error event.
169 * 08-30-05 01.05.10 Added 4 new events and their event data structures.
170 * Added new ReasonCode value for SAS Device Status Change
171 * event.
172 * Added new family code for FC949E.
167 * -------------------------------------------------------------------------- 173 * --------------------------------------------------------------------------
168 174
169mpi_cnfg.h 175mpi_cnfg.h
@@ -402,6 +408,23 @@ mpi_cnfg.h
402 * Added OwnerDevHandle and Flags field to SAS PHY Page 0. 408 * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
403 * Added IOC GPIO Flags define to SAS Enclosure Page 0. 409 * Added IOC GPIO Flags define to SAS Enclosure Page 0.
404 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. 410 * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
411 * 08-03-05 01.05.10 Removed ISDataScrubRate and ISResyncRate from
412 * Manufacturing Page 4.
413 * Added MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE bit.
414 * Added NumDevsPerEnclosure field to SAS IO Unit page 2.
415 * Added MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP
416 * define.
417 * Added EnclosureHandle field to SAS Expander page 0.
418 * Removed redundant NumTableEntriesProg field from SAS
419 * Expander Page 1.
420 * 08-30-05 01.05.11 Added DeviceID for FC949E and changed the DeviceID for
421 * SAS1078.
422 * Added more defines for Manufacturing Page 4 Flags field.
423 * Added more defines for IOCSettings and added
424 * ExpanderSpinup field to Bios Page 1.
425 * Added postpone SATA Init bit to SAS IO Unit Page 1
426 * ControlFlags.
427 * Changed LogEntry format for Log Page 0.
405 * -------------------------------------------------------------------------- 428 * --------------------------------------------------------------------------
406 429
407mpi_init.h 430mpi_init.h
@@ -442,6 +465,8 @@ mpi_init.h
442 * addressing. 465 * addressing.
443 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. 466 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
444 * Added four new defines for SEP SlotStatus. 467 * Added four new defines for SEP SlotStatus.
468 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
469 * unique in the first 32 characters.
445 * -------------------------------------------------------------------------- 470 * --------------------------------------------------------------------------
446 471
447mpi_targ.h 472mpi_targ.h
@@ -582,6 +607,9 @@ mpi_inb.h
582 607
583mpi_sas.h 608mpi_sas.h
584 * 08-19-04 01.05.01 Original release. 609 * 08-19-04 01.05.01 Original release.
610 * 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
611 * Added PrimFlags and Primitive field to SAS IO Unit
612 * Control request, and added a new operation code.
585 * -------------------------------------------------------------------------- 613 * --------------------------------------------------------------------------
586 614
587mpi_type.h 615mpi_type.h
@@ -592,24 +620,25 @@ mpi_type.h
592 * 08-08-01 01.02.01 Original release for v1.2 work. 620 * 08-08-01 01.02.01 Original release for v1.2 work.
593 * 05-11-04 01.03.01 Original release for MPI v1.3. 621 * 05-11-04 01.03.01 Original release for MPI v1.3.
594 * 08-19-04 01.05.01 Original release for MPI v1.5. 622 * 08-19-04 01.05.01 Original release for MPI v1.5.
623 * 08-30-05 01.05.02 Added PowerPC option to #ifdef's.
595 * -------------------------------------------------------------------------- 624 * --------------------------------------------------------------------------
596 625
597mpi_history.txt Parts list history 626mpi_history.txt Parts list history
598 627
599Filename 01.05.10 01.05.09 628Filename 01.05.12 01.05.11 01.05.10 01.05.09
600---------- -------- -------- 629---------- -------- -------- -------- --------
601mpi.h 01.05.08 01.05.07 630mpi.h 01.05.10 01.05.09 01.05.08 01.05.07
602mpi_ioc.h 01.05.09 01.05.08 631mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08
603mpi_cnfg.h 01.05.09 01.05.08 632mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08
604mpi_init.h 01.05.05 01.05.04 633mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04
605mpi_targ.h 01.05.05 01.05.04 634mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04
606mpi_fc.h 01.05.01 01.05.01 635mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01
607mpi_lan.h 01.05.01 01.05.01 636mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01
608mpi_raid.h 01.05.02 01.05.02 637mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02
609mpi_tool.h 01.05.03 01.05.03 638mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03
610mpi_inb.h 01.05.01 01.05.01 639mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01
611mpi_sas.h 01.05.01 01.05.01 640mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01
612mpi_type.h 01.05.01 01.05.01 641mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01
613 642
614Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 643Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
615---------- -------- -------- -------- -------- -------- -------- 644---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index d5af75afbd94..68941f459ca3 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -6,7 +6,7 @@
6 * Title: MPI initiator mode messages and structures 6 * Title: MPI initiator mode messages and structures
7 * Creation Date: June 8, 2000 7 * Creation Date: June 8, 2000
8 * 8 *
9 * mpi_init.h Version: 01.05.05 9 * mpi_init.h Version: 01.05.06
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -50,6 +50,8 @@
50 * addressing. 50 * addressing.
51 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. 51 * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
52 * Added four new defines for SEP SlotStatus. 52 * Added four new defines for SEP SlotStatus.
53 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
54 * unique in the first 32 characters.
53 * -------------------------------------------------------------------------- 55 * --------------------------------------------------------------------------
54 */ 56 */
55 57
@@ -290,8 +292,8 @@ typedef struct _MSG_SCSI_IO32_REQUEST
290 292
291/* SCSI IO 32 MsgFlags bits */ 293/* SCSI IO 32 MsgFlags bits */
292#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01) 294#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
293#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00) 295#define MPI_SCSIIO32_MSGFLGS_32_SENSE_WIDTH (0x00)
294#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01) 296#define MPI_SCSIIO32_MSGFLGS_64_SENSE_WIDTH (0x01)
295 297
296#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02) 298#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
297#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00) 299#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 93b70e2b4266..2c5f43fa7c73 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_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: August 11, 2000 7 * Creation Date: August 11, 2000
8 * 8 *
9 * mpi_ioc.h Version: 01.05.09 9 * mpi_ioc.h Version: 01.05.10
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -83,6 +83,10 @@
83 * Removed IOCFacts Reply EEDP Capability bit. 83 * Removed IOCFacts Reply EEDP Capability bit.
84 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. 84 * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
85 * Added Max SATA Targets to SAS Discovery Error event. 85 * Added Max SATA Targets to SAS Discovery Error event.
86 * 08-30-05 01.05.10 Added 4 new events and their event data structures.
87 * Added new ReasonCode value for SAS Device Status Change
88 * event.
89 * Added new family code for FC949E.
86 * -------------------------------------------------------------------------- 90 * --------------------------------------------------------------------------
87 */ 91 */
88 92
@@ -464,6 +468,10 @@ typedef struct _MSG_EVENT_ACK_REPLY
464#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) 468#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
465#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) 469#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
466#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) 470#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
471#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
472#define MPI_EVENT_IR2 (0x00000015)
473#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
474#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
467 475
468/* AckRequired field values */ 476/* AckRequired field values */
469 477
@@ -480,6 +488,29 @@ typedef struct _EVENT_DATA_EVENT_CHANGE
480} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE, 488} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
481 EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t; 489 EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;
482 490
491/* LogEntryAdded Event data */
492
493/* this structure matches MPI_LOG_0_ENTRY in mpi_cnfg.h */
494#define MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH (0x1C)
495typedef struct _EVENT_DATA_LOG_ENTRY
496{
497 U32 TimeStamp; /* 00h */
498 U32 Reserved1; /* 04h */
499 U16 LogSequence; /* 08h */
500 U16 LogEntryQualifier; /* 0Ah */
501 U8 LogData[MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH]; /* 0Ch */
502} EVENT_DATA_LOG_ENTRY, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY,
503 MpiEventDataLogEntry_t, MPI_POINTER pMpiEventDataLogEntry_t;
504
505typedef struct _EVENT_DATA_LOG_ENTRY_ADDED
506{
507 U16 LogSequence; /* 00h */
508 U16 Reserved1; /* 02h */
509 U32 Reserved2; /* 04h */
510 EVENT_DATA_LOG_ENTRY LogEntry; /* 08h */
511} EVENT_DATA_LOG_ENTRY_ADDED, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY_ADDED,
512 MpiEventDataLogEntryAdded_t, MPI_POINTER pMpiEventDataLogEntryAdded_t;
513
483/* SCSI Event data for Port, Bus and Device forms */ 514/* SCSI Event data for Port, Bus and Device forms */
484 515
485typedef struct _EVENT_DATA_SCSI 516typedef struct _EVENT_DATA_SCSI
@@ -538,6 +569,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
538#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) 569#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
539#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) 570#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
540#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) 571#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
572#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
541 573
542 574
543/* SCSI Event data for Queue Full event */ 575/* SCSI Event data for Queue Full event */
@@ -579,6 +611,79 @@ typedef struct _EVENT_DATA_RAID
579#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A) 611#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
580#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B) 612#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)
581 613
614
615/* MPI Integrated RAID Resync Update Event data */
616
617typedef struct _MPI_EVENT_DATA_IR_RESYNC_UPDATE
618{
619 U8 VolumeID; /* 00h */
620 U8 VolumeBus; /* 01h */
621 U8 ResyncComplete; /* 02h */
622 U8 Reserved1; /* 03h */
623 U32 Reserved2; /* 04h */
624} MPI_EVENT_DATA_IR_RESYNC_UPDATE,
625 MPI_POINTER PTR_MPI_EVENT_DATA_IR_RESYNC_UPDATE,
626 MpiEventDataIrResyncUpdate_t, MPI_POINTER pMpiEventDataIrResyncUpdate_t;
627
628/* MPI IR2 Event data */
629
630/* MPI_LD_STATE or MPI_PD_STATE */
631typedef struct _IR2_STATE_CHANGED
632{
633 U16 PreviousState; /* 00h */
634 U16 NewState; /* 02h */
635} IR2_STATE_CHANGED, MPI_POINTER PTR_IR2_STATE_CHANGED;
636
637typedef struct _IR2_PD_INFO
638{
639 U16 DeviceHandle; /* 00h */
640 U8 TruncEnclosureHandle; /* 02h */
641 U8 TruncatedSlot; /* 03h */
642} IR2_PD_INFO, MPI_POINTER PTR_IR2_PD_INFO;
643
644typedef union _MPI_IR2_RC_EVENT_DATA
645{
646 IR2_STATE_CHANGED StateChanged;
647 U32 Lba;
648 IR2_PD_INFO PdInfo;
649} MPI_IR2_RC_EVENT_DATA, MPI_POINTER PTR_MPI_IR2_RC_EVENT_DATA;
650
651typedef struct _MPI_EVENT_DATA_IR2
652{
653 U8 TargetID; /* 00h */
654 U8 Bus; /* 01h */
655 U8 ReasonCode; /* 02h */
656 U8 PhysDiskNum; /* 03h */
657 MPI_IR2_RC_EVENT_DATA IR2EventData; /* 04h */
658} MPI_EVENT_DATA_IR2, MPI_POINTER PTR_MPI_EVENT_DATA_IR2,
659 MpiEventDataIR2_t, MPI_POINTER pMpiEventDataIR2_t;
660
661/* MPI IR2 Event data ReasonCode values */
662#define MPI_EVENT_IR2_RC_LD_STATE_CHANGED (0x01)
663#define MPI_EVENT_IR2_RC_PD_STATE_CHANGED (0x02)
664#define MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL (0x03)
665#define MPI_EVENT_IR2_RC_PD_INSERTED (0x04)
666#define MPI_EVENT_IR2_RC_PD_REMOVED (0x05)
667#define MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED (0x06)
668#define MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR (0x07)
669
670/* defines for logical disk states */
671#define MPI_LD_STATE_OPTIMAL (0x00)
672#define MPI_LD_STATE_DEGRADED (0x01)
673#define MPI_LD_STATE_FAILED (0x02)
674#define MPI_LD_STATE_MISSING (0x03)
675#define MPI_LD_STATE_OFFLINE (0x04)
676
677/* defines for physical disk states */
678#define MPI_PD_STATE_ONLINE (0x00)
679#define MPI_PD_STATE_MISSING (0x01)
680#define MPI_PD_STATE_NOT_COMPATIBLE (0x02)
681#define MPI_PD_STATE_FAILED (0x03)
682#define MPI_PD_STATE_INITIALIZING (0x04)
683#define MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST (0x05)
684#define MPI_PD_STATE_FAILED_AT_HOST_REQUEST (0x06)
685#define MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON (0xFF)
686
582/* MPI Link Status Change Event data */ 687/* MPI Link Status Change Event data */
583 688
584typedef struct _EVENT_DATA_LINK_STATUS 689typedef struct _EVENT_DATA_LINK_STATUS
@@ -660,6 +765,20 @@ typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
660#define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08) 765#define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08)
661#define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09) 766#define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09)
662 767
768/* SAS Discovery Event data */
769
770typedef struct _EVENT_DATA_SAS_DISCOVERY
771{
772 U32 DiscoveryStatus; /* 00h */
773 U32 Reserved1; /* 04h */
774} EVENT_DATA_SAS_DISCOVERY, MPI_POINTER PTR_EVENT_DATA_SAS_DISCOVERY,
775 EventDataSasDiscovery_t, MPI_POINTER pEventDataSasDiscovery_t;
776
777#define MPI_EVENT_SAS_DSCVRY_COMPLETE (0x00000000)
778#define MPI_EVENT_SAS_DSCVRY_IN_PROGRESS (0x00000001)
779#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_MASK (0xFFFF0000)
780#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_SHIFT (16)
781
663/* SAS Discovery Errror Event data */ 782/* SAS Discovery Errror Event data */
664 783
665typedef struct _EVENT_DATA_DISCOVERY_ERROR 784typedef struct _EVENT_DATA_DISCOVERY_ERROR
@@ -869,6 +988,7 @@ typedef struct _MPI_FW_HEADER
869#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */ 988#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */
870#define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */ 989#define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */
871#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005) 990#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)
991#define MPI_FW_HEADER_PID_FAMILY_949E_FC (0x0006)
872/* SAS */ 992/* SAS */
873#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001) 993#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)
874#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002) 994#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002)
diff --git a/drivers/message/fusion/lsi/mpi_log_fc.h b/drivers/message/fusion/lsi/mpi_log_fc.h
new file mode 100644
index 000000000000..dc98d46f9071
--- /dev/null
+++ b/drivers/message/fusion/lsi/mpi_log_fc.h
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved.
3 *
4 * NAME: fc_log.h
5 * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips
6 * DESCRIPTION: Contains the enumerated list of values that may be returned
7 * in the IOCLogInfo field of a MPI Default Reply Message.
8 *
9 * CREATION DATE: 6/02/2000
10 * ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
11 */
12
13
14/*
15 * MpiIocLogInfo_t enum
16 *
17 * These 32 bit values are used in the IOCLogInfo field of the MPI reply
18 * messages.
19 * The value is 0xabcccccc where
20 * a = The type of log info as per the MPI spec. Since these codes are
21 * all for Fibre Channel this value will always be 2.
22 * b = Specifies a subclass of the firmware where
23 * 0 = FCP Initiator
24 * 1 = FCP Target
25 * 2 = LAN
26 * 3 = MPI Message Layer
27 * 4 = FC Link
28 * 5 = Context Manager
29 * 6 = Invalid Field Offset
30 * 7 = State Change Info
31 * all others are reserved for future use
32 * c = A specific value within the subclass.
33 *
34 * NOTE: Any new values should be added to the end of each subclass so that the
35 * codes remain consistent across firmware releases.
36 */
37typedef enum _MpiIocLogInfoFc
38{
39 MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,
40 MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
41 MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
42 MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
43 MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */
44 MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */
45 MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */
46 MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */
47 MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */
48 MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */
49 MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */
50 MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */
51
52 MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,
53 MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
54 MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */
55 MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */
56 MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */
57 MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */
58 MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */
59 MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */
60 MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */
61 MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */
62 MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */
63 MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */
64 MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */
65 MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */
66 MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */
67
68 MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,
69 MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */
70 MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */
71 MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */
72 MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */
73
74 MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000,
75
76 MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000,
77 MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */
78 MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */
79 MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
80 MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */
81
82 MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,
83
84 MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
85 MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,
86
87 MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */
88
89} MpiIocLogInfoFc_t;
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
new file mode 100644
index 000000000000..9259d1ad6e6e
--- /dev/null
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -0,0 +1,162 @@
1
2/***************************************************************************
3 * *
4 * Copyright 2003 LSI Logic Corporation. All rights reserved. *
5 * *
6 * This file is confidential and a trade secret of LSI Logic. The *
7 * receipt of or possession of this file does not convey any rights to *
8 * reproduce or disclose its contents or to manufacture, use, or sell *
9 * anything it may describe, in whole, or in part, without the specific *
10 * written consent of LSI Logic Corporation. *
11 * *
12 ***************************************************************************
13 *
14 * Name: iopiIocLogInfo.h
15 * Title: SAS Firmware IOP Interface IOC Log Info Definitions
16 * Programmer: Guy Kendall
17 * Creation Date: September 24, 2003
18 *
19 * Version History
20 * ---------------
21 *
22 * Last Updated
23 * -------------
24 * Version %version: 22 %
25 * Date Updated %date_modified: %
26 * Programmer %created_by: nperucca %
27 *
28 * Date Who Description
29 * -------- --- -------------------------------------------------------
30 * 09/24/03 GWK Initial version
31 *
32 *
33 * Description
34 * ------------
35 * This include file contains SAS firmware interface IOC Log Info codes
36 *
37 *-------------------------------------------------------------------------
38 */
39
40#ifndef IOPI_IOCLOGINFO_H_INCLUDED
41#define IOPI_IOCLOGINFO_H_INCLUDED
42
43
44/****************************************************************************/
45/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
46/* Format: */
47/* Bits 31-28: MPI_IOCLOGINFO_TYPE_SAS (3) */
48/* Bits 27-24: IOC_LOGINFO_ORIGINATOR: 0=IOP, 1=PL, 2=IR */
49/* Bits 23-16: LOGINFO_CODE */
50/* Bits 15-0: LOGINFO_CODE Specific */
51/****************************************************************************/
52
53/****************************************************************************/
54/* IOC_LOGINFO_ORIGINATOR defines */
55/****************************************************************************/
56#define IOC_LOGINFO_ORIGINATOR_IOP (0x00000000)
57#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
58#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
59
60/****************************************************************************/
61/* LOGINFO_CODE defines */
62/****************************************************************************/
63#define IOC_LOGINFO_CODE_MASK (0x00FF0000)
64#define IOC_LOGINFO_CODE_SHIFT (16)
65
66/****************************************************************************/
67/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */
68/****************************************************************************/
69#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)
70#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)
71#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)
72#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */
73#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */
74#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */
75#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */
76#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
77#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
78#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
79#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
80
81
82/****************************************************************************/
83/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
84/****************************************************************************/
85#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
86#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
87#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
88#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
89#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)
90#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)
91#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)
92#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)
93#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)
94#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)
95#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)
96#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)
97#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
98#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
99#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
100#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
101#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
102#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
103#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */
104#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */
105#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
106#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
107#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
108#define PL_LOGINFO_CODE_RESET (0x00110000)
109#define PL_LOGINFO_CODE_ABORT (0x00120000)
110#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
111#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
112#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
113#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
114#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
115#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
116#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
117#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
118#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)
119#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
120#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
121#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)
122#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)
123#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
124#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
125#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
126#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
127
128
129#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
130#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */
131#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */
132#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */
133#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */
134#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */
135#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */
136
137#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
138#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
139#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
140#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
141#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */
142#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */
143#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */
144#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */
145#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/
146
147
148/****************************************************************************/
149/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */
150/****************************************************************************/
151#define IR_LOGINFO_CODE_UNUSED1 (0x00010000)
152#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
153
154/****************************************************************************/
155/* Defines for convienence */
156/****************************************************************************/
157#define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)
158#define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)
159#define IOC_LOGINFO_PREFIX_IR ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IR)
160
161#endif /* end of file */
162
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index 230fa69b5353..70514867bddf 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_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: August 19, 2004 7 * Creation Date: August 19, 2004
8 * 8 *
9 * mpi_sas.h Version: 01.05.01 9 * mpi_sas.h Version: 01.05.02
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -14,6 +14,9 @@
14 * Date Version Description 14 * Date Version Description
15 * -------- -------- ------------------------------------------------------ 15 * -------- -------- ------------------------------------------------------
16 * 08-19-04 01.05.01 Original release. 16 * 08-19-04 01.05.01 Original release.
17 * 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
18 * Added PrimFlags and Primitive field to SAS IO Unit
19 * Control request, and added a new operation code.
17 * -------------------------------------------------------------------------- 20 * --------------------------------------------------------------------------
18 */ 21 */
19 22
@@ -51,6 +54,7 @@
51 * Values for the SAS DeviceInfo field used in SAS Device Status Change Event 54 * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
52 * data and SAS IO Unit Configuration pages. 55 * data and SAS IO Unit Configuration pages.
53 */ 56 */
57#define MPI_SAS_DEVICE_INFO_SEP (0x00004000)
54#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) 58#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
55#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) 59#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
56#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) 60#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
@@ -212,20 +216,26 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
212 U8 TargetID; /* 0Ch */ 216 U8 TargetID; /* 0Ch */
213 U8 Bus; /* 0Dh */ 217 U8 Bus; /* 0Dh */
214 U8 PhyNum; /* 0Eh */ 218 U8 PhyNum; /* 0Eh */
215 U8 Reserved4; /* 0Fh */ 219 U8 PrimFlags; /* 0Fh */
216 U32 Reserved5; /* 10h */ 220 U32 Primitive; /* 10h */
217 U64 SASAddress; /* 14h */ 221 U64 SASAddress; /* 14h */
218 U32 Reserved6; /* 1Ch */ 222 U32 Reserved4; /* 1Ch */
219} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST, 223} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
220 SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t; 224 SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
221 225
222/* values for the Operation field */ 226/* values for the Operation field */
223#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01) 227#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
224#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02) 228#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
225#define MPI_SAS_OP_PHY_LINK_RESET (0x06) 229#define MPI_SAS_OP_PHY_LINK_RESET (0x06)
226#define MPI_SAS_OP_PHY_HARD_RESET (0x07) 230#define MPI_SAS_OP_PHY_HARD_RESET (0x07)
227#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) 231#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
228#define MPI_SAS_OP_MAP_CURRENT (0x09) 232#define MPI_SAS_OP_MAP_CURRENT (0x09)
233#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
234
235/* values for the PrimFlags field */
236#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
237#define MPI_SAS_PRIMFLAGS_TRIPLE (0x02)
238#define MPI_SAS_PRIMFLAGS_REDUNDANT (0x01)
229 239
230 240
231/* SAS IO Unit Control Reply */ 241/* SAS IO Unit Control Reply */
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 537836068c49..d890b2b8a93e 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -148,7 +148,6 @@ static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
148static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 148static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 149static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150static int GetLanConfigPages(MPT_ADAPTER *ioc); 150static int GetLanConfigPages(MPT_ADAPTER *ioc);
151static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
152static int GetIoUnitPage2(MPT_ADAPTER *ioc); 151static int GetIoUnitPage2(MPT_ADAPTER *ioc);
153int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 152int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
154static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 153static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
@@ -1232,12 +1231,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1232 dprintk((KERN_INFO MYNAM 1231 dprintk((KERN_INFO MYNAM
1233 ": Not using 64 bit consistent mask\n")); 1232 ": Not using 64 bit consistent mask\n"));
1234 1233
1235 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); 1234 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1236 if (ioc == NULL) { 1235 if (ioc == NULL) {
1237 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); 1236 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1238 return -ENOMEM; 1237 return -ENOMEM;
1239 } 1238 }
1240 memset(ioc, 0, sizeof(MPT_ADAPTER));
1241 ioc->alloc_total = sizeof(MPT_ADAPTER); 1239 ioc->alloc_total = sizeof(MPT_ADAPTER);
1242 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1240 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1243 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1241 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
@@ -1245,6 +1243,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1245 ioc->pcidev = pdev; 1243 ioc->pcidev = pdev;
1246 ioc->diagPending = 0; 1244 ioc->diagPending = 0;
1247 spin_lock_init(&ioc->diagLock); 1245 spin_lock_init(&ioc->diagLock);
1246 spin_lock_init(&ioc->fc_rescan_work_lock);
1247 spin_lock_init(&ioc->fc_rport_lock);
1248 spin_lock_init(&ioc->initializing_hba_lock); 1248 spin_lock_init(&ioc->initializing_hba_lock);
1249 1249
1250 /* Initialize the event logging. 1250 /* Initialize the event logging.
@@ -1268,6 +1268,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1268 */ 1268 */
1269 INIT_LIST_HEAD(&ioc->configQ); 1269 INIT_LIST_HEAD(&ioc->configQ);
1270 1270
1271 /* Initialize the fc rport list head.
1272 */
1273 INIT_LIST_HEAD(&ioc->fc_rports);
1274
1271 /* Find lookup slot. */ 1275 /* Find lookup slot. */
1272 INIT_LIST_HEAD(&ioc->list); 1276 INIT_LIST_HEAD(&ioc->list);
1273 ioc->id = mpt_ids++; 1277 ioc->id = mpt_ids++;
@@ -1374,6 +1378,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1374 ioc->bus_type = FC; 1378 ioc->bus_type = FC;
1375 ioc->errata_flag_1064 = 1; 1379 ioc->errata_flag_1064 = 1;
1376 } 1380 }
1381 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1382 ioc->prod_name = "LSIFC949E";
1383 ioc->bus_type = FC;
1384 }
1377 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { 1385 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1378 ioc->prod_name = "LSI53C1030"; 1386 ioc->prod_name = "LSI53C1030";
1379 ioc->bus_type = SPI; 1387 ioc->bus_type = SPI;
@@ -1622,7 +1630,7 @@ mpt_resume(struct pci_dev *pdev)
1622 pci_enable_device(pdev); 1630 pci_enable_device(pdev);
1623 1631
1624 /* enable interrupts */ 1632 /* enable interrupts */
1625 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); 1633 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1626 ioc->active = 1; 1634 ioc->active = 1;
1627 1635
1628 /* F/W not running */ 1636 /* F/W not running */
@@ -1715,7 +1723,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1715 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ 1723 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1716 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", 1724 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1717 ioc->alt_ioc->name)); 1725 ioc->alt_ioc->name));
1718 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); 1726 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1719 ioc->alt_ioc->active = 1; 1727 ioc->alt_ioc->active = 1;
1720 } 1728 }
1721 1729
@@ -1831,7 +1839,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1831 1839
1832 if (ret == 0) { 1840 if (ret == 0) {
1833 /* Enable! (reply interrupt) */ 1841 /* Enable! (reply interrupt) */
1834 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); 1842 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1835 ioc->active = 1; 1843 ioc->active = 1;
1836 } 1844 }
1837 1845
@@ -1839,7 +1847,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1839 /* (re)Enable alt-IOC! (reply interrupt) */ 1847 /* (re)Enable alt-IOC! (reply interrupt) */
1840 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", 1848 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1841 ioc->alt_ioc->name)); 1849 ioc->alt_ioc->name));
1842 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); 1850 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1843 ioc->alt_ioc->active = 1; 1851 ioc->alt_ioc->active = 1;
1844 } 1852 }
1845 1853
@@ -1880,7 +1888,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1880 * (FCPortPage0_t stuff) 1888 * (FCPortPage0_t stuff)
1881 */ 1889 */
1882 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 1890 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1883 (void) GetFcPortPage0(ioc, ii); 1891 (void) mptbase_GetFcPortPage0(ioc, ii);
1884 } 1892 }
1885 1893
1886 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 1894 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
@@ -4199,7 +4207,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
4199 4207
4200/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4208/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4201/* 4209/*
4202 * GetFcPortPage0 - Fetch FCPort config Page0. 4210 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4203 * @ioc: Pointer to MPT_ADAPTER structure 4211 * @ioc: Pointer to MPT_ADAPTER structure
4204 * @portnum: IOC Port number 4212 * @portnum: IOC Port number
4205 * 4213 *
@@ -4209,8 +4217,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
4209 * -EAGAIN if no msg frames currently available 4217 * -EAGAIN if no msg frames currently available
4210 * -EFAULT for non-successful reply or no reply (timeout) 4218 * -EFAULT for non-successful reply or no reply (timeout)
4211 */ 4219 */
4212static int 4220int
4213GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) 4221mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4214{ 4222{
4215 ConfigPageHeader_t hdr; 4223 ConfigPageHeader_t hdr;
4216 CONFIGPARMS cfg; 4224 CONFIGPARMS cfg;
@@ -4220,6 +4228,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4220 int data_sz; 4228 int data_sz;
4221 int copy_sz; 4229 int copy_sz;
4222 int rc; 4230 int rc;
4231 int count = 400;
4232
4223 4233
4224 /* Get FCPort Page 0 header */ 4234 /* Get FCPort Page 0 header */
4225 hdr.PageVersion = 0; 4235 hdr.PageVersion = 0;
@@ -4243,6 +4253,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4243 rc = -ENOMEM; 4253 rc = -ENOMEM;
4244 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); 4254 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4245 if (ppage0_alloc) { 4255 if (ppage0_alloc) {
4256
4257 try_again:
4246 memset((u8 *)ppage0_alloc, 0, data_sz); 4258 memset((u8 *)ppage0_alloc, 0, data_sz);
4247 cfg.physAddr = page0_dma; 4259 cfg.physAddr = page0_dma;
4248 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4260 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
@@ -4274,6 +4286,19 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4274 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount); 4286 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4275 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators); 4287 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4276 4288
4289 /*
4290 * if still doing discovery,
4291 * hang loose a while until finished
4292 */
4293 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4294 if (count-- > 0) {
4295 msleep_interruptible(100);
4296 goto try_again;
4297 }
4298 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4299 " complete.\n",
4300 ioc->name);
4301 }
4277 } 4302 }
4278 4303
4279 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); 4304 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
@@ -6358,6 +6383,7 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
6358EXPORT_SYMBOL(mpt_free_fw_memory); 6383EXPORT_SYMBOL(mpt_free_fw_memory);
6359EXPORT_SYMBOL(mptbase_sas_persist_operation); 6384EXPORT_SYMBOL(mptbase_sas_persist_operation);
6360EXPORT_SYMBOL(mpt_alt_ioc_wait); 6385EXPORT_SYMBOL(mpt_alt_ioc_wait);
6386EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6361 6387
6362 6388
6363/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6389/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 6c48d1f54ac9..47053ac65068 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.05" 79#define MPT_LINUX_VERSION_COMMON "3.03.06"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -413,7 +413,7 @@ typedef struct _MPT_IOCTL {
413 u8 status; /* current command status */ 413 u8 status; /* current command status */
414 u8 reset; /* 1 if bus reset allowed */ 414 u8 reset; /* 1 if bus reset allowed */
415 u8 target; /* target for reset */ 415 u8 target; /* target for reset */
416 struct semaphore sem_ioc; 416 struct mutex ioctl_mutex;
417} MPT_IOCTL; 417} MPT_IOCTL;
418 418
419#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */ 419#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
@@ -421,7 +421,7 @@ typedef struct _MPT_IOCTL {
421#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */ 421#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */
422 422
423typedef struct _MPT_SAS_MGMT { 423typedef struct _MPT_SAS_MGMT {
424 struct semaphore mutex; 424 struct mutex mutex;
425 struct completion done; 425 struct completion done;
426 u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */ 426 u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
427 u8 status; /* current command status */ 427 u8 status; /* current command status */
@@ -499,6 +499,22 @@ typedef struct _RaidCfgData {
499 int isRaid; /* bit field, 1 if RAID */ 499 int isRaid; /* bit field, 1 if RAID */
500}RaidCfgData; 500}RaidCfgData;
501 501
502#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
503#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
504#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */
505
506/*
507 * data allocated for each fc rport device
508 */
509struct mptfc_rport_info
510{
511 struct list_head list;
512 struct fc_rport *rport;
513 VirtDevice *vdev;
514 FCDevicePage0_t pg0;
515 u8 flags;
516};
517
502/* 518/*
503 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 519 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
504 */ 520 */
@@ -612,7 +628,16 @@ typedef struct _MPT_ADAPTER
612 struct list_head list; 628 struct list_head list;
613 struct net_device *netdev; 629 struct net_device *netdev;
614 struct list_head sas_topology; 630 struct list_head sas_topology;
631 struct mutex sas_topology_mutex;
615 MPT_SAS_MGMT sas_mgmt; 632 MPT_SAS_MGMT sas_mgmt;
633 int num_ports;
634
635 struct list_head fc_rports;
636 spinlock_t fc_rport_lock; /* list and ri flags */
637 spinlock_t fc_rescan_work_lock;
638 int fc_rescan_work_count;
639 struct work_struct fc_rescan_work;
640
616} MPT_ADAPTER; 641} MPT_ADAPTER;
617 642
618/* 643/*
@@ -999,6 +1024,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
999extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1024extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1000extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 1025extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
1001extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1026extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1027extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
1002extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); 1028extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
1003 1029
1004/* 1030/*
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 7c340240a50e..bdf709987982 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -177,10 +177,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
177 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock)); 177 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
178 178
179 if (nonblock) { 179 if (nonblock) {
180 if (down_trylock(&ioc->ioctl->sem_ioc)) 180 if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))
181 rc = -EAGAIN; 181 rc = -EAGAIN;
182 } else { 182 } else {
183 if (down_interruptible(&ioc->ioctl->sem_ioc)) 183 if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))
184 rc = -ERESTARTSYS; 184 rc = -ERESTARTSYS;
185 } 185 }
186 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc)); 186 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
@@ -557,7 +557,7 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
557 else 557 else
558 ret = -EINVAL; 558 ret = -EINVAL;
559 559
560 up(&iocp->ioctl->sem_ioc); 560 mutex_unlock(&iocp->ioctl->ioctl_mutex);
561 561
562 return ret; 562 return ret;
563} 563}
@@ -2619,7 +2619,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2619 2619
2620 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); 2620 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2621 2621
2622 up(&iocp->ioctl->sem_ioc); 2622 mutex_unlock(&iocp->ioctl->ioctl_mutex);
2623 2623
2624 return ret; 2624 return ret;
2625} 2625}
@@ -2673,7 +2673,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
2673 */ 2673 */
2674 ret = mptctl_do_mpt_command (karg, &uarg->MF); 2674 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2675 2675
2676 up(&iocp->ioctl->sem_ioc); 2676 mutex_unlock(&iocp->ioctl->ioctl_mutex);
2677 2677
2678 return ret; 2678 return ret;
2679} 2679}
@@ -2743,7 +2743,7 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2743 memset(mem, 0, sz); 2743 memset(mem, 0, sz);
2744 ioc->ioctl = (MPT_IOCTL *) mem; 2744 ioc->ioctl = (MPT_IOCTL *) mem;
2745 ioc->ioctl->ioc = ioc; 2745 ioc->ioctl->ioc = ioc;
2746 sema_init(&ioc->ioctl->sem_ioc, 1); 2746 mutex_init(&ioc->ioctl->ioctl_mutex);
2747 return 0; 2747 return 0;
2748 2748
2749out_fail: 2749out_fail:
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index ba61e1828858..b102c7666d0e 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -55,12 +55,14 @@
55#include <linux/reboot.h> /* notifier code */ 55#include <linux/reboot.h> /* notifier code */
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/workqueue.h> 57#include <linux/workqueue.h>
58#include <linux/sort.h>
58 59
59#include <scsi/scsi.h> 60#include <scsi/scsi.h>
60#include <scsi/scsi_cmnd.h> 61#include <scsi/scsi_cmnd.h>
61#include <scsi/scsi_device.h> 62#include <scsi/scsi_device.h>
62#include <scsi/scsi_host.h> 63#include <scsi/scsi_host.h>
63#include <scsi/scsi_tcq.h> 64#include <scsi/scsi_tcq.h>
65#include <scsi/scsi_transport_fc.h>
64 66
65#include "mptbase.h" 67#include "mptbase.h"
66#include "mptscsih.h" 68#include "mptscsih.h"
@@ -79,19 +81,34 @@ static int mpt_pq_filter = 0;
79module_param(mpt_pq_filter, int, 0); 81module_param(mpt_pq_filter, int, 0);
80MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); 82MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
81 83
84#define MPTFC_DEV_LOSS_TMO (60)
85static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
86module_param(mptfc_dev_loss_tmo, int, 0);
87MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
88 " transport to wait for an rport to "
89 " return following a device loss event."
90 " Default=60.");
91
82static int mptfcDoneCtx = -1; 92static int mptfcDoneCtx = -1;
83static int mptfcTaskCtx = -1; 93static int mptfcTaskCtx = -1;
84static int mptfcInternalCtx = -1; /* Used only for internal commands */ 94static int mptfcInternalCtx = -1; /* Used only for internal commands */
85 95
96int mptfc_slave_alloc(struct scsi_device *device);
97static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
98 void (*done)(struct scsi_cmnd *));
99
100static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
101static void __devexit mptfc_remove(struct pci_dev *pdev);
102
86static struct scsi_host_template mptfc_driver_template = { 103static struct scsi_host_template mptfc_driver_template = {
87 .module = THIS_MODULE, 104 .module = THIS_MODULE,
88 .proc_name = "mptfc", 105 .proc_name = "mptfc",
89 .proc_info = mptscsih_proc_info, 106 .proc_info = mptscsih_proc_info,
90 .name = "MPT FC Host", 107 .name = "MPT FC Host",
91 .info = mptscsih_info, 108 .info = mptscsih_info,
92 .queuecommand = mptscsih_qcmd, 109 .queuecommand = mptfc_qcmd,
93 .target_alloc = mptscsih_target_alloc, 110 .target_alloc = mptscsih_target_alloc,
94 .slave_alloc = mptscsih_slave_alloc, 111 .slave_alloc = mptfc_slave_alloc,
95 .slave_configure = mptscsih_slave_configure, 112 .slave_configure = mptscsih_slave_configure,
96 .target_destroy = mptscsih_target_destroy, 113 .target_destroy = mptscsih_target_destroy,
97 .slave_destroy = mptscsih_slave_destroy, 114 .slave_destroy = mptscsih_slave_destroy,
@@ -128,19 +145,478 @@ static struct pci_device_id mptfc_pci_table[] = {
128 PCI_ANY_ID, PCI_ANY_ID }, 145 PCI_ANY_ID, PCI_ANY_ID },
129 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, 146 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
130 PCI_ANY_ID, PCI_ANY_ID }, 147 PCI_ANY_ID, PCI_ANY_ID },
148 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
149 PCI_ANY_ID, PCI_ANY_ID },
131 {0} /* Terminating entry */ 150 {0} /* Terminating entry */
132}; 151};
133MODULE_DEVICE_TABLE(pci, mptfc_pci_table); 152MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
134 153
135/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 154static struct scsi_transport_template *mptfc_transport_template = NULL;
136/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 155
156struct fc_function_template mptfc_transport_functions = {
157 .dd_fcrport_size = 8,
158 .show_host_node_name = 1,
159 .show_host_port_name = 1,
160 .show_host_supported_classes = 1,
161 .show_host_port_id = 1,
162 .show_rport_supported_classes = 1,
163 .show_starget_node_name = 1,
164 .show_starget_port_name = 1,
165 .show_starget_port_id = 1,
166 .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
167 .show_rport_dev_loss_tmo = 1,
168
169};
170
171/* FIXME! values controlling firmware RESCAN event
172 * need to be set low to allow dev_loss_tmo to
173 * work as expected. Currently, firmware doesn't
174 * notify driver of RESCAN event until some number
175 * of seconds elapse. This value can be set via
176 * lsiutil.
177 */
178static void
179mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
180{
181 if (timeout > 0)
182 rport->dev_loss_tmo = timeout;
183 else
184 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
185}
186
187static int
188mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
189{
190 FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
191 FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
192
193 if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
194 if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
195 return 0;
196 if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
197 return -1;
198 return 1;
199 }
200 if ((*aa)->CurrentBus < (*bb)->CurrentBus)
201 return -1;
202 return 1;
203}
204
205static int
206mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
207 void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
208{
209 ConfigPageHeader_t hdr;
210 CONFIGPARMS cfg;
211 FCDevicePage0_t *ppage0_alloc, *fc;
212 dma_addr_t page0_dma;
213 int data_sz;
214 int ii;
215
216 FCDevicePage0_t *p0_array=NULL, *p_p0;
217 FCDevicePage0_t **pp0_array=NULL, **p_pp0;
218
219 int rc = -ENOMEM;
220 U32 port_id = 0xffffff;
221 int num_targ = 0;
222 int max_bus = ioc->facts.MaxBuses;
223 int max_targ = ioc->facts.MaxDevices;
224
225 if (max_bus == 0 || max_targ == 0)
226 goto out;
227
228 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
229 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
230 if (!p0_array)
231 goto out;
232
233 data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
234 p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
235 if (!pp0_array)
236 goto out;
237
238 do {
239 /* Get FC Device Page 0 header */
240 hdr.PageVersion = 0;
241 hdr.PageLength = 0;
242 hdr.PageNumber = 0;
243 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
244 cfg.cfghdr.hdr = &hdr;
245 cfg.physAddr = -1;
246 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
247 cfg.dir = 0;
248 cfg.pageAddr = port_id;
249 cfg.timeout = 0;
250
251 if ((rc = mpt_config(ioc, &cfg)) != 0)
252 break;
253
254 if (hdr.PageLength <= 0)
255 break;
256
257 data_sz = hdr.PageLength * 4;
258 ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
259 &page0_dma);
260 rc = -ENOMEM;
261 if (!ppage0_alloc)
262 break;
263
264 cfg.physAddr = page0_dma;
265 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
266
267 if ((rc = mpt_config(ioc, &cfg)) == 0) {
268 ppage0_alloc->PortIdentifier =
269 le32_to_cpu(ppage0_alloc->PortIdentifier);
270
271 ppage0_alloc->WWNN.Low =
272 le32_to_cpu(ppage0_alloc->WWNN.Low);
273
274 ppage0_alloc->WWNN.High =
275 le32_to_cpu(ppage0_alloc->WWNN.High);
276
277 ppage0_alloc->WWPN.Low =
278 le32_to_cpu(ppage0_alloc->WWPN.Low);
279
280 ppage0_alloc->WWPN.High =
281 le32_to_cpu(ppage0_alloc->WWPN.High);
282
283 ppage0_alloc->BBCredit =
284 le16_to_cpu(ppage0_alloc->BBCredit);
285
286 ppage0_alloc->MaxRxFrameSize =
287 le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
288
289 port_id = ppage0_alloc->PortIdentifier;
290 num_targ++;
291 *p_p0 = *ppage0_alloc; /* save data */
292 *p_pp0++ = p_p0++; /* save addr */
293 }
294 pci_free_consistent(ioc->pcidev, data_sz,
295 (u8 *) ppage0_alloc, page0_dma);
296 if (rc != 0)
297 break;
298
299 } while (port_id <= 0xff0000);
300
301 if (num_targ) {
302 /* sort array */
303 if (num_targ > 1)
304 sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
305 mptfc_FcDevPage0_cmp_func, NULL);
306 /* call caller's func for each targ */
307 for (ii = 0; ii < num_targ; ii++) {
308 fc = *(pp0_array+ii);
309 func(ioc, ioc_port, fc);
310 }
311 }
312
313 out:
314 if (pp0_array)
315 kfree(pp0_array);
316 if (p0_array)
317 kfree(p0_array);
318 return rc;
319}
320
321static int
322mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
323{
324 /* not currently usable */
325 if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
326 MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
327 return -1;
328
329 if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
330 return -1;
331
332 if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
333 return -1;
334
335 /*
336 * board data structure already normalized to platform endianness
337 * shifted to avoid unaligned access on 64 bit architecture
338 */
339 rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
340 rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
341 rid->port_id = pg0->PortIdentifier;
342 rid->roles = FC_RPORT_ROLE_UNKNOWN;
343 rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
344 if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
345 rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
346
347 return 0;
348}
349
350static void
351mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
352{
353 struct fc_rport_identifiers rport_ids;
354 struct fc_rport *rport;
355 struct mptfc_rport_info *ri;
356 int match = 0;
357 u64 port_name;
358 unsigned long flags;
359
360 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
361 return;
362
363 /* scan list looking for a match */
364 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
365 list_for_each_entry(ri, &ioc->fc_rports, list) {
366 port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
367 if (port_name == rport_ids.port_name) { /* match */
368 list_move_tail(&ri->list, &ioc->fc_rports);
369 match = 1;
370 break;
371 }
372 }
373 if (!match) { /* allocate one */
374 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
375 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
376 if (!ri)
377 return;
378 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
379 list_add_tail(&ri->list, &ioc->fc_rports);
380 }
381
382 ri->pg0 = *pg0; /* add/update pg0 data */
383 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
384
385 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
386 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
387 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
388 rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
389 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
390 if (rport) {
391 if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
392 ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
393 ri->vdev = NULL;
394 ri->rport = rport;
395 *((struct mptfc_rport_info **)rport->dd_data) = ri;
396 }
397 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
398 /*
399 * if already mapped, remap here. If not mapped,
400 * slave_alloc will allocate vdev and map
401 */
402 if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
403 ri->vdev->target_id = ri->pg0.CurrentTargetID;
404 ri->vdev->bus_id = ri->pg0.CurrentBus;
405 ri->vdev->vtarget->target_id = ri->vdev->target_id;
406 ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
407 }
408 #ifdef MPT_DEBUG
409 printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
410 "rport tid %d, tmo %d\n",
411 ioc->sh->host_no,
412 pg0->PortIdentifier,
413 pg0->WWNN,
414 pg0->WWPN,
415 pg0->CurrentTargetID,
416 ri->rport->scsi_target_id,
417 ri->rport->dev_loss_tmo);
418 #endif
419 } else {
420 list_del(&ri->list);
421 kfree(ri);
422 ri = NULL;
423 }
424 }
425 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
426
427}
428
137/* 429/*
138 * mptfc_probe - Installs scsi devices per bus. 430 * OS entry point to allow host driver to alloc memory
139 * @pdev: Pointer to pci_dev structure 431 * for each scsi device. Called once per device the bus scan.
140 * 432 * Return non-zero if allocation fails.
141 * Returns 0 for success, non-zero for failure. 433 * Init memory once per LUN.
142 *
143 */ 434 */
435int
436mptfc_slave_alloc(struct scsi_device *sdev)
437{
438 MPT_SCSI_HOST *hd;
439 VirtTarget *vtarget;
440 VirtDevice *vdev;
441 struct scsi_target *starget;
442 struct fc_rport *rport;
443 struct mptfc_rport_info *ri;
444 unsigned long flags;
445
446
447 rport = starget_to_rport(scsi_target(sdev));
448
449 if (!rport || fc_remote_port_chkready(rport))
450 return -ENXIO;
451
452 hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
453
454 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
455 if (!vdev) {
456 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
457 hd->ioc->name, sizeof(VirtDevice));
458 return -ENOMEM;
459 }
460 memset(vdev, 0, sizeof(VirtDevice));
461
462 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
463
464 if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
465 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
466 kfree(vdev);
467 return -ENODEV;
468 }
469
470 sdev->hostdata = vdev;
471 starget = scsi_target(sdev);
472 vtarget = starget->hostdata;
473 if (vtarget->num_luns == 0) {
474 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
475 MPT_TARGET_FLAGS_VALID_INQUIRY;
476 hd->Targets[sdev->id] = vtarget;
477 }
478
479 vtarget->target_id = vdev->target_id;
480 vtarget->bus_id = vdev->bus_id;
481
482 vdev->vtarget = vtarget;
483 vdev->ioc_id = hd->ioc->id;
484 vdev->lun = sdev->lun;
485 vdev->target_id = ri->pg0.CurrentTargetID;
486 vdev->bus_id = ri->pg0.CurrentBus;
487
488 ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
489 ri->vdev = vdev;
490
491 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
492
493 vtarget->num_luns++;
494
495#ifdef MPT_DEBUG
496 printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
497 "CurrentTargetID %d, %x %llx %llx\n",
498 sdev->host->host_no,
499 vtarget->num_luns,
500 sdev->id, ri->pg0.CurrentTargetID,
501 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);
502#endif
503
504 return 0;
505}
506
507static int
508mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
509{
510 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
511 int err;
512
513 err = fc_remote_port_chkready(rport);
514 if (unlikely(err)) {
515 SCpnt->result = err;
516 done(SCpnt);
517 return 0;
518 }
519 return mptscsih_qcmd(SCpnt,done);
520}
521
522static void
523mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
524{
525 unsigned class = 0, cos = 0;
526
527 /* don't know what to do as only one scsi (fc) host was allocated */
528 if (portnum != 0)
529 return;
530
531 class = ioc->fc_port_page0[portnum].SupportedServiceClass;
532 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
533 cos |= FC_COS_CLASS1;
534 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
535 cos |= FC_COS_CLASS2;
536 if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
537 cos |= FC_COS_CLASS3;
538
539 fc_host_node_name(ioc->sh) =
540 (u64)ioc->fc_port_page0[portnum].WWNN.High << 32
541 | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
542
543 fc_host_port_name(ioc->sh) =
544 (u64)ioc->fc_port_page0[portnum].WWPN.High << 32
545 | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
546
547 fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
548
549 fc_host_supported_classes(ioc->sh) = cos;
550
551 fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
552}
553
554static void
555mptfc_rescan_devices(void *arg)
556{
557 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
558 int ii;
559 int work_to_do;
560 unsigned long flags;
561 struct mptfc_rport_info *ri;
562
563 do {
564 /* start by tagging all ports as missing */
565 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
566 list_for_each_entry(ri, &ioc->fc_rports, list) {
567 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
568 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
569 }
570 }
571 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
572
573 /*
574 * now rescan devices known to adapter,
575 * will reregister existing rports
576 */
577 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
578 (void) mptbase_GetFcPortPage0(ioc, ii);
579 mptfc_init_host_attr(ioc,ii); /* refresh */
580 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
581 }
582
583 /* delete devices still missing */
584 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
585 list_for_each_entry(ri, &ioc->fc_rports, list) {
586 /* if newly missing, delete it */
587 if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
588 MPT_RPORT_INFO_FLAGS_MISSING))
589 == (MPT_RPORT_INFO_FLAGS_REGISTERED |
590 MPT_RPORT_INFO_FLAGS_MISSING)) {
591
592 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
593 MPT_RPORT_INFO_FLAGS_MISSING);
594 fc_remote_port_delete(ri->rport);
595 /*
596 * remote port not really deleted 'cause
597 * binding is by WWPN and driver only
598 * registers FCP_TARGETs
599 */
600 #ifdef MPT_DEBUG
601 printk ("mptfc_rescan.%d: %llx deleted\n",
602 ioc->sh->host_no, ri->pg0.WWPN);
603 #endif
604 }
605 }
606 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
607
608 /*
609 * allow multiple passes as target state
610 * might have changed during scan
611 */
612 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
613 if (ioc->fc_rescan_work_count > 2) /* only need one more */
614 ioc->fc_rescan_work_count = 2;
615 work_to_do = --ioc->fc_rescan_work_count;
616 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
617 } while (work_to_do);
618}
619
144static int 620static int
145mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) 621mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
146{ 622{
@@ -148,17 +624,16 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
148 MPT_SCSI_HOST *hd; 624 MPT_SCSI_HOST *hd;
149 MPT_ADAPTER *ioc; 625 MPT_ADAPTER *ioc;
150 unsigned long flags; 626 unsigned long flags;
151 int sz, ii; 627 int ii;
152 int numSGE = 0; 628 int numSGE = 0;
153 int scale; 629 int scale;
154 int ioc_cap; 630 int ioc_cap;
155 u8 *mem;
156 int error=0; 631 int error=0;
157 int r; 632 int r;
158 633
159 if ((r = mpt_attach(pdev,id)) != 0) 634 if ((r = mpt_attach(pdev,id)) != 0)
160 return r; 635 return r;
161 636
162 ioc = pci_get_drvdata(pdev); 637 ioc = pci_get_drvdata(pdev);
163 ioc->DoneCtx = mptfcDoneCtx; 638 ioc->DoneCtx = mptfcDoneCtx;
164 ioc->TaskCtx = mptfcTaskCtx; 639 ioc->TaskCtx = mptfcTaskCtx;
@@ -194,7 +669,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
194 printk(MYIOC_s_WARN_FMT 669 printk(MYIOC_s_WARN_FMT
195 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 670 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
196 ioc->name, ioc); 671 ioc->name, ioc);
197 return 0; 672 return -ENODEV;
198 } 673 }
199 674
200 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 675 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
@@ -207,6 +682,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
207 goto out_mptfc_probe; 682 goto out_mptfc_probe;
208 } 683 }
209 684
685 INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
686
210 spin_lock_irqsave(&ioc->FreeQlock, flags); 687 spin_lock_irqsave(&ioc->FreeQlock, flags);
211 688
212 /* Attach the SCSI Host to the IOC structure 689 /* Attach the SCSI Host to the IOC structure
@@ -268,36 +745,27 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
268 /* SCSI needs scsi_cmnd lookup table! 745 /* SCSI needs scsi_cmnd lookup table!
269 * (with size equal to req_depth*PtrSz!) 746 * (with size equal to req_depth*PtrSz!)
270 */ 747 */
271 sz = ioc->req_depth * sizeof(void *); 748 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
272 mem = kmalloc(sz, GFP_ATOMIC); 749 if (!hd->ScsiLookup) {
273 if (mem == NULL) {
274 error = -ENOMEM; 750 error = -ENOMEM;
275 goto out_mptfc_probe; 751 goto out_mptfc_probe;
276 } 752 }
277 753
278 memset(mem, 0, sz); 754 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
279 hd->ScsiLookup = (struct scsi_cmnd **) mem; 755 ioc->name, hd->ScsiLookup));
280
281 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
282 ioc->name, hd->ScsiLookup, sz));
283 756
284 /* Allocate memory for the device structures. 757 /* Allocate memory for the device structures.
285 * A non-Null pointer at an offset 758 * A non-Null pointer at an offset
286 * indicates a device exists. 759 * indicates a device exists.
287 * max_id = 1 + maximum id (hosts.h) 760 * max_id = 1 + maximum id (hosts.h)
288 */ 761 */
289 sz = sh->max_id * sizeof(void *); 762 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
290 mem = kmalloc(sz, GFP_ATOMIC); 763 if (!hd->Targets) {
291 if (mem == NULL) {
292 error = -ENOMEM; 764 error = -ENOMEM;
293 goto out_mptfc_probe; 765 goto out_mptfc_probe;
294 } 766 }
295 767
296 memset(mem, 0, sz); 768 dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
297 hd->Targets = (VirtTarget **) mem;
298
299 dprintk((KERN_INFO
300 " vdev @ %p, sz=%d\n", hd->Targets, sz));
301 769
302 /* Clear the TM flags 770 /* Clear the TM flags
303 */ 771 */
@@ -332,6 +800,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
332 hd->scandv_wait_done = 0; 800 hd->scandv_wait_done = 0;
333 hd->last_queue_full = 0; 801 hd->last_queue_full = 0;
334 802
803 sh->transportt = mptfc_transport_template;
335 error = scsi_add_host (sh, &ioc->pcidev->dev); 804 error = scsi_add_host (sh, &ioc->pcidev->dev);
336 if(error) { 805 if(error) {
337 dprintk((KERN_ERR MYNAM 806 dprintk((KERN_ERR MYNAM
@@ -339,7 +808,11 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
339 goto out_mptfc_probe; 808 goto out_mptfc_probe;
340 } 809 }
341 810
342 scsi_scan_host(sh); 811 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
812 mptfc_init_host_attr(ioc,ii);
813 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
814 }
815
343 return 0; 816 return 0;
344 817
345out_mptfc_probe: 818out_mptfc_probe:
@@ -352,7 +825,7 @@ static struct pci_driver mptfc_driver = {
352 .name = "mptfc", 825 .name = "mptfc",
353 .id_table = mptfc_pci_table, 826 .id_table = mptfc_pci_table,
354 .probe = mptfc_probe, 827 .probe = mptfc_probe,
355 .remove = __devexit_p(mptscsih_remove), 828 .remove = __devexit_p(mptfc_remove),
356 .shutdown = mptscsih_shutdown, 829 .shutdown = mptscsih_shutdown,
357#ifdef CONFIG_PM 830#ifdef CONFIG_PM
358 .suspend = mptscsih_suspend, 831 .suspend = mptscsih_suspend,
@@ -370,9 +843,20 @@ static struct pci_driver mptfc_driver = {
370static int __init 843static int __init
371mptfc_init(void) 844mptfc_init(void)
372{ 845{
846 int error;
373 847
374 show_mptmod_ver(my_NAME, my_VERSION); 848 show_mptmod_ver(my_NAME, my_VERSION);
375 849
850 /* sanity check module parameter */
851 if (mptfc_dev_loss_tmo == 0)
852 mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
853
854 mptfc_transport_template =
855 fc_attach_transport(&mptfc_transport_functions);
856
857 if (!mptfc_transport_template)
858 return -ENODEV;
859
376 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 860 mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
377 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 861 mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
378 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 862 mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
@@ -387,7 +871,33 @@ mptfc_init(void)
387 ": Registered for IOC reset notifications\n")); 871 ": Registered for IOC reset notifications\n"));
388 } 872 }
389 873
390 return pci_register_driver(&mptfc_driver); 874 error = pci_register_driver(&mptfc_driver);
875 if (error) {
876 fc_release_transport(mptfc_transport_template);
877 }
878
879 return error;
880}
881
882/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
883/**
884 * mptfc_remove - Removed fc infrastructure for devices
885 * @pdev: Pointer to pci_dev structure
886 *
887 */
888static void __devexit mptfc_remove(struct pci_dev *pdev)
889{
890 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
891 struct mptfc_rport_info *p, *n;
892
893 fc_remove_host(ioc->sh);
894
895 list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
896 list_del(&p->list);
897 kfree(p);
898 }
899
900 mptscsih_remove(pdev);
391} 901}
392 902
393/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 903/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -400,7 +910,8 @@ static void __exit
400mptfc_exit(void) 910mptfc_exit(void)
401{ 911{
402 pci_unregister_driver(&mptfc_driver); 912 pci_unregister_driver(&mptfc_driver);
403 913 fc_release_transport(mptfc_transport_template);
914
404 mpt_reset_deregister(mptfcDoneCtx); 915 mpt_reset_deregister(mptfcDoneCtx);
405 dprintk((KERN_INFO MYNAM 916 dprintk((KERN_INFO MYNAM
406 ": Deregistered for IOC reset notifications\n")); 917 ": Deregistered for IOC reset notifications\n"));
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 014085d8ec85..0b1b72825ae2 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -411,14 +411,12 @@ mpt_lan_open(struct net_device *dev)
411 goto out; 411 goto out;
412 priv->mpt_txfidx_tail = -1; 412 priv->mpt_txfidx_tail = -1;
413 413
414 priv->SendCtl = kmalloc(priv->tx_max_out * sizeof(struct BufferControl), 414 priv->SendCtl = kcalloc(priv->tx_max_out, sizeof(struct BufferControl),
415 GFP_KERNEL); 415 GFP_KERNEL);
416 if (priv->SendCtl == NULL) 416 if (priv->SendCtl == NULL)
417 goto out_mpt_txfidx; 417 goto out_mpt_txfidx;
418 for (i = 0; i < priv->tx_max_out; i++) { 418 for (i = 0; i < priv->tx_max_out; i++)
419 memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));
420 priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i; 419 priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
421 }
422 420
423 dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n")); 421 dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
424 422
@@ -428,15 +426,13 @@ mpt_lan_open(struct net_device *dev)
428 goto out_SendCtl; 426 goto out_SendCtl;
429 priv->mpt_rxfidx_tail = -1; 427 priv->mpt_rxfidx_tail = -1;
430 428
431 priv->RcvCtl = kmalloc(priv->max_buckets_out * 429 priv->RcvCtl = kcalloc(priv->max_buckets_out,
432 sizeof(struct BufferControl), 430 sizeof(struct BufferControl),
433 GFP_KERNEL); 431 GFP_KERNEL);
434 if (priv->RcvCtl == NULL) 432 if (priv->RcvCtl == NULL)
435 goto out_mpt_rxfidx; 433 goto out_mpt_rxfidx;
436 for (i = 0; i < priv->max_buckets_out; i++) { 434 for (i = 0; i < priv->max_buckets_out; i++)
437 memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));
438 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; 435 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
439 }
440 436
441/**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - ")); 437/**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
442/**/ for (i = 0; i < priv->tx_max_out; i++) 438/**/ for (i = 0; i < priv->tx_max_out; i++)
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 17e9757e728b..5a06d8d8694e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (c) 1999-2005 LSI Logic Corporation 6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsil.com)
8 * Copyright (c) 2005 Dell 8 * Copyright (c) 2005-2006 Dell
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/* 11/*
@@ -86,6 +86,24 @@ static int mptsasInternalCtx = -1; /* Used only for internal commands */
86static int mptsasMgmtCtx = -1; 86static int mptsasMgmtCtx = -1;
87 87
88 88
89enum mptsas_hotplug_action {
90 MPTSAS_ADD_DEVICE,
91 MPTSAS_DEL_DEVICE,
92};
93
94struct mptsas_hotplug_event {
95 struct work_struct work;
96 MPT_ADAPTER *ioc;
97 enum mptsas_hotplug_action event_type;
98 u64 sas_address;
99 u32 channel;
100 u32 id;
101 u32 device_info;
102 u16 handle;
103 u16 parent_handle;
104 u8 phy_id;
105};
106
89/* 107/*
90 * SAS topology structures 108 * SAS topology structures
91 * 109 *
@@ -99,8 +117,8 @@ struct mptsas_devinfo {
99 u8 phy_id; /* phy number of parent device */ 117 u8 phy_id; /* phy number of parent device */
100 u8 port_id; /* sas physical port this device 118 u8 port_id; /* sas physical port this device
101 is assoc'd with */ 119 is assoc'd with */
102 u8 target; /* logical target id of this device */ 120 u8 id; /* logical target id of this device */
103 u8 bus; /* logical bus number of this device */ 121 u8 channel; /* logical bus number of this device */
104 u64 sas_address; /* WWN of this device, 122 u64 sas_address; /* WWN of this device,
105 SATA is assigned by HBA,expander */ 123 SATA is assigned by HBA,expander */
106 u32 device_info; /* bitfield detailed info about this device */ 124 u32 device_info; /* bitfield detailed info about this device */
@@ -114,6 +132,7 @@ struct mptsas_phyinfo {
114 u8 programmed_link_rate; /* programmed max/min phy link rate */ 132 u8 programmed_link_rate; /* programmed max/min phy link rate */
115 struct mptsas_devinfo identify; /* point to phy device info */ 133 struct mptsas_devinfo identify; /* point to phy device info */
116 struct mptsas_devinfo attached; /* point to attached device info */ 134 struct mptsas_devinfo attached; /* point to attached device info */
135 struct sas_phy *phy;
117 struct sas_rphy *rphy; 136 struct sas_rphy *rphy;
118}; 137};
119 138
@@ -239,13 +258,12 @@ mptsas_slave_alloc(struct scsi_device *sdev)
239 struct scsi_target *starget; 258 struct scsi_target *starget;
240 int i; 259 int i;
241 260
242 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 261 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
243 if (!vdev) { 262 if (!vdev) {
244 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 263 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
245 hd->ioc->name, sizeof(VirtDevice)); 264 hd->ioc->name, sizeof(VirtDevice));
246 return -ENOMEM; 265 return -ENOMEM;
247 } 266 }
248 memset(vdev, 0, sizeof(VirtDevice));
249 vdev->ioc_id = hd->ioc->id; 267 vdev->ioc_id = hd->ioc->id;
250 sdev->hostdata = vdev; 268 sdev->hostdata = vdev;
251 starget = scsi_target(sdev); 269 starget = scsi_target(sdev);
@@ -256,19 +274,32 @@ mptsas_slave_alloc(struct scsi_device *sdev)
256 hd->Targets[sdev->id] = vtarget; 274 hd->Targets[sdev->id] = vtarget;
257 } 275 }
258 276
277 /*
278 RAID volumes placed beyond the last expected port.
279 */
280 if (sdev->channel == hd->ioc->num_ports) {
281 vdev->target_id = sdev->id;
282 vdev->bus_id = 0;
283 vdev->lun = 0;
284 goto out;
285 }
286
259 rphy = dev_to_rphy(sdev->sdev_target->dev.parent); 287 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
288 mutex_lock(&hd->ioc->sas_topology_mutex);
260 list_for_each_entry(p, &hd->ioc->sas_topology, list) { 289 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
261 for (i = 0; i < p->num_phys; i++) { 290 for (i = 0; i < p->num_phys; i++) {
262 if (p->phy_info[i].attached.sas_address == 291 if (p->phy_info[i].attached.sas_address ==
263 rphy->identify.sas_address) { 292 rphy->identify.sas_address) {
264 vdev->target_id = 293 vdev->target_id =
265 p->phy_info[i].attached.target; 294 p->phy_info[i].attached.id;
266 vdev->bus_id = p->phy_info[i].attached.bus; 295 vdev->bus_id = p->phy_info[i].attached.channel;
267 vdev->lun = sdev->lun; 296 vdev->lun = sdev->lun;
297 mutex_unlock(&hd->ioc->sas_topology_mutex);
268 goto out; 298 goto out;
269 } 299 }
270 } 300 }
271 } 301 }
302 mutex_unlock(&hd->ioc->sas_topology_mutex);
272 303
273 printk("No matching SAS device found!!\n"); 304 printk("No matching SAS device found!!\n");
274 kfree(vdev); 305 kfree(vdev);
@@ -282,6 +313,42 @@ mptsas_slave_alloc(struct scsi_device *sdev)
282 return 0; 313 return 0;
283} 314}
284 315
316static void
317mptsas_slave_destroy(struct scsi_device *sdev)
318{
319 struct Scsi_Host *host = sdev->host;
320 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
321 struct sas_rphy *rphy;
322 struct mptsas_portinfo *p;
323 int i;
324
325 /*
326 * Handle hotplug removal case.
327 * We need to clear out attached data structure.
328 */
329 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
330
331 mutex_lock(&hd->ioc->sas_topology_mutex);
332 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
333 for (i = 0; i < p->num_phys; i++) {
334 if (p->phy_info[i].attached.sas_address ==
335 rphy->identify.sas_address) {
336 memset(&p->phy_info[i].attached, 0,
337 sizeof(struct mptsas_devinfo));
338 p->phy_info[i].rphy = NULL;
339 goto out;
340 }
341 }
342 }
343
344 out:
345 mutex_unlock(&hd->ioc->sas_topology_mutex);
346 /*
347 * TODO: Issue target reset to flush firmware outstanding commands.
348 */
349 mptscsih_slave_destroy(sdev);
350}
351
285static struct scsi_host_template mptsas_driver_template = { 352static struct scsi_host_template mptsas_driver_template = {
286 .module = THIS_MODULE, 353 .module = THIS_MODULE,
287 .proc_name = "mptsas", 354 .proc_name = "mptsas",
@@ -293,7 +360,7 @@ static struct scsi_host_template mptsas_driver_template = {
293 .slave_alloc = mptsas_slave_alloc, 360 .slave_alloc = mptsas_slave_alloc,
294 .slave_configure = mptscsih_slave_configure, 361 .slave_configure = mptscsih_slave_configure,
295 .target_destroy = mptscsih_target_destroy, 362 .target_destroy = mptscsih_target_destroy,
296 .slave_destroy = mptscsih_slave_destroy, 363 .slave_destroy = mptsas_slave_destroy,
297 .change_queue_depth = mptscsih_change_queue_depth, 364 .change_queue_depth = mptscsih_change_queue_depth,
298 .eh_abort_handler = mptscsih_abort, 365 .eh_abort_handler = mptscsih_abort,
299 .eh_device_reset_handler = mptscsih_dev_reset, 366 .eh_device_reset_handler = mptscsih_dev_reset,
@@ -399,7 +466,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
399 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP) 466 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
400 return -ENXIO; 467 return -ENXIO;
401 468
402 if (down_interruptible(&ioc->sas_mgmt.mutex)) 469 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
403 goto out; 470 goto out;
404 471
405 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); 472 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
@@ -450,7 +517,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
450 error = 0; 517 error = 0;
451 518
452 out_unlock: 519 out_unlock:
453 up(&ioc->sas_mgmt.mutex); 520 mutex_unlock(&ioc->sas_mgmt.mutex);
454 out: 521 out:
455 return error; 522 return error;
456} 523}
@@ -649,8 +716,8 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
649 device_info->handle = le16_to_cpu(buffer->DevHandle); 716 device_info->handle = le16_to_cpu(buffer->DevHandle);
650 device_info->phy_id = buffer->PhyNum; 717 device_info->phy_id = buffer->PhyNum;
651 device_info->port_id = buffer->PhysicalPort; 718 device_info->port_id = buffer->PhysicalPort;
652 device_info->target = buffer->TargetID; 719 device_info->id = buffer->TargetID;
653 device_info->bus = buffer->Bus; 720 device_info->channel = buffer->Bus;
654 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); 721 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
655 device_info->sas_address = le64_to_cpu(sas_address); 722 device_info->sas_address = le64_to_cpu(sas_address);
656 device_info->device_info = 723 device_info->device_info =
@@ -858,36 +925,36 @@ mptsas_parse_device_info(struct sas_identify *identify,
858static int mptsas_probe_one_phy(struct device *dev, 925static int mptsas_probe_one_phy(struct device *dev,
859 struct mptsas_phyinfo *phy_info, int index, int local) 926 struct mptsas_phyinfo *phy_info, int index, int local)
860{ 927{
861 struct sas_phy *port; 928 struct sas_phy *phy;
862 int error; 929 int error;
863 930
864 port = sas_phy_alloc(dev, index); 931 phy = sas_phy_alloc(dev, index);
865 if (!port) 932 if (!phy)
866 return -ENOMEM; 933 return -ENOMEM;
867 934
868 port->port_identifier = phy_info->port_id; 935 phy->port_identifier = phy_info->port_id;
869 mptsas_parse_device_info(&port->identify, &phy_info->identify); 936 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
870 937
871 /* 938 /*
872 * Set Negotiated link rate. 939 * Set Negotiated link rate.
873 */ 940 */
874 switch (phy_info->negotiated_link_rate) { 941 switch (phy_info->negotiated_link_rate) {
875 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED: 942 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
876 port->negotiated_linkrate = SAS_PHY_DISABLED; 943 phy->negotiated_linkrate = SAS_PHY_DISABLED;
877 break; 944 break;
878 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION: 945 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
879 port->negotiated_linkrate = SAS_LINK_RATE_FAILED; 946 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
880 break; 947 break;
881 case MPI_SAS_IOUNIT0_RATE_1_5: 948 case MPI_SAS_IOUNIT0_RATE_1_5:
882 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS; 949 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
883 break; 950 break;
884 case MPI_SAS_IOUNIT0_RATE_3_0: 951 case MPI_SAS_IOUNIT0_RATE_3_0:
885 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS; 952 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
886 break; 953 break;
887 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE: 954 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
888 case MPI_SAS_IOUNIT0_RATE_UNKNOWN: 955 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
889 default: 956 default:
890 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; 957 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
891 break; 958 break;
892 } 959 }
893 960
@@ -896,10 +963,10 @@ static int mptsas_probe_one_phy(struct device *dev,
896 */ 963 */
897 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 964 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
898 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5: 965 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
899 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 966 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
900 break; 967 break;
901 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 968 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
902 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 969 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
903 break; 970 break;
904 default: 971 default:
905 break; 972 break;
@@ -911,10 +978,10 @@ static int mptsas_probe_one_phy(struct device *dev,
911 switch (phy_info->programmed_link_rate & 978 switch (phy_info->programmed_link_rate &
912 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 979 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
913 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5: 980 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
914 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS; 981 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
915 break; 982 break;
916 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 983 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
917 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS; 984 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
918 break; 985 break;
919 default: 986 default:
920 break; 987 break;
@@ -925,10 +992,10 @@ static int mptsas_probe_one_phy(struct device *dev,
925 */ 992 */
926 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) { 993 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
927 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5: 994 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
928 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 995 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
929 break; 996 break;
930 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 997 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
931 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 998 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
932 break; 999 break;
933 default: 1000 default:
934 break; 1001 break;
@@ -940,28 +1007,29 @@ static int mptsas_probe_one_phy(struct device *dev,
940 switch (phy_info->programmed_link_rate & 1007 switch (phy_info->programmed_link_rate &
941 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) { 1008 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
942 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5: 1009 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
943 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS; 1010 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
944 break; 1011 break;
945 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 1012 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
946 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS; 1013 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
947 break; 1014 break;
948 default: 1015 default:
949 break; 1016 break;
950 } 1017 }
951 1018
952 if (local) 1019 if (local)
953 port->local_attached = 1; 1020 phy->local_attached = 1;
954 1021
955 error = sas_phy_add(port); 1022 error = sas_phy_add(phy);
956 if (error) { 1023 if (error) {
957 sas_phy_free(port); 1024 sas_phy_free(phy);
958 return error; 1025 return error;
959 } 1026 }
1027 phy_info->phy = phy;
960 1028
961 if (phy_info->attached.handle) { 1029 if (phy_info->attached.handle) {
962 struct sas_rphy *rphy; 1030 struct sas_rphy *rphy;
963 1031
964 rphy = sas_rphy_alloc(port); 1032 rphy = sas_rphy_alloc(phy);
965 if (!rphy) 1033 if (!rphy)
966 return 0; /* non-fatal: an rphy can be added later */ 1034 return 0; /* non-fatal: an rphy can be added later */
967 1035
@@ -985,16 +1053,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
985 u32 handle = 0xFFFF; 1053 u32 handle = 0xFFFF;
986 int error = -ENOMEM, i; 1054 int error = -ENOMEM, i;
987 1055
988 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 1056 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
989 if (!port_info) 1057 if (!port_info)
990 goto out; 1058 goto out;
991 memset(port_info, 0, sizeof(*port_info));
992 1059
993 error = mptsas_sas_io_unit_pg0(ioc, port_info); 1060 error = mptsas_sas_io_unit_pg0(ioc, port_info);
994 if (error) 1061 if (error)
995 goto out_free_port_info; 1062 goto out_free_port_info;
996 1063
1064 ioc->num_ports = port_info->num_phys;
1065 mutex_lock(&ioc->sas_topology_mutex);
997 list_add_tail(&port_info->list, &ioc->sas_topology); 1066 list_add_tail(&port_info->list, &ioc->sas_topology);
1067 mutex_unlock(&ioc->sas_topology_mutex);
1068
998 for (i = 0; i < port_info->num_phys; i++) { 1069 for (i = 0; i < port_info->num_phys; i++) {
999 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 1070 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1000 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << 1071 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1034,10 +1105,9 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1034 struct mptsas_portinfo *port_info, *p; 1105 struct mptsas_portinfo *port_info, *p;
1035 int error = -ENOMEM, i, j; 1106 int error = -ENOMEM, i, j;
1036 1107
1037 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 1108 port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
1038 if (!port_info) 1109 if (!port_info)
1039 goto out; 1110 goto out;
1040 memset(port_info, 0, sizeof(*port_info));
1041 1111
1042 error = mptsas_sas_expander_pg0(ioc, port_info, 1112 error = mptsas_sas_expander_pg0(ioc, port_info,
1043 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 1113 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
@@ -1047,7 +1117,10 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1047 1117
1048 *handle = port_info->handle; 1118 *handle = port_info->handle;
1049 1119
1120 mutex_lock(&ioc->sas_topology_mutex);
1050 list_add_tail(&port_info->list, &ioc->sas_topology); 1121 list_add_tail(&port_info->list, &ioc->sas_topology);
1122 mutex_unlock(&ioc->sas_topology_mutex);
1123
1051 for (i = 0; i < port_info->num_phys; i++) { 1124 for (i = 0; i < port_info->num_phys; i++) {
1052 struct device *parent; 1125 struct device *parent;
1053 1126
@@ -1079,6 +1152,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1079 * HBA phys. 1152 * HBA phys.
1080 */ 1153 */
1081 parent = &ioc->sh->shost_gendev; 1154 parent = &ioc->sh->shost_gendev;
1155 mutex_lock(&ioc->sas_topology_mutex);
1082 list_for_each_entry(p, &ioc->sas_topology, list) { 1156 list_for_each_entry(p, &ioc->sas_topology, list) {
1083 for (j = 0; j < p->num_phys; j++) { 1157 for (j = 0; j < p->num_phys; j++) {
1084 if (port_info->phy_info[i].identify.handle == 1158 if (port_info->phy_info[i].identify.handle ==
@@ -1086,6 +1160,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
1086 parent = &p->phy_info[j].rphy->dev; 1160 parent = &p->phy_info[j].rphy->dev;
1087 } 1161 }
1088 } 1162 }
1163 mutex_unlock(&ioc->sas_topology_mutex);
1089 1164
1090 mptsas_probe_one_phy(parent, &port_info->phy_info[i], 1165 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
1091 *index, 0); 1166 *index, 0);
@@ -1111,6 +1186,211 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1111 ; 1186 ;
1112} 1187}
1113 1188
1189static struct mptsas_phyinfo *
1190mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
1191{
1192 struct mptsas_portinfo *port_info;
1193 struct mptsas_devinfo device_info;
1194 struct mptsas_phyinfo *phy_info = NULL;
1195 int i, error;
1196
1197 /*
1198 * Retrieve the parent sas_address
1199 */
1200 error = mptsas_sas_device_pg0(ioc, &device_info,
1201 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1202 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
1203 parent_handle);
1204 if (error) {
1205 printk("mptsas: failed to retrieve device page\n");
1206 return NULL;
1207 }
1208
1209 /*
1210 * The phy_info structures are never deallocated during lifetime of
1211 * a host, so the code below is safe without additional refcounting.
1212 */
1213 mutex_lock(&ioc->sas_topology_mutex);
1214 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1215 for (i = 0; i < port_info->num_phys; i++) {
1216 if (port_info->phy_info[i].identify.sas_address ==
1217 device_info.sas_address &&
1218 port_info->phy_info[i].phy_id == phy_id) {
1219 phy_info = &port_info->phy_info[i];
1220 break;
1221 }
1222 }
1223 }
1224 mutex_unlock(&ioc->sas_topology_mutex);
1225
1226 return phy_info;
1227}
1228
1229static struct mptsas_phyinfo *
1230mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
1231{
1232 struct mptsas_portinfo *port_info;
1233 struct mptsas_phyinfo *phy_info = NULL;
1234 int i;
1235
1236 /*
1237 * The phy_info structures are never deallocated during lifetime of
1238 * a host, so the code below is safe without additional refcounting.
1239 */
1240 mutex_lock(&ioc->sas_topology_mutex);
1241 list_for_each_entry(port_info, &ioc->sas_topology, list) {
1242 for (i = 0; i < port_info->num_phys; i++) {
1243 if (port_info->phy_info[i].attached.handle == handle) {
1244 phy_info = &port_info->phy_info[i];
1245 break;
1246 }
1247 }
1248 }
1249 mutex_unlock(&ioc->sas_topology_mutex);
1250
1251 return phy_info;
1252}
1253
1254static void
1255mptsas_hotplug_work(void *arg)
1256{
1257 struct mptsas_hotplug_event *ev = arg;
1258 MPT_ADAPTER *ioc = ev->ioc;
1259 struct mptsas_phyinfo *phy_info;
1260 struct sas_rphy *rphy;
1261 char *ds = NULL;
1262
1263 if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1264 ds = "ssp";
1265 if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
1266 ds = "stp";
1267 if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1268 ds = "sata";
1269
1270 switch (ev->event_type) {
1271 case MPTSAS_DEL_DEVICE:
1272 printk(MYIOC_s_INFO_FMT
1273 "removing %s device, channel %d, id %d, phy %d\n",
1274 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1275
1276 phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
1277 if (!phy_info) {
1278 printk("mptsas: remove event for non-existant PHY.\n");
1279 break;
1280 }
1281
1282 if (phy_info->rphy) {
1283 sas_rphy_delete(phy_info->rphy);
1284 phy_info->rphy = NULL;
1285 }
1286 break;
1287 case MPTSAS_ADD_DEVICE:
1288 printk(MYIOC_s_INFO_FMT
1289 "attaching %s device, channel %d, id %d, phy %d\n",
1290 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
1291
1292 phy_info = mptsas_find_phyinfo_by_parent(ioc,
1293 ev->parent_handle, ev->phy_id);
1294 if (!phy_info) {
1295 printk("mptsas: add event for non-existant PHY.\n");
1296 break;
1297 }
1298
1299 if (phy_info->rphy) {
1300 printk("mptsas: trying to add existing device.\n");
1301 break;
1302 }
1303
1304 /* fill attached info */
1305 phy_info->attached.handle = ev->handle;
1306 phy_info->attached.phy_id = ev->phy_id;
1307 phy_info->attached.port_id = phy_info->identify.port_id;
1308 phy_info->attached.id = ev->id;
1309 phy_info->attached.channel = ev->channel;
1310 phy_info->attached.sas_address = ev->sas_address;
1311 phy_info->attached.device_info = ev->device_info;
1312
1313 rphy = sas_rphy_alloc(phy_info->phy);
1314 if (!rphy)
1315 break; /* non-fatal: an rphy can be added later */
1316
1317 mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
1318 if (sas_rphy_add(rphy)) {
1319 sas_rphy_free(rphy);
1320 break;
1321 }
1322
1323 phy_info->rphy = rphy;
1324 break;
1325 }
1326
1327 kfree(ev);
1328}
1329
1330static void
1331mptscsih_send_sas_event(MPT_ADAPTER *ioc,
1332 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1333{
1334 struct mptsas_hotplug_event *ev;
1335 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
1336 __le64 sas_address;
1337
1338 if ((device_info &
1339 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
1340 MPI_SAS_DEVICE_INFO_STP_TARGET |
1341 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
1342 return;
1343
1344 if ((sas_event_data->ReasonCode &
1345 (MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
1346 MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
1347 return;
1348
1349 ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
1350 if (!ev) {
1351 printk(KERN_WARNING "mptsas: lost hotplug event\n");
1352 return;
1353 }
1354
1355
1356 INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
1357 ev->ioc = ioc;
1358 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
1359 ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
1360 ev->channel = sas_event_data->Bus;
1361 ev->id = sas_event_data->TargetID;
1362 ev->phy_id = sas_event_data->PhyNum;
1363 memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
1364 ev->sas_address = le64_to_cpu(sas_address);
1365 ev->device_info = device_info;
1366
1367 if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
1368 ev->event_type = MPTSAS_ADD_DEVICE;
1369 else
1370 ev->event_type = MPTSAS_DEL_DEVICE;
1371
1372 schedule_work(&ev->work);
1373}
1374
1375static int
1376mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
1377{
1378 u8 event = le32_to_cpu(reply->Event) & 0xFF;
1379
1380 if (!ioc->sh)
1381 return 1;
1382
1383 switch (event) {
1384 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1385 mptscsih_send_sas_event(ioc,
1386 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
1387 return 1; /* currently means nothing really */
1388
1389 default:
1390 return mptscsih_event_process(ioc, reply);
1391 }
1392}
1393
1114static int 1394static int
1115mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1395mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1116{ 1396{
@@ -1118,11 +1398,10 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1118 MPT_SCSI_HOST *hd; 1398 MPT_SCSI_HOST *hd;
1119 MPT_ADAPTER *ioc; 1399 MPT_ADAPTER *ioc;
1120 unsigned long flags; 1400 unsigned long flags;
1121 int sz, ii; 1401 int ii;
1122 int numSGE = 0; 1402 int numSGE = 0;
1123 int scale; 1403 int scale;
1124 int ioc_cap; 1404 int ioc_cap;
1125 u8 *mem;
1126 int error=0; 1405 int error=0;
1127 int r; 1406 int r;
1128 1407
@@ -1203,7 +1482,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1203 sh->unique_id = ioc->id; 1482 sh->unique_id = ioc->id;
1204 1483
1205 INIT_LIST_HEAD(&ioc->sas_topology); 1484 INIT_LIST_HEAD(&ioc->sas_topology);
1206 init_MUTEX(&ioc->sas_mgmt.mutex); 1485 mutex_init(&ioc->sas_topology_mutex);
1486
1487 mutex_init(&ioc->sas_mgmt.mutex);
1207 init_completion(&ioc->sas_mgmt.done); 1488 init_completion(&ioc->sas_mgmt.done);
1208 1489
1209 /* Verify that we won't exceed the maximum 1490 /* Verify that we won't exceed the maximum
@@ -1244,36 +1525,27 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1244 /* SCSI needs scsi_cmnd lookup table! 1525 /* SCSI needs scsi_cmnd lookup table!
1245 * (with size equal to req_depth*PtrSz!) 1526 * (with size equal to req_depth*PtrSz!)
1246 */ 1527 */
1247 sz = ioc->req_depth * sizeof(void *); 1528 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1248 mem = kmalloc(sz, GFP_ATOMIC); 1529 if (!hd->ScsiLookup) {
1249 if (mem == NULL) {
1250 error = -ENOMEM; 1530 error = -ENOMEM;
1251 goto out_mptsas_probe; 1531 goto out_mptsas_probe;
1252 } 1532 }
1253 1533
1254 memset(mem, 0, sz); 1534 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1255 hd->ScsiLookup = (struct scsi_cmnd **) mem; 1535 ioc->name, hd->ScsiLookup));
1256
1257 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1258 ioc->name, hd->ScsiLookup, sz));
1259 1536
1260 /* Allocate memory for the device structures. 1537 /* Allocate memory for the device structures.
1261 * A non-Null pointer at an offset 1538 * A non-Null pointer at an offset
1262 * indicates a device exists. 1539 * indicates a device exists.
1263 * max_id = 1 + maximum id (hosts.h) 1540 * max_id = 1 + maximum id (hosts.h)
1264 */ 1541 */
1265 sz = sh->max_id * sizeof(void *); 1542 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1266 mem = kmalloc(sz, GFP_ATOMIC); 1543 if (!hd->Targets) {
1267 if (mem == NULL) {
1268 error = -ENOMEM; 1544 error = -ENOMEM;
1269 goto out_mptsas_probe; 1545 goto out_mptsas_probe;
1270 } 1546 }
1271 1547
1272 memset(mem, 0, sz); 1548 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
1273 hd->Targets = (VirtTarget **) mem;
1274
1275 dprintk((KERN_INFO
1276 " vtarget @ %p, sz=%d\n", hd->Targets, sz));
1277 1549
1278 /* Clear the TM flags 1550 /* Clear the TM flags
1279 */ 1551 */
@@ -1324,6 +1596,20 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1324 1596
1325 mptsas_scan_sas_topology(ioc); 1597 mptsas_scan_sas_topology(ioc);
1326 1598
1599 /*
1600 Reporting RAID volumes.
1601 */
1602 if (!ioc->raid_data.pIocPg2)
1603 return 0;
1604 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1605 return 0;
1606 for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
1607 scsi_add_device(sh,
1608 ioc->num_ports,
1609 ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
1610 0);
1611 }
1612
1327 return 0; 1613 return 0;
1328 1614
1329out_mptsas_probe: 1615out_mptsas_probe:
@@ -1339,10 +1625,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
1339 1625
1340 sas_remove_host(ioc->sh); 1626 sas_remove_host(ioc->sh);
1341 1627
1628 mutex_lock(&ioc->sas_topology_mutex);
1342 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { 1629 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
1343 list_del(&p->list); 1630 list_del(&p->list);
1344 kfree(p); 1631 kfree(p);
1345 } 1632 }
1633 mutex_unlock(&ioc->sas_topology_mutex);
1346 1634
1347 mptscsih_remove(pdev); 1635 mptscsih_remove(pdev);
1348} 1636}
@@ -1393,7 +1681,7 @@ mptsas_init(void)
1393 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); 1681 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
1394 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); 1682 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
1395 1683
1396 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) { 1684 if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
1397 devtprintk((KERN_INFO MYNAM 1685 devtprintk((KERN_INFO MYNAM
1398 ": Registered for IOC event notifications\n")); 1686 ": Registered for IOC event notifications\n"));
1399 } 1687 }
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 93a16fa3c4ba..cdac5578fdf2 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -893,6 +893,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
893 * when a lun is disable by mid-layer. 893 * when a lun is disable by mid-layer.
894 * Do NOT access the referenced scsi_cmnd structure or 894 * Do NOT access the referenced scsi_cmnd structure or
895 * members. Will cause either a paging or NULL ptr error. 895 * members. Will cause either a paging or NULL ptr error.
896 * (BUT, BUT, BUT, the code does reference it! - mdr)
896 * @hd: Pointer to a SCSI HOST structure 897 * @hd: Pointer to a SCSI HOST structure
897 * @vdevice: per device private data 898 * @vdevice: per device private data
898 * 899 *
@@ -2162,10 +2163,9 @@ mptscsih_target_alloc(struct scsi_target *starget)
2162{ 2163{
2163 VirtTarget *vtarget; 2164 VirtTarget *vtarget;
2164 2165
2165 vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL); 2166 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
2166 if (!vtarget) 2167 if (!vtarget)
2167 return -ENOMEM; 2168 return -ENOMEM;
2168 memset(vtarget, 0, sizeof(VirtTarget));
2169 starget->hostdata = vtarget; 2169 starget->hostdata = vtarget;
2170 return 0; 2170 return 0;
2171} 2171}
@@ -2185,14 +2185,13 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
2185 VirtDevice *vdev; 2185 VirtDevice *vdev;
2186 struct scsi_target *starget; 2186 struct scsi_target *starget;
2187 2187
2188 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 2188 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
2189 if (!vdev) { 2189 if (!vdev) {
2190 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 2190 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2191 hd->ioc->name, sizeof(VirtDevice)); 2191 hd->ioc->name, sizeof(VirtDevice));
2192 return -ENOMEM; 2192 return -ENOMEM;
2193 } 2193 }
2194 2194
2195 memset(vdev, 0, sizeof(VirtDevice));
2196 vdev->ioc_id = hd->ioc->id; 2195 vdev->ioc_id = hd->ioc->id;
2197 vdev->target_id = sdev->id; 2196 vdev->target_id = sdev->id;
2198 vdev->bus_id = sdev->channel; 2197 vdev->bus_id = sdev->channel;
@@ -2559,13 +2558,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2559 hd->cmdPtr = NULL; 2558 hd->cmdPtr = NULL;
2560 } 2559 }
2561 2560
2562 /* 7. Set flag to force DV and re-read IOC Page 3 2561 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
2563 */ 2562 */
2564 if (ioc->bus_type == SPI) { 2563 if (ioc->bus_type == SPI) {
2565 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; 2564 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2566 ddvtprintk(("Set reload IOC Pg3 Flag\n")); 2565 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2567 } 2566 }
2568 2567
2568 /* 7. FC: Rescan for blocked rports which might have returned.
2569 */
2570 else if (ioc->bus_type == FC) {
2571 int work_count;
2572 unsigned long flags;
2573
2574 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2575 work_count = ++ioc->fc_rescan_work_count;
2576 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2577 if (work_count == 1)
2578 schedule_work(&ioc->fc_rescan_work);
2579 }
2569 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2580 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2570 2581
2571 } 2582 }
@@ -2589,6 +2600,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2589{ 2600{
2590 MPT_SCSI_HOST *hd; 2601 MPT_SCSI_HOST *hd;
2591 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2602 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2603 int work_count;
2604 unsigned long flags;
2592 2605
2593 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2606 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2594 ioc->name, event)); 2607 ioc->name, event));
@@ -2610,11 +2623,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2610 /* FIXME! */ 2623 /* FIXME! */
2611 break; 2624 break;
2612 2625
2626 case MPI_EVENT_RESCAN: /* 06 */
2627 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2628 work_count = ++ioc->fc_rescan_work_count;
2629 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2630 if (work_count == 1)
2631 schedule_work(&ioc->fc_rescan_work);
2632 break;
2633
2613 /* 2634 /*
2614 * CHECKME! Don't think we need to do 2635 * CHECKME! Don't think we need to do
2615 * anything for these, but... 2636 * anything for these, but...
2616 */ 2637 */
2617 case MPI_EVENT_RESCAN: /* 06 */
2618 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */ 2638 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2619 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */ 2639 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2620 /* 2640 /*
@@ -3954,8 +3974,6 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3954 3974
3955/* Search IOC page 3 to determine if this is hidden physical disk 3975/* Search IOC page 3 to determine if this is hidden physical disk
3956 */ 3976 */
3957/* Search IOC page 3 to determine if this is hidden physical disk
3958 */
3959static int 3977static int
3960mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 3978mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
3961{ 3979{
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index ce332a6085e5..7dce29277cb7 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -158,11 +158,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
158 MPT_SCSI_HOST *hd; 158 MPT_SCSI_HOST *hd;
159 MPT_ADAPTER *ioc; 159 MPT_ADAPTER *ioc;
160 unsigned long flags; 160 unsigned long flags;
161 int sz, ii; 161 int ii;
162 int numSGE = 0; 162 int numSGE = 0;
163 int scale; 163 int scale;
164 int ioc_cap; 164 int ioc_cap;
165 u8 *mem;
166 int error=0; 165 int error=0;
167 int r; 166 int r;
168 167
@@ -288,36 +287,27 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
288 /* SCSI needs scsi_cmnd lookup table! 287 /* SCSI needs scsi_cmnd lookup table!
289 * (with size equal to req_depth*PtrSz!) 288 * (with size equal to req_depth*PtrSz!)
290 */ 289 */
291 sz = ioc->req_depth * sizeof(void *); 290 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
292 mem = kmalloc(sz, GFP_ATOMIC); 291 if (!hd->ScsiLookup) {
293 if (mem == NULL) {
294 error = -ENOMEM; 292 error = -ENOMEM;
295 goto out_mptspi_probe; 293 goto out_mptspi_probe;
296 } 294 }
297 295
298 memset(mem, 0, sz); 296 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
299 hd->ScsiLookup = (struct scsi_cmnd **) mem; 297 ioc->name, hd->ScsiLookup));
300
301 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
302 ioc->name, hd->ScsiLookup, sz));
303 298
304 /* Allocate memory for the device structures. 299 /* Allocate memory for the device structures.
305 * A non-Null pointer at an offset 300 * A non-Null pointer at an offset
306 * indicates a device exists. 301 * indicates a device exists.
307 * max_id = 1 + maximum id (hosts.h) 302 * max_id = 1 + maximum id (hosts.h)
308 */ 303 */
309 sz = sh->max_id * sizeof(void *); 304 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
310 mem = kmalloc(sz, GFP_ATOMIC); 305 if (!hd->Targets) {
311 if (mem == NULL) {
312 error = -ENOMEM; 306 error = -ENOMEM;
313 goto out_mptspi_probe; 307 goto out_mptspi_probe;
314 } 308 }
315 309
316 memset(mem, 0, sz); 310 dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
317 hd->Targets = (VirtTarget **) mem;
318
319 dprintk((KERN_INFO
320 " vdev @ %p, sz=%d\n", hd->Targets, sz));
321 311
322 /* Clear the TM flags 312 /* Clear the TM flags
323 */ 313 */