aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/Kconfig2
-rw-r--r--drivers/message/fusion/Makefile7
-rw-r--r--drivers/message/fusion/lsi/mpi.h7
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h131
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt77
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h7
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h75
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h284
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h9
-rw-r--r--drivers/message/fusion/mptbase.c875
-rw-r--r--drivers/message/fusion/mptbase.h47
-rw-r--r--drivers/message/fusion/mptctl.c163
-rw-r--r--drivers/message/fusion/mptctl.h2
-rw-r--r--drivers/message/fusion/mptfc.c53
-rw-r--r--drivers/message/fusion/mptlan.c1
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/message/fusion/mptsas.c718
-rw-r--r--drivers/message/fusion/mptscsih.c997
-rw-r--r--drivers/message/fusion/mptscsih.h44
-rw-r--r--drivers/message/fusion/mptspi.c527
20 files changed, 2673 insertions, 1354 deletions
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index ea31d8470510..71037f91c222 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -66,7 +66,7 @@ config FUSION_MAX_SGE
66 66
67config FUSION_CTL 67config FUSION_CTL
68 tristate "Fusion MPT misc device (ioctl) driver" 68 tristate "Fusion MPT misc device (ioctl) driver"
69 depends on FUSION_SPI || FUSION_FC 69 depends on FUSION_SPI || FUSION_FC || FUSION_SAS
70 ---help--- 70 ---help---
71 The Fusion MPT misc device driver provides specialized control 71 The Fusion MPT misc device driver provides specialized control
72 of MPT adapters via system ioctl calls. Use of ioctl calls to 72 of MPT adapters via system ioctl calls. Use of ioctl calls to
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 341691390e86..6003b46c8438 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -8,6 +8,9 @@
8#EXTRA_CFLAGS += -DMPT_DEBUG_INIT 8#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
9#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT 9#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
10#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL 10#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
11#EXTRA_CFLAGS += -DMPT_DEBUG_DV
12#EXTRA_CFLAGS += -DMPT_DEBUG_TM
13#EXTRA_CFLAGS += -DMPT_DEBUG_REPLY
11 14
12# 15#
13# driver/module specifics... 16# driver/module specifics...
@@ -20,11 +23,7 @@
20#CFLAGS_mptbase.o += -DMPT_DEBUG_RESET 23#CFLAGS_mptbase.o += -DMPT_DEBUG_RESET
21# 24#
22# For mptscsih: 25# For mptscsih:
23#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV
24#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO
25#CFLAGS_mptscsih.o += -DMPT_DEBUG_TM
26#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI 26#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI
27#CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY
28# 27#
29# For mptctl: 28# For mptctl:
30#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL 29#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 81ad77622dac..75223bf24ae8 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2005 LSI Logic Corporation. 2 * Copyright (c) 2000-2006 LSI Logic Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi.h 5 * Name: mpi.h
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.11 9 * mpi.h Version: 01.05.12
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -77,6 +77,7 @@
77 * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. 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. 78 * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
79 * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. 79 * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
80 * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
80 * -------------------------------------------------------------------------- 81 * --------------------------------------------------------------------------
81 */ 82 */
82 83
@@ -107,7 +108,7 @@
107/* Note: The major versions of 0xe0 through 0xff are reserved */ 108/* Note: The major versions of 0xe0 through 0xff are reserved */
108 109
109/* versioning for this MPI header set */ 110/* versioning for this MPI header set */
110#define MPI_HEADER_VERSION_UNIT (0x0D) 111#define MPI_HEADER_VERSION_UNIT (0x0E)
111#define MPI_HEADER_VERSION_DEV (0x00) 112#define MPI_HEADER_VERSION_DEV (0x00)
112#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) 113#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
113#define MPI_HEADER_VERSION_UNIT_SHIFT (8) 114#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index 47e13e360c10..0e4c8e77a81d 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2005 LSI Logic Corporation. 2 * Copyright (c) 2000-2006 LSI Logic Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi_cnfg.h 5 * Name: mpi_cnfg.h
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.12 9 * mpi_cnfg.h Version: 01.05.13
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -276,6 +276,23 @@
276 * Added AdditionalControlFlags, MaxTargetPortConnectTime, 276 * Added AdditionalControlFlags, MaxTargetPortConnectTime,
277 * ReportDeviceMissingDelay, and IODeviceMissingDelay 277 * ReportDeviceMissingDelay, and IODeviceMissingDelay
278 * fields to SAS IO Unit Page 1. 278 * fields to SAS IO Unit Page 1.
279 * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to
280 * Manufacturing Page 5.
281 * Added Manufacturing pages 8 through 10.
282 * Added defines for supported metadata size bits in
283 * CapabilitiesFlags field of IOC Page 6.
284 * Added defines for metadata size bits in VolumeSettings
285 * field of RAID Volume Page 0.
286 * Added SATA Link Reset settings, Enable SATA Asynchronous
287 * Notification bit, and HideNonZeroAttachedPhyIdentifiers
288 * bit to AdditionalControlFlags field of SAS IO Unit
289 * Page 1.
290 * Added defines for Enclosure Devices Unmapped and
291 * Device Limit Exceeded bits in Status field of SAS IO
292 * Unit Page 2.
293 * Added more AccessStatus values for SAS Device Page 0.
294 * Added bit for SATA Asynchronous Notification Support in
295 * Flags field of SAS Device Page 0.
279 * -------------------------------------------------------------------------- 296 * --------------------------------------------------------------------------
280 */ 297 */
281 298
@@ -654,17 +671,24 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
654#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) 671#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
655 672
656 673
674#ifndef MPI_MANPAGE5_NUM_FORCEWWID
675#define MPI_MANPAGE5_NUM_FORCEWWID (1)
676#endif
677
657typedef struct _CONFIG_PAGE_MANUFACTURING_5 678typedef struct _CONFIG_PAGE_MANUFACTURING_5
658{ 679{
659 CONFIG_PAGE_HEADER Header; /* 00h */ 680 CONFIG_PAGE_HEADER Header; /* 00h */
660 U64 BaseWWID; /* 04h */ 681 U64 BaseWWID; /* 04h */
661 U8 Flags; /* 0Ch */ 682 U8 Flags; /* 0Ch */
662 U8 Reserved1; /* 0Dh */ 683 U8 NumForceWWID; /* 0Dh */
663 U16 Reserved2; /* 0Eh */ 684 U16 Reserved2; /* 0Eh */
685 U32 Reserved3; /* 10h */
686 U32 Reserved4; /* 14h */
687 U64 ForceWWID[MPI_MANPAGE5_NUM_FORCEWWID]; /* 18h */
664} CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5, 688} CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
665 ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t; 689 ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
666 690
667#define MPI_MANUFACTURING5_PAGEVERSION (0x01) 691#define MPI_MANUFACTURING5_PAGEVERSION (0x02)
668 692
669/* defines for the Flags field */ 693/* defines for the Flags field */
670#define MPI_MANPAGE5_TWO_WWID_PER_PHY (0x01) 694#define MPI_MANPAGE5_TWO_WWID_PER_PHY (0x01)
@@ -740,6 +764,36 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_7
740#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) 764#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
741 765
742 766
767typedef struct _CONFIG_PAGE_MANUFACTURING_8
768{
769 CONFIG_PAGE_HEADER Header; /* 00h */
770 U32 ProductSpecificInfo;/* 04h */
771} CONFIG_PAGE_MANUFACTURING_8, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_8,
772 ManufacturingPage8_t, MPI_POINTER pManufacturingPage8_t;
773
774#define MPI_MANUFACTURING8_PAGEVERSION (0x00)
775
776
777typedef struct _CONFIG_PAGE_MANUFACTURING_9
778{
779 CONFIG_PAGE_HEADER Header; /* 00h */
780 U32 ProductSpecificInfo;/* 04h */
781} CONFIG_PAGE_MANUFACTURING_9, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_9,
782 ManufacturingPage9_t, MPI_POINTER pManufacturingPage9_t;
783
784#define MPI_MANUFACTURING6_PAGEVERSION (0x00)
785
786
787typedef struct _CONFIG_PAGE_MANUFACTURING_10
788{
789 CONFIG_PAGE_HEADER Header; /* 00h */
790 U32 ProductSpecificInfo;/* 04h */
791} CONFIG_PAGE_MANUFACTURING_10, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_10,
792 ManufacturingPage10_t, MPI_POINTER pManufacturingPage10_t;
793
794#define MPI_MANUFACTURING10_PAGEVERSION (0x00)
795
796
743/**************************************************************************** 797/****************************************************************************
744* IO Unit Config Pages 798* IO Unit Config Pages
745****************************************************************************/ 799****************************************************************************/
@@ -1080,10 +1134,14 @@ typedef struct _CONFIG_PAGE_IOC_6
1080} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6, 1134} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6,
1081 IOCPage6_t, MPI_POINTER pIOCPage6_t; 1135 IOCPage6_t, MPI_POINTER pIOCPage6_t;
1082 1136
1083#define MPI_IOCPAGE6_PAGEVERSION (0x00) 1137#define MPI_IOCPAGE6_PAGEVERSION (0x01)
1084 1138
1085/* IOC Page 6 Capabilities Flags */ 1139/* IOC Page 6 Capabilities Flags */
1086 1140
1141#define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE (0x00000006)
1142#define MPI_IOCPAGE6_CAP_FLAGS_64MB_METADATA_SIZE (0x00000000)
1143#define MPI_IOCPAGE6_CAP_FLAGS_512MB_METADATA_SIZE (0x00000002)
1144
1087#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001) 1145#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001)
1088 1146
1089 1147
@@ -2160,6 +2218,11 @@ typedef struct _RAID_VOL0_SETTINGS
2160#define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004) 2218#define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004)
2161#define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008) 2219#define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008)
2162#define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102 (0x0020) /* obsolete */ 2220#define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102 (0x0020) /* obsolete */
2221
2222#define MPI_RAIDVOL0_SETTING_MASK_METADATA_SIZE (0x00C0)
2223#define MPI_RAIDVOL0_SETTING_64MB_METADATA_SIZE (0x0000)
2224#define MPI_RAIDVOL0_SETTING_512MB_METADATA_SIZE (0x0040)
2225
2163#define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010) 2226#define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010)
2164#define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000) 2227#define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000)
2165 2228
@@ -2203,7 +2266,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
2203} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0, 2266} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
2204 RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t; 2267 RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
2205 2268
2206#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06) 2269#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x07)
2207 2270
2208/* values for RAID Volume Page 0 InactiveStatus field */ 2271/* values for RAID Volume Page 0 InactiveStatus field */
2209#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00) 2272#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
@@ -2518,7 +2581,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2518} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, 2581} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
2519 SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; 2582 SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
2520 2583
2521#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06) 2584#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x07)
2522 2585
2523/* values for SAS IO Unit Page 1 ControlFlags */ 2586/* values for SAS IO Unit Page 1 ControlFlags */
2524#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) 2587#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
@@ -2544,7 +2607,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
2544#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) 2607#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
2545 2608
2546/* values for SAS IO Unit Page 1 AdditionalControlFlags */ 2609/* values for SAS IO Unit Page 1 AdditionalControlFlags */
2547#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001) 2610#define MPI_SAS_IOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040)
2611#define MPI_SAS_IOUNIT1_ACONTROL_HIDE_NONZERO_ATTACHED_PHY_IDENT (0x0020)
2612#define MPI_SAS_IOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010)
2613#define MPI_SAS_IOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008)
2614#define MPI_SAS_IOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004)
2615#define MPI_SAS_IOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002)
2616#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
2548 2617
2549/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */ 2618/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
2550#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F) 2619#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F)
@@ -2585,9 +2654,11 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
2585} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, 2654} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
2586 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; 2655 SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
2587 2656
2588#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x05) 2657#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x06)
2589 2658
2590/* values for SAS IO Unit Page 2 Status field */ 2659/* values for SAS IO Unit Page 2 Status field */
2660#define MPI_SAS_IOUNIT2_STATUS_DEVICE_LIMIT_EXCEEDED (0x08)
2661#define MPI_SAS_IOUNIT2_STATUS_ENCLOSURE_DEVICES_UNMAPPED (0x04)
2591#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) 2662#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
2592#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01) 2663#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01)
2593 2664
@@ -2739,24 +2810,38 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_0
2739} CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0, 2810} CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
2740 SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t; 2811 SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
2741 2812
2742#define MPI_SASDEVICE0_PAGEVERSION (0x04) 2813#define MPI_SASDEVICE0_PAGEVERSION (0x05)
2743 2814
2744/* values for SAS Device Page 0 AccessStatus field */ 2815/* values for SAS Device Page 0 AccessStatus field */
2745#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) 2816#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00)
2746#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01) 2817#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01)
2747#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02) 2818#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02)
2819#define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03)
2820/* specific values for SATA Init failures */
2821#define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10)
2822#define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11)
2823#define MPI_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12)
2824#define MPI_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13)
2825#define MPI_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14)
2826#define MPI_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15)
2827#define MPI_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16)
2828#define MPI_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17)
2829#define MPI_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18)
2830#define MPI_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19)
2831#define MPI_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F)
2748 2832
2749/* values for SAS Device Page 0 Flags field */ 2833/* values for SAS Device Page 0 Flags field */
2750#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200) 2834#define MPI_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400)
2751#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100) 2835#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200)
2752#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080) 2836#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
2753#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040) 2837#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080)
2754#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) 2838#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040)
2755#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) 2839#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020)
2756#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) 2840#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010)
2757#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004) 2841#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008)
2758#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002) 2842#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004)
2759#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) 2843#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002)
2844#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
2760 2845
2761/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */ 2846/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
2762 2847
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index 582cfe7c2aa1..d6b4c607453b 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -3,28 +3,28 @@
3 MPI Header File Change History 3 MPI Header File Change History
4 ============================== 4 ==============================
5 5
6 Copyright (c) 2000-2005 LSI Logic Corporation. 6 Copyright (c) 2000-2006 LSI Logic Corporation.
7 7
8 --------------------------------------- 8 ---------------------------------------
9 Header Set Release Version: 01.05.13 9 Header Set Release Version: 01.05.14
10 Header Set Release Date: 03-27-06 10 Header Set Release Date: 10-11-06
11 --------------------------------------- 11 ---------------------------------------
12 12
13 Filename Current version Prior version 13 Filename Current version Prior version
14 ---------- --------------- ------------- 14 ---------- --------------- -------------
15 mpi.h 01.05.11 01.05.10 15 mpi.h 01.05.12 01.05.11
16 mpi_ioc.h 01.05.11 01.05.10 16 mpi_ioc.h 01.05.12 01.05.11
17 mpi_cnfg.h 01.05.12 01.05.11 17 mpi_cnfg.h 01.05.13 01.05.12
18 mpi_init.h 01.05.07 01.05.06 18 mpi_init.h 01.05.08 01.05.07
19 mpi_targ.h 01.05.06 01.05.05 19 mpi_targ.h 01.05.06 01.05.06
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.03 01.05.02 25 mpi_sas.h 01.05.04 01.05.03
26 mpi_type.h 01.05.02 01.05.02 26 mpi_type.h 01.05.02 01.05.02
27 mpi_history.txt 01.05.13 01.05.12 27 mpi_history.txt 01.05.14 01.05.13
28 28
29 29
30 * Date Version Description 30 * Date Version Description
@@ -94,6 +94,7 @@ mpi.h
94 * 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT. 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. 95 * 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
96 * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT. 96 * 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
97 * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
97 * -------------------------------------------------------------------------- 98 * --------------------------------------------------------------------------
98 99
99mpi_ioc.h 100mpi_ioc.h
@@ -182,6 +183,14 @@ mpi_ioc.h
182 * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event 183 * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
183 * data structure. 184 * data structure.
184 * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. 185 * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
186 * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
187 * Added MaxInitiators field to PortFacts reply.
188 * Added SAS Device Status Change ReasonCode for
189 * asynchronous notificaiton.
190 * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
191 * data structure.
192 * Added new ImageType values for FWDownload and FWUpload
193 * requests.
185 * -------------------------------------------------------------------------- 194 * --------------------------------------------------------------------------
186 195
187mpi_cnfg.h 196mpi_cnfg.h
@@ -447,6 +456,23 @@ mpi_cnfg.h
447 * Added AdditionalControlFlags, MaxTargetPortConnectTime, 456 * Added AdditionalControlFlags, MaxTargetPortConnectTime,
448 * ReportDeviceMissingDelay, and IODeviceMissingDelay 457 * ReportDeviceMissingDelay, and IODeviceMissingDelay
449 * fields to SAS IO Unit Page 1. 458 * fields to SAS IO Unit Page 1.
459 * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to
460 * Manufacturing Page 5.
461 * Added Manufacturing pages 8 through 10.
462 * Added defines for supported metadata size bits in
463 * CapabilitiesFlags field of IOC Page 6.
464 * Added defines for metadata size bits in VolumeSettings
465 * field of RAID Volume Page 0.
466 * Added SATA Link Reset settings, Enable SATA Asynchronous
467 * Notification bit, and HideNonZeroAttachedPhyIdentifiers
468 * bit to AdditionalControlFlags field of SAS IO Unit
469 * Page 1.
470 * Added defines for Enclosure Devices Unmapped and
471 * Device Limit Exceeded bits in Status field of SAS IO
472 * Unit Page 2.
473 * Added more AccessStatus values for SAS Device Page 0.
474 * Added bit for SATA Asynchronous Notification Support in
475 * Flags field of SAS Device Page 0.
450 * -------------------------------------------------------------------------- 476 * --------------------------------------------------------------------------
451 477
452mpi_init.h 478mpi_init.h
@@ -490,6 +516,7 @@ mpi_init.h
490 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them 516 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
491 * unique in the first 32 characters. 517 * unique in the first 32 characters.
492 * 03-27-06 01.05.07 Added Task Management type of Clear ACA. 518 * 03-27-06 01.05.07 Added Task Management type of Clear ACA.
519 * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA.
493 * -------------------------------------------------------------------------- 520 * --------------------------------------------------------------------------
494 521
495mpi_targ.h 522mpi_targ.h
@@ -638,6 +665,8 @@ mpi_sas.h
638 * and Remove Device operations to SAS IO Unit Control. 665 * and Remove Device operations to SAS IO Unit Control.
639 * Added DevHandle field to SAS IO Unit Control request and 666 * Added DevHandle field to SAS IO Unit Control request and
640 * reply. 667 * reply.
668 * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
669 * Unit Control request.
641 * -------------------------------------------------------------------------- 670 * --------------------------------------------------------------------------
642 671
643mpi_type.h 672mpi_type.h
@@ -653,20 +682,20 @@ mpi_type.h
653 682
654mpi_history.txt Parts list history 683mpi_history.txt Parts list history
655 684
656Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 685Filename 01.05.13 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
657---------- -------- -------- -------- -------- -------- 686---------- -------- -------- -------- -------- -------- --------
658mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07 687mpi.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07
659mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08 688mpi_ioc.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08
660mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 689mpi_cnfg.h 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08
661mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04 690mpi_init.h 01.05.08 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04
662mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04 691mpi_targ.h 01.05.06 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04
663mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 692mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
664mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 693mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
665mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 694mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
666mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 695mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
667mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 696mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
668mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01 697mpi_sas.h 01.05.04 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01
669mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01 698mpi_type.h 01.05.02 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01
670 699
671Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 700Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
672---------- -------- -------- -------- -------- -------- -------- 701---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index c1c678989a23..ec9dff2249a7 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2005 LSI Logic Corporation. 2 * Copyright (c) 2000-2006 LSI Logic Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi_init.h 5 * Name: mpi_init.h
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.07 9 * mpi_init.h Version: 01.05.08
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -53,6 +53,7 @@
53 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them 53 * 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
54 * unique in the first 32 characters. 54 * unique in the first 32 characters.
55 * 03-27-06 01.05.07 Added Task Management type of Clear ACA. 55 * 03-27-06 01.05.07 Added Task Management type of Clear ACA.
56 * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA.
56 * -------------------------------------------------------------------------- 57 * --------------------------------------------------------------------------
57 */ 58 */
58 59
@@ -428,7 +429,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
428#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) 429#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
429#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) 430#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
430#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) 431#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
431#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) 432#define MPI_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
432 433
433/* MsgFlags bits */ 434/* MsgFlags bits */
434#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00) 435#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 18ba407fd399..6c33e3353375 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2005 LSI Logic Corporation. 2 * Copyright (c) 2000-2006 LSI Logic Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi_ioc.h 5 * Name: mpi_ioc.h
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.11 9 * mpi_ioc.h Version: 01.05.12
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -98,6 +98,14 @@
98 * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event 98 * Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
99 * data structure. 99 * data structure.
100 * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION. 100 * Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
101 * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
102 * Added MaxInitiators field to PortFacts reply.
103 * Added SAS Device Status Change ReasonCode for
104 * asynchronous notificaiton.
105 * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
106 * data structure.
107 * Added new ImageType values for FWDownload and FWUpload
108 * requests.
101 * -------------------------------------------------------------------------- 109 * --------------------------------------------------------------------------
102 */ 110 */
103 111
@@ -264,6 +272,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
264#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002) 272#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
265#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004) 273#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
266#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008) 274#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008)
275#define MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010)
267 276
268#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01) 277#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
269#define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02) 278#define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
@@ -328,7 +337,8 @@ typedef struct _MSG_PORT_FACTS_REPLY
328 U16 MaxPostedCmdBuffers; /* 1Ch */ 337 U16 MaxPostedCmdBuffers; /* 1Ch */
329 U16 MaxPersistentIDs; /* 1Eh */ 338 U16 MaxPersistentIDs; /* 1Eh */
330 U16 MaxLanBuckets; /* 20h */ 339 U16 MaxLanBuckets; /* 20h */
331 U16 Reserved4; /* 22h */ 340 U8 MaxInitiators; /* 22h */
341 U8 Reserved4; /* 23h */
332 U32 Reserved5; /* 24h */ 342 U32 Reserved5; /* 24h */
333} MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY, 343} MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
334 PortFactsReply_t, MPI_POINTER pPortFactsReply_t; 344 PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
@@ -487,6 +497,7 @@ typedef struct _MSG_EVENT_ACK_REPLY
487#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018) 497#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018)
488#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019) 498#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019)
489#define MPI_EVENT_SAS_SMP_ERROR (0x0000001A) 499#define MPI_EVENT_SAS_SMP_ERROR (0x0000001A)
500#define MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE (0x0000001B)
490#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021) 501#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
491 502
492/* AckRequired field values */ 503/* AckRequired field values */
@@ -593,6 +604,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
593#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) 604#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
594#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) 605#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
595#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) 606#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
607#define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
596 608
597 609
598/* SCSI Event data for Queue Full event */ 610/* SCSI Event data for Queue Full event */
@@ -895,6 +907,54 @@ typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
895 MpiEventDataSasInitTableOverflow_t, 907 MpiEventDataSasInitTableOverflow_t,
896 MPI_POINTER pMpiEventDataSasInitTableOverflow_t; 908 MPI_POINTER pMpiEventDataSasInitTableOverflow_t;
897 909
910/* SAS Expander Status Change Event data */
911
912typedef struct _EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE
913{
914 U8 ReasonCode; /* 00h */
915 U8 Reserved1; /* 01h */
916 U16 Reserved2; /* 02h */
917 U8 PhysicalPort; /* 04h */
918 U8 Reserved3; /* 05h */
919 U16 EnclosureHandle; /* 06h */
920 U64 SASAddress; /* 08h */
921 U32 DiscoveryStatus; /* 10h */
922 U16 DevHandle; /* 14h */
923 U16 ParentDevHandle; /* 16h */
924 U16 ExpanderChangeCount; /* 18h */
925 U16 ExpanderRouteIndexes; /* 1Ah */
926 U8 NumPhys; /* 1Ch */
927 U8 SASLevel; /* 1Dh */
928 U8 Flags; /* 1Eh */
929 U8 Reserved4; /* 1Fh */
930} EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
931 MPI_POINTER PTR_EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
932 MpiEventDataSasExpanderStatusChange_t,
933 MPI_POINTER pMpiEventDataSasExpanderStatusChange_t;
934
935/* values for ReasonCode field of SAS Expander Status Change Event data */
936#define MPI_EVENT_SAS_EXP_RC_ADDED (0x00)
937#define MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING (0x01)
938
939/* values for DiscoveryStatus field of SAS Expander Status Change Event data */
940#define MPI_EVENT_SAS_EXP_DS_LOOP_DETECTED (0x00000001)
941#define MPI_EVENT_SAS_EXP_DS_UNADDRESSABLE_DEVICE (0x00000002)
942#define MPI_EVENT_SAS_EXP_DS_MULTIPLE_PORTS (0x00000004)
943#define MPI_EVENT_SAS_EXP_DS_EXPANDER_ERR (0x00000008)
944#define MPI_EVENT_SAS_EXP_DS_SMP_TIMEOUT (0x00000010)
945#define MPI_EVENT_SAS_EXP_DS_OUT_ROUTE_ENTRIES (0x00000020)
946#define MPI_EVENT_SAS_EXP_DS_INDEX_NOT_EXIST (0x00000040)
947#define MPI_EVENT_SAS_EXP_DS_SMP_FUNCTION_FAILED (0x00000080)
948#define MPI_EVENT_SAS_EXP_DS_SMP_CRC_ERROR (0x00000100)
949#define MPI_EVENT_SAS_EXP_DS_SUBTRACTIVE_LINK (0x00000200)
950#define MPI_EVENT_SAS_EXP_DS_TABLE_LINK (0x00000400)
951#define MPI_EVENT_SAS_EXP_DS_UNSUPPORTED_DEVICE (0x00000800)
952
953/* values for Flags field of SAS Expander Status Change Event data */
954#define MPI_EVENT_SAS_EXP_FLAGS_ROUTE_TABLE_CONFIG (0x02)
955#define MPI_EVENT_SAS_EXP_FLAGS_CONFIG_IN_PROGRESS (0x01)
956
957
898 958
899/***************************************************************************** 959/*****************************************************************************
900* 960*
@@ -926,6 +986,10 @@ typedef struct _MSG_FW_DOWNLOAD
926#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02) 986#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
927#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03) 987#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
928#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04) 988#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04)
989#define MPI_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06)
990#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07)
991#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08)
992#define MPI_FW_DOWNLOAD_ITYPE_MEGARAID (0x09)
929 993
930 994
931typedef struct _FWDownloadTCSGE 995typedef struct _FWDownloadTCSGE
@@ -980,6 +1044,11 @@ typedef struct _MSG_FW_UPLOAD
980#define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03) 1044#define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03)
981#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04) 1045#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04)
982#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05) 1046#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05)
1047#define MPI_FW_UPLOAD_ITYPE_MANUFACTURING (0x06)
1048#define MPI_FW_UPLOAD_ITYPE_CONFIG_1 (0x07)
1049#define MPI_FW_UPLOAD_ITYPE_CONFIG_2 (0x08)
1050#define MPI_FW_UPLOAD_ITYPE_MEGARAID (0x09)
1051#define MPI_FW_UPLOAD_ITYPE_COMPLETE (0x0A)
983 1052
984typedef struct _FWUploadTCSGE 1053typedef struct _FWUploadTCSGE
985{ 1054{
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index 871ebc08b706..635bbe04513e 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -1,4 +1,3 @@
1
2/*************************************************************************** 1/***************************************************************************
3 * * 2 * *
4 * Copyright 2003 LSI Logic Corporation. All rights reserved. * 3 * Copyright 2003 LSI Logic Corporation. All rights reserved. *
@@ -14,7 +13,7 @@
14#define IOPI_IOCLOGINFO_H_INCLUDED 13#define IOPI_IOCLOGINFO_H_INCLUDED
15 14
16#define SAS_LOGINFO_NEXUS_LOSS 0x31170000 15#define SAS_LOGINFO_NEXUS_LOSS 0x31170000
17#define SAS_LOGINFO_MASK 0xFFFF0000 16#define SAS_LOGINFO_MASK 0xFFFF0000
18 17
19/****************************************************************************/ 18/****************************************************************************/
20/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */ 19/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
@@ -43,129 +42,172 @@
43/****************************************************************************/ 42/****************************************************************************/
44/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */ 43/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */
45/****************************************************************************/ 44/****************************************************************************/
46#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000) 45#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)
47#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000) 46#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)
48#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000) 47#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)
49#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */ 48#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */
50#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */ 49#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */
51#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */ 50#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */
52#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */ 51#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */
53#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */ 52#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
54#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */ 53#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
55#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */ 54#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
56 55
57#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */ 56#define IOP_LOGINFO_CODE_FWUPLOAD_NO_FLASH_AVAILABLE (0x0003E000) /* Tried to upload from flash, but there is none */
58 57#define IOP_LOGINFO_CODE_FWUPLOAD_UNKNOWN_IMAGE_TYPE (0x0003E001) /* ImageType field contents were invalid */
59#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000) 58#define IOP_LOGINFO_CODE_FWUPLOAD_WRONG_IMAGE_SIZE (0x0003E002) /* ImageSize field in TCSGE was bad/offset in MfgPg 4 was wrong */
60 59#define IOP_LOGINFO_CODE_FWUPLOAD_ENTIRE_FLASH_UPLOAD_FAILED (0x0003E003) /* Error occured while attempting to upload the entire flash */
61#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */ 60#define IOP_LOGINFO_CODE_FWUPLOAD_REGION_UPLOAD_FAILED (0x0003E004) /* Error occured while attempting to upload single flash region */
62#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */ 61#define IOP_LOGINFO_CODE_FWUPLOAD_DMA_FAILURE (0x0003E005) /* Problem occured while DMAing FW to host memory */
63 62
64#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001) 63#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */
65#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002) 64
66#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003) 65#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
67#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004) 66
68#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005) 67#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
68#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
69
70#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
71#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
72#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
73#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
74#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
69 75
70/****************************************************************************/ 76/****************************************************************************/
71/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */ 77/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
72/****************************************************************************/ 78/****************************************************************************/
73#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) 79#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) /* see SUB_CODE_OPEN_FAIL_ below */
74#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001) 80
75#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011) 81#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_NO_DEST_TIME_OUT (0x00000001)
76#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013) 82#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATHWAY_BLOCKED (0x00000002)
77#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018) 83#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE0 (0x00000003)
78#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019) 84#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE1 (0x00000004)
79#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A) 85#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE0 (0x00000005)
80#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B) 86#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE1 (0x00000006)
81#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C) 87#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP0 (0x00000007)
82#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000) 88#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP1 (0x00000008)
83#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000) 89#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RETRY (0x00000009)
84#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000) 90#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_BREAK (0x0000000A)
85#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000) 91#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0B (0x0000000B)
86#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000) 92#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_OPEN_TIMEOUT_EXP (0x0000000C)
87#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000) 93#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0D (0x0000000D)
88#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000) 94#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_DVTBLE_ACCSS_FAIL (0x0000000E)
89#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000) 95#define PL_LOGINFO_SUB CODE_OPEN_FAIL_BAD_DEST (0x00000011)
90#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000) 96#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RATE_NOT_SUPP (0x00000012)
91#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000) 97#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PROT_NOT_SUPP (0x00000013)
92#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000) 98#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON0 (0x00000014)
93#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000) 99#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON1 (0x00000015)
94#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000) 100#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON2 (0x00000016)
95#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000) 101#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON3 (0x00000017)
96#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */ 102#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_STP_RESOURCES_BSY (0x00000018)
97#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */ 103#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_WRONG_DESTINATION (0x00000019)
98#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */ 104
99#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */ 105#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATH_BLOCKED (0x0000001B) /* Retry Timeout */
100#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */ 106#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_AWT_MAXED (0x0000001C) /* Retry Timeout */
101#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */ 107
102#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */ 108
103#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */ 109
104#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000) 110#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
105#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */ 111#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
106#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */ 112#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
107#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000) 113#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)
108#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000) 114#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)
109#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000) 115#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)
110#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000) 116#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)
111#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000) 117#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)
112#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100) 118#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)
113#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101) 119#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)
114#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */ 120#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)
115#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B) 121#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
116#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */ 122#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
117 123#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
118#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120) 124#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
119#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */ 125#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
120#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */ 126#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
121 127#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
122 128#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */
123#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200) 129#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */
124#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300) 130#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
125#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) 131#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
126#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500) 132#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
127#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600) 133#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE) */
128#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700) 134#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE)*/
129#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800) 135#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
130#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900) 136#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
131#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00) 137#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
132#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00) 138#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
133#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00) 139#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000)
134#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00) 140#define PL_LOGINFO_CODE_IO_CANCELLED_DUE_TO_R_ERR (0x00180000)
135#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00) 141#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
136#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01) 142#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
137#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00) 143#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_SATA_NEG_RATE_2HI (0x00000102)
138#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000) 144#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_RATE_NOT_SUPPORTED (0x00000103)
139 145#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_BREAK (0x00000104)
140 146#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ZONE_VIOLATION (0x00000114)
141#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */ 147#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON0 (0x00000114) /* Open Reject (Zone Violation) - available on SAS-2 devices */
142#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */ 148#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON1 (0x00000115)
143#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */ 149#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON2 (0x00000116)
144#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */ 150#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON3 (0x00000117)
145#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */ 151#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
146#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */ 152#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATH_BLOCKED (0x0000011B)
147#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */ 153#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
148#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */ 154
149#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */ 155#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
150#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */ 156#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
151#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */ 157#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
152#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */ 158
153#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */ 159
154#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */ 160#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
155 161#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
156#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */ 162#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) /* Bits 0-3 encode Transport Status Register (offset 0x08) */
157#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */ 163 /* Bit 0 is Status Bit 0: FrameXferErr */
158#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */ 164 /* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */
159#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */ 165 /* Bit 3 is Status Bit 18 WriteDataLenghtGTDataLengthErr */
160#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */ 166
161#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */ 167#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
162#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */ 168#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
163#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */ 169#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)
164#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */ 170#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
165#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */ 171#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
166#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */ 172#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)
167#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/ 173#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)
168#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */ 174#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
175#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
176#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
177#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
178#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
179#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
180
181#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
182#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
183#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
184#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
185#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
186#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
187#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
188#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
189#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
190#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
191#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
192#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
193#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
194#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
195
196#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
197#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
198#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
199#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
200#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
201#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
202#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
203#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
204#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
205#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
206#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
207#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
208#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode f/w location 1 */
209#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_2 (0x0020010D) /* SEP doesn't support CDB opcode f/w location 2 */
210#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_3 (0x0020010E) /* SEP doesn't support CDB opcode f/w location 3 */
169 211
170 212
171/****************************************************************************/ 213/****************************************************************************/
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index 50b8f0a8f456..8e990a0fa7a2 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2004 LSI Logic Corporation. 2 * Copyright (c) 2004-2006 LSI Logic Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi_sas.h 5 * Name: mpi_sas.h
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.03 9 * mpi_sas.h Version: 01.05.04
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -21,6 +21,8 @@
21 * and Remove Device operations to SAS IO Unit Control. 21 * and Remove Device operations to SAS IO Unit Control.
22 * Added DevHandle field to SAS IO Unit Control request and 22 * Added DevHandle field to SAS IO Unit Control request and
23 * reply. 23 * reply.
24 * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
25 * Unit Control request.
24 * -------------------------------------------------------------------------- 26 * --------------------------------------------------------------------------
25 */ 27 */
26 28
@@ -237,7 +239,8 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
237#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A) 239#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
238#define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) 240#define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
239#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) 241#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
240#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) 242#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) /* obsolete name */
243#define MPI_SAS_OP_REMOVE_DEVICE (0x0D)
241 244
242/* values for the PrimFlags field */ 245/* values for the PrimFlags field */
243#define MPI_SAS_PRIMFLAGS_SINGLE (0x08) 246#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index b3f28a03b6a9..083acfd91d8b 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -6,7 +6,7 @@
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2007 LSI Logic Corporation 8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com) 9 * (mailto:mpt_linux_developer@lsi.com)
10 * 10 *
11 */ 11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -82,6 +82,10 @@ static int mpt_msi_enable;
82module_param(mpt_msi_enable, int, 0); 82module_param(mpt_msi_enable, int, 0);
83MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); 83MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
84 84
85static int mpt_channel_mapping;
86module_param(mpt_channel_mapping, int, 0);
87MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
88
85#ifdef MFCNT 89#ifdef MFCNT
86static int mfcounter = 0; 90static int mfcounter = 0;
87#define PRINT_MF_COUNT 20000 91#define PRINT_MF_COUNT 20000
@@ -173,11 +177,14 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
173 177
174//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 178//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
175static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); 179static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
176static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 180#ifdef MPT_DEBUG_REPLY
181static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
182#endif
177static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 183static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
178static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 184static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
179static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 185static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
180static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 186static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
187static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
181 188
182/* module entry point */ 189/* module entry point */
183static int __init fusion_init (void); 190static int __init fusion_init (void);
@@ -319,13 +326,11 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
319 else if (ioc->bus_type == SAS) 326 else if (ioc->bus_type == SAS)
320 mpt_sas_log_info(ioc, log_info); 327 mpt_sas_log_info(ioc, log_info);
321 } 328 }
322 if (ioc_stat & MPI_IOCSTATUS_MASK) {
323 if (ioc->bus_type == SPI &&
324 cb_idx != mpt_stm_index &&
325 cb_idx != mpt_lan_index)
326 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
327 }
328 329
330#ifdef MPT_DEBUG_REPLY
331 if (ioc_stat & MPI_IOCSTATUS_MASK)
332 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
333#endif
329 334
330 /* Check for (valid) IO callback! */ 335 /* Check for (valid) IO callback! */
331 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 336 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
@@ -911,7 +916,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
911int 916int
912mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) 917mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
913{ 918{
914 int r = 0; 919 int r = 0;
915 u8 *req_as_bytes; 920 u8 *req_as_bytes;
916 int ii; 921 int ii;
917 922
@@ -1811,6 +1816,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1811 * and we try GetLanConfigPages again... 1816 * and we try GetLanConfigPages again...
1812 */ 1817 */
1813 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 1818 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1819
1820 /*
1821 * Initalize link list for inactive raid volumes.
1822 */
1823 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
1824 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
1825
1814 if (ioc->bus_type == SAS) { 1826 if (ioc->bus_type == SAS) {
1815 1827
1816 /* clear persistency table */ 1828 /* clear persistency table */
@@ -2017,6 +2029,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2017 } 2029 }
2018 2030
2019 kfree(ioc->spi_data.nvram); 2031 kfree(ioc->spi_data.nvram);
2032 mpt_inactive_raid_list_free(ioc);
2033 kfree(ioc->raid_data.pIocPg2);
2020 kfree(ioc->raid_data.pIocPg3); 2034 kfree(ioc->raid_data.pIocPg3);
2021 ioc->spi_data.nvram = NULL; 2035 ioc->spi_data.nvram = NULL;
2022 ioc->raid_data.pIocPg3 = NULL; 2036 ioc->raid_data.pIocPg3 = NULL;
@@ -2413,6 +2427,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2413 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 2427 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2414 2428
2415 facts->ProductID = le16_to_cpu(facts->ProductID); 2429 facts->ProductID = le16_to_cpu(facts->ProductID);
2430 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2431 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2432 ioc->ir_firmware = 1;
2416 facts->CurrentHostMfaHighAddr = 2433 facts->CurrentHostMfaHighAddr =
2417 le32_to_cpu(facts->CurrentHostMfaHighAddr); 2434 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2418 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 2435 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
@@ -2505,6 +2522,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2505 int ii; 2522 int ii;
2506 int req_sz; 2523 int req_sz;
2507 int reply_sz; 2524 int reply_sz;
2525 int max_id;
2508 2526
2509 /* IOC *must* NOT be in RESET state! */ 2527 /* IOC *must* NOT be in RESET state! */
2510 if (ioc->last_state == MPI_IOC_STATE_RESET) { 2528 if (ioc->last_state == MPI_IOC_STATE_RESET) {
@@ -2552,6 +2570,21 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2552 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); 2570 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2553 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); 2571 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2554 2572
2573 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2574 pfacts->MaxDevices;
2575 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2576 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2577
2578 /*
2579 * Place all the devices on channels
2580 *
2581 * (for debuging)
2582 */
2583 if (mpt_channel_mapping) {
2584 ioc->devices_per_bus = 1;
2585 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2586 }
2587
2555 return 0; 2588 return 0;
2556} 2589}
2557 2590
@@ -2592,13 +2625,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2592 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n", 2625 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2593 ioc->name, ioc->upload_fw, ioc->facts.Flags)); 2626 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2594 2627
2595 if(ioc->bus_type == SAS) 2628 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2596 ioc_init.MaxDevices = ioc->facts.MaxDevices; 2629 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2597 else if(ioc->bus_type == FC)
2598 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2599 else
2600 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2601 ioc_init.MaxBuses = MPT_MAX_BUS;
2602 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n", 2630 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2603 ioc->name, ioc->facts.MsgVersion)); 2631 ioc->name, ioc->facts.MsgVersion));
2604 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 2632 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
@@ -2720,9 +2748,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2720 2748
2721 /* RAID FW may take a long time to enable 2749 /* RAID FW may take a long time to enable
2722 */ 2750 */
2723 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 2751 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2724 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2725 (ioc->bus_type == SAS)) {
2726 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 2752 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2727 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 2753 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2728 300 /*seconds*/, sleepFlag); 2754 300 /*seconds*/, sleepFlag);
@@ -3193,6 +3219,9 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3193 u32 diag1val = 0; 3219 u32 diag1val = 0;
3194#endif 3220#endif
3195 3221
3222 /* Clear any existing interrupts */
3223 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3224
3196 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3225 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3197 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3226 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3198 "address=%p\n", ioc->name, __FUNCTION__, 3227 "address=%p\n", ioc->name, __FUNCTION__,
@@ -3212,7 +3241,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3212 " count=%d\n", 3241 " count=%d\n",
3213 ioc->name, doorbell, count)); 3242 ioc->name, doorbell, count));
3214 if (doorbell == MPI_IOC_STATE_READY) { 3243 if (doorbell == MPI_IOC_STATE_READY) {
3215 return 0; 3244 return 1;
3216 } 3245 }
3217 3246
3218 /* wait 1 sec */ 3247 /* wait 1 sec */
@@ -3224,9 +3253,6 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3224 return -1; 3253 return -1;
3225 } 3254 }
3226 3255
3227 /* Clear any existing interrupts */
3228 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3229
3230 /* Use "Diagnostic reset" method! (only thing available!) */ 3256 /* Use "Diagnostic reset" method! (only thing available!) */
3231 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3257 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3232 3258
@@ -3942,7 +3968,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3942 } 3968 }
3943 } else { 3969 } else {
3944 while (--cntdn) { 3970 while (--cntdn) {
3945 mdelay (1); 3971 udelay (1000);
3946 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 3972 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3947 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 3973 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3948 break; 3974 break;
@@ -3994,7 +4020,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3994 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4020 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3995 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4021 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3996 break; 4022 break;
3997 mdelay(1); 4023 udelay (1000);
3998 count++; 4024 count++;
3999 } 4025 }
4000 } 4026 }
@@ -4310,8 +4336,8 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4310 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && 4336 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4311 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || 4337 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4312 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { 4338 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4313 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", 4339 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4314 ioc->name, disk); 4340 ioc->name, disk, volume);
4315 } else { 4341 } else {
4316 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", 4342 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4317 ioc->name, volume); 4343 ioc->name, volume);
@@ -4712,7 +4738,187 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4712 return 0; 4738 return 0;
4713} 4739}
4714 4740
4715/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4741/**
4742 * mpt_inactive_raid_list_free
4743 *
4744 * This clears this link list.
4745 *
4746 * @ioc - pointer to per adapter structure
4747 *
4748 **/
4749static void
4750mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4751{
4752 struct inactive_raid_component_info *component_info, *pNext;
4753
4754 if (list_empty(&ioc->raid_data.inactive_list))
4755 return;
4756
4757 down(&ioc->raid_data.inactive_list_mutex);
4758 list_for_each_entry_safe(component_info, pNext,
4759 &ioc->raid_data.inactive_list, list) {
4760 list_del(&component_info->list);
4761 kfree(component_info);
4762 }
4763 up(&ioc->raid_data.inactive_list_mutex);
4764}
4765
4766/**
4767 * mpt_inactive_raid_volumes
4768 *
4769 * This sets up link list of phy_disk_nums for devices belonging in an inactive volume
4770 *
4771 * @ioc - pointer to per adapter structure
4772 * @channel - volume channel
4773 * @id - volume target id
4774 *
4775 *
4776 **/
4777static void
4778mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4779{
4780 CONFIGPARMS cfg;
4781 ConfigPageHeader_t hdr;
4782 dma_addr_t dma_handle;
4783 pRaidVolumePage0_t buffer = NULL;
4784 int i;
4785 RaidPhysDiskPage0_t phys_disk;
4786 struct inactive_raid_component_info *component_info;
4787 int handle_inactive_volumes;
4788
4789 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4790 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4791 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4792 cfg.pageAddr = (channel << 8) + id;
4793 cfg.cfghdr.hdr = &hdr;
4794 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4795
4796 if (mpt_config(ioc, &cfg) != 0)
4797 goto out;
4798
4799 if (!hdr.PageLength)
4800 goto out;
4801
4802 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4803 &dma_handle);
4804
4805 if (!buffer)
4806 goto out;
4807
4808 cfg.physAddr = dma_handle;
4809 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4810
4811 if (mpt_config(ioc, &cfg) != 0)
4812 goto out;
4813
4814 if (!buffer->NumPhysDisks)
4815 goto out;
4816
4817 handle_inactive_volumes =
4818 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
4819 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
4820 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
4821 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
4822
4823 if (!handle_inactive_volumes)
4824 goto out;
4825
4826 down(&ioc->raid_data.inactive_list_mutex);
4827 for (i = 0; i < buffer->NumPhysDisks; i++) {
4828 if(mpt_raid_phys_disk_pg0(ioc,
4829 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4830 continue;
4831
4832 if ((component_info = kmalloc(sizeof (*component_info),
4833 GFP_KERNEL)) == NULL)
4834 continue;
4835
4836 component_info->volumeID = id;
4837 component_info->volumeBus = channel;
4838 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
4839 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
4840 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
4841 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
4842
4843 list_add_tail(&component_info->list,
4844 &ioc->raid_data.inactive_list);
4845 }
4846 up(&ioc->raid_data.inactive_list_mutex);
4847
4848 out:
4849 if (buffer)
4850 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4851 dma_handle);
4852}
4853
4854/**
4855 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
4856 * @ioc: Pointer to a Adapter Structure
4857 * @phys_disk_num: io unit unique phys disk num generated by the ioc
4858 * @phys_disk: requested payload data returned
4859 *
4860 * Return:
4861 * 0 on success
4862 * -EFAULT if read of config page header fails or data pointer not NULL
4863 * -ENOMEM if pci_alloc failed
4864 **/
4865int
4866mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
4867{
4868 CONFIGPARMS cfg;
4869 ConfigPageHeader_t hdr;
4870 dma_addr_t dma_handle;
4871 pRaidPhysDiskPage0_t buffer = NULL;
4872 int rc;
4873
4874 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4875 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4876
4877 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
4878 cfg.cfghdr.hdr = &hdr;
4879 cfg.physAddr = -1;
4880 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4881
4882 if (mpt_config(ioc, &cfg) != 0) {
4883 rc = -EFAULT;
4884 goto out;
4885 }
4886
4887 if (!hdr.PageLength) {
4888 rc = -EFAULT;
4889 goto out;
4890 }
4891
4892 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4893 &dma_handle);
4894
4895 if (!buffer) {
4896 rc = -ENOMEM;
4897 goto out;
4898 }
4899
4900 cfg.physAddr = dma_handle;
4901 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4902 cfg.pageAddr = phys_disk_num;
4903
4904 if (mpt_config(ioc, &cfg) != 0) {
4905 rc = -EFAULT;
4906 goto out;
4907 }
4908
4909 rc = 0;
4910 memcpy(phys_disk, buffer, sizeof(*buffer));
4911 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
4912
4913 out:
4914
4915 if (buffer)
4916 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4917 dma_handle);
4918
4919 return rc;
4920}
4921
4716/** 4922/**
4717 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 4923 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4718 * @ioc: Pointer to a Adapter Strucutre 4924 * @ioc: Pointer to a Adapter Strucutre
@@ -4722,21 +4928,27 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4722 * 0 on success 4928 * 0 on success
4723 * -EFAULT if read of config page header fails or data pointer not NULL 4929 * -EFAULT if read of config page header fails or data pointer not NULL
4724 * -ENOMEM if pci_alloc failed 4930 * -ENOMEM if pci_alloc failed
4725 */ 4931 **/
4726int 4932int
4727mpt_findImVolumes(MPT_ADAPTER *ioc) 4933mpt_findImVolumes(MPT_ADAPTER *ioc)
4728{ 4934{
4729 IOCPage2_t *pIoc2; 4935 IOCPage2_t *pIoc2;
4730 u8 *mem; 4936 u8 *mem;
4731 ConfigPageIoc2RaidVol_t *pIocRv;
4732 dma_addr_t ioc2_dma; 4937 dma_addr_t ioc2_dma;
4733 CONFIGPARMS cfg; 4938 CONFIGPARMS cfg;
4734 ConfigPageHeader_t header; 4939 ConfigPageHeader_t header;
4735 int jj;
4736 int rc = 0; 4940 int rc = 0;
4737 int iocpage2sz; 4941 int iocpage2sz;
4738 u8 nVols, nPhys; 4942 int i;
4739 u8 vid, vbus, vioc; 4943
4944 if (!ioc->ir_firmware)
4945 return 0;
4946
4947 /* Free the old page
4948 */
4949 kfree(ioc->raid_data.pIocPg2);
4950 ioc->raid_data.pIocPg2 = NULL;
4951 mpt_inactive_raid_list_free(ioc);
4740 4952
4741 /* Read IOCP2 header then the page. 4953 /* Read IOCP2 header then the page.
4742 */ 4954 */
@@ -4764,55 +4976,23 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4764 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4976 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4765 cfg.physAddr = ioc2_dma; 4977 cfg.physAddr = ioc2_dma;
4766 if (mpt_config(ioc, &cfg) != 0) 4978 if (mpt_config(ioc, &cfg) != 0)
4767 goto done_and_free; 4979 goto out;
4980
4981 mem = kmalloc(iocpage2sz, GFP_KERNEL);
4982 if (!mem)
4983 goto out;
4768 4984
4769 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4770 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4771 if (mem) {
4772 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4773 } else {
4774 goto done_and_free;
4775 }
4776 }
4777 memcpy(mem, (u8 *)pIoc2, iocpage2sz); 4985 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4986 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4778 4987
4779 /* Identify RAID Volume Id's */ 4988 mpt_read_ioc_pg_3(ioc);
4780 nVols = pIoc2->NumActiveVolumes;
4781 if ( nVols == 0) {
4782 /* No RAID Volume.
4783 */
4784 goto done_and_free;
4785 } else {
4786 /* At least 1 RAID Volume
4787 */
4788 pIocRv = pIoc2->RaidVolume;
4789 ioc->raid_data.isRaid = 0;
4790 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4791 vid = pIocRv->VolumeID;
4792 vbus = pIocRv->VolumeBus;
4793 vioc = pIocRv->VolumeIOC;
4794
4795 /* find the match
4796 */
4797 if (vbus == 0) {
4798 ioc->raid_data.isRaid |= (1 << vid);
4799 } else {
4800 /* Error! Always bus 0
4801 */
4802 }
4803 }
4804 }
4805 4989
4806 /* Identify Hidden Physical Disk Id's */ 4990 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
4807 nPhys = pIoc2->NumActivePhysDisks; 4991 mpt_inactive_raid_volumes(ioc,
4808 if (nPhys == 0) { 4992 pIoc2->RaidVolume[i].VolumeBus,
4809 /* No physical disks. 4993 pIoc2->RaidVolume[i].VolumeID);
4810 */
4811 } else {
4812 mpt_read_ioc_pg_3(ioc);
4813 }
4814 4994
4815done_and_free: 4995 out:
4816 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); 4996 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4817 4997
4818 return rc; 4998 return rc;
@@ -4865,7 +5045,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4865 cfg.physAddr = ioc3_dma; 5045 cfg.physAddr = ioc3_dma;
4866 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5046 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4867 if (mpt_config(ioc, &cfg) == 0) { 5047 if (mpt_config(ioc, &cfg) == 0) {
4868 mem = kmalloc(iocpage3sz, GFP_ATOMIC); 5048 mem = kmalloc(iocpage3sz, GFP_KERNEL);
4869 if (mem) { 5049 if (mem) {
4870 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 5050 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4871 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; 5051 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
@@ -5679,8 +5859,6 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5679 return rc; 5859 return rc;
5680} 5860}
5681 5861
5682# define EVENT_DESCR_STR_SZ 100
5683
5684/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5862/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5685static void 5863static void
5686EventDescriptionStr(u8 event, u32 evData0, char *evStr) 5864EventDescriptionStr(u8 event, u32 evData0, char *evStr)
@@ -5708,9 +5886,6 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5708 break; 5886 break;
5709 case MPI_EVENT_RESCAN: 5887 case MPI_EVENT_RESCAN:
5710 ds = "Bus Rescan Event"; 5888 ds = "Bus Rescan Event";
5711 /* Ok, do we need to do anything here? As far as
5712 I can tell, this is when a new device gets added
5713 to the loop. */
5714 break; 5889 break;
5715 case MPI_EVENT_LINK_STATUS_CHANGE: 5890 case MPI_EVENT_LINK_STATUS_CHANGE:
5716 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) 5891 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
@@ -5787,48 +5962,63 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5787 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 5962 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5788 { 5963 {
5789 u8 id = (u8)(evData0); 5964 u8 id = (u8)(evData0);
5965 u8 channel = (u8)(evData0 >> 8);
5790 u8 ReasonCode = (u8)(evData0 >> 16); 5966 u8 ReasonCode = (u8)(evData0 >> 16);
5791 switch (ReasonCode) { 5967 switch (ReasonCode) {
5792 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 5968 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5793 snprintf(evStr, EVENT_DESCR_STR_SZ, 5969 snprintf(evStr, EVENT_DESCR_STR_SZ,
5794 "SAS Device Status Change: Added: id=%d", id); 5970 "SAS Device Status Change: Added: "
5971 "id=%d channel=%d", id, channel);
5795 break; 5972 break;
5796 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 5973 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5797 snprintf(evStr, EVENT_DESCR_STR_SZ, 5974 snprintf(evStr, EVENT_DESCR_STR_SZ,
5798 "SAS Device Status Change: Deleted: id=%d", id); 5975 "SAS Device Status Change: Deleted: "
5976 "id=%d channel=%d", id, channel);
5799 break; 5977 break;
5800 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 5978 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5801 snprintf(evStr, EVENT_DESCR_STR_SZ, 5979 snprintf(evStr, EVENT_DESCR_STR_SZ,
5802 "SAS Device Status Change: SMART Data: id=%d", 5980 "SAS Device Status Change: SMART Data: "
5803 id); 5981 "id=%d channel=%d", id, channel);
5804 break; 5982 break;
5805 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 5983 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5806 snprintf(evStr, EVENT_DESCR_STR_SZ, 5984 snprintf(evStr, EVENT_DESCR_STR_SZ,
5807 "SAS Device Status Change: No Persistancy: id=%d", id); 5985 "SAS Device Status Change: No Persistancy: "
5986 "id=%d channel=%d", id, channel);
5987 break;
5988 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
5989 snprintf(evStr, EVENT_DESCR_STR_SZ,
5990 "SAS Device Status Change: Unsupported Device "
5991 "Discovered : id=%d channel=%d", id, channel);
5808 break; 5992 break;
5809 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 5993 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5810 snprintf(evStr, EVENT_DESCR_STR_SZ, 5994 snprintf(evStr, EVENT_DESCR_STR_SZ,
5811 "SAS Device Status Change: Internal Device Reset : id=%d", id); 5995 "SAS Device Status Change: Internal Device "
5996 "Reset : id=%d channel=%d", id, channel);
5812 break; 5997 break;
5813 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 5998 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5814 snprintf(evStr, EVENT_DESCR_STR_SZ, 5999 snprintf(evStr, EVENT_DESCR_STR_SZ,
5815 "SAS Device Status Change: Internal Task Abort : id=%d", id); 6000 "SAS Device Status Change: Internal Task "
6001 "Abort : id=%d channel=%d", id, channel);
5816 break; 6002 break;
5817 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 6003 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
5818 snprintf(evStr, EVENT_DESCR_STR_SZ, 6004 snprintf(evStr, EVENT_DESCR_STR_SZ,
5819 "SAS Device Status Change: Internal Abort Task Set : id=%d", id); 6005 "SAS Device Status Change: Internal Abort "
6006 "Task Set : id=%d channel=%d", id, channel);
5820 break; 6007 break;
5821 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 6008 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
5822 snprintf(evStr, EVENT_DESCR_STR_SZ, 6009 snprintf(evStr, EVENT_DESCR_STR_SZ,
5823 "SAS Device Status Change: Internal Clear Task Set : id=%d", id); 6010 "SAS Device Status Change: Internal Clear "
6011 "Task Set : id=%d channel=%d", id, channel);
5824 break; 6012 break;
5825 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 6013 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
5826 snprintf(evStr, EVENT_DESCR_STR_SZ, 6014 snprintf(evStr, EVENT_DESCR_STR_SZ,
5827 "SAS Device Status Change: Internal Query Task : id=%d", id); 6015 "SAS Device Status Change: Internal Query "
6016 "Task : id=%d channel=%d", id, channel);
5828 break; 6017 break;
5829 default: 6018 default:
5830 snprintf(evStr, EVENT_DESCR_STR_SZ, 6019 snprintf(evStr, EVENT_DESCR_STR_SZ,
5831 "SAS Device Status Change: Unknown: id=%d", id); 6020 "SAS Device Status Change: Unknown: "
6021 "id=%d channel=%d", id, channel);
5832 break; 6022 break;
5833 } 6023 }
5834 break; 6024 break;
@@ -5837,8 +6027,16 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5837 ds = "Bus Timer Expired"; 6027 ds = "Bus Timer Expired";
5838 break; 6028 break;
5839 case MPI_EVENT_QUEUE_FULL: 6029 case MPI_EVENT_QUEUE_FULL:
5840 ds = "Queue Full"; 6030 {
6031 u16 curr_depth = (u16)(evData0 >> 16);
6032 u8 channel = (u8)(evData0 >> 8);
6033 u8 id = (u8)(evData0);
6034
6035 snprintf(evStr, EVENT_DESCR_STR_SZ,
6036 "Queue Full: channel=%d id=%d depth=%d",
6037 channel, id, curr_depth);
5841 break; 6038 break;
6039 }
5842 case MPI_EVENT_SAS_SES: 6040 case MPI_EVENT_SAS_SES:
5843 ds = "SAS SES Event"; 6041 ds = "SAS SES Event";
5844 break; 6042 break;
@@ -5942,6 +6140,76 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5942 ds = "SAS Log Entry Added"; 6140 ds = "SAS Log Entry Added";
5943 break; 6141 break;
5944 6142
6143 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6144 {
6145 u8 phy_num = (u8)(evData0);
6146 u8 port_num = (u8)(evData0 >> 8);
6147 u8 port_width = (u8)(evData0 >> 16);
6148 u8 primative = (u8)(evData0 >> 24);
6149 snprintf(evStr, EVENT_DESCR_STR_SZ,
6150 "SAS Broadcase Primative: phy=%d port=%d "
6151 "width=%d primative=0x%02x",
6152 phy_num, port_num, port_width, primative);
6153 break;
6154 }
6155
6156 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6157 {
6158 u8 reason = (u8)(evData0);
6159 u8 port_num = (u8)(evData0 >> 8);
6160 u16 handle = le16_to_cpu(evData0 >> 16);
6161
6162 snprintf(evStr, EVENT_DESCR_STR_SZ,
6163 "SAS Initiator Device Status Change: reason=0x%02x "
6164 "port=%d handle=0x%04x",
6165 reason, port_num, handle);
6166 break;
6167 }
6168
6169 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6170 {
6171 u8 max_init = (u8)(evData0);
6172 u8 current_init = (u8)(evData0 >> 8);
6173
6174 snprintf(evStr, EVENT_DESCR_STR_SZ,
6175 "SAS Initiator Device Table Overflow: max initiators=%02d "
6176 "current initators=%02d",
6177 max_init, current_init);
6178 break;
6179 }
6180 case MPI_EVENT_SAS_SMP_ERROR:
6181 {
6182 u8 status = (u8)(evData0);
6183 u8 port_num = (u8)(evData0 >> 8);
6184 u8 result = (u8)(evData0 >> 16);
6185
6186 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6187 snprintf(evStr, EVENT_DESCR_STR_SZ,
6188 "SAS SMP Error: port=%d result=0x%02x",
6189 port_num, result);
6190 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6191 snprintf(evStr, EVENT_DESCR_STR_SZ,
6192 "SAS SMP Error: port=%d : CRC Error",
6193 port_num);
6194 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6195 snprintf(evStr, EVENT_DESCR_STR_SZ,
6196 "SAS SMP Error: port=%d : Timeout",
6197 port_num);
6198 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6199 snprintf(evStr, EVENT_DESCR_STR_SZ,
6200 "SAS SMP Error: port=%d : No Destination",
6201 port_num);
6202 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6203 snprintf(evStr, EVENT_DESCR_STR_SZ,
6204 "SAS SMP Error: port=%d : Bad Destination",
6205 port_num);
6206 else
6207 snprintf(evStr, EVENT_DESCR_STR_SZ,
6208 "SAS SMP Error: port=%d : status=0x%02x",
6209 port_num, status);
6210 break;
6211 }
6212
5945 /* 6213 /*
5946 * MPT base "custom" events may be added here... 6214 * MPT base "custom" events may be added here...
5947 */ 6215 */
@@ -6205,10 +6473,11 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6205 "Abort", /* 12h */ 6473 "Abort", /* 12h */
6206 "IO Not Yet Executed", /* 13h */ 6474 "IO Not Yet Executed", /* 13h */
6207 "IO Executed", /* 14h */ 6475 "IO Executed", /* 14h */
6208 "Persistent Reservation Out Not Affiliation Owner", /* 15h */ 6476 "Persistent Reservation Out Not Affiliation "
6477 "Owner", /* 15h */
6209 "Open Transmit DMA Abort", /* 16h */ 6478 "Open Transmit DMA Abort", /* 16h */
6210 "IO Device Missing Delay Retry", /* 17h */ 6479 "IO Device Missing Delay Retry", /* 17h */
6211 NULL, /* 18h */ 6480 "IO Cancelled Due to Recieve Error", /* 18h */
6212 NULL, /* 19h */ 6481 NULL, /* 19h */
6213 NULL, /* 1Ah */ 6482 NULL, /* 1Ah */
6214 NULL, /* 1Bh */ 6483 NULL, /* 1Bh */
@@ -6218,6 +6487,96 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6218 NULL, /* 1Fh */ 6487 NULL, /* 1Fh */
6219 "Enclosure Management" /* 20h */ 6488 "Enclosure Management" /* 20h */
6220 }; 6489 };
6490 static char *ir_code_str[] = {
6491 "Raid Action Error", /* 00h */
6492 NULL, /* 00h */
6493 NULL, /* 01h */
6494 NULL, /* 02h */
6495 NULL, /* 03h */
6496 NULL, /* 04h */
6497 NULL, /* 05h */
6498 NULL, /* 06h */
6499 NULL /* 07h */
6500 };
6501 static char *raid_sub_code_str[] = {
6502 NULL, /* 00h */
6503 "Volume Creation Failed: Data Passed too "
6504 "Large", /* 01h */
6505 "Volume Creation Failed: Duplicate Volumes "
6506 "Attempted", /* 02h */
6507 "Volume Creation Failed: Max Number "
6508 "Supported Volumes Exceeded", /* 03h */
6509 "Volume Creation Failed: DMA Error", /* 04h */
6510 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6511 "Volume Creation Failed: Error Reading "
6512 "MFG Page 4", /* 06h */
6513 "Volume Creation Failed: Creating Internal "
6514 "Structures", /* 07h */
6515 NULL, /* 08h */
6516 NULL, /* 09h */
6517 NULL, /* 0Ah */
6518 NULL, /* 0Bh */
6519 NULL, /* 0Ch */
6520 NULL, /* 0Dh */
6521 NULL, /* 0Eh */
6522 NULL, /* 0Fh */
6523 "Activation failed: Already Active Volume", /* 10h */
6524 "Activation failed: Unsupported Volume Type", /* 11h */
6525 "Activation failed: Too Many Active Volumes", /* 12h */
6526 "Activation failed: Volume ID in Use", /* 13h */
6527 "Activation failed: Reported Failure", /* 14h */
6528 "Activation failed: Importing a Volume", /* 15h */
6529 NULL, /* 16h */
6530 NULL, /* 17h */
6531 NULL, /* 18h */
6532 NULL, /* 19h */
6533 NULL, /* 1Ah */
6534 NULL, /* 1Bh */
6535 NULL, /* 1Ch */
6536 NULL, /* 1Dh */
6537 NULL, /* 1Eh */
6538 NULL, /* 1Fh */
6539 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6540 "Phys Disk failed: Data Passed too Large", /* 21h */
6541 "Phys Disk failed: DMA Error", /* 22h */
6542 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6543 "Phys Disk failed: Creating Phys Disk Config "
6544 "Page", /* 24h */
6545 NULL, /* 25h */
6546 NULL, /* 26h */
6547 NULL, /* 27h */
6548 NULL, /* 28h */
6549 NULL, /* 29h */
6550 NULL, /* 2Ah */
6551 NULL, /* 2Bh */
6552 NULL, /* 2Ch */
6553 NULL, /* 2Dh */
6554 NULL, /* 2Eh */
6555 NULL, /* 2Fh */
6556 "Compatibility Error: IR Disabled", /* 30h */
6557 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6558 "Compatibility Error: Device not Direct Access "
6559 "Device ", /* 32h */
6560 "Compatibility Error: Removable Device Found", /* 33h */
6561 "Compatibility Error: Device SCSI Version not "
6562 "2 or Higher", /* 34h */
6563 "Compatibility Error: SATA Device, 48 BIT LBA "
6564 "not Supported", /* 35h */
6565 "Compatibility Error: Device doesn't have "
6566 "512 Byte Block Sizes", /* 36h */
6567 "Compatibility Error: Volume Type Check Failed", /* 37h */
6568 "Compatibility Error: Volume Type is "
6569 "Unsupported by FW", /* 38h */
6570 "Compatibility Error: Disk Drive too Small for "
6571 "use in Volume", /* 39h */
6572 "Compatibility Error: Phys Disk for Create "
6573 "Volume not Found", /* 3Ah */
6574 "Compatibility Error: Too Many or too Few "
6575 "Disks for Volume Type", /* 3Bh */
6576 "Compatibility Error: Disk stripe Sizes "
6577 "Must be 64KB", /* 3Ch */
6578 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6579 };
6221 6580
6222/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6581/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6223/** 6582/**
@@ -6226,7 +6585,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6226 * @log_info: U32 LogInfo reply word from the IOC 6585 * @log_info: U32 LogInfo reply word from the IOC
6227 * 6586 *
6228 * Refer to lsi/mpi_log_sas.h. 6587 * Refer to lsi/mpi_log_sas.h.
6229 */ 6588 **/
6230static void 6589static void
6231mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) 6590mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6232{ 6591{
@@ -6240,56 +6599,165 @@ union loginfo_type {
6240 }dw; 6599 }dw;
6241}; 6600};
6242 union loginfo_type sas_loginfo; 6601 union loginfo_type sas_loginfo;
6602 char *originator_desc = NULL;
6243 char *code_desc = NULL; 6603 char *code_desc = NULL;
6604 char *sub_code_desc = NULL;
6244 6605
6245 sas_loginfo.loginfo = log_info; 6606 sas_loginfo.loginfo = log_info;
6246 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && 6607 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6247 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*))) 6608 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6248 return; 6609 return;
6249 if ((sas_loginfo.dw.originator == 0 /*IOP*/) && 6610
6250 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) { 6611 originator_desc = originator_str[sas_loginfo.dw.originator];
6251 code_desc = iop_code_str[sas_loginfo.dw.code]; 6612
6252 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) && 6613 switch (sas_loginfo.dw.originator) {
6253 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) { 6614
6254 code_desc = pl_code_str[sas_loginfo.dw.code]; 6615 case 0: /* IOP */
6616 if (sas_loginfo.dw.code <
6617 sizeof(iop_code_str)/sizeof(char*))
6618 code_desc = iop_code_str[sas_loginfo.dw.code];
6619 break;
6620 case 1: /* PL */
6621 if (sas_loginfo.dw.code <
6622 sizeof(pl_code_str)/sizeof(char*))
6623 code_desc = pl_code_str[sas_loginfo.dw.code];
6624 break;
6625 case 2: /* IR */
6626 if (sas_loginfo.dw.code >=
6627 sizeof(ir_code_str)/sizeof(char*))
6628 break;
6629 code_desc = ir_code_str[sas_loginfo.dw.code];
6630 if (sas_loginfo.dw.subcode >=
6631 sizeof(raid_sub_code_str)/sizeof(char*))
6632 break;
6633 if (sas_loginfo.dw.code == 0)
6634 sub_code_desc =
6635 raid_sub_code_str[sas_loginfo.dw.subcode];
6636 break;
6637 default:
6638 return;
6255 } 6639 }
6256 6640
6257 if (code_desc != NULL) 6641 if (sub_code_desc != NULL)
6642 printk(MYIOC_s_INFO_FMT
6643 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6644 " SubCode={%s}\n",
6645 ioc->name, log_info, originator_desc, code_desc,
6646 sub_code_desc);
6647 else if (code_desc != NULL)
6258 printk(MYIOC_s_INFO_FMT 6648 printk(MYIOC_s_INFO_FMT
6259 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 6649 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6260 " SubCode(0x%04x)\n", 6650 " SubCode(0x%04x)\n",
6261 ioc->name, 6651 ioc->name, log_info, originator_desc, code_desc,
6262 log_info,
6263 originator_str[sas_loginfo.dw.originator],
6264 code_desc,
6265 sas_loginfo.dw.subcode); 6652 sas_loginfo.dw.subcode);
6266 else 6653 else
6267 printk(MYIOC_s_INFO_FMT 6654 printk(MYIOC_s_INFO_FMT
6268 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," 6655 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6269 " SubCode(0x%04x)\n", 6656 " SubCode(0x%04x)\n",
6270 ioc->name, 6657 ioc->name, log_info, originator_desc,
6271 log_info, 6658 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6272 originator_str[sas_loginfo.dw.originator],
6273 sas_loginfo.dw.code,
6274 sas_loginfo.dw.subcode);
6275} 6659}
6276 6660
6661#ifdef MPT_DEBUG_REPLY
6277/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6662/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6278/** 6663/**
6279 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC. 6664 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6665 * @ioc: Pointer to MPT_ADAPTER structure
6666 * ioc_status: U32 IOCStatus word from IOC
6667 * @mf: Pointer to MPT request frame
6668 *
6669 * Refer to lsi/mpi.h.
6670 **/
6671static void
6672mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6673{
6674 Config_t *pReq = (Config_t *)mf;
6675 char extend_desc[EVENT_DESCR_STR_SZ];
6676 char *desc = NULL;
6677 u32 form;
6678 u8 page_type;
6679
6680 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6681 page_type = pReq->ExtPageType;
6682 else
6683 page_type = pReq->Header.PageType;
6684
6685 /*
6686 * ignore invalid page messages for GET_NEXT_HANDLE
6687 */
6688 form = le32_to_cpu(pReq->PageAddress);
6689 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6690 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6691 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6692 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6693 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6694 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6695 return;
6696 }
6697 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6698 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6699 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6700 return;
6701 }
6702
6703 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6704 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6705 page_type, pReq->Header.PageNumber, pReq->Action, form);
6706
6707 switch (ioc_status) {
6708
6709 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6710 desc = "Config Page Invalid Action";
6711 break;
6712
6713 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6714 desc = "Config Page Invalid Type";
6715 break;
6716
6717 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6718 desc = "Config Page Invalid Page";
6719 break;
6720
6721 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6722 desc = "Config Page Invalid Data";
6723 break;
6724
6725 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6726 desc = "Config Page No Defaults";
6727 break;
6728
6729 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6730 desc = "Config Page Can't Commit";
6731 break;
6732 }
6733
6734 if (!desc)
6735 return;
6736
6737 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
6738 ioc->name, ioc_status, desc, extend_desc);
6739}
6740
6741/**
6742 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
6280 * @ioc: Pointer to MPT_ADAPTER structure 6743 * @ioc: Pointer to MPT_ADAPTER structure
6281 * @ioc_status: U32 IOCStatus word from IOC 6744 * @ioc_status: U32 IOCStatus word from IOC
6282 * @mf: Pointer to MPT request frame 6745 * @mf: Pointer to MPT request frame
6283 * 6746 *
6284 * Refer to lsi/mpi.h. 6747 * Refer to lsi/mpi.h.
6285 */ 6748 **/
6286static void 6749static void
6287mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 6750mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6288{ 6751{
6289 u32 status = ioc_status & MPI_IOCSTATUS_MASK; 6752 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6290 char *desc = NULL; 6753 char *desc = NULL;
6291 6754
6292 switch (status) { 6755 switch (status) {
6756
6757/****************************************************************************/
6758/* Common IOCStatus values for all replies */
6759/****************************************************************************/
6760
6293 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 6761 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6294 desc = "Invalid Function"; 6762 desc = "Invalid Function";
6295 break; 6763 break;
@@ -6322,84 +6790,180 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6322 desc = "Invalid State"; 6790 desc = "Invalid State";
6323 break; 6791 break;
6324 6792
6793/****************************************************************************/
6794/* Config IOCStatus values */
6795/****************************************************************************/
6796
6325 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 6797 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6326 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 6798 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6327 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 6799 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6328 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 6800 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6329 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 6801 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6330 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 6802 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6331 /* No message for Config IOCStatus values */ 6803 mpt_iocstatus_info_config(ioc, status, mf);
6332 break; 6804 break;
6333 6805
6806/****************************************************************************/
6807/* SCSIIO Reply (SPI, FCP, SAS) initiator values */
6808/* */
6809/* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
6810/* */
6811/****************************************************************************/
6812
6334 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 6813 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6335 /* No message for recovered error 6814 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6336 desc = "SCSI Recovered Error"; 6815 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6337 */ 6816 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6817 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6818 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6819 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6820 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6821 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6822 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6823 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6824 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6825 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6338 break; 6826 break;
6339 6827
6340 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ 6828/****************************************************************************/
6341 desc = "SCSI Invalid Bus"; 6829/* SCSI Target values */
6830/****************************************************************************/
6831
6832 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
6833 desc = "Target: Priority IO";
6342 break; 6834 break;
6343 6835
6344 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ 6836 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
6345 desc = "SCSI Invalid TargetID"; 6837 desc = "Target: Invalid Port";
6346 break; 6838 break;
6347 6839
6348 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 6840 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
6349 { 6841 desc = "Target Invalid IO Index:";
6350 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6351 U8 cdb = pScsiReq->CDB[0];
6352 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6353 desc = "SCSI Device Not There";
6354 }
6355 break; 6842 break;
6356 }
6357 6843
6358 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ 6844 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
6359 desc = "SCSI Data Overrun"; 6845 desc = "Target: Aborted";
6360 break; 6846 break;
6361 6847
6362 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 6848 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
6363 /* This error is checked in scsi_io_done(). Skip. 6849 desc = "Target: No Conn Retryable";
6364 desc = "SCSI Data Underrun";
6365 */
6366 break; 6850 break;
6367 6851
6368 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 6852 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
6369 desc = "SCSI I/O Data Error"; 6853 desc = "Target: No Connection";
6370 break; 6854 break;
6371 6855
6372 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 6856 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
6373 desc = "SCSI Protocol Error"; 6857 desc = "Target: Transfer Count Mismatch";
6374 break; 6858 break;
6375 6859
6376 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 6860 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
6377 desc = "SCSI Task Terminated"; 6861 desc = "Target: STS Data not Sent";
6378 break; 6862 break;
6379 6863
6380 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 6864 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
6381 desc = "SCSI Residual Mismatch"; 6865 desc = "Target: Data Offset Error";
6382 break; 6866 break;
6383 6867
6384 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 6868 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
6385 desc = "SCSI Task Management Failed"; 6869 desc = "Target: Too Much Write Data";
6386 break; 6870 break;
6387 6871
6388 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 6872 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
6389 desc = "SCSI IOC Terminated"; 6873 desc = "Target: IU Too Short";
6390 break; 6874 break;
6391 6875
6392 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 6876 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
6393 desc = "SCSI Ext Terminated"; 6877 desc = "Target: ACK NAK Timeout";
6878 break;
6879
6880 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
6881 desc = "Target: Nak Received";
6882 break;
6883
6884/****************************************************************************/
6885/* Fibre Channel Direct Access values */
6886/****************************************************************************/
6887
6888 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
6889 desc = "FC: Aborted";
6890 break;
6891
6892 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
6893 desc = "FC: RX ID Invalid";
6894 break;
6895
6896 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
6897 desc = "FC: DID Invalid";
6898 break;
6899
6900 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
6901 desc = "FC: Node Logged Out";
6902 break;
6903
6904 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
6905 desc = "FC: Exchange Canceled";
6906 break;
6907
6908/****************************************************************************/
6909/* LAN values */
6910/****************************************************************************/
6911
6912 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
6913 desc = "LAN: Device not Found";
6914 break;
6915
6916 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
6917 desc = "LAN: Device Failure";
6918 break;
6919
6920 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
6921 desc = "LAN: Transmit Error";
6922 break;
6923
6924 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
6925 desc = "LAN: Transmit Aborted";
6926 break;
6927
6928 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
6929 desc = "LAN: Receive Error";
6930 break;
6931
6932 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
6933 desc = "LAN: Receive Aborted";
6934 break;
6935
6936 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
6937 desc = "LAN: Partial Packet";
6938 break;
6939
6940 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
6941 desc = "LAN: Canceled";
6942 break;
6943
6944/****************************************************************************/
6945/* Serial Attached SCSI values */
6946/****************************************************************************/
6947
6948 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
6949 desc = "SAS: SMP Request Failed";
6950 break;
6951
6952 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
6953 desc = "SAS: SMP Data Overrun";
6394 break; 6954 break;
6395 6955
6396 default: 6956 default:
6397 desc = "Others"; 6957 desc = "Others";
6398 break; 6958 break;
6399 } 6959 }
6400 if (desc != NULL) 6960
6401 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); 6961 if (!desc)
6962 return;
6963
6964 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
6402} 6965}
6966#endif
6403 6967
6404/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6968/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6405EXPORT_SYMBOL(mpt_attach); 6969EXPORT_SYMBOL(mpt_attach);
@@ -6434,6 +6998,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
6434EXPORT_SYMBOL(mpt_alloc_fw_memory); 6998EXPORT_SYMBOL(mpt_alloc_fw_memory);
6435EXPORT_SYMBOL(mpt_free_fw_memory); 6999EXPORT_SYMBOL(mpt_free_fw_memory);
6436EXPORT_SYMBOL(mptbase_sas_persist_operation); 7000EXPORT_SYMBOL(mptbase_sas_persist_operation);
7001EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
6437 7002
6438/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7003/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6439/** 7004/**
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e316708f76bd..e3a39272aad6 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -6,7 +6,7 @@
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2007 LSI Logic Corporation 8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com) 9 * (mailto:mpt_linux_developer@lsi.com)
10 * 10 *
11 */ 11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -75,8 +75,8 @@
75#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR 75#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR
76#endif 76#endif
77 77
78#define MPT_LINUX_VERSION_COMMON "3.04.03" 78#define MPT_LINUX_VERSION_COMMON "3.04.04"
79#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.03" 79#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.04"
80#define WHAT_MAGIC_STRING "@" "(" "#" ")" 80#define WHAT_MAGIC_STRING "@" "(" "#" ")"
81 81
82#define show_mptmod_ver(s,ver) \ 82#define show_mptmod_ver(s,ver) \
@@ -172,6 +172,9 @@
172#define MPT_SCSI_SG_DEPTH 40 172#define MPT_SCSI_SG_DEPTH 40
173#endif 173#endif
174 174
175/* debug print string length used for events and iocstatus */
176# define EVENT_DESCR_STR_SZ 100
177
175#ifdef __KERNEL__ /* { */ 178#ifdef __KERNEL__ /* { */
176/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 179/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
177 180
@@ -334,8 +337,8 @@ typedef struct _VirtTarget {
334 struct scsi_target *starget; 337 struct scsi_target *starget;
335 u8 tflags; 338 u8 tflags;
336 u8 ioc_id; 339 u8 ioc_id;
337 u8 target_id; 340 u8 id;
338 u8 bus_id; 341 u8 channel;
339 u8 minSyncFactor; /* 0xFF is async */ 342 u8 minSyncFactor; /* 0xFF is async */
340 u8 maxOffset; /* 0 if async */ 343 u8 maxOffset; /* 0 if async */
341 u8 maxWidth; /* 0 if narrow, 1 if wide */ 344 u8 maxWidth; /* 0 if narrow, 1 if wide */
@@ -344,13 +347,12 @@ typedef struct _VirtTarget {
344 u8 type; /* byte 0 of Inquiry data */ 347 u8 type; /* byte 0 of Inquiry data */
345 u8 deleted; /* target in process of being removed */ 348 u8 deleted; /* target in process of being removed */
346 u32 num_luns; 349 u32 num_luns;
347 u32 luns[8]; /* Max LUNs is 256 */
348} VirtTarget; 350} VirtTarget;
349 351
350typedef struct _VirtDevice { 352typedef struct _VirtDevice {
351 VirtTarget *vtarget; 353 VirtTarget *vtarget;
352 u8 configured_lun; 354 u8 configured_lun;
353 u32 lun; 355 int lun;
354} VirtDevice; 356} VirtDevice;
355 357
356/* 358/*
@@ -412,7 +414,7 @@ typedef struct _MPT_IOCTL {
412 u8 rsvd; 414 u8 rsvd;
413 u8 status; /* current command status */ 415 u8 status; /* current command status */
414 u8 reset; /* 1 if bus reset allowed */ 416 u8 reset; /* 1 if bus reset allowed */
415 u8 target; /* target for reset */ 417 u8 id; /* target for reset */
416 struct mutex ioctl_mutex; 418 struct mutex ioctl_mutex;
417} MPT_IOCTL; 419} MPT_IOCTL;
418 420
@@ -483,10 +485,24 @@ typedef struct _SasCfgData {
483 */ 485 */
484}SasCfgData; 486}SasCfgData;
485 487
488/*
489 * Inactive volume link list of raid component data
490 * @inactive_list
491 */
492struct inactive_raid_component_info {
493 struct list_head list;
494 u8 volumeID; /* volume target id */
495 u8 volumeBus; /* volume channel */
496 IOC_3_PHYS_DISK d; /* phys disk info */
497};
498
486typedef struct _RaidCfgData { 499typedef struct _RaidCfgData {
487 IOCPage2_t *pIocPg2; /* table of Raid Volumes */ 500 IOCPage2_t *pIocPg2; /* table of Raid Volumes */
488 IOCPage3_t *pIocPg3; /* table of physical disks */ 501 IOCPage3_t *pIocPg3; /* table of physical disks */
489 int isRaid; /* bit field, 1 if RAID */ 502 struct semaphore inactive_list_mutex;
503 struct list_head inactive_list; /* link list for physical
504 disk that belong in
505 inactive volumes */
490}RaidCfgData; 506}RaidCfgData;
491 507
492typedef struct _FcCfgData { 508typedef struct _FcCfgData {
@@ -528,6 +544,8 @@ typedef struct _MPT_ADAPTER
528 u32 mem_phys; /* == f4020000 (mmap) */ 544 u32 mem_phys; /* == f4020000 (mmap) */
529 u32 pio_mem_phys; /* Programmed IO (downloadboot) */ 545 u32 pio_mem_phys; /* Programmed IO (downloadboot) */
530 int mem_size; /* mmap memory size */ 546 int mem_size; /* mmap memory size */
547 int number_of_buses;
548 int devices_per_bus;
531 int alloc_total; 549 int alloc_total;
532 u32 last_state; 550 u32 last_state;
533 int active; 551 int active;
@@ -607,6 +625,8 @@ typedef struct _MPT_ADAPTER
607 u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */ 625 u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
608 LANPage0_t lan_cnfg_page0; 626 LANPage0_t lan_cnfg_page0;
609 LANPage1_t lan_cnfg_page1; 627 LANPage1_t lan_cnfg_page1;
628
629 u8 ir_firmware; /* =1 if IR firmware detected */
610 /* 630 /*
611 * Description: errata_flag_1064 631 * Description: errata_flag_1064
612 * If a PCIX read occurs within 1 or 2 cycles after the chip receives 632 * If a PCIX read occurs within 1 or 2 cycles after the chip receives
@@ -790,12 +810,6 @@ typedef struct _mpt_sge {
790#define ddvprintk(x) 810#define ddvprintk(x)
791#endif 811#endif
792 812
793#ifdef MPT_DEBUG_NEGO
794#define dnegoprintk(x) printk x
795#else
796#define dnegoprintk(x)
797#endif
798
799#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) 813#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
800#define ddvtprintk(x) printk x 814#define ddvtprintk(x) printk x
801#else 815#else
@@ -957,7 +971,6 @@ typedef struct _MPT_SCSI_HOST {
957 int port; 971 int port;
958 u32 pad0; 972 u32 pad0;
959 struct scsi_cmnd **ScsiLookup; 973 struct scsi_cmnd **ScsiLookup;
960 VirtTarget **Targets;
961 MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ 974 MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
962 struct timer_list timer; 975 struct timer_list timer;
963 /* Pool of memory for holding SCpnts before doing 976 /* Pool of memory for holding SCpnts before doing
@@ -981,6 +994,7 @@ typedef struct _MPT_SCSI_HOST {
981 int scandv_wait_done; 994 int scandv_wait_done;
982 long last_queue_full; 995 long last_queue_full;
983 u16 tm_iocstatus; 996 u16 tm_iocstatus;
997 struct list_head target_reset_list;
984} MPT_SCSI_HOST; 998} MPT_SCSI_HOST;
985 999
986/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1000/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1046,6 +1060,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1046extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1060extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1047extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1061extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1048extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1062extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1063extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk);
1049 1064
1050/* 1065/*
1051 * Public data decl's... 1066 * Public data decl's...
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 504632da4347..b0b80428d110 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -5,7 +5,7 @@
5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * 6 *
7 * Copyright (c) 1999-2007 LSI Logic Corporation 7 * Copyright (c) 1999-2007 LSI Logic Corporation
8 * (mailto:mpt_linux_developer@lsil.com) 8 * (mailto:mpt_linux_developer@lsi.com)
9 * 9 *
10 */ 10 */
11/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 11/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -313,7 +313,7 @@ static void mptctl_timeout_expired (MPT_IOCTL *ioctl)
313 */ 313 */
314 dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 314 dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
315 ioctl->ioc->name)); 315 ioctl->ioc->name));
316 mpt_HardResetHandler(ioctl->ioc, NO_SLEEP); 316 mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP);
317 } 317 }
318 return; 318 return;
319 319
@@ -361,7 +361,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
361 ioctl->ioc->name, mf)); 361 ioctl->ioc->name, mf));
362 362
363 pScsiTm = (SCSITaskMgmt_t *) mf; 363 pScsiTm = (SCSITaskMgmt_t *) mf;
364 pScsiTm->TargetID = ioctl->target; 364 pScsiTm->TargetID = ioctl->id;
365 pScsiTm->Bus = hd->port; /* 0 */ 365 pScsiTm->Bus = hd->port; /* 0 */
366 pScsiTm->ChainOffset = 0; 366 pScsiTm->ChainOffset = 0;
367 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; 367 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
@@ -1159,15 +1159,12 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1159 struct mpt_ioctl_iocinfo *karg; 1159 struct mpt_ioctl_iocinfo *karg;
1160 MPT_ADAPTER *ioc; 1160 MPT_ADAPTER *ioc;
1161 struct pci_dev *pdev; 1161 struct pci_dev *pdev;
1162 struct Scsi_Host *sh;
1163 MPT_SCSI_HOST *hd;
1164 int iocnum; 1162 int iocnum;
1165 int numDevices = 0;
1166 unsigned int max_id;
1167 int ii;
1168 unsigned int port; 1163 unsigned int port;
1169 int cim_rev; 1164 int cim_rev;
1170 u8 revision; 1165 u8 revision;
1166 struct scsi_device *sdev;
1167 VirtDevice *vdev;
1171 1168
1172 dctlprintk((": mptctl_getiocinfo called.\n")); 1169 dctlprintk((": mptctl_getiocinfo called.\n"));
1173 /* Add of PCI INFO results in unaligned access for 1170 /* Add of PCI INFO results in unaligned access for
@@ -1257,23 +1254,16 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1257 1254
1258 /* Get number of devices 1255 /* Get number of devices
1259 */ 1256 */
1260 if ((sh = ioc->sh) != NULL) { 1257 karg->numDevices = 0;
1261 /* sh->max_id = maximum target ID + 1 1258 if (ioc->sh) {
1262 */ 1259 shost_for_each_device(sdev, ioc->sh) {
1263 max_id = sh->max_id - 1; 1260 vdev = sdev->hostdata;
1264 hd = (MPT_SCSI_HOST *) sh->hostdata; 1261 if (vdev->vtarget->tflags &
1265 1262 MPT_TARGET_FLAGS_RAID_COMPONENT)
1266 /* Check all of the target structures and 1263 continue;
1267 * keep a counter. 1264 karg->numDevices++;
1268 */
1269 if (hd && hd->Targets) {
1270 for (ii = 0; ii <= max_id; ii++) {
1271 if (hd->Targets[ii])
1272 numDevices++;
1273 }
1274 } 1265 }
1275 } 1266 }
1276 karg->numDevices = numDevices;
1277 1267
1278 /* Set the BIOS and FW Version 1268 /* Set the BIOS and FW Version
1279 */ 1269 */
@@ -1319,21 +1309,16 @@ mptctl_gettargetinfo (unsigned long arg)
1319 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; 1309 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1320 struct mpt_ioctl_targetinfo karg; 1310 struct mpt_ioctl_targetinfo karg;
1321 MPT_ADAPTER *ioc; 1311 MPT_ADAPTER *ioc;
1322 struct Scsi_Host *sh; 1312 VirtDevice *vdev;
1323 MPT_SCSI_HOST *hd;
1324 VirtTarget *vdev;
1325 char *pmem; 1313 char *pmem;
1326 int *pdata; 1314 int *pdata;
1327 IOCPage2_t *pIoc2;
1328 IOCPage3_t *pIoc3;
1329 int iocnum; 1315 int iocnum;
1330 int numDevices = 0; 1316 int numDevices = 0;
1331 unsigned int max_id; 1317 int lun;
1332 int id, jj, indexed_lun, lun_index;
1333 u32 lun;
1334 int maxWordsLeft; 1318 int maxWordsLeft;
1335 int numBytes; 1319 int numBytes;
1336 u8 port, devType, bus_id; 1320 u8 port;
1321 struct scsi_device *sdev;
1337 1322
1338 dctlprintk(("mptctl_gettargetinfo called.\n")); 1323 dctlprintk(("mptctl_gettargetinfo called.\n"));
1339 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { 1324 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
@@ -1389,74 +1374,22 @@ mptctl_gettargetinfo (unsigned long arg)
1389 1374
1390 /* Get number of devices 1375 /* Get number of devices
1391 */ 1376 */
1392 if ((sh = ioc->sh) != NULL) { 1377 if (ioc->sh){
1393 1378 shost_for_each_device(sdev, ioc->sh) {
1394 max_id = sh->max_id - 1; 1379 if (!maxWordsLeft)
1395 hd = (MPT_SCSI_HOST *) sh->hostdata; 1380 continue;
1396 1381 vdev = sdev->hostdata;
1397 /* Check all of the target structures. 1382 if (vdev->vtarget->tflags &
1398 * Save the Id and increment the counter, 1383 MPT_TARGET_FLAGS_RAID_COMPONENT)
1399 * if ptr non-null. 1384 continue;
1400 * sh->max_id = maximum target ID + 1 1385 lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun;
1401 */ 1386 *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) +
1402 if (hd && hd->Targets) { 1387 (vdev->vtarget->id ));
1403 mpt_findImVolumes(ioc); 1388 pdata++;
1404 pIoc2 = ioc->raid_data.pIocPg2; 1389 numDevices++;
1405 for ( id = 0; id <= max_id; ) { 1390 --maxWordsLeft;
1406 if ( pIoc2 && pIoc2->NumActiveVolumes ) {
1407 if ( id == pIoc2->RaidVolume[0].VolumeID ) {
1408 if (maxWordsLeft <= 0) {
1409 printk(KERN_ERR "mptctl_gettargetinfo - "
1410 "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
1411 goto data_space_full;
1412 }
1413 if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
1414 devType = 0x80;
1415 else
1416 devType = 0xC0;
1417 bus_id = pIoc2->RaidVolume[0].VolumeBus;
1418 numDevices++;
1419 *pdata = ( (devType << 24) | (bus_id << 8) | id );
1420 dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1421 "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1422 pdata++;
1423 --maxWordsLeft;
1424 goto next_id;
1425 } else {
1426 pIoc3 = ioc->raid_data.pIocPg3;
1427 for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
1428 if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
1429 goto next_id;
1430 }
1431 }
1432 }
1433 if ( (vdev = hd->Targets[id]) ) {
1434 for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
1435 lun_index = (jj >> 5);
1436 indexed_lun = (jj % 32);
1437 lun = (1 << indexed_lun);
1438 if (vdev->luns[lun_index] & lun) {
1439 if (maxWordsLeft <= 0) {
1440 printk(KERN_ERR "mptctl_gettargetinfo - "
1441 "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
1442 goto data_space_full;
1443 }
1444 bus_id = vdev->bus_id;
1445 numDevices++;
1446 *pdata = ( (jj << 16) | (bus_id << 8) | id );
1447 dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1448 "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1449 pdata++;
1450 --maxWordsLeft;
1451 }
1452 }
1453 }
1454next_id:
1455 id++;
1456 }
1457 } 1391 }
1458 } 1392 }
1459data_space_full:
1460 karg.numDevices = numDevices; 1393 karg.numDevices = numDevices;
1461 1394
1462 /* Copy part of the data from kernel memory to user memory 1395 /* Copy part of the data from kernel memory to user memory
@@ -1821,6 +1754,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1821 int msgContext; 1754 int msgContext;
1822 u16 req_idx; 1755 u16 req_idx;
1823 ulong timeout; 1756 ulong timeout;
1757 struct scsi_device *sdev;
1824 1758
1825 dctlprintk(("mptctl_do_mpt_command called.\n")); 1759 dctlprintk(("mptctl_do_mpt_command called.\n"));
1826 bufIn.kptr = bufOut.kptr = NULL; 1760 bufIn.kptr = bufOut.kptr = NULL;
@@ -1902,14 +1836,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1902 case MPI_FUNCTION_SCSI_IO_REQUEST: 1836 case MPI_FUNCTION_SCSI_IO_REQUEST:
1903 if (ioc->sh) { 1837 if (ioc->sh) {
1904 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; 1838 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1905 VirtTarget *pTarget = NULL;
1906 MPT_SCSI_HOST *hd = NULL;
1907 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; 1839 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1908 int scsidir = 0; 1840 int scsidir = 0;
1909 int target = (int) pScsiReq->TargetID;
1910 int dataSize; 1841 int dataSize;
1842 u32 id;
1911 1843
1912 if ((target < 0) || (target >= ioc->sh->max_id)) { 1844 id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1845 if (pScsiReq->TargetID > id) {
1913 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " 1846 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1914 "Target ID out of bounds. \n", 1847 "Target ID out of bounds. \n",
1915 __FILE__, __LINE__); 1848 __FILE__, __LINE__);
@@ -1917,6 +1850,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1917 goto done_free_mem; 1850 goto done_free_mem;
1918 } 1851 }
1919 1852
1853 if (pScsiReq->Bus >= ioc->number_of_buses) {
1854 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1855 "Target Bus out of bounds. \n",
1856 __FILE__, __LINE__);
1857 rc = -ENODEV;
1858 goto done_free_mem;
1859 }
1860
1920 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; 1861 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1921 pScsiReq->MsgFlags |= mpt_msg_flags(); 1862 pScsiReq->MsgFlags |= mpt_msg_flags();
1922 1863
@@ -1936,13 +1877,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1936 cpu_to_le32(ioc->sense_buf_low_dma 1877 cpu_to_le32(ioc->sense_buf_low_dma
1937 + (req_idx * MPT_SENSE_BUFFER_ALLOC)); 1878 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1938 1879
1939 if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) { 1880 shost_for_each_device(sdev, ioc->sh) {
1940 if (hd->Targets) 1881 struct scsi_target *starget = scsi_target(sdev);
1941 pTarget = hd->Targets[target]; 1882 VirtTarget *vtarget = starget->hostdata;
1942 }
1943 1883
1944 if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) 1884 if ((pScsiReq->TargetID == vtarget->id) &&
1945 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; 1885 (pScsiReq->Bus == vtarget->channel) &&
1886 (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1887 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1888 }
1946 1889
1947 /* Have the IOCTL driver set the direction based 1890 /* Have the IOCTL driver set the direction based
1948 * on the dataOutSize (ordering issue with Sparc). 1891 * on the dataOutSize (ordering issue with Sparc).
@@ -1959,7 +1902,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1959 pScsiReq->DataLength = cpu_to_le32(dataSize); 1902 pScsiReq->DataLength = cpu_to_le32(dataSize);
1960 1903
1961 ioc->ioctl->reset = MPTCTL_RESET_OK; 1904 ioc->ioctl->reset = MPTCTL_RESET_OK;
1962 ioc->ioctl->target = target; 1905 ioc->ioctl->id = pScsiReq->TargetID;
1963 1906
1964 } else { 1907 } else {
1965 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " 1908 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
@@ -2038,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
2038 pScsiReq->DataLength = cpu_to_le32(dataSize); 1981 pScsiReq->DataLength = cpu_to_le32(dataSize);
2039 1982
2040 ioc->ioctl->reset = MPTCTL_RESET_OK; 1983 ioc->ioctl->reset = MPTCTL_RESET_OK;
2041 ioc->ioctl->target = pScsiReq->TargetID; 1984 ioc->ioctl->id = pScsiReq->TargetID;
2042 } else { 1985 } else {
2043 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " 1986 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2044 "SCSI driver is not loaded. \n", 1987 "SCSI driver is not loaded. \n",
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index e65a1cf5eb0b..f7e72c5e47de 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -6,7 +6,7 @@
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2007 LSI Logic Corporation 8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com) 9 * (mailto:mpt_linux_developer@lsi.com)
10 * 10 *
11 */ 11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index c819c23b55b1..b7d4c7265ec6 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -4,7 +4,7 @@
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 * 5 *
6 * Copyright (c) 1999-2007 LSI Logic Corporation 6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsi.com)
8 * 8 *
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -86,6 +86,12 @@ MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
86 " return following a device loss event." 86 " return following a device loss event."
87 " Default=60."); 87 " Default=60.");
88 88
89/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
90#define MPTFC_MAX_LUN (16895)
91static int max_lun = MPTFC_MAX_LUN;
92module_param(max_lun, int, 0);
93MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
94
89static int mptfcDoneCtx = -1; 95static int mptfcDoneCtx = -1;
90static int mptfcTaskCtx = -1; 96static int mptfcTaskCtx = -1;
91static int mptfcInternalCtx = -1; /* Used only for internal commands */ 97static int mptfcInternalCtx = -1; /* Used only for internal commands */
@@ -292,10 +298,9 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
292 U32 port_id = 0xffffff; 298 U32 port_id = 0xffffff;
293 int num_targ = 0; 299 int num_targ = 0;
294 int max_bus = ioc->facts.MaxBuses; 300 int max_bus = ioc->facts.MaxBuses;
295 int max_targ = ioc->facts.MaxDevices; 301 int max_targ;
296 302
297 if (max_bus == 0 || max_targ == 0) 303 max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
298 goto out;
299 304
300 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ; 305 data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
301 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL); 306 p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
@@ -467,8 +472,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
467 if (ri->starget) { 472 if (ri->starget) {
468 vtarget = ri->starget->hostdata; 473 vtarget = ri->starget->hostdata;
469 if (vtarget) { 474 if (vtarget) {
470 vtarget->target_id = pg0->CurrentTargetID; 475 vtarget->id = pg0->CurrentTargetID;
471 vtarget->bus_id = pg0->CurrentBus; 476 vtarget->channel = pg0->CurrentBus;
472 } 477 }
473 } 478 }
474 *((struct mptfc_rport_info **)rport->dd_data) = ri; 479 *((struct mptfc_rport_info **)rport->dd_data) = ri;
@@ -540,8 +545,8 @@ mptfc_target_alloc(struct scsi_target *starget)
540 if (rport) { 545 if (rport) {
541 ri = *((struct mptfc_rport_info **)rport->dd_data); 546 ri = *((struct mptfc_rport_info **)rport->dd_data);
542 if (ri) { /* better be! */ 547 if (ri) { /* better be! */
543 vtarget->target_id = ri->pg0.CurrentTargetID; 548 vtarget->id = ri->pg0.CurrentTargetID;
544 vtarget->bus_id = ri->pg0.CurrentBus; 549 vtarget->channel = ri->pg0.CurrentBus;
545 ri->starget = starget; 550 ri->starget = starget;
546 rc = 0; 551 rc = 0;
547 } 552 }
@@ -592,7 +597,6 @@ mptfc_slave_alloc(struct scsi_device *sdev)
592 if (vtarget->num_luns == 0) { 597 if (vtarget->num_luns == 0) {
593 vtarget->ioc_id = hd->ioc->id; 598 vtarget->ioc_id = hd->ioc->id;
594 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; 599 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
595 hd->Targets[sdev->id] = vtarget;
596 } 600 }
597 601
598 vdev->vtarget = vtarget; 602 vdev->vtarget = vtarget;
@@ -630,16 +634,17 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
630 struct mptfc_rport_info *ri; 634 struct mptfc_rport_info *ri;
631 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); 635 struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
632 int err; 636 int err;
637 VirtDevice *vdev = SCpnt->device->hostdata;
633 638
634 err = fc_remote_port_chkready(rport); 639 if (!vdev || !vdev->vtarget) {
635 if (unlikely(err)) { 640 SCpnt->result = DID_NO_CONNECT << 16;
636 SCpnt->result = err;
637 done(SCpnt); 641 done(SCpnt);
638 return 0; 642 return 0;
639 } 643 }
640 644
641 if (!SCpnt->device->hostdata) { /* vdev */ 645 err = fc_remote_port_chkready(rport);
642 SCpnt->result = DID_NO_CONNECT << 16; 646 if (unlikely(err)) {
647 SCpnt->result = err;
643 done(SCpnt); 648 done(SCpnt);
644 return 0; 649 return 0;
645 } 650 }
@@ -1143,7 +1148,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1143 printk(MYIOC_s_WARN_FMT 1148 printk(MYIOC_s_WARN_FMT
1144 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 1149 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1145 ioc->name, ioc); 1150 ioc->name, ioc);
1146 return -ENODEV; 1151 return 0;
1147 } 1152 }
1148 1153
1149 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 1154 sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
@@ -1173,10 +1178,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1173 /* set 16 byte cdb's */ 1178 /* set 16 byte cdb's */
1174 sh->max_cmd_len = 16; 1179 sh->max_cmd_len = 16;
1175 1180
1176 sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; 1181 sh->max_id = ioc->pfacts->MaxDevices;
1182 sh->max_lun = max_lun;
1177 1183
1178 sh->max_lun = MPT_LAST_LUN + 1;
1179 sh->max_channel = 0;
1180 sh->this_id = ioc->pfacts[0].PortSCSIID; 1184 sh->this_id = ioc->pfacts[0].PortSCSIID;
1181 1185
1182 /* Required entry. 1186 /* Required entry.
@@ -1230,19 +1234,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1230 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", 1234 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1231 ioc->name, hd->ScsiLookup)); 1235 ioc->name, hd->ScsiLookup));
1232 1236
1233 /* Allocate memory for the device structures.
1234 * A non-Null pointer at an offset
1235 * indicates a device exists.
1236 * max_id = 1 + maximum id (hosts.h)
1237 */
1238 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1239 if (!hd->Targets) {
1240 error = -ENOMEM;
1241 goto out_mptfc_probe;
1242 }
1243
1244 dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
1245
1246 /* Clear the TM flags 1237 /* Clear the TM flags
1247 */ 1238 */
1248 hd->tmPending = 0; 1239 hd->tmPending = 0;
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 2936204d8ad6..b691292ff599 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -5,6 +5,7 @@
5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * 6 *
7 * Copyright (c) 2000-2007 LSI Logic Corporation 7 * Copyright (c) 2000-2007 LSI Logic Corporation
8 * (mailto:mpt_linux_developer@lsi.com)
8 * 9 *
9 */ 10 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 11/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 70ab75e7c263..fe438bf119f6 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -5,6 +5,7 @@
5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 5 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
6 * 6 *
7 * Copyright (c) 2000-2007 LSI Logic Corporation 7 * Copyright (c) 2000-2007 LSI Logic Corporation
8 * (mailto:mpt_linux_developer@lsi.com)
8 * 9 *
9 */ 10 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 11/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 09e9a9d96410..84b8b485e95b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -4,7 +4,7 @@
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 * 5 *
6 * Copyright (c) 1999-2007 LSI Logic Corporation 6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsi.com)
8 * Copyright (c) 2005-2007 Dell 8 * Copyright (c) 2005-2007 Dell
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -83,17 +83,31 @@ MODULE_PARM_DESC(mpt_pt_clear,
83 " Clear persistency table: enable=1 " 83 " Clear persistency table: enable=1 "
84 "(default=MPTSCSIH_PT_CLEAR=0)"); 84 "(default=MPTSCSIH_PT_CLEAR=0)");
85 85
86/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
87#define MPTSAS_MAX_LUN (16895)
88static int max_lun = MPTSAS_MAX_LUN;
89module_param(max_lun, int, 0);
90MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
91
86static int mptsasDoneCtx = -1; 92static int mptsasDoneCtx = -1;
87static int mptsasTaskCtx = -1; 93static int mptsasTaskCtx = -1;
88static int mptsasInternalCtx = -1; /* Used only for internal commands */ 94static int mptsasInternalCtx = -1; /* Used only for internal commands */
89static int mptsasMgmtCtx = -1; 95static int mptsasMgmtCtx = -1;
90 96
97static void mptsas_hotplug_work(struct work_struct *work);
98
99struct mptsas_target_reset_event {
100 struct list_head list;
101 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
102 u8 target_reset_issued;
103};
91 104
92enum mptsas_hotplug_action { 105enum mptsas_hotplug_action {
93 MPTSAS_ADD_DEVICE, 106 MPTSAS_ADD_DEVICE,
94 MPTSAS_DEL_DEVICE, 107 MPTSAS_DEL_DEVICE,
95 MPTSAS_ADD_RAID, 108 MPTSAS_ADD_RAID,
96 MPTSAS_DEL_RAID, 109 MPTSAS_DEL_RAID,
110 MPTSAS_ADD_INACTIVE_VOLUME,
97 MPTSAS_IGNORE_EVENT, 111 MPTSAS_IGNORE_EVENT,
98}; 112};
99 113
@@ -102,14 +116,15 @@ struct mptsas_hotplug_event {
102 MPT_ADAPTER *ioc; 116 MPT_ADAPTER *ioc;
103 enum mptsas_hotplug_action event_type; 117 enum mptsas_hotplug_action event_type;
104 u64 sas_address; 118 u64 sas_address;
105 u32 channel; 119 u8 channel;
106 u32 id; 120 u8 id;
107 u32 device_info; 121 u32 device_info;
108 u16 handle; 122 u16 handle;
109 u16 parent_handle; 123 u16 parent_handle;
110 u8 phy_id; 124 u8 phy_id;
111 u8 phys_disk_num; 125 u8 phys_disk_num_valid; /* hrc (hidden raid component) */
112 u8 phys_disk_num_valid; 126 u8 phys_disk_num; /* hrc - unique index*/
127 u8 hidden_raid_component; /* hrc - don't expose*/
113}; 128};
114 129
115struct mptsas_discovery_event { 130struct mptsas_discovery_event {
@@ -134,6 +149,7 @@ struct mptsas_devinfo {
134 u8 port_id; /* sas physical port this device 149 u8 port_id; /* sas physical port this device
135 is assoc'd with */ 150 is assoc'd with */
136 u8 id; /* logical target id of this device */ 151 u8 id; /* logical target id of this device */
152 u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
137 u8 channel; /* logical bus number of this device */ 153 u8 channel; /* logical bus number of this device */
138 u64 sas_address; /* WWN of this device, 154 u64 sas_address; /* WWN of this device,
139 SATA is assigned by HBA,expander */ 155 SATA is assigned by HBA,expander */
@@ -153,6 +169,7 @@ struct mptsas_portinfo_details{
153}; 169};
154 170
155struct mptsas_phyinfo { 171struct mptsas_phyinfo {
172 u16 handle; /* unique id to address this */
156 u8 phy_id; /* phy index */ 173 u8 phy_id; /* phy index */
157 u8 port_id; /* firmware port identifier */ 174 u8 port_id; /* firmware port identifier */
158 u8 negotiated_link_rate; /* nego'd link rate for this phy */ 175 u8 negotiated_link_rate; /* nego'd link rate for this phy */
@@ -168,7 +185,6 @@ struct mptsas_phyinfo {
168 185
169struct mptsas_portinfo { 186struct mptsas_portinfo {
170 struct list_head list; 187 struct list_head list;
171 u16 handle; /* unique id to address this */
172 u16 num_phys; /* number of phys */ 188 u16 num_phys; /* number of phys */
173 struct mptsas_phyinfo *phy_info; 189 struct mptsas_phyinfo *phy_info;
174}; 190};
@@ -561,22 +577,273 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
561 mutex_unlock(&ioc->sas_topology_mutex); 577 mutex_unlock(&ioc->sas_topology_mutex);
562} 578}
563 579
580/**
581 * csmisas_find_vtarget
582 *
583 * @ioc
584 * @volume_id
585 * @volume_bus
586 *
587 **/
588static VirtTarget *
589mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
590{
591 struct scsi_device *sdev;
592 VirtDevice *vdev;
593 VirtTarget *vtarget = NULL;
594
595 shost_for_each_device(sdev, ioc->sh) {
596 if ((vdev = sdev->hostdata) == NULL)
597 continue;
598 if (vdev->vtarget->id == id &&
599 vdev->vtarget->channel == channel)
600 vtarget = vdev->vtarget;
601 }
602 return vtarget;
603}
604
605/**
606 * mptsas_target_reset
607 *
608 * Issues TARGET_RESET to end device using handshaking method
609 *
610 * @ioc
611 * @channel
612 * @id
613 *
614 * Returns (1) success
615 * (0) failure
616 *
617 **/
618static int
619mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
620{
621 MPT_FRAME_HDR *mf;
622 SCSITaskMgmt_t *pScsiTm;
623
624 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
625 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
626 ioc->name,__FUNCTION__, __LINE__));
627 return 0;
628 }
629
630 /* Format the Request
631 */
632 pScsiTm = (SCSITaskMgmt_t *) mf;
633 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
634 pScsiTm->TargetID = id;
635 pScsiTm->Bus = channel;
636 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
637 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
638 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
639
640 DBG_DUMP_TM_REQUEST_FRAME(mf);
641
642 if (mpt_send_handshake_request(ioc->TaskCtx, ioc,
643 sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) {
644 mpt_free_msg_frame(ioc, mf);
645 dfailprintk((MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n",
646 ioc->name,__FUNCTION__, __LINE__));
647 return 0;
648 }
649
650 return 1;
651}
652
653/**
654 * mptsas_target_reset_queue
655 *
656 * Receive request for TARGET_RESET after recieving an firmware
657 * event NOT_RESPONDING_EVENT, then put command in link list
658 * and queue if task_queue already in use.
659 *
660 * @ioc
661 * @sas_event_data
662 *
663 **/
564static void 664static void
565mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget) 665mptsas_target_reset_queue(MPT_ADAPTER *ioc,
666 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
566{ 667{
567 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; 668 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
669 VirtTarget *vtarget = NULL;
670 struct mptsas_target_reset_event *target_reset_list;
671 u8 id, channel;
568 672
569 if (mptscsih_TMHandler(hd, 673 id = sas_event_data->TargetID;
570 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 674 channel = sas_event_data->Bus;
571 vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) { 675
572 hd->tmPending = 0; 676 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
573 hd->tmState = TM_STATE_NONE; 677 return;
574 printk(MYIOC_s_WARN_FMT 678
575 "Error processing TaskMgmt id=%d TARGET_RESET\n", 679 vtarget->deleted = 1; /* block IO */
576 ioc->name, vtarget->target_id); 680
681 target_reset_list = kzalloc(sizeof(*target_reset_list),
682 GFP_ATOMIC);
683 if (!target_reset_list) {
684 dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
685 ioc->name,__FUNCTION__, __LINE__));
686 return;
687 }
688
689 memcpy(&target_reset_list->sas_event_data, sas_event_data,
690 sizeof(*sas_event_data));
691 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
692
693 if (hd->resetPending)
694 return;
695
696 if (mptsas_target_reset(ioc, channel, id)) {
697 target_reset_list->target_reset_issued = 1;
698 hd->resetPending = 1;
577 } 699 }
578} 700}
579 701
702/**
703 * mptsas_dev_reset_complete
704 *
705 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
706 * enable work queue to finish off removing device from upper layers.
707 * then send next TARGET_RESET in the queue.
708 *
709 * @ioc
710 *
711 **/
712static void
713mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
714{
715 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
716 struct list_head *head = &hd->target_reset_list;
717 struct mptsas_target_reset_event *target_reset_list;
718 struct mptsas_hotplug_event *ev;
719 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
720 u8 id, channel;
721 __le64 sas_address;
722
723 if (list_empty(head))
724 return;
725
726 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
727
728 sas_event_data = &target_reset_list->sas_event_data;
729 id = sas_event_data->TargetID;
730 channel = sas_event_data->Bus;
731 hd->resetPending = 0;
732
733 /*
734 * retry target reset
735 */
736 if (!target_reset_list->target_reset_issued) {
737 if (mptsas_target_reset(ioc, channel, id)) {
738 target_reset_list->target_reset_issued = 1;
739 hd->resetPending = 1;
740 }
741 return;
742 }
743
744 /*
745 * enable work queue to remove device from upper layers
746 */
747 list_del(&target_reset_list->list);
748
749 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
750 if (!ev) {
751 dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
752 ioc->name,__FUNCTION__, __LINE__));
753 return;
754 }
755
756 INIT_WORK(&ev->work, mptsas_hotplug_work);
757 ev->ioc = ioc;
758 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
759 ev->parent_handle =
760 le16_to_cpu(sas_event_data->ParentDevHandle);
761 ev->channel = channel;
762 ev->id =id;
763 ev->phy_id = sas_event_data->PhyNum;
764 memcpy(&sas_address, &sas_event_data->SASAddress,
765 sizeof(__le64));
766 ev->sas_address = le64_to_cpu(sas_address);
767 ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
768 ev->event_type = MPTSAS_DEL_DEVICE;
769 schedule_work(&ev->work);
770 kfree(target_reset_list);
771
772 /*
773 * issue target reset to next device in the queue
774 */
775
776 head = &hd->target_reset_list;
777 if (list_empty(head))
778 return;
779
780 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
781 list);
782
783 sas_event_data = &target_reset_list->sas_event_data;
784 id = sas_event_data->TargetID;
785 channel = sas_event_data->Bus;
786
787 if (mptsas_target_reset(ioc, channel, id)) {
788 target_reset_list->target_reset_issued = 1;
789 hd->resetPending = 1;
790 }
791}
792
793/**
794 * mptsas_taskmgmt_complete
795 *
796 * @ioc
797 * @mf
798 * @mr
799 *
800 **/
801static int
802mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
803{
804 mptsas_dev_reset_complete(ioc);
805 return mptscsih_taskmgmt_complete(ioc, mf, mr);
806}
807
808/**
809 * mptscsih_ioc_reset
810 *
811 * @ioc
812 * @reset_phase
813 *
814 **/
815static int
816mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
817{
818 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
819 struct mptsas_target_reset_event *target_reset_list, *n;
820 int rc;
821
822 rc = mptscsih_ioc_reset(ioc, reset_phase);
823
824 if (ioc->bus_type != SAS)
825 goto out;
826
827 if (reset_phase != MPT_IOC_POST_RESET)
828 goto out;
829
830 if (!hd || !hd->ioc)
831 goto out;
832
833 if (list_empty(&hd->target_reset_list))
834 goto out;
835
836 /* flush the target_reset_list */
837 list_for_each_entry_safe(target_reset_list, n,
838 &hd->target_reset_list, list) {
839 list_del(&target_reset_list->list);
840 kfree(target_reset_list);
841 }
842
843 out:
844 return rc;
845}
846
580static int 847static int
581mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, 848mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
582 u32 form, u32 form_specific) 849 u32 form, u32 form_specific)
@@ -661,8 +928,7 @@ mptsas_target_alloc(struct scsi_target *starget)
661 struct Scsi_Host *host = dev_to_shost(&starget->dev); 928 struct Scsi_Host *host = dev_to_shost(&starget->dev);
662 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 929 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
663 VirtTarget *vtarget; 930 VirtTarget *vtarget;
664 u32 target_id; 931 u8 id, channel;
665 u32 channel;
666 struct sas_rphy *rphy; 932 struct sas_rphy *rphy;
667 struct mptsas_portinfo *p; 933 struct mptsas_portinfo *p;
668 int i; 934 int i;
@@ -673,15 +939,19 @@ mptsas_target_alloc(struct scsi_target *starget)
673 939
674 vtarget->starget = starget; 940 vtarget->starget = starget;
675 vtarget->ioc_id = hd->ioc->id; 941 vtarget->ioc_id = hd->ioc->id;
676 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; 942 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
677 943 id = starget->id;
678 target_id = starget->id;
679 channel = 0; 944 channel = 0;
680 945
681 hd->Targets[target_id] = vtarget; 946 /*
682 947 * RAID volumes placed beyond the last expected port.
683 if (starget->channel == MPTSAS_RAID_CHANNEL) 948 */
949 if (starget->channel == MPTSAS_RAID_CHANNEL) {
950 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
951 if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
952 channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
684 goto out; 953 goto out;
954 }
685 955
686 rphy = dev_to_rphy(starget->dev.parent); 956 rphy = dev_to_rphy(starget->dev.parent);
687 mutex_lock(&hd->ioc->sas_topology_mutex); 957 mutex_lock(&hd->ioc->sas_topology_mutex);
@@ -690,18 +960,19 @@ mptsas_target_alloc(struct scsi_target *starget)
690 if (p->phy_info[i].attached.sas_address != 960 if (p->phy_info[i].attached.sas_address !=
691 rphy->identify.sas_address) 961 rphy->identify.sas_address)
692 continue; 962 continue;
693 target_id = p->phy_info[i].attached.id; 963 id = p->phy_info[i].attached.id;
694 channel = p->phy_info[i].attached.channel; 964 channel = p->phy_info[i].attached.channel;
695 mptsas_set_starget(&p->phy_info[i], starget); 965 mptsas_set_starget(&p->phy_info[i], starget);
696 966
697 /* 967 /*
698 * Exposing hidden raid components 968 * Exposing hidden raid components
699 */ 969 */
700 if (mptscsih_is_phys_disk(hd->ioc, target_id)) { 970 if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
701 target_id = mptscsih_raid_id_to_num(hd, 971 id = mptscsih_raid_id_to_num(hd->ioc,
702 target_id); 972 channel, id);
703 vtarget->tflags |= 973 vtarget->tflags |=
704 MPT_TARGET_FLAGS_RAID_COMPONENT; 974 MPT_TARGET_FLAGS_RAID_COMPONENT;
975 p->phy_info[i].attached.phys_disk_num = id;
705 } 976 }
706 mutex_unlock(&hd->ioc->sas_topology_mutex); 977 mutex_unlock(&hd->ioc->sas_topology_mutex);
707 goto out; 978 goto out;
@@ -713,8 +984,8 @@ mptsas_target_alloc(struct scsi_target *starget)
713 return -ENXIO; 984 return -ENXIO;
714 985
715 out: 986 out:
716 vtarget->target_id = target_id; 987 vtarget->id = id;
717 vtarget->bus_id = channel; 988 vtarget->channel = channel;
718 starget->hostdata = vtarget; 989 starget->hostdata = vtarget;
719 return 0; 990 return 0;
720} 991}
@@ -786,7 +1057,8 @@ mptsas_slave_alloc(struct scsi_device *sdev)
786 * Exposing hidden raid components 1057 * Exposing hidden raid components
787 */ 1058 */
788 if (mptscsih_is_phys_disk(hd->ioc, 1059 if (mptscsih_is_phys_disk(hd->ioc,
789 p->phy_info[i].attached.id)) 1060 p->phy_info[i].attached.channel,
1061 p->phy_info[i].attached.id))
790 sdev->no_uld_attach = 1; 1062 sdev->no_uld_attach = 1;
791 mutex_unlock(&hd->ioc->sas_topology_mutex); 1063 mutex_unlock(&hd->ioc->sas_topology_mutex);
792 goto out; 1064 goto out;
@@ -808,13 +1080,14 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
808{ 1080{
809 VirtDevice *vdev = SCpnt->device->hostdata; 1081 VirtDevice *vdev = SCpnt->device->hostdata;
810 1082
811// scsi_print_command(SCpnt); 1083 if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
812 if (vdev->vtarget->deleted) {
813 SCpnt->result = DID_NO_CONNECT << 16; 1084 SCpnt->result = DID_NO_CONNECT << 16;
814 done(SCpnt); 1085 done(SCpnt);
815 return 0; 1086 return 0;
816 } 1087 }
817 1088
1089// scsi_print_command(SCpnt);
1090
818 return mptscsih_qcmd(SCpnt,done); 1091 return mptscsih_qcmd(SCpnt,done);
819} 1092}
820 1093
@@ -1114,9 +1387,6 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1114 goto out_free_consistent; 1387 goto out_free_consistent;
1115 } 1388 }
1116 1389
1117 if (port_info->num_phys)
1118 port_info->handle =
1119 le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
1120 for (i = 0; i < port_info->num_phys; i++) { 1390 for (i = 0; i < port_info->num_phys; i++) {
1121 mptsas_print_phy_data(&buffer->PhyData[i]); 1391 mptsas_print_phy_data(&buffer->PhyData[i]);
1122 port_info->phy_info[i].phy_id = i; 1392 port_info->phy_info[i].phy_id = i;
@@ -1125,6 +1395,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1125 port_info->phy_info[i].negotiated_link_rate = 1395 port_info->phy_info[i].negotiated_link_rate =
1126 buffer->PhyData[i].NegotiatedLinkRate; 1396 buffer->PhyData[i].NegotiatedLinkRate;
1127 port_info->phy_info[i].portinfo = port_info; 1397 port_info->phy_info[i].portinfo = port_info;
1398 port_info->phy_info[i].handle =
1399 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
1128 } 1400 }
1129 1401
1130 out_free_consistent: 1402 out_free_consistent:
@@ -1261,6 +1533,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1261 device_info->phy_id = buffer->PhyNum; 1533 device_info->phy_id = buffer->PhyNum;
1262 device_info->port_id = buffer->PhysicalPort; 1534 device_info->port_id = buffer->PhysicalPort;
1263 device_info->id = buffer->TargetID; 1535 device_info->id = buffer->TargetID;
1536 device_info->phys_disk_num = ~0;
1264 device_info->channel = buffer->Bus; 1537 device_info->channel = buffer->Bus;
1265 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); 1538 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1266 device_info->sas_address = le64_to_cpu(sas_address); 1539 device_info->sas_address = le64_to_cpu(sas_address);
@@ -1325,7 +1598,6 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1325 1598
1326 /* save config data */ 1599 /* save config data */
1327 port_info->num_phys = buffer->NumPhys; 1600 port_info->num_phys = buffer->NumPhys;
1328 port_info->handle = le16_to_cpu(buffer->DevHandle);
1329 port_info->phy_info = kcalloc(port_info->num_phys, 1601 port_info->phy_info = kcalloc(port_info->num_phys,
1330 sizeof(*port_info->phy_info),GFP_KERNEL); 1602 sizeof(*port_info->phy_info),GFP_KERNEL);
1331 if (!port_info->phy_info) { 1603 if (!port_info->phy_info) {
@@ -1333,8 +1605,11 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1333 goto out_free_consistent; 1605 goto out_free_consistent;
1334 } 1606 }
1335 1607
1336 for (i = 0; i < port_info->num_phys; i++) 1608 for (i = 0; i < port_info->num_phys; i++) {
1337 port_info->phy_info[i].portinfo = port_info; 1609 port_info->phy_info[i].portinfo = port_info;
1610 port_info->phy_info[i].handle =
1611 le16_to_cpu(buffer->DevHandle);
1612 }
1338 1613
1339 out_free_consistent: 1614 out_free_consistent:
1340 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 1615 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
@@ -1702,7 +1977,6 @@ static int
1702mptsas_probe_hba_phys(MPT_ADAPTER *ioc) 1977mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1703{ 1978{
1704 struct mptsas_portinfo *port_info, *hba; 1979 struct mptsas_portinfo *port_info, *hba;
1705 u32 handle = 0xFFFF;
1706 int error = -ENOMEM, i; 1980 int error = -ENOMEM, i;
1707 1981
1708 hba = kzalloc(sizeof(*port_info), GFP_KERNEL); 1982 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
@@ -1714,34 +1988,36 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
1714 goto out_free_port_info; 1988 goto out_free_port_info;
1715 1989
1716 mutex_lock(&ioc->sas_topology_mutex); 1990 mutex_lock(&ioc->sas_topology_mutex);
1717 ioc->handle = hba->handle; 1991 ioc->handle = hba->phy_info[0].handle;
1718 port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle); 1992 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1719 if (!port_info) { 1993 if (!port_info) {
1720 port_info = hba; 1994 port_info = hba;
1721 list_add_tail(&port_info->list, &ioc->sas_topology); 1995 list_add_tail(&port_info->list, &ioc->sas_topology);
1722 } else { 1996 } else {
1723 port_info->handle = hba->handle; 1997 for (i = 0; i < hba->num_phys; i++) {
1724 for (i = 0; i < hba->num_phys; i++)
1725 port_info->phy_info[i].negotiated_link_rate = 1998 port_info->phy_info[i].negotiated_link_rate =
1726 hba->phy_info[i].negotiated_link_rate; 1999 hba->phy_info[i].negotiated_link_rate;
2000 port_info->phy_info[i].handle =
2001 hba->phy_info[i].handle;
2002 port_info->phy_info[i].port_id =
2003 hba->phy_info[i].port_id;
2004 }
1727 kfree(hba->phy_info); 2005 kfree(hba->phy_info);
1728 kfree(hba); 2006 kfree(hba);
1729 hba = NULL; 2007 hba = NULL;
1730 } 2008 }
1731 mutex_unlock(&ioc->sas_topology_mutex); 2009 mutex_unlock(&ioc->sas_topology_mutex);
1732
1733 for (i = 0; i < port_info->num_phys; i++) { 2010 for (i = 0; i < port_info->num_phys; i++) {
1734 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 2011 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
1735 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << 2012 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
1736 MPI_SAS_PHY_PGAD_FORM_SHIFT), i); 2013 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
1737 2014
1738 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify, 2015 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
1739 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE << 2016 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
1740 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle); 2017 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2018 port_info->phy_info[i].handle);
1741 port_info->phy_info[i].identify.phy_id = 2019 port_info->phy_info[i].identify.phy_id =
1742 port_info->phy_info[i].phy_id; 2020 port_info->phy_info[i].phy_id = i;
1743 handle = port_info->phy_info[i].identify.handle;
1744
1745 if (port_info->phy_info[i].attached.handle) 2021 if (port_info->phy_info[i].attached.handle)
1746 mptsas_sas_device_pg0(ioc, 2022 mptsas_sas_device_pg0(ioc,
1747 &port_info->phy_info[i].attached, 2023 &port_info->phy_info[i].attached,
@@ -1777,12 +2053,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1777 goto out; 2053 goto out;
1778 2054
1779 error = mptsas_sas_expander_pg0(ioc, ex, 2055 error = mptsas_sas_expander_pg0(ioc, ex,
1780 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 2056 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
1781 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); 2057 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
1782 if (error) 2058 if (error)
1783 goto out_free_port_info; 2059 goto out_free_port_info;
1784 2060
1785 *handle = ex->handle; 2061 *handle = ex->phy_info[0].handle;
1786 2062
1787 mutex_lock(&ioc->sas_topology_mutex); 2063 mutex_lock(&ioc->sas_topology_mutex);
1788 port_info = mptsas_find_portinfo_by_handle(ioc, *handle); 2064 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
@@ -1790,7 +2066,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
1790 port_info = ex; 2066 port_info = ex;
1791 list_add_tail(&port_info->list, &ioc->sas_topology); 2067 list_add_tail(&port_info->list, &ioc->sas_topology);
1792 } else { 2068 } else {
1793 port_info->handle = ex->handle; 2069 for (i = 0; i < ex->num_phys; i++) {
2070 port_info->phy_info[i].handle =
2071 ex->phy_info[i].handle;
2072 port_info->phy_info[i].port_id =
2073 ex->phy_info[i].port_id;
2074 }
1794 kfree(ex->phy_info); 2075 kfree(ex->phy_info);
1795 kfree(ex); 2076 kfree(ex);
1796 ex = NULL; 2077 ex = NULL;
@@ -1868,8 +2149,6 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1868 struct mptsas_portinfo buffer; 2149 struct mptsas_portinfo buffer;
1869 struct mptsas_portinfo *port_info, *n, *parent; 2150 struct mptsas_portinfo *port_info, *n, *parent;
1870 struct mptsas_phyinfo *phy_info; 2151 struct mptsas_phyinfo *phy_info;
1871 struct scsi_target * starget;
1872 VirtTarget * vtarget;
1873 struct sas_port * port; 2152 struct sas_port * port;
1874 int i; 2153 int i;
1875 u64 expander_sas_address; 2154 u64 expander_sas_address;
@@ -1884,26 +2163,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
1884 2163
1885 if (mptsas_sas_expander_pg0(ioc, &buffer, 2164 if (mptsas_sas_expander_pg0(ioc, &buffer,
1886 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE << 2165 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
1887 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) { 2166 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
1888 2167 port_info->phy_info[0].handle)) {
1889 /*
1890 * Issue target reset to all child end devices
1891 * then mark them deleted to prevent further
1892 * IO going to them.
1893 */
1894 phy_info = port_info->phy_info;
1895 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
1896 starget = mptsas_get_starget(phy_info);
1897 if (!starget)
1898 continue;
1899 vtarget = starget->hostdata;
1900 if(vtarget->deleted)
1901 continue;
1902 vtarget->deleted = 1;
1903 mptsas_target_reset(ioc, vtarget);
1904 sas_port_delete(mptsas_get_port(phy_info));
1905 mptsas_port_delete(phy_info->port_details);
1906 }
1907 2168
1908 /* 2169 /*
1909 * Obtain the port_info instance to the parent port 2170 * Obtain the port_info instance to the parent port
@@ -1972,11 +2233,13 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1972 /* 2233 /*
1973 Reporting RAID volumes. 2234 Reporting RAID volumes.
1974 */ 2235 */
2236 if (!ioc->ir_firmware)
2237 goto out;
1975 if (!ioc->raid_data.pIocPg2) 2238 if (!ioc->raid_data.pIocPg2)
1976 goto out; 2239 goto out;
1977 if (!ioc->raid_data.pIocPg2->NumActiveVolumes) 2240 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
1978 goto out; 2241 goto out;
1979 for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { 2242 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1980 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, 2243 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
1981 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); 2244 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
1982 } 2245 }
@@ -2030,12 +2293,37 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2030 mutex_lock(&ioc->sas_topology_mutex); 2293 mutex_lock(&ioc->sas_topology_mutex);
2031 list_for_each_entry(port_info, &ioc->sas_topology, list) { 2294 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2032 for (i = 0; i < port_info->num_phys; i++) { 2295 for (i = 0; i < port_info->num_phys; i++) {
2296 if (!mptsas_is_end_device(
2297 &port_info->phy_info[i].attached))
2298 continue;
2033 if (port_info->phy_info[i].attached.sas_address 2299 if (port_info->phy_info[i].attached.sas_address
2034 != sas_address) 2300 != sas_address)
2035 continue; 2301 continue;
2302 phy_info = &port_info->phy_info[i];
2303 break;
2304 }
2305 }
2306 mutex_unlock(&ioc->sas_topology_mutex);
2307 return phy_info;
2308}
2309
2310static struct mptsas_phyinfo *
2311mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2312{
2313 struct mptsas_portinfo *port_info;
2314 struct mptsas_phyinfo *phy_info = NULL;
2315 int i;
2316
2317 mutex_lock(&ioc->sas_topology_mutex);
2318 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2319 for (i = 0; i < port_info->num_phys; i++) {
2036 if (!mptsas_is_end_device( 2320 if (!mptsas_is_end_device(
2037 &port_info->phy_info[i].attached)) 2321 &port_info->phy_info[i].attached))
2038 continue; 2322 continue;
2323 if (port_info->phy_info[i].attached.id != id)
2324 continue;
2325 if (port_info->phy_info[i].attached.channel != channel)
2326 continue;
2039 phy_info = &port_info->phy_info[i]; 2327 phy_info = &port_info->phy_info[i];
2040 break; 2328 break;
2041 } 2329 }
@@ -2045,7 +2333,7 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2045} 2333}
2046 2334
2047static struct mptsas_phyinfo * 2335static struct mptsas_phyinfo *
2048mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) 2336mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2049{ 2337{
2050 struct mptsas_portinfo *port_info; 2338 struct mptsas_portinfo *port_info;
2051 struct mptsas_phyinfo *phy_info = NULL; 2339 struct mptsas_phyinfo *phy_info = NULL;
@@ -2054,11 +2342,15 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
2054 mutex_lock(&ioc->sas_topology_mutex); 2342 mutex_lock(&ioc->sas_topology_mutex);
2055 list_for_each_entry(port_info, &ioc->sas_topology, list) { 2343 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2056 for (i = 0; i < port_info->num_phys; i++) { 2344 for (i = 0; i < port_info->num_phys; i++) {
2057 if (port_info->phy_info[i].attached.id != id)
2058 continue;
2059 if (!mptsas_is_end_device( 2345 if (!mptsas_is_end_device(
2060 &port_info->phy_info[i].attached)) 2346 &port_info->phy_info[i].attached))
2061 continue; 2347 continue;
2348 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2349 continue;
2350 if (port_info->phy_info[i].attached.phys_disk_num != id)
2351 continue;
2352 if (port_info->phy_info[i].attached.channel != channel)
2353 continue;
2062 phy_info = &port_info->phy_info[i]; 2354 phy_info = &port_info->phy_info[i];
2063 break; 2355 break;
2064 } 2356 }
@@ -2094,6 +2386,76 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2094 mptsas_reprobe_lun); 2386 mptsas_reprobe_lun);
2095} 2387}
2096 2388
2389static void
2390mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2391{
2392 CONFIGPARMS cfg;
2393 ConfigPageHeader_t hdr;
2394 dma_addr_t dma_handle;
2395 pRaidVolumePage0_t buffer = NULL;
2396 RaidPhysDiskPage0_t phys_disk;
2397 int i;
2398 struct mptsas_hotplug_event *ev;
2399
2400 memset(&cfg, 0 , sizeof(CONFIGPARMS));
2401 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2402 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2403 cfg.pageAddr = (channel << 8) + id;
2404 cfg.cfghdr.hdr = &hdr;
2405 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2406
2407 if (mpt_config(ioc, &cfg) != 0)
2408 goto out;
2409
2410 if (!hdr.PageLength)
2411 goto out;
2412
2413 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2414 &dma_handle);
2415
2416 if (!buffer)
2417 goto out;
2418
2419 cfg.physAddr = dma_handle;
2420 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2421
2422 if (mpt_config(ioc, &cfg) != 0)
2423 goto out;
2424
2425 if (!(buffer->VolumeStatus.Flags &
2426 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2427 goto out;
2428
2429 if (!buffer->NumPhysDisks)
2430 goto out;
2431
2432 for (i = 0; i < buffer->NumPhysDisks; i++) {
2433
2434 if (mpt_raid_phys_disk_pg0(ioc,
2435 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2436 continue;
2437
2438 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2439 if (!ev) {
2440 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2441 goto out;
2442 }
2443
2444 INIT_WORK(&ev->work, mptsas_hotplug_work);
2445 ev->ioc = ioc;
2446 ev->id = phys_disk.PhysDiskID;
2447 ev->channel = phys_disk.PhysDiskBus;
2448 ev->phys_disk_num_valid = 1;
2449 ev->phys_disk_num = phys_disk.PhysDiskNum;
2450 ev->event_type = MPTSAS_ADD_DEVICE;
2451 schedule_work(&ev->work);
2452 }
2453
2454 out:
2455 if (buffer)
2456 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2457 dma_handle);
2458}
2097/* 2459/*
2098 * Work queue thread to handle SAS hotplug events 2460 * Work queue thread to handle SAS hotplug events
2099 */ 2461 */
@@ -2102,6 +2464,7 @@ mptsas_hotplug_work(struct work_struct *work)
2102{ 2464{
2103 struct mptsas_hotplug_event *ev = 2465 struct mptsas_hotplug_event *ev =
2104 container_of(work, struct mptsas_hotplug_event, work); 2466 container_of(work, struct mptsas_hotplug_event, work);
2467
2105 MPT_ADAPTER *ioc = ev->ioc; 2468 MPT_ADAPTER *ioc = ev->ioc;
2106 struct mptsas_phyinfo *phy_info; 2469 struct mptsas_phyinfo *phy_info;
2107 struct sas_rphy *rphy; 2470 struct sas_rphy *rphy;
@@ -2114,17 +2477,43 @@ mptsas_hotplug_work(struct work_struct *work)
2114 VirtTarget *vtarget; 2477 VirtTarget *vtarget;
2115 VirtDevice *vdevice; 2478 VirtDevice *vdevice;
2116 2479
2117
2118 mutex_lock(&ioc->sas_discovery_mutex); 2480 mutex_lock(&ioc->sas_discovery_mutex);
2119 switch (ev->event_type) { 2481 switch (ev->event_type) {
2120 case MPTSAS_DEL_DEVICE: 2482 case MPTSAS_DEL_DEVICE:
2121 2483
2122 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); 2484 phy_info = NULL;
2485 if (ev->phys_disk_num_valid) {
2486 if (ev->hidden_raid_component){
2487 if (mptsas_sas_device_pg0(ioc, &sas_device,
2488 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2489 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2490 (ev->channel << 8) + ev->id)) {
2491 dfailprintk((MYIOC_s_ERR_FMT
2492 "%s: exit at line=%d\n", ioc->name,
2493 __FUNCTION__, __LINE__));
2494 break;
2495 }
2496 phy_info = mptsas_find_phyinfo_by_sas_address(
2497 ioc, sas_device.sas_address);
2498 }else
2499 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2500 ioc, ev->channel, ev->phys_disk_num);
2501 }
2502
2503 if (!phy_info)
2504 phy_info = mptsas_find_phyinfo_by_target(ioc,
2505 ev->channel, ev->id);
2123 2506
2124 /* 2507 /*
2125 * Sanity checks, for non-existing phys and remote rphys. 2508 * Sanity checks, for non-existing phys and remote rphys.
2126 */ 2509 */
2127 if (!phy_info || !phy_info->port_details) { 2510 if (!phy_info){
2511 dfailprintk((MYIOC_s_ERR_FMT
2512 "%s: exit at line=%d\n", ioc->name,
2513 __FUNCTION__, __LINE__));
2514 break;
2515 }
2516 if (!phy_info->port_details) {
2128 dfailprintk((MYIOC_s_ERR_FMT 2517 dfailprintk((MYIOC_s_ERR_FMT
2129 "%s: exit at line=%d\n", ioc->name, 2518 "%s: exit at line=%d\n", ioc->name,
2130 __FUNCTION__, __LINE__)); 2519 __FUNCTION__, __LINE__));
@@ -2137,6 +2526,7 @@ mptsas_hotplug_work(struct work_struct *work)
2137 __FUNCTION__, __LINE__)); 2526 __FUNCTION__, __LINE__));
2138 break; 2527 break;
2139 } 2528 }
2529
2140 port = mptsas_get_port(phy_info); 2530 port = mptsas_get_port(phy_info);
2141 if (!port) { 2531 if (!port) {
2142 dfailprintk((MYIOC_s_ERR_FMT 2532 dfailprintk((MYIOC_s_ERR_FMT
@@ -2159,28 +2549,35 @@ mptsas_hotplug_work(struct work_struct *work)
2159 /* 2549 /*
2160 * Handling RAID components 2550 * Handling RAID components
2161 */ 2551 */
2162 if (ev->phys_disk_num_valid) { 2552 if (ev->phys_disk_num_valid &&
2163 vtarget->target_id = ev->phys_disk_num; 2553 ev->hidden_raid_component) {
2164 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; 2554 printk(MYIOC_s_INFO_FMT
2555 "RAID Hidding: channel=%d, id=%d, "
2556 "physdsk %d \n", ioc->name, ev->channel,
2557 ev->id, ev->phys_disk_num);
2558 vtarget->id = ev->phys_disk_num;
2559 vtarget->tflags |=
2560 MPT_TARGET_FLAGS_RAID_COMPONENT;
2165 mptsas_reprobe_target(starget, 1); 2561 mptsas_reprobe_target(starget, 1);
2166 break; 2562 phy_info->attached.phys_disk_num =
2563 ev->phys_disk_num;
2564 break;
2167 } 2565 }
2168
2169 vtarget->deleted = 1;
2170 mptsas_target_reset(ioc, vtarget);
2171 } 2566 }
2172 2567
2173 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 2568 if (phy_info->attached.device_info &
2569 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2174 ds = "ssp"; 2570 ds = "ssp";
2175 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) 2571 if (phy_info->attached.device_info &
2572 MPI_SAS_DEVICE_INFO_STP_TARGET)
2176 ds = "stp"; 2573 ds = "stp";
2177 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) 2574 if (phy_info->attached.device_info &
2575 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2178 ds = "sata"; 2576 ds = "sata";
2179 2577
2180 printk(MYIOC_s_INFO_FMT 2578 printk(MYIOC_s_INFO_FMT
2181 "removing %s device, channel %d, id %d, phy %d\n", 2579 "removing %s device, channel %d, id %d, phy %d\n",
2182 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); 2580 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2183
2184#ifdef MPT_DEBUG_SAS_WIDE 2581#ifdef MPT_DEBUG_SAS_WIDE
2185 dev_printk(KERN_DEBUG, &port->dev, 2582 dev_printk(KERN_DEBUG, &port->dev,
2186 "delete port (%d)\n", port->port_identifier); 2583 "delete port (%d)\n", port->port_identifier);
@@ -2198,14 +2595,14 @@ mptsas_hotplug_work(struct work_struct *work)
2198 */ 2595 */
2199 if (mptsas_sas_device_pg0(ioc, &sas_device, 2596 if (mptsas_sas_device_pg0(ioc, &sas_device,
2200 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << 2597 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2201 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { 2598 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2599 (ev->channel << 8) + ev->id)) {
2202 dfailprintk((MYIOC_s_ERR_FMT 2600 dfailprintk((MYIOC_s_ERR_FMT
2203 "%s: exit at line=%d\n", ioc->name, 2601 "%s: exit at line=%d\n", ioc->name,
2204 __FUNCTION__, __LINE__)); 2602 __FUNCTION__, __LINE__));
2205 break; 2603 break;
2206 } 2604 }
2207 2605
2208 ssleep(2);
2209 __mptsas_discovery_work(ioc); 2606 __mptsas_discovery_work(ioc);
2210 2607
2211 phy_info = mptsas_find_phyinfo_by_sas_address(ioc, 2608 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
@@ -2219,7 +2616,8 @@ mptsas_hotplug_work(struct work_struct *work)
2219 } 2616 }
2220 2617
2221 starget = mptsas_get_starget(phy_info); 2618 starget = mptsas_get_starget(phy_info);
2222 if (starget) { 2619 if (starget && (!ev->hidden_raid_component)){
2620
2223 vtarget = starget->hostdata; 2621 vtarget = starget->hostdata;
2224 2622
2225 if (!vtarget) { 2623 if (!vtarget) {
@@ -2232,9 +2630,15 @@ mptsas_hotplug_work(struct work_struct *work)
2232 * Handling RAID components 2630 * Handling RAID components
2233 */ 2631 */
2234 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { 2632 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2235 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; 2633 printk(MYIOC_s_INFO_FMT
2236 vtarget->target_id = ev->id; 2634 "RAID Exposing: channel=%d, id=%d, "
2635 "physdsk %d \n", ioc->name, ev->channel,
2636 ev->id, ev->phys_disk_num);
2637 vtarget->tflags &=
2638 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2639 vtarget->id = ev->id;
2237 mptsas_reprobe_target(starget, 0); 2640 mptsas_reprobe_target(starget, 0);
2641 phy_info->attached.phys_disk_num = ~0;
2238 } 2642 }
2239 break; 2643 break;
2240 } 2644 }
@@ -2243,8 +2647,10 @@ mptsas_hotplug_work(struct work_struct *work)
2243 dfailprintk((MYIOC_s_ERR_FMT 2647 dfailprintk((MYIOC_s_ERR_FMT
2244 "%s: exit at line=%d\n", ioc->name, 2648 "%s: exit at line=%d\n", ioc->name,
2245 __FUNCTION__, __LINE__)); 2649 __FUNCTION__, __LINE__));
2650 if (ev->channel) printk("%d\n", __LINE__);
2246 break; 2651 break;
2247 } 2652 }
2653
2248 port = mptsas_get_port(phy_info); 2654 port = mptsas_get_port(phy_info);
2249 if (!port) { 2655 if (!port) {
2250 dfailprintk((MYIOC_s_ERR_FMT 2656 dfailprintk((MYIOC_s_ERR_FMT
@@ -2252,15 +2658,17 @@ mptsas_hotplug_work(struct work_struct *work)
2252 __FUNCTION__, __LINE__)); 2658 __FUNCTION__, __LINE__));
2253 break; 2659 break;
2254 } 2660 }
2255
2256 memcpy(&phy_info->attached, &sas_device, 2661 memcpy(&phy_info->attached, &sas_device,
2257 sizeof(struct mptsas_devinfo)); 2662 sizeof(struct mptsas_devinfo));
2258 2663
2259 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 2664 if (phy_info->attached.device_info &
2665 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2260 ds = "ssp"; 2666 ds = "ssp";
2261 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) 2667 if (phy_info->attached.device_info &
2668 MPI_SAS_DEVICE_INFO_STP_TARGET)
2262 ds = "stp"; 2669 ds = "stp";
2263 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) 2670 if (phy_info->attached.device_info &
2671 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2264 ds = "sata"; 2672 ds = "sata";
2265 2673
2266 printk(MYIOC_s_INFO_FMT 2674 printk(MYIOC_s_INFO_FMT
@@ -2301,19 +2709,21 @@ mptsas_hotplug_work(struct work_struct *work)
2301 break; 2709 break;
2302 case MPTSAS_DEL_RAID: 2710 case MPTSAS_DEL_RAID:
2303 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, 2711 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2304 ev->id, 0); 2712 ev->id, 0);
2305 if (!sdev) 2713 if (!sdev)
2306 break; 2714 break;
2307 printk(MYIOC_s_INFO_FMT 2715 printk(MYIOC_s_INFO_FMT
2308 "removing raid volume, channel %d, id %d\n", 2716 "removing raid volume, channel %d, id %d\n",
2309 ioc->name, MPTSAS_RAID_CHANNEL, ev->id); 2717 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2310 vdevice = sdev->hostdata; 2718 vdevice = sdev->hostdata;
2311 vdevice->vtarget->deleted = 1;
2312 mptsas_target_reset(ioc, vdevice->vtarget);
2313 scsi_remove_device(sdev); 2719 scsi_remove_device(sdev);
2314 scsi_device_put(sdev); 2720 scsi_device_put(sdev);
2315 mpt_findImVolumes(ioc); 2721 mpt_findImVolumes(ioc);
2316 break; 2722 break;
2723 case MPTSAS_ADD_INACTIVE_VOLUME:
2724 mptsas_adding_inactive_raid_components(ioc,
2725 ev->channel, ev->id);
2726 break;
2317 case MPTSAS_IGNORE_EVENT: 2727 case MPTSAS_IGNORE_EVENT:
2318 default: 2728 default:
2319 break; 2729 break;
@@ -2321,7 +2731,6 @@ mptsas_hotplug_work(struct work_struct *work)
2321 2731
2322 mutex_unlock(&ioc->sas_discovery_mutex); 2732 mutex_unlock(&ioc->sas_discovery_mutex);
2323 kfree(ev); 2733 kfree(ev);
2324
2325} 2734}
2326 2735
2327static void 2736static void
@@ -2339,8 +2748,12 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
2339 return; 2748 return;
2340 2749
2341 switch (sas_event_data->ReasonCode) { 2750 switch (sas_event_data->ReasonCode) {
2342 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2343 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 2751 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2752
2753 mptsas_target_reset_queue(ioc, sas_event_data);
2754 break;
2755
2756 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2344 ev = kzalloc(sizeof(*ev), GFP_ATOMIC); 2757 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2345 if (!ev) { 2758 if (!ev) {
2346 printk(KERN_WARNING "mptsas: lost hotplug event\n"); 2759 printk(KERN_WARNING "mptsas: lost hotplug event\n");
@@ -2375,15 +2788,20 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
2375 mptsas_persist_clear_table); 2788 mptsas_persist_clear_table);
2376 schedule_work(&ioc->sas_persist_task); 2789 schedule_work(&ioc->sas_persist_task);
2377 break; 2790 break;
2791 /*
2792 * TODO, handle other events
2793 */
2378 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 2794 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2379 /* TODO */ 2795 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2380 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 2796 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2381 /* TODO */ 2797 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2798 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2799 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2800 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2382 default: 2801 default:
2383 break; 2802 break;
2384 } 2803 }
2385} 2804}
2386
2387static void 2805static void
2388mptsas_send_raid_event(MPT_ADAPTER *ioc, 2806mptsas_send_raid_event(MPT_ADAPTER *ioc,
2389 EVENT_DATA_RAID *raid_event_data) 2807 EVENT_DATA_RAID *raid_event_data)
@@ -2404,31 +2822,36 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc,
2404 INIT_WORK(&ev->work, mptsas_hotplug_work); 2822 INIT_WORK(&ev->work, mptsas_hotplug_work);
2405 ev->ioc = ioc; 2823 ev->ioc = ioc;
2406 ev->id = raid_event_data->VolumeID; 2824 ev->id = raid_event_data->VolumeID;
2825 ev->channel = raid_event_data->VolumeBus;
2407 ev->event_type = MPTSAS_IGNORE_EVENT; 2826 ev->event_type = MPTSAS_IGNORE_EVENT;
2408 2827
2409 switch (raid_event_data->ReasonCode) { 2828 switch (raid_event_data->ReasonCode) {
2410 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 2829 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2830 ev->phys_disk_num_valid = 1;
2831 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2411 ev->event_type = MPTSAS_ADD_DEVICE; 2832 ev->event_type = MPTSAS_ADD_DEVICE;
2412 break; 2833 break;
2413 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 2834 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2414 ioc->raid_data.isRaid = 1;
2415 ev->phys_disk_num_valid = 1; 2835 ev->phys_disk_num_valid = 1;
2416 ev->phys_disk_num = raid_event_data->PhysDiskNum; 2836 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2837 ev->hidden_raid_component = 1;
2417 ev->event_type = MPTSAS_DEL_DEVICE; 2838 ev->event_type = MPTSAS_DEL_DEVICE;
2418 break; 2839 break;
2419 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: 2840 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2420 switch (state) { 2841 switch (state) {
2421 case MPI_PD_STATE_ONLINE: 2842 case MPI_PD_STATE_ONLINE:
2422 ioc->raid_data.isRaid = 1; 2843 case MPI_PD_STATE_NOT_COMPATIBLE:
2423 ev->phys_disk_num_valid = 1; 2844 ev->phys_disk_num_valid = 1;
2424 ev->phys_disk_num = raid_event_data->PhysDiskNum; 2845 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2846 ev->hidden_raid_component = 1;
2425 ev->event_type = MPTSAS_ADD_DEVICE; 2847 ev->event_type = MPTSAS_ADD_DEVICE;
2426 break; 2848 break;
2427 case MPI_PD_STATE_MISSING: 2849 case MPI_PD_STATE_MISSING:
2428 case MPI_PD_STATE_NOT_COMPATIBLE:
2429 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: 2850 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2430 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: 2851 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2431 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: 2852 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2853 ev->phys_disk_num_valid = 1;
2854 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2432 ev->event_type = MPTSAS_DEL_DEVICE; 2855 ev->event_type = MPTSAS_DEL_DEVICE;
2433 break; 2856 break;
2434 default: 2857 default:
@@ -2485,6 +2908,35 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2485 schedule_work(&ev->work); 2908 schedule_work(&ev->work);
2486}; 2909};
2487 2910
2911/*
2912 * mptsas_send_ir2_event - handle exposing hidden disk when
2913 * an inactive raid volume is added
2914 *
2915 * @ioc: Pointer to MPT_ADAPTER structure
2916 * @ir2_data
2917 *
2918 */
2919static void
2920mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
2921{
2922 struct mptsas_hotplug_event *ev;
2923
2924 if (ir2_data->ReasonCode !=
2925 MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
2926 return;
2927
2928 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2929 if (!ev)
2930 return;
2931
2932 INIT_WORK(&ev->work, mptsas_hotplug_work);
2933 ev->ioc = ioc;
2934 ev->id = ir2_data->TargetID;
2935 ev->channel = ir2_data->Bus;
2936 ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
2937
2938 schedule_work(&ev->work);
2939};
2488 2940
2489static int 2941static int
2490mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) 2942mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
@@ -2524,6 +2976,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2524 mptsas_send_discovery_event(ioc, 2976 mptsas_send_discovery_event(ioc,
2525 (EVENT_DATA_SAS_DISCOVERY *)reply->Data); 2977 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2526 break; 2978 break;
2979 case MPI_EVENT_IR2:
2980 mptsas_send_ir2_event(ioc,
2981 (PTR_MPI_EVENT_DATA_IR2)reply->Data);
2982 break;
2527 default: 2983 default:
2528 rc = mptscsih_event_process(ioc, reply); 2984 rc = mptscsih_event_process(ioc, reply);
2529 break; 2985 break;
@@ -2611,12 +3067,11 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2611 /* set 16 byte cdb's */ 3067 /* set 16 byte cdb's */
2612 sh->max_cmd_len = 16; 3068 sh->max_cmd_len = 16;
2613 3069
2614 sh->max_id = ioc->pfacts->MaxDevices + 1; 3070 sh->max_id = ioc->pfacts[0].PortSCSIID;
3071 sh->max_lun = max_lun;
2615 3072
2616 sh->transportt = mptsas_transport_template; 3073 sh->transportt = mptsas_transport_template;
2617 3074
2618 sh->max_lun = MPT_LAST_LUN + 1;
2619 sh->max_channel = 0;
2620 sh->this_id = ioc->pfacts[0].PortSCSIID; 3075 sh->this_id = ioc->pfacts[0].PortSCSIID;
2621 3076
2622 /* Required entry. 3077 /* Required entry.
@@ -2659,8 +3114,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2659 sh->sg_tablesize = numSGE; 3114 sh->sg_tablesize = numSGE;
2660 } 3115 }
2661 3116
2662 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2663
2664 hd = (MPT_SCSI_HOST *) sh->hostdata; 3117 hd = (MPT_SCSI_HOST *) sh->hostdata;
2665 hd->ioc = ioc; 3118 hd->ioc = ioc;
2666 3119
@@ -2676,19 +3129,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2676 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", 3129 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
2677 ioc->name, hd->ScsiLookup)); 3130 ioc->name, hd->ScsiLookup));
2678 3131
2679 /* Allocate memory for the device structures.
2680 * A non-Null pointer at an offset
2681 * indicates a device exists.
2682 * max_id = 1 + maximum id (hosts.h)
2683 */
2684 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
2685 if (!hd->Targets) {
2686 error = -ENOMEM;
2687 goto out_mptsas_probe;
2688 }
2689
2690 dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
2691
2692 /* Clear the TM flags 3132 /* Clear the TM flags
2693 */ 3133 */
2694 hd->tmPending = 0; 3134 hd->tmPending = 0;
@@ -2713,15 +3153,17 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2713 3153
2714 ioc->sas_data.ptClear = mpt_pt_clear; 3154 ioc->sas_data.ptClear = mpt_pt_clear;
2715 3155
3156 init_waitqueue_head(&hd->scandv_waitq);
3157 hd->scandv_wait_done = 0;
3158 hd->last_queue_full = 0;
3159 INIT_LIST_HEAD(&hd->target_reset_list);
3160 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3161
2716 if (ioc->sas_data.ptClear==1) { 3162 if (ioc->sas_data.ptClear==1) {
2717 mptbase_sas_persist_operation( 3163 mptbase_sas_persist_operation(
2718 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); 3164 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
2719 } 3165 }
2720 3166
2721 init_waitqueue_head(&hd->scandv_waitq);
2722 hd->scandv_wait_done = 0;
2723 hd->last_queue_full = 0;
2724
2725 error = scsi_add_host(sh, &ioc->pcidev->dev); 3167 error = scsi_add_host(sh, &ioc->pcidev->dev);
2726 if (error) { 3168 if (error) {
2727 dprintk((KERN_ERR MYNAM 3169 dprintk((KERN_ERR MYNAM
@@ -2745,7 +3187,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
2745 struct mptsas_portinfo *p, *n; 3187 struct mptsas_portinfo *p, *n;
2746 int i; 3188 int i;
2747 3189
2748 ioc->sas_discovery_ignore_events=1; 3190 ioc->sas_discovery_ignore_events = 1;
2749 sas_remove_host(ioc->sh); 3191 sas_remove_host(ioc->sh);
2750 3192
2751 mutex_lock(&ioc->sas_topology_mutex); 3193 mutex_lock(&ioc->sas_topology_mutex);
@@ -2800,7 +3242,7 @@ mptsas_init(void)
2800 return -ENODEV; 3242 return -ENODEV;
2801 3243
2802 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER); 3244 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
2803 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER); 3245 mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
2804 mptsasInternalCtx = 3246 mptsasInternalCtx =
2805 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); 3247 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
2806 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER); 3248 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
@@ -2810,7 +3252,7 @@ mptsas_init(void)
2810 ": Registered for IOC event notifications\n")); 3252 ": Registered for IOC event notifications\n"));
2811 } 3253 }
2812 3254
2813 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) { 3255 if (mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset) == 0) {
2814 dprintk((KERN_INFO MYNAM 3256 dprintk((KERN_INFO MYNAM
2815 ": Registered for IOC reset notifications\n")); 3257 ": Registered for IOC reset notifications\n"));
2816 } 3258 }
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index f0cca3ea93b2..c417ae0b5fe6 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -4,7 +4,7 @@
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 * 5 *
6 * Copyright (c) 1999-2007 LSI Logic Corporation 6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsi.com)
8 * 8 *
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -79,43 +79,6 @@ MODULE_LICENSE("GPL");
79MODULE_VERSION(my_VERSION); 79MODULE_VERSION(my_VERSION);
80 80
81/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 81/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
82
83typedef struct _BIG_SENSE_BUF {
84 u8 data[MPT_SENSE_BUFFER_ALLOC];
85} BIG_SENSE_BUF;
86
87#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
88#define MPT_SCANDV_DID_RESET (0x00000001)
89#define MPT_SCANDV_SENSE (0x00000002)
90#define MPT_SCANDV_SOME_ERROR (0x00000004)
91#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
92#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
93#define MPT_SCANDV_FALLBACK (0x00000020)
94
95#define MPT_SCANDV_MAX_RETRIES (10)
96
97#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
98#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
99#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
100#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
101#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
102#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
103#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
104
105typedef struct _internal_cmd {
106 char *data; /* data pointer */
107 dma_addr_t data_dma; /* data dma address */
108 int size; /* transfer size */
109 u8 cmd; /* SCSI Op Code */
110 u8 bus; /* bus number */
111 u8 id; /* SCSI ID (virtual) */
112 u8 lun;
113 u8 flags; /* Bit Field - See above */
114 u8 physDiskNum; /* Phys disk number, -1 else */
115 u8 rsvd2;
116 u8 rsvd;
117} INTERNAL_CMD;
118
119/* 82/*
120 * Other private/forward protos... 83 * Other private/forward protos...
121 */ 84 */
@@ -131,14 +94,11 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
131static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 94static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
132static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); 95static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
133 96
134static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 97static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
135 98
136int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 99int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
137int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 100int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
138 101
139static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
140static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
141static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
142int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 102int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
143static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 103static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
144static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 104static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
@@ -517,16 +477,100 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
517 477
518 SEPMsg = (SEPRequest_t *)mf; 478 SEPMsg = (SEPRequest_t *)mf;
519 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 479 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
520 SEPMsg->Bus = vtarget->bus_id; 480 SEPMsg->Bus = vtarget->channel;
521 SEPMsg->TargetID = vtarget->target_id; 481 SEPMsg->TargetID = vtarget->id;
522 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; 482 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
523 SEPMsg->SlotStatus = SlotStatus; 483 SEPMsg->SlotStatus = SlotStatus;
524 devtverboseprintk((MYIOC_s_WARN_FMT 484 devtverboseprintk((MYIOC_s_WARN_FMT
525 "Sending SEP cmd=%x id=%d bus=%d\n", 485 "Sending SEP cmd=%x channel=%d id=%d\n",
526 ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); 486 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
527 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); 487 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
528} 488}
529 489
490#ifdef MPT_DEBUG_REPLY
491/**
492 * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
493 * @ioc: Pointer to MPT_ADAPTER structure
494 * @ioc_status: U32 IOCStatus word from IOC
495 * @scsi_status: U8 sam status from target
496 * @scsi_state: U8 scsi state
497 * @sc: original scsi cmnd pointer
498 * @mf: Pointer to MPT request frame
499 *
500 * Refer to lsi/mpi.h.
501 **/
502static void
503mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
504 u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
505{
506 char extend_desc[EVENT_DESCR_STR_SZ];
507 char *desc = NULL;
508
509 switch (ioc_status) {
510
511 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
512 desc = "SCSI Invalid Bus";
513 break;
514
515 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
516 desc = "SCSI Invalid TargetID";
517 break;
518
519 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
520 /*
521 * Inquiry is issued for device scanning
522 */
523 if (sc->cmnd[0] != 0x12)
524 desc = "SCSI Device Not There";
525 break;
526
527 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
528 desc = "SCSI Data Overrun";
529 break;
530
531 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
532 desc = "SCSI I/O Data Error";
533 break;
534
535 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
536 desc = "SCSI Protocol Error";
537 break;
538
539 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
540 desc = "SCSI Task Terminated";
541 break;
542
543 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
544 desc = "SCSI Residual Mismatch";
545 break;
546
547 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
548 desc = "SCSI Task Management Failed";
549 break;
550
551 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
552 desc = "SCSI IOC Terminated";
553 break;
554
555 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
556 desc = "SCSI Ext Terminated";
557 break;
558 }
559
560 if (!desc)
561 return;
562
563 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
564 "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
565 sc->device->host->host_no,
566 sc->device->channel, sc->device->id, sc->device->lun,
567 sc->cmnd[0], scsi_status, scsi_state);
568
569 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
570 ioc->name, ioc_status, desc, extend_desc);
571}
572#endif
573
530/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 574/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
531/* 575/*
532 * mptscsih_io_done - Main SCSI IO callback routine registered to 576 * mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -613,12 +657,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
613 u32 xfer_cnt; 657 u32 xfer_cnt;
614 u16 status; 658 u16 status;
615 u8 scsi_state, scsi_status; 659 u8 scsi_state, scsi_status;
660 u32 log_info;
616 661
617 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; 662 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
618 scsi_state = pScsiReply->SCSIState; 663 scsi_state = pScsiReply->SCSIState;
619 scsi_status = pScsiReply->SCSIStatus; 664 scsi_status = pScsiReply->SCSIStatus;
620 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); 665 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
621 sc->resid = sc->request_bufflen - xfer_cnt; 666 sc->resid = sc->request_bufflen - xfer_cnt;
667 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
622 668
623 /* 669 /*
624 * if we get a data underrun indication, yet no data was 670 * if we get a data underrun indication, yet no data was
@@ -633,13 +679,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
633 status = MPI_IOCSTATUS_SUCCESS; 679 status = MPI_IOCSTATUS_SUCCESS;
634 } 680 }
635 681
636 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
637 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
638 "resid=%d bufflen=%d xfer_cnt=%d\n",
639 ioc->id, sc->device->id, sc->device->lun,
640 status, scsi_state, scsi_status, sc->resid,
641 sc->request_bufflen, xfer_cnt));
642
643 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) 682 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
644 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); 683 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
645 684
@@ -648,9 +687,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
648 */ 687 */
649 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && 688 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
650 pScsiReply->ResponseInfo) { 689 pScsiReply->ResponseInfo) {
651 printk(KERN_NOTICE "ha=%d id=%d lun=%d: " 690 printk(KERN_NOTICE "[%d:%d:%d:%d] "
652 "FCP_ResponseInfo=%08xh\n", 691 "FCP_ResponseInfo=%08xh\n",
653 ioc->id, sc->device->id, sc->device->lun, 692 sc->device->host->host_no, sc->device->channel,
693 sc->device->id, sc->device->lun,
654 le32_to_cpu(pScsiReply->ResponseInfo)); 694 le32_to_cpu(pScsiReply->ResponseInfo));
655 } 695 }
656 696
@@ -695,9 +735,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
695 if ( ioc->bus_type == SAS ) { 735 if ( ioc->bus_type == SAS ) {
696 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); 736 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
697 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 737 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
698 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); 738 if ((log_info & SAS_LOGINFO_MASK)
699 log_info &=SAS_LOGINFO_MASK; 739 == SAS_LOGINFO_NEXUS_LOSS) {
700 if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
701 sc->result = (DID_BUS_BUSY << 16); 740 sc->result = (DID_BUS_BUSY << 16);
702 break; 741 break;
703 } 742 }
@@ -735,7 +774,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
735 else /* Sufficient data transfer occurred */ 774 else /* Sufficient data transfer occurred */
736 sc->result = (DID_OK << 16) | scsi_status; 775 sc->result = (DID_OK << 16) | scsi_status;
737 dreplyprintk((KERN_NOTICE 776 dreplyprintk((KERN_NOTICE
738 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); 777 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
778 sc->result, sc->device->channel, sc->device->id));
739 break; 779 break;
740 780
741 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 781 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -848,7 +888,28 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
848 888
849 } /* switch(status) */ 889 } /* switch(status) */
850 890
851 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result)); 891#ifdef MPT_DEBUG_REPLY
892 if (sc->result) {
893
894 mptscsih_iocstatus_info_scsiio(ioc, status,
895 scsi_status, scsi_state, sc);
896
897 dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
898 "result=0x%08x\n\tiocstatus=0x%04X "
899 "scsi_state=0x%02X scsi_status=0x%02X "
900 "loginfo=0x%08X\n", __FUNCTION__,
901 sc->device->host->host_no, sc->device->channel, sc->device->id,
902 sc->device->lun, sc->cmnd[0], sc->result, status,
903 scsi_state, scsi_status, log_info));
904
905 dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
906 "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
907 sc->device->host->host_no, sc->device->channel, sc->device->id,
908 sc->device->lun, sc->resid, sc->request_bufflen,
909 xfer_cnt));
910 }
911#endif
912
852 } /* end of address reply case */ 913 } /* end of address reply case */
853 914
854 /* Unmap the DMA buffers, if any. */ 915 /* Unmap the DMA buffers, if any. */
@@ -955,9 +1016,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
955 int ii; 1016 int ii;
956 int max = hd->ioc->req_depth; 1017 int max = hd->ioc->req_depth;
957 struct scsi_cmnd *sc; 1018 struct scsi_cmnd *sc;
1019 struct scsi_lun lun;
958 1020
959 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", 1021 dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
960 vdevice->vtarget->target_id, vdevice->lun, max)); 1022 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
961 1023
962 for (ii=0; ii < max; ii++) { 1024 for (ii=0; ii < max; ii++) {
963 if ((sc = hd->ScsiLookup[ii]) != NULL) { 1025 if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -965,10 +1027,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
965 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); 1027 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
966 if (mf == NULL) 1028 if (mf == NULL)
967 continue; 1029 continue;
968 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", 1030 int_to_scsilun(vdevice->lun, &lun);
969 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); 1031 if ((mf->Bus != vdevice->vtarget->channel) ||
970 if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) 1032 (mf->TargetID != vdevice->vtarget->id) ||
1033 memcmp(lun.scsi_lun, mf->LUN, 8))
971 continue; 1034 continue;
1035 dsprintk(( "search_running: found (sc=%p, mf = %p) "
1036 "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
1037 mf, mf->Bus, mf->TargetID, vdevice->lun));
972 1038
973 /* Cleanup 1039 /* Cleanup
974 */ 1040 */
@@ -1065,12 +1131,6 @@ mptscsih_remove(struct pci_dev *pdev)
1065 hd->ScsiLookup = NULL; 1131 hd->ScsiLookup = NULL;
1066 } 1132 }
1067 1133
1068 /*
1069 * Free pointer array.
1070 */
1071 kfree(hd->Targets);
1072 hd->Targets = NULL;
1073
1074 dprintk((MYIOC_s_INFO_FMT 1134 dprintk((MYIOC_s_INFO_FMT
1075 "Free'd ScsiLookup (%d) memory\n", 1135 "Free'd ScsiLookup (%d) memory\n",
1076 hd->ioc->name, sz1)); 1136 hd->ioc->name, sz1));
@@ -1317,14 +1377,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1317 return SCSI_MLQUEUE_HOST_BUSY; 1377 return SCSI_MLQUEUE_HOST_BUSY;
1318 } 1378 }
1319 1379
1320 if ((hd->ioc->bus_type == SPI) &&
1321 vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
1322 mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
1323 SCpnt->result = DID_NO_CONNECT << 16;
1324 done(SCpnt);
1325 return 0;
1326 }
1327
1328 /* 1380 /*
1329 * Put together a MPT SCSI request... 1381 * Put together a MPT SCSI request...
1330 */ 1382 */
@@ -1368,8 +1420,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1368 1420
1369 /* Use the above information to set up the message frame 1421 /* Use the above information to set up the message frame
1370 */ 1422 */
1371 pScsiReq->TargetID = (u8) vdev->vtarget->target_id; 1423 pScsiReq->TargetID = (u8) vdev->vtarget->id;
1372 pScsiReq->Bus = vdev->vtarget->bus_id; 1424 pScsiReq->Bus = vdev->vtarget->channel;
1373 pScsiReq->ChainOffset = 0; 1425 pScsiReq->ChainOffset = 0;
1374 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) 1426 if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1375 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; 1427 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
@@ -1379,14 +1431,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1379 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; 1431 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1380 pScsiReq->Reserved = 0; 1432 pScsiReq->Reserved = 0;
1381 pScsiReq->MsgFlags = mpt_msg_flags(); 1433 pScsiReq->MsgFlags = mpt_msg_flags();
1382 pScsiReq->LUN[0] = 0; 1434 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1383 pScsiReq->LUN[1] = lun;
1384 pScsiReq->LUN[2] = 0;
1385 pScsiReq->LUN[3] = 0;
1386 pScsiReq->LUN[4] = 0;
1387 pScsiReq->LUN[5] = 0;
1388 pScsiReq->LUN[6] = 0;
1389 pScsiReq->LUN[7] = 0;
1390 pScsiReq->Control = cpu_to_le32(scsictl); 1435 pScsiReq->Control = cpu_to_le32(scsictl);
1391 1436
1392 /* 1437 /*
@@ -1491,14 +1536,14 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1491 */ 1536 */
1492 1537
1493/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1538/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494/* 1539/**
1495 * mptscsih_TMHandler - Generic handler for SCSI Task Management. 1540 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1496 * Fall through to mpt_HardResetHandler if: not operational, too many 1541 * Fall through to mpt_HardResetHandler if: not operational, too many
1497 * failed TM requests or handshake failure. 1542 * failed TM requests or handshake failure.
1498 * 1543 *
1499 * @ioc: Pointer to MPT_ADAPTER structure 1544 * @ioc: Pointer to MPT_ADAPTER structure
1500 * @type: Task Management type 1545 * @type: Task Management type
1501 * @target: Logical Target ID for reset (if appropriate) 1546 * @id: Logical Target ID for reset (if appropriate)
1502 * @lun: Logical Unit for reset (if appropriate) 1547 * @lun: Logical Unit for reset (if appropriate)
1503 * @ctx2abort: Context for the task to be aborted (if appropriate) 1548 * @ctx2abort: Context for the task to be aborted (if appropriate)
1504 * 1549 *
@@ -1507,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1507 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC 1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1508 * will be active. 1553 * will be active.
1509 * 1554 *
1510 * Returns 0 for SUCCESS or -1 if FAILED. 1555 * Returns 0 for SUCCESS, or FAILED.
1511 */ 1556 **/
1512int 1557int
1513mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1558mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1514{ 1559{
1515 MPT_ADAPTER *ioc; 1560 MPT_ADAPTER *ioc;
1516 int rc = -1; 1561 int rc = -1;
1517 int doTask = 1;
1518 u32 ioc_raw_state; 1562 u32 ioc_raw_state;
1519 unsigned long flags; 1563 unsigned long flags;
1520 1564
1521 /* If FW is being reloaded currently, return success to
1522 * the calling function.
1523 */
1524 if (hd == NULL)
1525 return 0;
1526
1527 ioc = hd->ioc; 1565 ioc = hd->ioc;
1528 if (ioc == NULL) {
1529 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1530 return FAILED;
1531 }
1532 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); 1566 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1533 1567
1534 // SJR - CHECKME - Can we avoid this here? 1568 // SJR - CHECKME - Can we avoid this here?
@@ -1541,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1541 spin_unlock_irqrestore(&ioc->diagLock, flags); 1575 spin_unlock_irqrestore(&ioc->diagLock, flags);
1542 1576
1543 /* Wait a fixed amount of time for the TM pending flag to be cleared. 1577 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1544 * If we time out and not bus reset, then we return a FAILED status to the caller. 1578 * If we time out and not bus reset, then we return a FAILED status
1545 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are 1579 * to the caller.
1580 * The call to mptscsih_tm_pending_wait() will set the pending flag
1581 * if we are
1546 * successful. Otherwise, reload the FW. 1582 * successful. Otherwise, reload the FW.
1547 */ 1583 */
1548 if (mptscsih_tm_pending_wait(hd) == FAILED) { 1584 if (mptscsih_tm_pending_wait(hd) == FAILED) {
@@ -1552,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1552 hd->ioc->name, hd->tmPending)); 1588 hd->ioc->name, hd->tmPending));
1553 return FAILED; 1589 return FAILED;
1554 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { 1590 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1555 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " 1591 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
1556 "Timed out waiting for last TM (%d) to complete! \n", 1592 "reset: Timed out waiting for last TM (%d) "
1557 hd->ioc->name, hd->tmPending)); 1593 "to complete! \n", hd->ioc->name,
1594 hd->tmPending));
1558 return FAILED; 1595 return FAILED;
1559 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 1596 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1560 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " 1597 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
1561 "Timed out waiting for last TM (%d) to complete! \n", 1598 "Timed out waiting for last TM (%d) to complete! \n",
1562 hd->ioc->name, hd->tmPending)); 1599 hd->ioc->name, hd->tmPending));
1563 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) 1600 return FAILED;
1564 return FAILED;
1565
1566 doTask = 0;
1567 } 1601 }
1568 } else { 1602 } else {
1569 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 1603 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
@@ -1571,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1571 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1605 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1572 } 1606 }
1573 1607
1574 /* Is operational?
1575 */
1576 ioc_raw_state = mpt_GetIocState(hd->ioc, 0); 1608 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1577 1609
1578#ifdef MPT_DEBUG_RESET
1579 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { 1610 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1580 printk(MYIOC_s_WARN_FMT 1611 printk(MYIOC_s_WARN_FMT
1581 "TM Handler: IOC Not operational(0x%x)!\n", 1612 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1582 hd->ioc->name, ioc_raw_state); 1613 ioc->name, type, ioc_raw_state);
1583 } 1614 printk(KERN_WARNING " Issuing HardReset!!\n");
1584#endif 1615 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1585 1616 printk((KERN_WARNING "TMHandler: HardReset "
1586 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) 1617 "FAILED!!\n"));
1587 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { 1618 return FAILED;
1588
1589 /* Isse the Task Mgmt request.
1590 */
1591 if (hd->hard_resets < -1)
1592 hd->hard_resets++;
1593 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1594 if (rc) {
1595 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1596 } else {
1597 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1598 }
1599 } 1619 }
1600 1620
1601 /* Only fall through to the HRH if this is a bus reset 1621 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1602 */ 1622 printk(MYIOC_s_WARN_FMT
1603 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || 1623 "TM Handler for type=%x: ioc_state: "
1604 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { 1624 "DOORBELL_ACTIVE (0x%x)!\n",
1605 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1625 ioc->name, type, ioc_raw_state);
1606 hd->ioc->name)); 1626 return FAILED;
1607 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1608 } 1627 }
1609 1628
1610 /* 1629 /* Isse the Task Mgmt request.
1611 * Check IOCStatus from TM reply message
1612 */ 1630 */
1613 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) 1631 if (hd->hard_resets < -1)
1614 rc = FAILED; 1632 hd->hard_resets++;
1633
1634 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1635 ctx2abort, timeout);
1636 if (rc)
1637 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1638 hd->ioc->name);
1639 else
1640 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
1641 hd->ioc->name));
1615 1642
1616 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); 1643 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
1617 1644
@@ -1620,11 +1647,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1620 1647
1621 1648
1622/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1649/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1623/* 1650/**
1624 * mptscsih_IssueTaskMgmt - Generic send Task Management function. 1651 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1625 * @hd: Pointer to MPT_SCSI_HOST structure 1652 * @hd: Pointer to MPT_SCSI_HOST structure
1626 * @type: Task Management type 1653 * @type: Task Management type
1627 * @target: Logical Target ID for reset (if appropriate) 1654 * @id: Logical Target ID for reset (if appropriate)
1628 * @lun: Logical Unit for reset (if appropriate) 1655 * @lun: Logical Unit for reset (if appropriate)
1629 * @ctx2abort: Context for the task to be aborted (if appropriate) 1656 * @ctx2abort: Context for the task to be aborted (if appropriate)
1630 * 1657 *
@@ -1633,11 +1660,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
1633 * 1660 *
1634 * Not all fields are meaningfull for all task types. 1661 * Not all fields are meaningfull for all task types.
1635 * 1662 *
1636 * Returns 0 for SUCCESS, -999 for "no msg frames", 1663 * Returns 0 for SUCCESS, or FAILED.
1637 * else other non-zero value returned. 1664 *
1638 */ 1665 **/
1639static int 1666static int
1640mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1667mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1641{ 1668{
1642 MPT_FRAME_HDR *mf; 1669 MPT_FRAME_HDR *mf;
1643 SCSITaskMgmt_t *pScsiTm; 1670 SCSITaskMgmt_t *pScsiTm;
@@ -1657,7 +1684,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
1657 /* Format the Request 1684 /* Format the Request
1658 */ 1685 */
1659 pScsiTm = (SCSITaskMgmt_t *) mf; 1686 pScsiTm = (SCSITaskMgmt_t *) mf;
1660 pScsiTm->TargetID = target; 1687 pScsiTm->TargetID = id;
1661 pScsiTm->Bus = channel; 1688 pScsiTm->Bus = channel;
1662 pScsiTm->ChainOffset = 0; 1689 pScsiTm->ChainOffset = 0;
1663 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; 1690 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
@@ -1668,42 +1695,59 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
1668 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) 1695 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1669 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; 1696 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1670 1697
1671 for (ii= 0; ii < 8; ii++) { 1698 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1672 pScsiTm->LUN[ii] = 0;
1673 }
1674 pScsiTm->LUN[1] = lun;
1675 1699
1676 for (ii=0; ii < 7; ii++) 1700 for (ii=0; ii < 7; ii++)
1677 pScsiTm->Reserved2[ii] = 0; 1701 pScsiTm->Reserved2[ii] = 0;
1678 1702
1679 pScsiTm->TaskMsgContext = ctx2abort; 1703 pScsiTm->TaskMsgContext = ctx2abort;
1680 1704
1681 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", 1705 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1682 hd->ioc->name, ctx2abort, type)); 1706 "type=%d\n", hd->ioc->name, ctx2abort, type));
1683 1707
1684 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); 1708 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
1685 1709
1686 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, 1710 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
1687 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, 1711 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
1688 CAN_SLEEP)) != 0) { 1712 dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
1689 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" 1713 " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
1690 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1714 hd->ioc, mf, retval));
1691 hd->ioc, mf)); 1715 goto fail_out;
1692 mpt_free_msg_frame(hd->ioc, mf);
1693 return retval;
1694 } 1716 }
1695 1717
1696 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { 1718 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1697 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" 1719 dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1698 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1720 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
1699 hd->ioc, mf)); 1721 hd->ioc, mf));
1700 mpt_free_msg_frame(hd->ioc, mf);
1701 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1722 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
1702 hd->ioc->name)); 1723 hd->ioc->name));
1703 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1724 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
1725 dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
1726 hd->ioc->name, retval));
1727 goto fail_out;
1704 } 1728 }
1705 1729
1730 /*
1731 * Handle success case, see if theres a non-zero ioc_status.
1732 */
1733 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1734 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1735 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1736 retval = 0;
1737 else
1738 retval = FAILED;
1739
1706 return retval; 1740 return retval;
1741
1742 fail_out:
1743
1744 /*
1745 * Free task managment mf, and corresponding tm flags
1746 */
1747 mpt_free_msg_frame(hd->ioc, mf);
1748 hd->tmPending = 0;
1749 hd->tmState = TM_STATE_NONE;
1750 return FAILED;
1707} 1751}
1708 1752
1709static int 1753static int
@@ -1728,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1728 * (linux scsi_host_template.eh_abort_handler routine) 1772 * (linux scsi_host_template.eh_abort_handler routine)
1729 * 1773 *
1730 * Returns SUCCESS or FAILED. 1774 * Returns SUCCESS or FAILED.
1731 */ 1775 **/
1732int 1776int
1733mptscsih_abort(struct scsi_cmnd * SCpnt) 1777mptscsih_abort(struct scsi_cmnd * SCpnt)
1734{ 1778{
@@ -1764,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1764 return SUCCESS; 1808 return SUCCESS;
1765 } 1809 }
1766 1810
1767 if (hd->resetPending) { 1811 if (hd->resetPending)
1768 return FAILED; 1812 return FAILED;
1769 }
1770 1813
1771 if (hd->timeouts < -1) 1814 if (hd->timeouts < -1)
1772 hd->timeouts++; 1815 hd->timeouts++;
@@ -1789,13 +1832,12 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1789 1832
1790 vdev = SCpnt->device->hostdata; 1833 vdev = SCpnt->device->hostdata;
1791 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1834 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1792 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, 1835 vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
1793 ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); 1836 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1794 1837
1795 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && 1838 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1796 SCpnt->serial_number == sn) { 1839 SCpnt->serial_number == sn)
1797 retval = FAILED; 1840 retval = FAILED;
1798 }
1799 1841
1800 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1842 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1801 hd->ioc->name, 1843 hd->ioc->name,
@@ -1803,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1803 1845
1804 if (retval == 0) 1846 if (retval == 0)
1805 return SUCCESS; 1847 return SUCCESS;
1806 1848 else
1807 if(retval != FAILED ) { 1849 return FAILED;
1808 hd->tmPending = 0;
1809 hd->tmState = TM_STATE_NONE;
1810 }
1811 return FAILED;
1812} 1850}
1813 1851
1814/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1852/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1819,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1819 * (linux scsi_host_template.eh_dev_reset_handler routine) 1857 * (linux scsi_host_template.eh_dev_reset_handler routine)
1820 * 1858 *
1821 * Returns SUCCESS or FAILED. 1859 * Returns SUCCESS or FAILED.
1822 */ 1860 **/
1823int 1861int
1824mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1862mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1825{ 1863{
@@ -1845,7 +1883,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1845 1883
1846 vdev = SCpnt->device->hostdata; 1884 vdev = SCpnt->device->hostdata;
1847 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1885 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1848 vdev->vtarget->bus_id, vdev->vtarget->target_id, 1886 vdev->vtarget->channel, vdev->vtarget->id,
1849 0, 0, mptscsih_get_tm_timeout(hd->ioc)); 1887 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1850 1888
1851 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", 1889 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1854,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1854 1892
1855 if (retval == 0) 1893 if (retval == 0)
1856 return SUCCESS; 1894 return SUCCESS;
1857 1895 else
1858 if(retval != FAILED ) { 1896 return FAILED;
1859 hd->tmPending = 0;
1860 hd->tmState = TM_STATE_NONE;
1861 }
1862 return FAILED;
1863} 1897}
1864 1898
1899
1865/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1900/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1866/** 1901/**
1867 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant 1902 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
@@ -1870,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1870 * (linux scsi_host_template.eh_bus_reset_handler routine) 1905 * (linux scsi_host_template.eh_bus_reset_handler routine)
1871 * 1906 *
1872 * Returns SUCCESS or FAILED. 1907 * Returns SUCCESS or FAILED.
1873 */ 1908 **/
1874int 1909int
1875mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1910mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1876{ 1911{
@@ -1896,7 +1931,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1896 1931
1897 vdev = SCpnt->device->hostdata; 1932 vdev = SCpnt->device->hostdata;
1898 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1933 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1899 vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); 1934 vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
1900 1935
1901 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", 1936 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
1902 hd->ioc->name, 1937 hd->ioc->name,
@@ -1904,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1904 1939
1905 if (retval == 0) 1940 if (retval == 0)
1906 return SUCCESS; 1941 return SUCCESS;
1907 1942 else
1908 if(retval != FAILED ) { 1943 return FAILED;
1909 hd->tmPending = 0;
1910 hd->tmState = TM_STATE_NONE;
1911 }
1912 return FAILED;
1913} 1944}
1914 1945
1915/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1946/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1992,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1992/** 2023/**
1993 * mptscsih_tm_wait_for_completion - wait for completion of TM task 2024 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1994 * @hd: Pointer to MPT host structure. 2025 * @hd: Pointer to MPT host structure.
1995 * @timeout: timeout in seconds
1996 * 2026 *
1997 * Returns {SUCCESS,FAILED}. 2027 * Returns {SUCCESS,FAILED}.
1998 */ 2028 */
@@ -2066,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2066 * load/init time via the mpt_register() API call. 2096 * load/init time via the mpt_register() API call.
2067 * 2097 *
2068 * Returns 1 indicating alloc'd request frame ptr should be freed. 2098 * Returns 1 indicating alloc'd request frame ptr should be freed.
2069 */ 2099 **/
2070int 2100int
2071mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2101mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2072{ 2102{
@@ -2076,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
2076 unsigned long flags; 2106 unsigned long flags;
2077 u16 iocstatus; 2107 u16 iocstatus;
2078 u8 tmType; 2108 u8 tmType;
2109 u32 termination_count;
2079 2110
2080 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", 2111 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2081 ioc->name, mf, mr)); 2112 ioc->name, mf, mr));
2082 if (ioc->sh) { 2113 if (!ioc->sh) {
2083 /* Depending on the thread, a timer is activated for 2114 dtmprintk((MYIOC_s_WARN_FMT
2084 * the TM request. Delete this timer on completion of TM. 2115 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2085 * Decrement count of outstanding TM requests.
2086 */
2087 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2088 } else {
2089 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2090 ioc->name));
2091 return 1; 2116 return 1;
2092 } 2117 }
2093 2118
2094 if (mr == NULL) { 2119 if (mr == NULL) {
2095 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", 2120 dtmprintk((MYIOC_s_WARN_FMT
2096 ioc->name, mf)); 2121 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2097 return 1; 2122 return 1;
2098 } else { 2123 }
2099 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2100 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2101
2102 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2103 tmType = pScsiTmReq->TaskType;
2104 2124
2105 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && 2125 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2106 pScsiTmReply->ResponseCode) 2126 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2107 mptscsih_taskmgmt_response_code(ioc, 2127 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2108 pScsiTmReply->ResponseCode); 2128 tmType = pScsiTmReq->TaskType;
2129 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2130 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2131
2132 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2133 pScsiTmReply->ResponseCode)
2134 mptscsih_taskmgmt_response_code(ioc,
2135 pScsiTmReply->ResponseCode);
2136 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2137
2138#if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
2139 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2140 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2141 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2142 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2143 le16_to_cpu(pScsiTmReply->IOCStatus),
2144 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2145 le32_to_cpu(pScsiTmReply->TerminationCount));
2146#endif
2147 if (!iocstatus) {
2148 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2149 hd->abortSCpnt = NULL;
2150 goto out;
2151 }
2109 2152
2110 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", 2153 /* Error? (anything non-zero?) */
2111 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2112 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2113 2154
2114 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 2155 /* clear flags and continue.
2115 hd->tm_iocstatus = iocstatus; 2156 */
2116 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", 2157 switch (tmType) {
2117 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2118 /* Error? (anything non-zero?) */
2119 if (iocstatus) {
2120 2158
2121 /* clear flags and continue. 2159 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2122 */ 2160 if (termination_count == 1)
2123 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) 2161 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2124 hd->abortSCpnt = NULL; 2162 hd->abortSCpnt = NULL;
2163 break;
2125 2164
2126 /* If an internal command is present 2165 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2127 * or the TM failed - reload the FW.
2128 * FC FW may respond FAILED to an ABORT
2129 */
2130 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2131 if ((hd->cmdPtr) ||
2132 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2133 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2134 printk((KERN_WARNING
2135 " Firmware Reload FAILED!!\n"));
2136 }
2137 }
2138 }
2139 } else {
2140 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2141 2166
2142 hd->abortSCpnt = NULL; 2167 /* If an internal command is present
2168 * or the TM failed - reload the FW.
2169 * FC FW may respond FAILED to an ABORT
2170 */
2171 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2172 hd->cmdPtr)
2173 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2174 printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
2175 break;
2143 2176
2144 } 2177 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2178 default:
2179 break;
2145 } 2180 }
2146 2181
2182 out:
2147 spin_lock_irqsave(&ioc->FreeQlock, flags); 2183 spin_lock_irqsave(&ioc->FreeQlock, flags);
2148 hd->tmPending = 0; 2184 hd->tmPending = 0;
2149 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2150 hd->tmState = TM_STATE_NONE; 2185 hd->tmState = TM_STATE_NONE;
2186 hd->tm_iocstatus = iocstatus;
2187 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2151 2188
2152 return 1; 2189 return 1;
2153} 2190}
@@ -2191,7 +2228,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2191 2228
2192 dprintk((KERN_NOTICE 2229 dprintk((KERN_NOTICE
2193 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", 2230 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2194 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors)); 2231 sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
2195 2232
2196 return 0; 2233 return 0;
2197} 2234}
@@ -2200,115 +2237,78 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2200 * 2237 *
2201 */ 2238 */
2202int 2239int
2203mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 2240mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2204{ 2241{
2242 struct inactive_raid_component_info *component_info;
2205 int i; 2243 int i;
2244 int rc = 0;
2206 2245
2207 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) 2246 if (!ioc->raid_data.pIocPg3)
2208 return 0; 2247 goto out;
2209 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { 2248 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2210 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) 2249 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2211 return 1; 2250 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2212 } 2251 rc = 1;
2213 return 0; 2252 goto out;
2214} 2253 }
2215EXPORT_SYMBOL(mptscsih_is_phys_disk);
2216
2217int
2218mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
2219{
2220 int i;
2221
2222 if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
2223 return -ENXIO;
2224
2225 for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2226 if (physdiskid ==
2227 hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
2228 return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2229 } 2254 }
2230 2255
2231 return -ENXIO; 2256 /*
2232} 2257 * Check inactive list for matching phys disks
2233EXPORT_SYMBOL(mptscsih_raid_id_to_num); 2258 */
2259 if (list_empty(&ioc->raid_data.inactive_list))
2260 goto out;
2234 2261
2235/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2262 down(&ioc->raid_data.inactive_list_mutex);
2236/* 2263 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2237 * OS entry point to allow host driver to alloc memory 2264 list) {
2238 * for each scsi target. Called once per device the bus scan. 2265 if ((component_info->d.PhysDiskID == id) &&
2239 * Return non-zero if allocation fails. 2266 (component_info->d.PhysDiskBus == channel))
2240 */ 2267 rc = 1;
2241int 2268 }
2242mptscsih_target_alloc(struct scsi_target *starget) 2269 up(&ioc->raid_data.inactive_list_mutex);
2243{
2244 VirtTarget *vtarget;
2245 2270
2246 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); 2271 out:
2247 if (!vtarget) 2272 return rc;
2248 return -ENOMEM;
2249 starget->hostdata = vtarget;
2250 vtarget->starget = starget;
2251 return 0;
2252} 2273}
2274EXPORT_SYMBOL(mptscsih_is_phys_disk);
2253 2275
2254/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2276u8
2255/* 2277mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2256 * OS entry point to allow host driver to alloc memory
2257 * for each scsi device. Called once per device the bus scan.
2258 * Return non-zero if allocation fails.
2259 */
2260int
2261mptscsih_slave_alloc(struct scsi_device *sdev)
2262{ 2278{
2263 struct Scsi_Host *host = sdev->host; 2279 struct inactive_raid_component_info *component_info;
2264 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 2280 int i;
2265 VirtTarget *vtarget; 2281 int rc = -ENXIO;
2266 VirtDevice *vdev;
2267 struct scsi_target *starget;
2268 2282
2269 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); 2283 if (!ioc->raid_data.pIocPg3)
2270 if (!vdev) { 2284 goto out;
2271 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 2285 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2272 hd->ioc->name, sizeof(VirtDevice)); 2286 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2273 return -ENOMEM; 2287 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2288 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2289 goto out;
2290 }
2274 } 2291 }
2275 2292
2276 vdev->lun = sdev->lun; 2293 /*
2277 sdev->hostdata = vdev; 2294 * Check inactive list for matching phys disks
2278 2295 */
2279 starget = scsi_target(sdev); 2296 if (list_empty(&ioc->raid_data.inactive_list))
2280 vtarget = starget->hostdata; 2297 goto out;
2281 2298
2282 vdev->vtarget = vtarget; 2299 down(&ioc->raid_data.inactive_list_mutex);
2283 2300 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2284 if (vtarget->num_luns == 0) { 2301 list) {
2285 hd->Targets[sdev->id] = vtarget; 2302 if ((component_info->d.PhysDiskID == id) &&
2286 vtarget->ioc_id = hd->ioc->id; 2303 (component_info->d.PhysDiskBus == channel))
2287 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; 2304 rc = component_info->d.PhysDiskNum;
2288 vtarget->target_id = sdev->id;
2289 vtarget->bus_id = sdev->channel;
2290 if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
2291 hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
2292 vtarget->raidVolume = 1;
2293 ddvtprintk((KERN_INFO
2294 "RAID Volume @ id %d\n", sdev->id));
2295 }
2296 } 2305 }
2297 vtarget->num_luns++; 2306 up(&ioc->raid_data.inactive_list_mutex);
2298 return 0;
2299}
2300 2307
2301/* 2308 out:
2302 * OS entry point to allow for host driver to free allocated memory 2309 return rc;
2303 * Called if no device present or device being unloaded
2304 */
2305void
2306mptscsih_target_destroy(struct scsi_target *starget)
2307{
2308 if (starget->hostdata)
2309 kfree(starget->hostdata);
2310 starget->hostdata = NULL;
2311} 2310}
2311EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2312 2312
2313/* 2313/*
2314 * OS entry point to allow for host driver to free allocated memory 2314 * OS entry point to allow for host driver to free allocated memory
@@ -2328,11 +2328,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
2328 vdevice = sdev->hostdata; 2328 vdevice = sdev->hostdata;
2329 2329
2330 mptscsih_search_running_cmds(hd, vdevice); 2330 mptscsih_search_running_cmds(hd, vdevice);
2331 vtarget->luns[0] &= ~(1 << vdevice->lun);
2332 vtarget->num_luns--; 2331 vtarget->num_luns--;
2333 if (vtarget->num_luns == 0) {
2334 hd->Targets[sdev->id] = NULL;
2335 }
2336 mptscsih_synchronize_cache(hd, vdevice); 2332 mptscsih_synchronize_cache(hd, vdevice);
2337 kfree(vdevice); 2333 kfree(vdevice);
2338 sdev->hostdata = NULL; 2334 sdev->hostdata = NULL;
@@ -2394,15 +2390,14 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2394 VirtDevice *vdevice; 2390 VirtDevice *vdevice;
2395 struct scsi_target *starget; 2391 struct scsi_target *starget;
2396 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; 2392 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2397 int indexed_lun, lun_index;
2398 2393
2399 starget = scsi_target(sdev); 2394 starget = scsi_target(sdev);
2400 vtarget = starget->hostdata; 2395 vtarget = starget->hostdata;
2401 vdevice = sdev->hostdata; 2396 vdevice = sdev->hostdata;
2402 2397
2403 dsprintk((MYIOC_s_INFO_FMT 2398 dsprintk((MYIOC_s_INFO_FMT
2404 "device @ %p, id=%d, LUN=%d, channel=%d\n", 2399 "device @ %p, channel=%d, id=%d, lun=%d\n",
2405 hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel)); 2400 hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2406 if (hd->ioc->bus_type == SPI) 2401 if (hd->ioc->bus_type == SPI)
2407 dsprintk((MYIOC_s_INFO_FMT 2402 dsprintk((MYIOC_s_INFO_FMT
2408 "sdtr %d wdtr %d ppr %d inq length=%d\n", 2403 "sdtr %d wdtr %d ppr %d inq length=%d\n",
@@ -2415,11 +2410,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
2415 goto slave_configure_exit; 2410 goto slave_configure_exit;
2416 } 2411 }
2417 2412
2418 vdevice->configured_lun=1; 2413 vdevice->configured_lun = 1;
2419 lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
2420 indexed_lun = (vdevice->lun % 32);
2421 vtarget->luns[lun_index] |= (1 << indexed_lun);
2422 mptscsih_initTarget(hd, vtarget, sdev);
2423 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); 2414 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2424 2415
2425 dsprintk((MYIOC_s_INFO_FMT 2416 dsprintk((MYIOC_s_INFO_FMT
@@ -2683,285 +2674,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2683 2674
2684/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2675/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2685/* 2676/*
2686 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2687 * @hd: Pointer to MPT_SCSI_HOST structure
2688 * @vtarget: per target private data
2689 * @sdev: SCSI device
2690 *
2691 * NOTE: It's only SAFE to call this routine if data points to
2692 * sane & valid STANDARD INQUIRY data!
2693 *
2694 * Allocate and initialize memory for this target.
2695 * Save inquiry data.
2696 *
2697 */
2698static void
2699mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
2700 struct scsi_device *sdev)
2701{
2702 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2703 hd->ioc->name, vtarget->bus_id, vtarget->target_id,
2704 sdev->lun, hd));
2705
2706 /* Is LUN supported? If so, upper 2 bits will be 0
2707 * in first byte of inquiry data.
2708 */
2709 if (sdev->inq_periph_qual != 0)
2710 return;
2711
2712 if (vtarget == NULL)
2713 return;
2714
2715 vtarget->type = sdev->type;
2716
2717 if (hd->ioc->bus_type != SPI)
2718 return;
2719
2720 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2721 /* Treat all Processors as SAF-TE if
2722 * command line option is set */
2723 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2724 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2725 }else if ((sdev->type == TYPE_PROCESSOR) &&
2726 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2727 if (sdev->inquiry_len > 49 ) {
2728 if (sdev->inquiry[44] == 'S' &&
2729 sdev->inquiry[45] == 'A' &&
2730 sdev->inquiry[46] == 'F' &&
2731 sdev->inquiry[47] == '-' &&
2732 sdev->inquiry[48] == 'T' &&
2733 sdev->inquiry[49] == 'E' ) {
2734 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2735 mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
2736 }
2737 }
2738 }
2739 mptscsih_setTargetNegoParms(hd, vtarget, sdev);
2740}
2741
2742/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2743/*
2744 * Update the target negotiation parameters based on the
2745 * the Inquiry data, adapter capabilities, and NVRAM settings.
2746 *
2747 */
2748static void
2749mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
2750 struct scsi_device *sdev)
2751{
2752 SpiCfgData *pspi_data = &hd->ioc->spi_data;
2753 int id = (int) target->target_id;
2754 int nvram;
2755 u8 width = MPT_NARROW;
2756 u8 factor = MPT_ASYNC;
2757 u8 offset = 0;
2758 u8 nfactor;
2759 u8 noQas = 1;
2760
2761 target->negoFlags = pspi_data->noQas;
2762
2763 /* noQas == 0 => device supports QAS. */
2764
2765 if (sdev->scsi_level < SCSI_2) {
2766 width = 0;
2767 factor = MPT_ULTRA2;
2768 offset = pspi_data->maxSyncOffset;
2769 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2770 } else {
2771 if (scsi_device_wide(sdev)) {
2772 width = 1;
2773 }
2774
2775 if (scsi_device_sync(sdev)) {
2776 factor = pspi_data->minSyncFactor;
2777 if (!scsi_device_dt(sdev))
2778 factor = MPT_ULTRA2;
2779 else {
2780 if (!scsi_device_ius(sdev) &&
2781 !scsi_device_qas(sdev))
2782 factor = MPT_ULTRA160;
2783 else {
2784 factor = MPT_ULTRA320;
2785 if (scsi_device_qas(sdev)) {
2786 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
2787 noQas = 0;
2788 }
2789 if (sdev->type == TYPE_TAPE &&
2790 scsi_device_ius(sdev))
2791 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2792 }
2793 }
2794 offset = pspi_data->maxSyncOffset;
2795
2796 /* If RAID, never disable QAS
2797 * else if non RAID, do not disable
2798 * QAS if bit 1 is set
2799 * bit 1 QAS support, non-raid only
2800 * bit 0 IU support
2801 */
2802 if (target->raidVolume == 1) {
2803 noQas = 0;
2804 }
2805 } else {
2806 factor = MPT_ASYNC;
2807 offset = 0;
2808 }
2809 }
2810
2811 if (!sdev->tagged_supported) {
2812 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2813 }
2814
2815 /* Update tflags based on NVRAM settings. (SCSI only)
2816 */
2817 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2818 nvram = pspi_data->nvram[id];
2819 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2820
2821 if (width)
2822 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2823
2824 if (offset > 0) {
2825 /* Ensure factor is set to the
2826 * maximum of: adapter, nvram, inquiry
2827 */
2828 if (nfactor) {
2829 if (nfactor < pspi_data->minSyncFactor )
2830 nfactor = pspi_data->minSyncFactor;
2831
2832 factor = max(factor, nfactor);
2833 if (factor == MPT_ASYNC)
2834 offset = 0;
2835 } else {
2836 offset = 0;
2837 factor = MPT_ASYNC;
2838 }
2839 } else {
2840 factor = MPT_ASYNC;
2841 }
2842 }
2843
2844 /* Make sure data is consistent
2845 */
2846 if ((!width) && (factor < MPT_ULTRA2)) {
2847 factor = MPT_ULTRA2;
2848 }
2849
2850 /* Save the data to the target structure.
2851 */
2852 target->minSyncFactor = factor;
2853 target->maxOffset = offset;
2854 target->maxWidth = width;
2855
2856 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2857
2858 /* Disable unused features.
2859 */
2860 if (!width)
2861 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2862
2863 if (!offset)
2864 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2865
2866 if ( factor > MPT_ULTRA320 )
2867 noQas = 0;
2868
2869 if (noQas && (pspi_data->noQas == 0)) {
2870 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2871 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2872
2873 /* Disable QAS in a mixed configuration case
2874 */
2875
2876 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2877 }
2878}
2879
2880/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2881
2882/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2883/*
2884 * SCSI Config Page functionality ...
2885 */
2886
2887/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2888/* mptscsih_writeIOCPage4 - write IOC Page 4
2889 * @hd: Pointer to a SCSI Host Structure
2890 * @target_id: write IOC Page4 for this ID & Bus
2891 *
2892 * Return: -EAGAIN if unable to obtain a Message Frame
2893 * or 0 if success.
2894 *
2895 * Remark: We do not wait for a return, write pages sequentially.
2896 */
2897static int
2898mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
2899{
2900 MPT_ADAPTER *ioc = hd->ioc;
2901 Config_t *pReq;
2902 IOCPage4_t *IOCPage4Ptr;
2903 MPT_FRAME_HDR *mf;
2904 dma_addr_t dataDma;
2905 u16 req_idx;
2906 u32 frameOffset;
2907 u32 flagsLength;
2908 int ii;
2909
2910 /* Get a MF for this command.
2911 */
2912 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
2913 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
2914 ioc->name));
2915 return -EAGAIN;
2916 }
2917
2918 /* Set the request and the data pointers.
2919 * Place data at end of MF.
2920 */
2921 pReq = (Config_t *)mf;
2922
2923 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2924 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
2925
2926 /* Complete the request frame (same for all requests).
2927 */
2928 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
2929 pReq->Reserved = 0;
2930 pReq->ChainOffset = 0;
2931 pReq->Function = MPI_FUNCTION_CONFIG;
2932 pReq->ExtPageLength = 0;
2933 pReq->ExtPageType = 0;
2934 pReq->MsgFlags = 0;
2935 for (ii=0; ii < 8; ii++) {
2936 pReq->Reserved2[ii] = 0;
2937 }
2938
2939 IOCPage4Ptr = ioc->spi_data.pIocPg4;
2940 dataDma = ioc->spi_data.IocPg4_dma;
2941 ii = IOCPage4Ptr->ActiveSEP++;
2942 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
2943 IOCPage4Ptr->SEP[ii].SEPBus = bus;
2944 pReq->Header = IOCPage4Ptr->Header;
2945 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
2946
2947 /* Add a SGE to the config request.
2948 */
2949 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
2950 (IOCPage4Ptr->Header.PageLength + ii) * 4;
2951
2952 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
2953
2954 dinitprintk((MYIOC_s_INFO_FMT
2955 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
2956 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
2957
2958 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
2959
2960 return 0;
2961}
2962
2963/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2964/*
2965 * Bus Scan and Domain Validation functionality ... 2677 * Bus Scan and Domain Validation functionality ...
2966 */ 2678 */
2967 2679
@@ -3343,7 +3055,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3343 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; 3055 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3344 } else { 3056 } else {
3345 pScsiReq->TargetID = io->id; 3057 pScsiReq->TargetID = io->id;
3346 pScsiReq->Bus = io->bus; 3058 pScsiReq->Bus = io->channel;
3347 pScsiReq->ChainOffset = 0; 3059 pScsiReq->ChainOffset = 0;
3348 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; 3060 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3349 } 3061 }
@@ -3356,9 +3068,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3356 pScsiReq->MsgFlags = mpt_msg_flags(); 3068 pScsiReq->MsgFlags = mpt_msg_flags();
3357 /* MsgContext set in mpt_get_msg_fram call */ 3069 /* MsgContext set in mpt_get_msg_fram call */
3358 3070
3359 for (ii=0; ii < 8; ii++) 3071 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3360 pScsiReq->LUN[ii] = 0;
3361 pScsiReq->LUN[1] = io->lun;
3362 3072
3363 if (io->flags & MPT_ICFLAG_TAGGED_CMD) 3073 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3364 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); 3074 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
@@ -3379,7 +3089,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3379 + (my_idx * MPT_SENSE_BUFFER_ALLOC)); 3089 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3380 3090
3381 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", 3091 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3382 hd->ioc->name, cmd, io->bus, io->id, io->lun)); 3092 hd->ioc->name, cmd, io->channel, io->id, io->lun));
3383 3093
3384 if (dir == MPI_SCSIIO_CONTROL_READ) { 3094 if (dir == MPI_SCSIIO_CONTROL_READ) {
3385 mpt_add_sge((char *) &pScsiReq->SGL, 3095 mpt_add_sge((char *) &pScsiReq->SGL,
@@ -3462,9 +3172,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3462 iocmd.data_dma = -1; 3172 iocmd.data_dma = -1;
3463 iocmd.size = 0; 3173 iocmd.size = 0;
3464 iocmd.rsvd = iocmd.rsvd2 = 0; 3174 iocmd.rsvd = iocmd.rsvd2 = 0;
3465 iocmd.bus = vdevice->vtarget->bus_id; 3175 iocmd.channel = vdevice->vtarget->channel;
3466 iocmd.id = vdevice->vtarget->target_id; 3176 iocmd.id = vdevice->vtarget->id;
3467 iocmd.lun = (u8)vdevice->lun; 3177 iocmd.lun = vdevice->lun;
3468 3178
3469 if ((vdevice->vtarget->type == TYPE_DISK) && 3179 if ((vdevice->vtarget->type == TYPE_DISK) &&
3470 (vdevice->configured_lun)) 3180 (vdevice->configured_lun))
@@ -3480,9 +3190,6 @@ EXPORT_SYMBOL(mptscsih_resume);
3480EXPORT_SYMBOL(mptscsih_proc_info); 3190EXPORT_SYMBOL(mptscsih_proc_info);
3481EXPORT_SYMBOL(mptscsih_info); 3191EXPORT_SYMBOL(mptscsih_info);
3482EXPORT_SYMBOL(mptscsih_qcmd); 3192EXPORT_SYMBOL(mptscsih_qcmd);
3483EXPORT_SYMBOL(mptscsih_target_alloc);
3484EXPORT_SYMBOL(mptscsih_slave_alloc);
3485EXPORT_SYMBOL(mptscsih_target_destroy);
3486EXPORT_SYMBOL(mptscsih_slave_destroy); 3193EXPORT_SYMBOL(mptscsih_slave_destroy);
3487EXPORT_SYMBOL(mptscsih_slave_configure); 3194EXPORT_SYMBOL(mptscsih_slave_configure);
3488EXPORT_SYMBOL(mptscsih_abort); 3195EXPORT_SYMBOL(mptscsih_abort);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 187c8af0890b..843c01a6aa0e 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -6,7 +6,7 @@
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2007 LSI Logic Corporation 8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com) 9 * (mailto:mpt_linux_developer@lsi.com)
10 * 10 *
11 */ 11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -53,6 +53,24 @@
53 * SCSI Public stuff... 53 * SCSI Public stuff...
54 */ 54 */
55 55
56#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
57#define MPT_SCANDV_DID_RESET (0x00000001)
58#define MPT_SCANDV_SENSE (0x00000002)
59#define MPT_SCANDV_SOME_ERROR (0x00000004)
60#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
61#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
62#define MPT_SCANDV_FALLBACK (0x00000020)
63
64#define MPT_SCANDV_MAX_RETRIES (10)
65
66#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
67#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
68#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
69#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
70#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
71#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
72#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
73
56#define MPT_SCSI_CMD_PER_DEV_HIGH 64 74#define MPT_SCSI_CMD_PER_DEV_HIGH 64
57#define MPT_SCSI_CMD_PER_DEV_LOW 32 75#define MPT_SCSI_CMD_PER_DEV_LOW 32
58 76
@@ -69,9 +87,22 @@
69#define MPTSCSIH_SAF_TE 0 87#define MPTSCSIH_SAF_TE 0
70#define MPTSCSIH_PT_CLEAR 0 88#define MPTSCSIH_PT_CLEAR 0
71 89
72
73#endif 90#endif
74 91
92typedef struct _internal_cmd {
93 char *data; /* data pointer */
94 dma_addr_t data_dma; /* data dma address */
95 int size; /* transfer size */
96 u8 cmd; /* SCSI Op Code */
97 u8 channel; /* bus number */
98 u8 id; /* SCSI ID (virtual) */
99 int lun;
100 u8 flags; /* Bit Field - See above */
101 u8 physDiskNum; /* Phys disk number, -1 else */
102 u8 rsvd2;
103 u8 rsvd;
104} INTERNAL_CMD;
105
75extern void mptscsih_remove(struct pci_dev *); 106extern void mptscsih_remove(struct pci_dev *);
76extern void mptscsih_shutdown(struct pci_dev *); 107extern void mptscsih_shutdown(struct pci_dev *);
77#ifdef CONFIG_PM 108#ifdef CONFIG_PM
@@ -81,9 +112,6 @@ extern int mptscsih_resume(struct pci_dev *pdev);
81extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); 112extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
82extern const char * mptscsih_info(struct Scsi_Host *SChost); 113extern const char * mptscsih_info(struct Scsi_Host *SChost);
83extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); 114extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
84extern int mptscsih_target_alloc(struct scsi_target *starget);
85extern int mptscsih_slave_alloc(struct scsi_device *device);
86extern void mptscsih_target_destroy(struct scsi_target *starget);
87extern void mptscsih_slave_destroy(struct scsi_device *device); 115extern void mptscsih_slave_destroy(struct scsi_device *device);
88extern int mptscsih_slave_configure(struct scsi_device *device); 116extern int mptscsih_slave_configure(struct scsi_device *device);
89extern int mptscsih_abort(struct scsi_cmnd * SCpnt); 117extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
@@ -98,6 +126,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
98extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 126extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
99extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); 127extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
100extern void mptscsih_timer_expired(unsigned long data); 128extern void mptscsih_timer_expired(unsigned long data);
101extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 129extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
102extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid); 130extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
103extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); 131extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 203c661d2c79..c31a9e3c8a26 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -4,7 +4,7 @@
4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5 * 5 *
6 * Copyright (c) 1999-2007 LSI Logic Corporation 6 * Copyright (c) 1999-2007 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com) 7 * (mailto:mpt_linux_developer@lsi.com)
8 * 8 *
9 */ 9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -65,6 +65,7 @@
65#include <scsi/scsi_tcq.h> 65#include <scsi/scsi_tcq.h>
66#include <scsi/scsi_transport.h> 66#include <scsi/scsi_transport.h>
67#include <scsi/scsi_transport_spi.h> 67#include <scsi/scsi_transport_spi.h>
68#include <scsi/scsi_dbg.h>
68 69
69#include "mptbase.h" 70#include "mptbase.h"
70#include "mptscsih.h" 71#include "mptscsih.h"
@@ -95,25 +96,339 @@ static int mptspiDoneCtx = -1;
95static int mptspiTaskCtx = -1; 96static int mptspiTaskCtx = -1;
96static int mptspiInternalCtx = -1; /* Used only for internal commands */ 97static int mptspiInternalCtx = -1; /* Used only for internal commands */
97 98
99/**
100 * mptspi_setTargetNegoParms - Update the target negotiation
101 * parameters based on the the Inquiry data, adapter capabilities,
102 * and NVRAM settings
103 *
104 * @hd: Pointer to a SCSI Host Structure
105 * @vtarget: per target private data
106 * @sdev: SCSI device
107 *
108 **/
109static void
110mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
111 struct scsi_device *sdev)
112{
113 SpiCfgData *pspi_data = &hd->ioc->spi_data;
114 int id = (int) target->id;
115 int nvram;
116 u8 width = MPT_NARROW;
117 u8 factor = MPT_ASYNC;
118 u8 offset = 0;
119 u8 nfactor;
120 u8 noQas = 1;
121
122 target->negoFlags = pspi_data->noQas;
123
124 if (sdev->scsi_level < SCSI_2) {
125 width = 0;
126 factor = MPT_ULTRA2;
127 offset = pspi_data->maxSyncOffset;
128 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
129 } else {
130 if (scsi_device_wide(sdev))
131 width = 1;
132
133 if (scsi_device_sync(sdev)) {
134 factor = pspi_data->minSyncFactor;
135 if (!scsi_device_dt(sdev))
136 factor = MPT_ULTRA2;
137 else {
138 if (!scsi_device_ius(sdev) &&
139 !scsi_device_qas(sdev))
140 factor = MPT_ULTRA160;
141 else {
142 factor = MPT_ULTRA320;
143 if (scsi_device_qas(sdev)) {
144 ddvprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
145 noQas = 0;
146 }
147 if (sdev->type == TYPE_TAPE &&
148 scsi_device_ius(sdev))
149 target->negoFlags |= MPT_TAPE_NEGO_IDP;
150 }
151 }
152 offset = pspi_data->maxSyncOffset;
153
154 /* If RAID, never disable QAS
155 * else if non RAID, do not disable
156 * QAS if bit 1 is set
157 * bit 1 QAS support, non-raid only
158 * bit 0 IU support
159 */
160 if (target->raidVolume == 1)
161 noQas = 0;
162 } else {
163 factor = MPT_ASYNC;
164 offset = 0;
165 }
166 }
167
168 if (!sdev->tagged_supported)
169 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
170
171 /* Update tflags based on NVRAM settings. (SCSI only)
172 */
173 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
174 nvram = pspi_data->nvram[id];
175 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
176
177 if (width)
178 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
179
180 if (offset > 0) {
181 /* Ensure factor is set to the
182 * maximum of: adapter, nvram, inquiry
183 */
184 if (nfactor) {
185 if (nfactor < pspi_data->minSyncFactor )
186 nfactor = pspi_data->minSyncFactor;
187
188 factor = max(factor, nfactor);
189 if (factor == MPT_ASYNC)
190 offset = 0;
191 } else {
192 offset = 0;
193 factor = MPT_ASYNC;
194 }
195 } else {
196 factor = MPT_ASYNC;
197 }
198 }
199
200 /* Make sure data is consistent
201 */
202 if ((!width) && (factor < MPT_ULTRA2))
203 factor = MPT_ULTRA2;
204
205 /* Save the data to the target structure.
206 */
207 target->minSyncFactor = factor;
208 target->maxOffset = offset;
209 target->maxWidth = width;
210
211 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
212
213 /* Disable unused features.
214 */
215 if (!width)
216 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
217
218 if (!offset)
219 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
220
221 if ( factor > MPT_ULTRA320 )
222 noQas = 0;
223
224 if (noQas && (pspi_data->noQas == 0)) {
225 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
226 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
227
228 /* Disable QAS in a mixed configuration case
229 */
230
231 ddvprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
232 }
233}
234
235/**
236 * mptspi_writeIOCPage4 - write IOC Page 4
237 * @hd: Pointer to a SCSI Host Structure
238 * @channel:
239 * @id: write IOC Page4 for this ID & Bus
240 *
241 * Return: -EAGAIN if unable to obtain a Message Frame
242 * or 0 if success.
243 *
244 * Remark: We do not wait for a return, write pages sequentially.
245 **/
246static int
247mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
248{
249 MPT_ADAPTER *ioc = hd->ioc;
250 Config_t *pReq;
251 IOCPage4_t *IOCPage4Ptr;
252 MPT_FRAME_HDR *mf;
253 dma_addr_t dataDma;
254 u16 req_idx;
255 u32 frameOffset;
256 u32 flagsLength;
257 int ii;
258
259 /* Get a MF for this command.
260 */
261 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
262 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
263 ioc->name));
264 return -EAGAIN;
265 }
266
267 /* Set the request and the data pointers.
268 * Place data at end of MF.
269 */
270 pReq = (Config_t *)mf;
271
272 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
273 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
274
275 /* Complete the request frame (same for all requests).
276 */
277 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
278 pReq->Reserved = 0;
279 pReq->ChainOffset = 0;
280 pReq->Function = MPI_FUNCTION_CONFIG;
281 pReq->ExtPageLength = 0;
282 pReq->ExtPageType = 0;
283 pReq->MsgFlags = 0;
284 for (ii=0; ii < 8; ii++) {
285 pReq->Reserved2[ii] = 0;
286 }
287
288 IOCPage4Ptr = ioc->spi_data.pIocPg4;
289 dataDma = ioc->spi_data.IocPg4_dma;
290 ii = IOCPage4Ptr->ActiveSEP++;
291 IOCPage4Ptr->SEP[ii].SEPTargetID = id;
292 IOCPage4Ptr->SEP[ii].SEPBus = channel;
293 pReq->Header = IOCPage4Ptr->Header;
294 pReq->PageAddress = cpu_to_le32(id | (channel << 8 ));
295
296 /* Add a SGE to the config request.
297 */
298 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
299 (IOCPage4Ptr->Header.PageLength + ii) * 4;
300
301 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
302
303 ddvprintk((MYIOC_s_INFO_FMT
304 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
305 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel));
306
307 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
308
309 return 0;
310}
311
312/**
313 * mptspi_initTarget - Target, LUN alloc/free functionality.
314 * @hd: Pointer to MPT_SCSI_HOST structure
315 * @vtarget: per target private data
316 * @sdev: SCSI device
317 *
318 * NOTE: It's only SAFE to call this routine if data points to
319 * sane & valid STANDARD INQUIRY data!
320 *
321 * Allocate and initialize memory for this target.
322 * Save inquiry data.
323 *
324 **/
325static void
326mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
327 struct scsi_device *sdev)
328{
329
330 /* Is LUN supported? If so, upper 2 bits will be 0
331 * in first byte of inquiry data.
332 */
333 if (sdev->inq_periph_qual != 0)
334 return;
335
336 if (vtarget == NULL)
337 return;
338
339 vtarget->type = sdev->type;
340
341 if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
342 /* Treat all Processors as SAF-TE if
343 * command line option is set */
344 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
345 mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
346 }else if ((sdev->type == TYPE_PROCESSOR) &&
347 !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
348 if (sdev->inquiry_len > 49 ) {
349 if (sdev->inquiry[44] == 'S' &&
350 sdev->inquiry[45] == 'A' &&
351 sdev->inquiry[46] == 'F' &&
352 sdev->inquiry[47] == '-' &&
353 sdev->inquiry[48] == 'T' &&
354 sdev->inquiry[49] == 'E' ) {
355 vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
356 mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
357 }
358 }
359 }
360 mptspi_setTargetNegoParms(hd, vtarget, sdev);
361}
362
363/**
364 * mptspi_is_raid - Determines whether target is belonging to volume
365 * @hd: Pointer to a SCSI HOST structure
366 * @id: target device id
367 *
368 * Return:
369 * non-zero = true
370 * zero = false
371 *
372 */
373static int
374mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
375{
376 int i, rc = 0;
377
378 if (!hd->ioc->raid_data.pIocPg2)
379 goto out;
380
381 if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes)
382 goto out;
383 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
384 if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) {
385 rc = 1;
386 goto out;
387 }
388 }
389
390 out:
391 return rc;
392}
393
98static int mptspi_target_alloc(struct scsi_target *starget) 394static int mptspi_target_alloc(struct scsi_target *starget)
99{ 395{
100 struct Scsi_Host *shost = dev_to_shost(&starget->dev); 396 struct Scsi_Host *shost = dev_to_shost(&starget->dev);
101 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; 397 struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
102 int ret; 398 VirtTarget *vtarget;
103 399
104 if (hd == NULL) 400 if (hd == NULL)
105 return -ENODEV; 401 return -ENODEV;
106 402
107 ret = mptscsih_target_alloc(starget); 403 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
108 if (ret) 404 if (!vtarget)
109 return ret; 405 return -ENOMEM;
406
407 vtarget->ioc_id = hd->ioc->id;
408 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
409 vtarget->id = (u8)starget->id;
410 vtarget->channel = (u8)starget->channel;
411 vtarget->starget = starget;
412 starget->hostdata = vtarget;
413
414 if (starget->channel == 1) {
415 if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0)
416 return 0;
417 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
418 /* The real channel for this device is zero */
419 vtarget->channel = 0;
420 /* The actual physdisknum (for RAID passthrough) */
421 vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0,
422 starget->id);
423 }
110 424
111 /* if we're a device on virtual channel 1 and we're not part 425 if (starget->channel == 0 &&
112 * of an array, just return here (otherwise the setup below 426 mptspi_is_raid(hd, starget->id)) {
113 * may actually affect a real physical device on channel 0 */ 427 vtarget->raidVolume = 1;
114 if (starget->channel == 1 && 428 ddvprintk((KERN_INFO
115 mptscsih_raid_id_to_num(hd, starget->id) < 0) 429 "RAID Volume @ channel=%d id=%d\n", starget->channel,
116 return 0; 430 starget->id));
431 }
117 432
118 if (hd->ioc->spi_data.nvram && 433 if (hd->ioc->spi_data.nvram &&
119 hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { 434 hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
@@ -132,6 +447,64 @@ static int mptspi_target_alloc(struct scsi_target *starget)
132 return 0; 447 return 0;
133} 448}
134 449
450void
451mptspi_target_destroy(struct scsi_target *starget)
452{
453 if (starget->hostdata)
454 kfree(starget->hostdata);
455 starget->hostdata = NULL;
456}
457
458/**
459 * mptspi_print_write_nego - negotiation parameters debug info that is being sent
460 * @hd: Pointer to a SCSI HOST structure
461 * @starget: SCSI target
462 * @ii: negotiation parameters
463 *
464 */
465static void
466mptspi_print_write_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
467{
468 ddvprintk((MYIOC_s_INFO_FMT "id=%d Requested = 0x%08x"
469 " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
470 hd->ioc->name, starget->id, ii,
471 ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
472 ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
473 ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
474 ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
475 ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
476 ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
477 ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
478 ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
479 ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
480 ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
481}
482
483/**
484 * mptspi_print_read_nego - negotiation parameters debug info that is being read
485 * @hd: Pointer to a SCSI HOST structure
486 * @starget: SCSI target
487 * @ii: negotiation parameters
488 *
489 */
490static void
491mptspi_print_read_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
492{
493 ddvprintk((MYIOC_s_INFO_FMT "id=%d Read = 0x%08x"
494 " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
495 hd->ioc->name, starget->id, ii,
496 ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
497 ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
498 ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
499 ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
500 ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
501 ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
502 ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
503 ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
504 ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
505 ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
506}
507
135static int mptspi_read_spi_device_pg0(struct scsi_target *starget, 508static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
136 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) 509 struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
137{ 510{
@@ -147,7 +520,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
147 520
148 /* No SPI parameters for RAID devices */ 521 /* No SPI parameters for RAID devices */
149 if (starget->channel == 0 && 522 if (starget->channel == 0 &&
150 (hd->ioc->raid_data.isRaid & (1 << starget->id))) 523 mptspi_is_raid(hd, starget->id))
151 return -1; 524 return -1;
152 525
153 size = ioc->spi_data.sdp0length * 4; 526 size = ioc->spi_data.sdp0length * 4;
@@ -185,6 +558,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
185 err = 0; 558 err = 0;
186 memcpy(pass_pg0, pg0, size); 559 memcpy(pass_pg0, pg0, size);
187 560
561 mptspi_print_read_nego(hd, starget, le32_to_cpu(pg0->NegotiatedParameters));
562
188 out_free: 563 out_free:
189 dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); 564 dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma);
190 return err; 565 return err;
@@ -233,7 +608,7 @@ static void mptspi_read_parameters(struct scsi_target *starget)
233} 608}
234 609
235static int 610static int
236mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk) 611mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
237{ 612{
238 MpiRaidActionRequest_t *pReq; 613 MpiRaidActionRequest_t *pReq;
239 MPT_FRAME_HDR *mf; 614 MPT_FRAME_HDR *mf;
@@ -253,8 +628,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
253 pReq->Reserved1 = 0; 628 pReq->Reserved1 = 0;
254 pReq->ChainOffset = 0; 629 pReq->ChainOffset = 0;
255 pReq->Function = MPI_FUNCTION_RAID_ACTION; 630 pReq->Function = MPI_FUNCTION_RAID_ACTION;
256 pReq->VolumeID = disk; 631 pReq->VolumeID = id;
257 pReq->VolumeBus = 0; 632 pReq->VolumeBus = channel;
258 pReq->PhysDiskNum = 0; 633 pReq->PhysDiskNum = 0;
259 pReq->MsgFlags = 0; 634 pReq->MsgFlags = 0;
260 pReq->Reserved2 = 0; 635 pReq->Reserved2 = 0;
@@ -263,8 +638,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
263 mpt_add_sge((char *)&pReq->ActionDataSGE, 638 mpt_add_sge((char *)&pReq->ActionDataSGE,
264 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); 639 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
265 640
266 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", 641 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action=%x channel=%d id=%d\n",
267 hd->ioc->name, action, io->id)); 642 hd->ioc->name, pReq->Action, channel, id));
268 643
269 hd->pLocal = NULL; 644 hd->pLocal = NULL;
270 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ 645 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
@@ -292,12 +667,12 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
292 667
293 /* no DV on RAID devices */ 668 /* no DV on RAID devices */
294 if (sdev->channel == 0 && 669 if (sdev->channel == 0 &&
295 (hd->ioc->raid_data.isRaid & (1 << sdev->id))) 670 mptspi_is_raid(hd, sdev->id))
296 return; 671 return;
297 672
298 /* If this is a piece of a RAID, then quiesce first */ 673 /* If this is a piece of a RAID, then quiesce first */
299 if (sdev->channel == 1 && 674 if (sdev->channel == 1 &&
300 mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) { 675 mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) {
301 starget_printk(KERN_ERR, scsi_target(sdev), 676 starget_printk(KERN_ERR, scsi_target(sdev),
302 "Integrated RAID quiesce failed\n"); 677 "Integrated RAID quiesce failed\n");
303 return; 678 return;
@@ -306,7 +681,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
306 spi_dv_device(sdev); 681 spi_dv_device(sdev);
307 682
308 if (sdev->channel == 1 && 683 if (sdev->channel == 1 &&
309 mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0) 684 mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
310 starget_printk(KERN_ERR, scsi_target(sdev), 685 starget_printk(KERN_ERR, scsi_target(sdev),
311 "Integrated RAID resume failed\n"); 686 "Integrated RAID resume failed\n");
312 687
@@ -317,54 +692,89 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
317 692
318static int mptspi_slave_alloc(struct scsi_device *sdev) 693static int mptspi_slave_alloc(struct scsi_device *sdev)
319{ 694{
320 int ret;
321 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; 695 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
322 /* gcc doesn't see that all uses of this variable occur within 696 VirtTarget *vtarget;
323 * the if() statements, so stop it from whining */ 697 VirtDevice *vdev;
324 int physdisknum = 0; 698 struct scsi_target *starget;
325
326 if (sdev->channel == 1) {
327 physdisknum = mptscsih_raid_id_to_num(hd, sdev->id);
328 699
329 if (physdisknum < 0) 700 if (sdev->channel == 1 &&
330 return physdisknum; 701 mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0)
702 return -ENXIO;
703
704 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
705 if (!vdev) {
706 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
707 hd->ioc->name, sizeof(VirtDevice));
708 return -ENOMEM;
331 } 709 }
332 710
333 ret = mptscsih_slave_alloc(sdev); 711 vdev->lun = sdev->lun;
712 sdev->hostdata = vdev;
334 713
335 if (ret) 714 starget = scsi_target(sdev);
336 return ret; 715 vtarget = starget->hostdata;
716 vdev->vtarget = vtarget;
717 vtarget->num_luns++;
337 718
338 if (sdev->channel == 1) { 719 if (sdev->channel == 1)
339 VirtDevice *vdev = sdev->hostdata;
340 sdev->no_uld_attach = 1; 720 sdev->no_uld_attach = 1;
341 vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
342 /* The real channel for this device is zero */
343 vdev->vtarget->bus_id = 0;
344 /* The actual physdisknum (for RAID passthrough) */
345 vdev->vtarget->target_id = physdisknum;
346 }
347 721
348 return 0; 722 return 0;
349} 723}
350 724
351static int mptspi_slave_configure(struct scsi_device *sdev) 725static int mptspi_slave_configure(struct scsi_device *sdev)
352{ 726{
353 int ret = mptscsih_slave_configure(sdev);
354 struct _MPT_SCSI_HOST *hd = 727 struct _MPT_SCSI_HOST *hd =
355 (struct _MPT_SCSI_HOST *)sdev->host->hostdata; 728 (struct _MPT_SCSI_HOST *)sdev->host->hostdata;
729 VirtTarget *vtarget = scsi_target(sdev)->hostdata;
730 int ret = mptscsih_slave_configure(sdev);
356 731
357 if (ret) 732 if (ret)
358 return ret; 733 return ret;
359 734
735 mptspi_initTarget(hd, vtarget, sdev);
736
737 ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x"
738 " max_offset=0x%02x max_width=%d\n", hd->ioc->name,
739 sdev->id, spi_min_period(scsi_target(sdev)),
740 spi_max_offset(scsi_target(sdev)),
741 spi_max_width(scsi_target(sdev))));
742
360 if ((sdev->channel == 1 || 743 if ((sdev->channel == 1 ||
361 !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) && 744 !(mptspi_is_raid(hd, sdev->id))) &&
362 !spi_initial_dv(sdev->sdev_target)) 745 !spi_initial_dv(sdev->sdev_target))
363 mptspi_dv_device(hd, sdev); 746 mptspi_dv_device(hd, sdev);
364 747
365 return 0; 748 return 0;
366} 749}
367 750
751static int
752mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
753{
754 struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
755 VirtDevice *vdev = SCpnt->device->hostdata;
756
757 if (!vdev || !vdev->vtarget) {
758 SCpnt->result = DID_NO_CONNECT << 16;
759 done(SCpnt);
760 return 0;
761 }
762
763 if (SCpnt->device->channel == 1 &&
764 mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) {
765 SCpnt->result = DID_NO_CONNECT << 16;
766 done(SCpnt);
767 return 0;
768 }
769
770#ifdef MPT_DEBUG_DV
771 if (spi_dv_pending(scsi_target(SCpnt->device)))
772 scsi_print_command(SCpnt);
773#endif
774
775 return mptscsih_qcmd(SCpnt,done);
776}
777
368static void mptspi_slave_destroy(struct scsi_device *sdev) 778static void mptspi_slave_destroy(struct scsi_device *sdev)
369{ 779{
370 struct scsi_target *starget = scsi_target(sdev); 780 struct scsi_target *starget = scsi_target(sdev);
@@ -392,11 +802,11 @@ static struct scsi_host_template mptspi_driver_template = {
392 .proc_info = mptscsih_proc_info, 802 .proc_info = mptscsih_proc_info,
393 .name = "MPT SPI Host", 803 .name = "MPT SPI Host",
394 .info = mptscsih_info, 804 .info = mptscsih_info,
395 .queuecommand = mptscsih_qcmd, 805 .queuecommand = mptspi_qcmd,
396 .target_alloc = mptspi_target_alloc, 806 .target_alloc = mptspi_target_alloc,
397 .slave_alloc = mptspi_slave_alloc, 807 .slave_alloc = mptspi_slave_alloc,
398 .slave_configure = mptspi_slave_configure, 808 .slave_configure = mptspi_slave_configure,
399 .target_destroy = mptscsih_target_destroy, 809 .target_destroy = mptspi_target_destroy,
400 .slave_destroy = mptspi_slave_destroy, 810 .slave_destroy = mptspi_slave_destroy,
401 .change_queue_depth = mptscsih_change_queue_depth, 811 .change_queue_depth = mptscsih_change_queue_depth,
402 .eh_abort_handler = mptscsih_abort, 812 .eh_abort_handler = mptscsih_abort,
@@ -427,7 +837,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
427 837
428 /* don't allow updating nego parameters on RAID devices */ 838 /* don't allow updating nego parameters on RAID devices */
429 if (starget->channel == 0 && 839 if (starget->channel == 0 &&
430 (hd->ioc->raid_data.isRaid & (1 << starget->id))) 840 mptspi_is_raid(hd, starget->id))
431 return -1; 841 return -1;
432 842
433 size = ioc->spi_data.sdp1length * 4; 843 size = ioc->spi_data.sdp1length * 4;
@@ -460,6 +870,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
460 pg1->Header.PageNumber = hdr.PageNumber; 870 pg1->Header.PageNumber = hdr.PageNumber;
461 pg1->Header.PageType = hdr.PageType; 871 pg1->Header.PageType = hdr.PageType;
462 872
873 mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));
874
463 if (mpt_config(ioc, &cfg)) { 875 if (mpt_config(ioc, &cfg)) {
464 starget_printk(KERN_ERR, starget, "mpt_config failed\n"); 876 starget_printk(KERN_ERR, starget, "mpt_config failed\n");
465 goto out_free; 877 goto out_free;
@@ -672,9 +1084,9 @@ static void mpt_work_wrapper(struct work_struct *work)
672 if (sdev->channel != 1) 1084 if (sdev->channel != 1)
673 continue; 1085 continue;
674 1086
675 /* The target_id is the raid PhysDiskNum, even if 1087 /* The id is the raid PhysDiskNum, even if
676 * starget->id is the actual target address */ 1088 * starget->id is the actual target address */
677 if(vtarget->target_id != disk) 1089 if(vtarget->id != disk)
678 continue; 1090 continue;
679 1091
680 starget_printk(KERN_INFO, vtarget->starget, 1092 starget_printk(KERN_INFO, vtarget->starget,
@@ -727,7 +1139,7 @@ mptspi_deny_binding(struct scsi_target *starget)
727{ 1139{
728 struct _MPT_SCSI_HOST *hd = 1140 struct _MPT_SCSI_HOST *hd =
729 (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata; 1141 (struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
730 return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) && 1142 return ((mptspi_is_raid(hd, starget->id)) &&
731 starget->channel == 0) ? 1 : 0; 1143 starget->channel == 0) ? 1 : 0;
732} 1144}
733 1145
@@ -945,14 +1357,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
945 * max_lun = 1 + actual last lun, 1357 * max_lun = 1 + actual last lun,
946 * see hosts.h :o( 1358 * see hosts.h :o(
947 */ 1359 */
948 sh->max_id = MPT_MAX_SCSI_DEVICES; 1360 sh->max_id = ioc->devices_per_bus;
949 1361
950 sh->max_lun = MPT_LAST_LUN + 1; 1362 sh->max_lun = MPT_LAST_LUN + 1;
951 /* 1363 /*
952 * If RAID Firmware Detected, setup virtual channel 1364 * If RAID Firmware Detected, setup virtual channel
953 */ 1365 */
954 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 1366 if (ioc->ir_firmware)
955 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
956 sh->max_channel = 1; 1367 sh->max_channel = 1;
957 else 1368 else
958 sh->max_channel = 0; 1369 sh->max_channel = 0;
@@ -1009,20 +1420,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1009 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", 1420 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1010 ioc->name, hd->ScsiLookup)); 1421 ioc->name, hd->ScsiLookup));
1011 1422
1012 /* Allocate memory for the device structures.
1013 * A non-Null pointer at an offset
1014 * indicates a device exists.
1015 * max_id = 1 + maximum id (hosts.h)
1016 */
1017 hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1),
1018 sizeof(void *), GFP_ATOMIC);
1019 if (!hd->Targets) {
1020 error = -ENOMEM;
1021 goto out_mptspi_probe;
1022 }
1023
1024 dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
1025
1026 /* Clear the TM flags 1423 /* Clear the TM flags
1027 */ 1424 */
1028 hd->tmPending = 0; 1425 hd->tmPending = 0;