提交 12dbf3fc 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

...@@ -3,46 +3,79 @@ AACRAID Driver for Linux (take two) ...@@ -3,46 +3,79 @@ AACRAID Driver for Linux (take two)
Introduction Introduction
------------------------- -------------------------
The aacraid driver adds support for Adaptec (http://www.adaptec.com) The aacraid driver adds support for Adaptec (http://www.adaptec.com)
RAID controllers. This is a major rewrite from the original RAID controllers. This is a major rewrite from the original
Adaptec supplied driver. It has signficantly cleaned up both the code Adaptec supplied driver. It has signficantly cleaned up both the code
and the running binary size (the module is less than half the size of and the running binary size (the module is less than half the size of
the original). the original).
Supported Cards/Chipsets Supported Cards/Chipsets
------------------------- -------------------------
Adaptec 2020S PCI ID (pci.ids) OEM Product
Adaptec 2025S 9005:0285:9005:028a Adaptec 2020ZCR (Skyhawk)
Adaptec 2120S 9005:0285:9005:028e Adaptec 2020SA (Skyhawk)
Adaptec 2130S 9005:0285:9005:028b Adaptec 2025ZCR (Terminator)
Adaptec 2200S 9005:0285:9005:028f Adaptec 2025SA (Terminator)
Adaptec 2230S 9005:0285:9005:0286 Adaptec 2120S (Crusader)
Adaptec 2240S 9005:0286:9005:028d Adaptec 2130S (Lancer)
Adaptec 2410SA 9005:0285:9005:0285 Adaptec 2200S (Vulcan)
Adaptec 2610SA 9005:0285:9005:0287 Adaptec 2200S (Vulcan-2m)
Adaptec 2810SA 9005:0286:9005:028c Adaptec 2230S (Lancer)
Adaptec 21610SA 9005:0286:9005:028c Adaptec 2230SLP (Lancer)
Adaptec 3230S 9005:0285:9005:0296 Adaptec 2240S (SabreExpress)
Adaptec 3240S 9005:0285:9005:0290 Adaptec 2410SA (Jaguar)
Adaptec 4000SAS 9005:0285:9005:0293 Adaptec 21610SA (Corsair-16)
Adaptec 4005SAS 9005:0285:103c:3227 Adaptec 2610SA (Bearcat)
Adaptec 4800SAS 9005:0285:9005:0292 Adaptec 2810SA (Corsair-8)
Adaptec 4805SAS 9005:0285:9005:0294 Adaptec Prowler
Adaptec 5400S 9005:0286:9005:029d Adaptec 2420SA (Intruder)
Dell PERC 2 Quad Channel 9005:0286:9005:029c Adaptec 2620SA (Intruder)
Dell PERC 2/Si 9005:0286:9005:029b Adaptec 2820SA (Intruder)
Dell PERC 3/Si 9005:0286:9005:02a7 Adaptec 2830SA (Skyray)
Dell PERC 3/Di 9005:0286:9005:02a8 Adaptec 2430SA (Skyray)
Dell CERC 2 9005:0285:9005:0288 Adaptec 3230S (Harrier)
HP NetRAID-4M 9005:0285:9005:0289 Adaptec 3240S (Tornado)
Legend S220 9005:0285:9005:0298 Adaptec 4000SAS (BlackBird)
Legend S230 9005:0285:9005:0297 Adaptec 4005SAS (AvonPark)
IBM ServeRAID 8i 9005:0285:9005:0299 Adaptec 4800SAS (Marauder-X)
ICP 9014R0 9005:0285:9005:029a Adaptec 4805SAS (Marauder-E)
ICP 9024R0 9005:0286:9005:02a2 Adaptec 4810SAS (Hurricane)
ICP 9047MA 1011:0046:9005:0364 Adaptec 5400S (Mustang)
ICP 9087MA 1011:0046:9005:0365 Adaptec 5400S (Mustang)
ICP 9085LI 9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
ICP 5085AU 9005:0284:9005:0284 Adaptec Tomcat (3410S with arc firmware)
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
9005:0200:9005:0200 Adaptec Themisto (Jupiter)
9005:0286:9005:0800 Adaptec Callisto (Jupiter)
1011:0046:9005:1364 Dell PERC 2/QC (Quad Channel, Mustang)
1028:0001:1028:0001 Dell PERC 2/Si (Iguana)
1028:0003:1028:0003 Dell PERC 3/Si (SlimFast)
1028:0002:1028:0002 Dell PERC 3/Di (Opal)
1028:0004:1028:0004 Dell PERC 3/DiF (Iguana)
1028:0002:1028:00d1 Dell PERC 3/DiV (Viper)
1028:0002:1028:00d9 Dell PERC 3/DiL (Lexus)
1028:000a:1028:0106 Dell PERC 3/DiJ (Jaguar)
1028:000a:1028:011b Dell PERC 3/DiD (Dagger)
1028:000a:1028:0121 Dell PERC 3/DiB (Boxster)
9005:0285:1028:0287 Dell PERC 320/DC (Vulcan)
9005:0285:1028:0291 Dell CERC 2 (DellCorsair)
1011:0046:103c:10c2 HP NetRAID-4M (Mustang)
9005:0285:17aa:0286 Legend S220 (Crusader)
9005:0285:17aa:0287 Legend S230 (Vulcan)
9005:0285:9005:0290 IBM ServeRAID 7t (Jaguar)
9005:0285:1014:02F2 IBM ServeRAID 8i (AvonPark)
9005:0285:1014:0312 IBM ServeRAID 8i (AvonParkLite)
9005:0286:1014:9580 IBM ServeRAID 8k/8k-l8 (Aurora)
9005:0286:1014:9540 IBM ServeRAID 8k/8k-l4 (AuroraLite)
9005:0286:9005:029f ICP ICP9014R0 (Lancer)
9005:0286:9005:029e ICP ICP9024R0 (Lancer)
9005:0286:9005:02a0 ICP ICP9047MA (Lancer)
9005:0286:9005:02a1 ICP ICP9087MA (Lancer)
9005:0286:9005:02a4 ICP ICP9085LI (Marauder-X)
9005:0286:9005:02a5 ICP ICP5085BR (Marauder-E)
9005:0286:9005:02a3 ICP ICP5085AU (Hurricane)
9005:0286:9005:02a6 ICP ICP9067MA (Intruder-6)
9005:0286:9005:02a9 ICP ICP5087AU (Skyray)
9005:0286:9005:02aa ICP ICP5047AU (Skyray)
People People
------------------------- -------------------------
...@@ -68,7 +101,8 @@ Mailing List ...@@ -68,7 +101,8 @@ Mailing List
linux-scsi@vger.kernel.org (Interested parties troll here) linux-scsi@vger.kernel.org (Interested parties troll here)
Also note this is very different to Brian's original driver Also note this is very different to Brian's original driver
so don't expect him to support it. so don't expect him to support it.
Adaptec does support this driver. Contact either tech support or Mark Salyzyn. Adaptec does support this driver. Contact Adaptec tech support or
aacraid@adaptec.com
Original by Brian Boerner February 2001 Original by Brian Boerner February 2001
Rewritten by Alan Cox, November 2001 Rewritten by Alan Cox, November 2001
...@@ -23,6 +23,7 @@ config FUSION_FC ...@@ -23,6 +23,7 @@ config FUSION_FC
tristate "Fusion MPT ScsiHost drivers for FC" tristate "Fusion MPT ScsiHost drivers for FC"
depends on PCI && SCSI depends on PCI && SCSI
select FUSION select FUSION
select SCSI_FC_ATTRS
---help--- ---help---
SCSI HOST support for a Fiber Channel host adapters. SCSI HOST support for a Fiber Channel host adapters.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Message independent structures and definitions * Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000 * Creation Date: July 27, 2000
* *
* mpi.h Version: 01.05.08 * mpi.h Version: 01.05.10
* *
* Version History * Version History
* --------------- * ---------------
...@@ -74,6 +74,8 @@ ...@@ -74,6 +74,8 @@
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
* TargetAssistExtended requests. * TargetAssistExtended requests.
* Added EEDP IOCStatus codes. * Added EEDP IOCStatus codes.
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -104,7 +106,7 @@ ...@@ -104,7 +106,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */ /* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */ /* versioning for this MPI header set */
#define MPI_HEADER_VERSION_UNIT (0x0A) #define MPI_HEADER_VERSION_UNIT (0x0C)
#define MPI_HEADER_VERSION_DEV (0x00) #define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8) #define MPI_HEADER_VERSION_UNIT_SHIFT (8)
...@@ -711,6 +713,8 @@ typedef struct _MSG_DEFAULT_REPLY ...@@ -711,6 +713,8 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D) #define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D)
#define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E) #define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E)
#define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F) #define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F)
#define MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070)
#define MPI_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071)
/****************************************************************************/ /****************************************************************************/
/* Additional FCP target values (obsolete) */ /* Additional FCP target values (obsolete) */
...@@ -745,7 +749,7 @@ typedef struct _MSG_DEFAULT_REPLY ...@@ -745,7 +749,7 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_LAN_CANCELED (0x0087) #define MPI_IOCSTATUS_LAN_CANCELED (0x0087)
/****************************************************************************/ /****************************************************************************/
/* Serial Attached SCSI values */ /* Serial Attached SCSI values */
/****************************************************************************/ /****************************************************************************/
#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) #define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Config message, structures, and Pages * Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000 * Creation Date: July 27, 2000
* *
* mpi_cnfg.h Version: 01.05.09 * mpi_cnfg.h Version: 01.05.11
* *
* Version History * Version History
* --------------- * ---------------
...@@ -249,6 +249,23 @@ ...@@ -249,6 +249,23 @@
* Added OwnerDevHandle and Flags field to SAS PHY Page 0. * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
* Added IOC GPIO Flags define to SAS Enclosure Page 0. * Added IOC GPIO Flags define to SAS Enclosure Page 0.
* Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* 08-03-05 01.05.10 Removed ISDataScrubRate and ISResyncRate from
* Manufacturing Page 4.
* Added MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE bit.
* Added NumDevsPerEnclosure field to SAS IO Unit page 2.
* Added MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP
* define.
* Added EnclosureHandle field to SAS Expander page 0.
* Removed redundant NumTableEntriesProg field from SAS
* Expander Page 1.
* 08-30-05 01.05.11 Added DeviceID for FC949E and changed the DeviceID for
* SAS1078.
* Added more defines for Manufacturing Page 4 Flags field.
* Added more defines for IOCSettings and added
* ExpanderSpinup field to Bios Page 1.
* Added postpone SATA Init bit to SAS IO Unit Page 1
* ControlFlags.
* Changed LogEntry format for Log Page 0.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -494,7 +511,7 @@ typedef struct _MSG_CONFIG_REPLY ...@@ -494,7 +511,7 @@ typedef struct _MSG_CONFIG_REPLY
#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626) #define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642) #define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642)
#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640) #define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646) #define MPI_MANUFACTPAGE_DEVICEID_FC949E (0x0646)
/* SCSI */ /* SCSI */
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030) #define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031) #define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
...@@ -510,7 +527,7 @@ typedef struct _MSG_CONFIG_REPLY ...@@ -510,7 +527,7 @@ typedef struct _MSG_CONFIG_REPLY
#define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A) #define MPI_MANUFACTPAGE_DEVID_SAS1066E (0x005A)
#define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054) #define MPI_MANUFACTPAGE_DEVID_SAS1068 (0x0054)
#define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058) #define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058)
#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0060) #define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0062)
typedef struct _CONFIG_PAGE_MANUFACTURING_0 typedef struct _CONFIG_PAGE_MANUFACTURING_0
...@@ -602,9 +619,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 ...@@ -602,9 +619,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
U32 IMVolumeSettings; /* 50h */ U32 IMVolumeSettings; /* 50h */
U32 Reserved3; /* 54h */ U32 Reserved3; /* 54h */
U32 Reserved4; /* 58h */ U32 Reserved4; /* 58h */
U8 ISDataScrubRate; /* 5Ch */ U32 Reserved5; /* 5Ch */
U8 ISResyncRate; /* 5Dh */
U16 Reserved5; /* 5Eh */
U8 IMEDataScrubRate; /* 60h */ U8 IMEDataScrubRate; /* 60h */
U8 IMEResyncRate; /* 61h */ U8 IMEResyncRate; /* 61h */
U16 Reserved6; /* 62h */ U16 Reserved6; /* 62h */
...@@ -616,9 +631,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4 ...@@ -616,9 +631,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4, } CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t; ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
#define MPI_MANUFACTURING4_PAGEVERSION (0x02) #define MPI_MANUFACTURING4_PAGEVERSION (0x03)
/* defines for the Flags field */ /* defines for the Flags field */
#define MPI_MANPAGE4_IME_DISABLE (0x20)
#define MPI_MANPAGE4_IM_DISABLE (0x10)
#define MPI_MANPAGE4_IS_DISABLE (0x08)
#define MPI_MANPAGE4_IR_MODEPAGE8_DISABLE (0x04)
#define MPI_MANPAGE4_IM_RESYNC_CACHE_ENABLE (0x02)
#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01) #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
...@@ -669,7 +689,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1 ...@@ -669,7 +689,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
} CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1, } CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t; IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
#define MPI_IOUNITPAGE1_PAGEVERSION (0x01) #define MPI_IOUNITPAGE1_PAGEVERSION (0x02)
/* IO Unit Page 1 Flags defines */ /* IO Unit Page 1 Flags defines */
#define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000) #define MPI_IOUNITPAGE1_MULTI_FUNCTION (0x00000000)
...@@ -681,7 +701,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1 ...@@ -681,7 +701,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
#define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040) #define MPI_IOUNITPAGE1_DISABLE_IR (0x00000040)
#define MPI_IOUNITPAGE1_FORCE_32 (0x00000080) #define MPI_IOUNITPAGE1_FORCE_32 (0x00000080)
#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100) #define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100)
#define MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE (0x00000200)
typedef struct _MPI_ADAPTER_INFO typedef struct _MPI_ADAPTER_INFO
{ {
...@@ -968,7 +988,8 @@ typedef struct _CONFIG_PAGE_BIOS_1 ...@@ -968,7 +988,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
U32 Reserved1; /* 0Ch */ U32 Reserved1; /* 0Ch */
U32 DeviceSettings; /* 10h */ U32 DeviceSettings; /* 10h */
U16 NumberOfDevices; /* 14h */ U16 NumberOfDevices; /* 14h */
U16 Reserved2; /* 16h */ U8 ExpanderSpinup; /* 16h */
U8 Reserved2; /* 17h */
U16 IOTimeoutBlockDevicesNonRM; /* 18h */ U16 IOTimeoutBlockDevicesNonRM; /* 18h */
U16 IOTimeoutSequential; /* 1Ah */ U16 IOTimeoutSequential; /* 1Ah */
U16 IOTimeoutOther; /* 1Ch */ U16 IOTimeoutOther; /* 1Ch */
...@@ -976,7 +997,7 @@ typedef struct _CONFIG_PAGE_BIOS_1 ...@@ -976,7 +997,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1, } CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
BIOSPage1_t, MPI_POINTER pBIOSPage1_t; BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
#define MPI_BIOSPAGE1_PAGEVERSION (0x02) #define MPI_BIOSPAGE1_PAGEVERSION (0x03)
/* values for the BiosOptions field */ /* values for the BiosOptions field */
#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400) #define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
...@@ -985,8 +1006,15 @@ typedef struct _CONFIG_PAGE_BIOS_1 ...@@ -985,8 +1006,15 @@ typedef struct _CONFIG_PAGE_BIOS_1
#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001) #define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
/* values for the IOCSettings field */ /* values for the IOCSettings field */
#define MPI_BIOSPAGE1_IOCSET_MASK_INITIAL_SPINUP_DELAY (0x0F000000)
#define MPI_BIOSPAGE1_IOCSET_SHIFT_INITIAL_SPINUP_DELAY (24)
#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000) #define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000)
#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20) #define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20)
#define MPI_BIOSPAGE1_IOCSET_AUTO_PORT_ENABLE (0x00080000)
#define MPI_BIOSPAGE1_IOCSET_DIRECT_ATTACH_SPINUP_MODE (0x00040000)
#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000) #define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000) #define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000) #define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
...@@ -1016,6 +1044,11 @@ typedef struct _CONFIG_PAGE_BIOS_1 ...@@ -1016,6 +1044,11 @@ typedef struct _CONFIG_PAGE_BIOS_1
#define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002) #define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN (0x00000002)
#define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001) #define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN (0x00000001)
/* defines for the ExpanderSpinup field */
#define MPI_BIOSPAGE1_EXPSPINUP_MASK_MAX_TARGET (0xF0)
#define MPI_BIOSPAGE1_EXPSPINUP_SHIFT_MAX_TARGET (4)
#define MPI_BIOSPAGE1_EXPSPINUP_MASK_DELAY (0x0F)
typedef struct _MPI_BOOT_DEVICE_ADAPTER_ORDER typedef struct _MPI_BOOT_DEVICE_ADAPTER_ORDER
{ {
U32 Reserved1; /* 00h */ U32 Reserved1; /* 00h */
...@@ -1233,13 +1266,13 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0 ...@@ -1233,13 +1266,13 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8) #define MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD (8)
#define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \ #define MPI_SCSIPORTPAGE0_CAP_GET_MIN_SYNC_PERIOD(Cap) \
( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MIN_SYNC_PERIOD) \ ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK) \
>> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \ >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MIN_SYNC_PERIOD \
) )
#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000) #define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16) #define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16)
#define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \ #define MPI_SCSIPORTPAGE0_CAP_GET_MAX_SYNC_OFFSET(Cap) \
( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \ ( ((Cap) & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK) \
>> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \ >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET \
) )
#define MPI_SCSIPORTPAGE0_CAP_IDP (0x08000000) #define MPI_SCSIPORTPAGE0_CAP_IDP (0x08000000)
...@@ -2370,47 +2403,48 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 ...@@ -2370,47 +2403,48 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1, } CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t; SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04) #define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05)
/* values for SAS IO Unit Page 1 ControlFlags */ /* values for SAS IO Unit Page 1 ControlFlags */
#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000) #define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000) #define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800) #define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800)
#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600) #define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600)
#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9) #define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00) #define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01) #define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02) #define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080) #define MPI_SAS_IOUNIT1_CONTROL_POSTPONE_SATA_INIT (0x0100)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040) #define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020) #define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010) #define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008) #define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010)
#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004) #define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008)
#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002) #define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004)
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001) #define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
/* values for SAS IO Unit Page 1 PortFlags */ /* values for SAS IO Unit Page 1 PortFlags */
#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00) #define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM (0x00)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04) #define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM (0x04)
#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01) #define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG (0x01)
/* values for SAS IO Unit Page 0 PhyFlags */ /* values for SAS IO Unit Page 0 PhyFlags */
#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04) #define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04)
#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02) #define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02)
#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01) #define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01)
/* values for SAS IO Unit Page 0 MaxMinLinkRate */ /* values for SAS IO Unit Page 0 MaxMinLinkRate */
#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0) #define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0)
#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80) #define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80)
#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90) #define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90)
#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F) #define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F)
#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08) #define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08)
#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09) #define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09)
/* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */ /* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
...@@ -2418,16 +2452,18 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1 ...@@ -2418,16 +2452,18 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
{ {
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */ U8 NumDevsPerEnclosure; /* 08h */
U8 Reserved1; /* 09h */
U16 Reserved2; /* 0Ah */
U16 MaxPersistentIDs; /* 0Ch */ U16 MaxPersistentIDs; /* 0Ch */
U16 NumPersistentIDsUsed; /* 0Eh */ U16 NumPersistentIDsUsed; /* 0Eh */
U8 Status; /* 10h */ U8 Status; /* 10h */
U8 Flags; /* 11h */ U8 Flags; /* 11h */
U16 MaxNumPhysicalMappedIDs;/* 12h */ /* 12h */ U16 MaxNumPhysicalMappedIDs;/* 12h */
} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2, } CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t; SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04) #define MPI_SASIOUNITPAGE2_PAGEVERSION (0x05)
/* values for SAS IO Unit Page 2 Status field */ /* values for SAS IO Unit Page 2 Status field */
#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02) #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
...@@ -2441,6 +2477,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2 ...@@ -2441,6 +2477,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
#define MPI_SAS_IOUNIT2_FLAGS_NO_PHYS_MAP (0x00) #define MPI_SAS_IOUNIT2_FLAGS_NO_PHYS_MAP (0x00)
#define MPI_SAS_IOUNIT2_FLAGS_DIRECT_ATTACH_PHYS_MAP (0x01) #define MPI_SAS_IOUNIT2_FLAGS_DIRECT_ATTACH_PHYS_MAP (0x01)
#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02) #define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02)
#define MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP (0x07)
#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10) #define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10)
#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20) #define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20)
...@@ -2473,7 +2510,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0 ...@@ -2473,7 +2510,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */ CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U8 PhysicalPort; /* 08h */ U8 PhysicalPort; /* 08h */
U8 Reserved1; /* 09h */ U8 Reserved1; /* 09h */
U16 Reserved2; /* 0Ah */ U16 EnclosureHandle; /* 0Ah */
U64 SASAddress; /* 0Ch */ U64 SASAddress; /* 0Ch */
U32 DiscoveryStatus; /* 14h */ U32 DiscoveryStatus; /* 14h */
U16 DevHandle; /* 18h */ U16 DevHandle; /* 18h */
...@@ -2487,7 +2524,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0 ...@@ -2487,7 +2524,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
} CONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0, } CONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t; SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
#define MPI_SASEXPANDER0_PAGEVERSION (0x02) #define MPI_SASEXPANDER0_PAGEVERSION (0x03)
/* values for SAS Expander Page 0 DiscoveryStatus field */ /* values for SAS Expander Page 0 DiscoveryStatus field */
#define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) #define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001)
...@@ -2527,9 +2564,9 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_1 ...@@ -2527,9 +2564,9 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_1
U8 NegotiatedLinkRate; /* 1Fh */ U8 NegotiatedLinkRate; /* 1Fh */
U8 PhyIdentifier; /* 20h */ U8 PhyIdentifier; /* 20h */
U8 AttachedPhyIdentifier; /* 21h */ U8 AttachedPhyIdentifier; /* 21h */
U8 NumTableEntriesProg; /* 22h */ U8 Reserved3; /* 22h */
U8 DiscoveryInfo; /* 23h */ U8 DiscoveryInfo; /* 23h */
U32 Reserved3; /* 24h */ U32 Reserved4; /* 24h */
} CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1, } CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1,
SasExpanderPage1_t, MPI_POINTER pSasExpanderPage1_t; SasExpanderPage1_t, MPI_POINTER pSasExpanderPage1_t;
...@@ -2766,16 +2803,15 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0 ...@@ -2766,16 +2803,15 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
#define MPI_LOG_0_NUM_LOG_ENTRIES (1) #define MPI_LOG_0_NUM_LOG_ENTRIES (1)
#endif #endif
#define MPI_LOG_0_LOG_DATA_LENGTH (20) #define MPI_LOG_0_LOG_DATA_LENGTH (0x1C)
typedef struct _MPI_LOG_0_ENTRY typedef struct _MPI_LOG_0_ENTRY
{ {
U64 WWID; /* 00h */ U32 TimeStamp; /* 00h */
U32 TimeStamp; /* 08h */ U32 Reserved1; /* 04h */
U32 Reserved1; /* 0Ch */ U16 LogSequence; /* 08h */
U16 LogSequence; /* 10h */ U16 LogEntryQualifier; /* 0Ah */
U16 LogEntryQualifier; /* 12h */ U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 0Ch */
U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 14h */
} MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY, } MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY,
MpiLog0Entry_t, MPI_POINTER pMpiLog0Entry_t; MpiLog0Entry_t, MPI_POINTER pMpiLog0Entry_t;
...@@ -2794,7 +2830,7 @@ typedef struct _CONFIG_PAGE_LOG_0 ...@@ -2794,7 +2830,7 @@ typedef struct _CONFIG_PAGE_LOG_0
} CONFIG_PAGE_LOG_0, MPI_POINTER PTR_CONFIG_PAGE_LOG_0, } CONFIG_PAGE_LOG_0, MPI_POINTER PTR_CONFIG_PAGE_LOG_0,
LogPage0_t, MPI_POINTER pLogPage0_t; LogPage0_t, MPI_POINTER pLogPage0_t;
#define MPI_LOG_0_PAGEVERSION (0x00) #define MPI_LOG_0_PAGEVERSION (0x01)
#endif #endif
......
...@@ -6,25 +6,25 @@ ...@@ -6,25 +6,25 @@
Copyright (c) 2000-2005 LSI Logic Corporation. Copyright (c) 2000-2005 LSI Logic Corporation.
--------------------------------------- ---------------------------------------
Header Set Release Version: 01.05.10 Header Set Release Version: 01.05.12
Header Set Release Date: 03-11-05 Header Set Release Date: 08-30-05
--------------------------------------- ---------------------------------------
Filename Current version Prior version Filename Current version Prior version
---------- --------------- ------------- ---------- --------------- -------------
mpi.h 01.05.08 01.05.07 mpi.h 01.05.10 01.05.09
mpi_ioc.h 01.05.09 01.05.08 mpi_ioc.h 01.05.10 01.05.09
mpi_cnfg.h 01.05.09 01.05.08 mpi_cnfg.h 01.05.11 01.05.10
mpi_init.h 01.05.05 01.05.04 mpi_init.h 01.05.06 01.05.06
mpi_targ.h 01.05.05 01.05.04 mpi_targ.h 01.05.05 01.05.05
mpi_fc.h 01.05.01 01.05.01 mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01 mpi_lan.h 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02 mpi_raid.h 01.05.02 01.05.02
mpi_tool.h 01.05.03 01.05.03 mpi_tool.h 01.05.03 01.05.03
mpi_inb.h 01.05.01 01.05.01 mpi_inb.h 01.05.01 01.05.01
mpi_sas.h 01.05.01 01.05.01 mpi_sas.h 01.05.02 01.05.01
mpi_type.h 01.05.01 01.05.01 mpi_type.h 01.05.02 01.05.01
mpi_history.txt 01.05.09 01.05.09 mpi_history.txt 01.05.12 01.05.11
* Date Version Description * Date Version Description
...@@ -91,6 +91,8 @@ mpi.h ...@@ -91,6 +91,8 @@ mpi.h
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and * 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
* TargetAssistExtended requests. * TargetAssistExtended requests.
* Added EEDP IOCStatus codes. * Added EEDP IOCStatus codes.
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_ioc.h mpi_ioc.h
...@@ -164,6 +166,10 @@ mpi_ioc.h ...@@ -164,6 +166,10 @@ mpi_ioc.h
* Removed IOCFacts Reply EEDP Capability bit. * Removed IOCFacts Reply EEDP Capability bit.
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
* Added Max SATA Targets to SAS Discovery Error event. * Added Max SATA Targets to SAS Discovery Error event.
* 08-30-05 01.05.10 Added 4 new events and their event data structures.
* Added new ReasonCode value for SAS Device Status Change
* event.
* Added new family code for FC949E.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_cnfg.h mpi_cnfg.h
...@@ -402,6 +408,23 @@ mpi_cnfg.h ...@@ -402,6 +408,23 @@ mpi_cnfg.h
* Added OwnerDevHandle and Flags field to SAS PHY Page 0. * Added OwnerDevHandle and Flags field to SAS PHY Page 0.
* Added IOC GPIO Flags define to SAS Enclosure Page 0. * Added IOC GPIO Flags define to SAS Enclosure Page 0.
* Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT. * Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* 08-03-05 01.05.10 Removed ISDataScrubRate and ISResyncRate from
* Manufacturing Page 4.
* Added MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE bit.
* Added NumDevsPerEnclosure field to SAS IO Unit page 2.
* Added MPI_SAS_IOUNIT2_FLAGS_HOST_ASSIGNED_PHYS_MAP
* define.
* Added EnclosureHandle field to SAS Expander page 0.
* Removed redundant NumTableEntriesProg field from SAS
* Expander Page 1.
* 08-30-05 01.05.11 Added DeviceID for FC949E and changed the DeviceID for
* SAS1078.
* Added more defines for Manufacturing Page 4 Flags field.
* Added more defines for IOCSettings and added
* ExpanderSpinup field to Bios Page 1.
* Added postpone SATA Init bit to SAS IO Unit Page 1
* ControlFlags.
* Changed LogEntry format for Log Page 0.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_init.h mpi_init.h
...@@ -442,6 +465,8 @@ mpi_init.h ...@@ -442,6 +465,8 @@ mpi_init.h
* addressing. * addressing.
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
* Added four new defines for SEP SlotStatus. * Added four new defines for SEP SlotStatus.
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_targ.h mpi_targ.h
...@@ -582,6 +607,9 @@ mpi_inb.h ...@@ -582,6 +607,9 @@ mpi_inb.h
mpi_sas.h mpi_sas.h
* 08-19-04 01.05.01 Original release. * 08-19-04 01.05.01 Original release.
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
* Added PrimFlags and Primitive field to SAS IO Unit
* Control request, and added a new operation code.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_type.h mpi_type.h
...@@ -592,24 +620,25 @@ mpi_type.h ...@@ -592,24 +620,25 @@ mpi_type.h
* 08-08-01 01.02.01 Original release for v1.2 work. * 08-08-01 01.02.01 Original release for v1.2 work.
* 05-11-04 01.03.01 Original release for MPI v1.3. * 05-11-04 01.03.01 Original release for MPI v1.3.
* 08-19-04 01.05.01 Original release for MPI v1.5. * 08-19-04 01.05.01 Original release for MPI v1.5.
* 08-30-05 01.05.02 Added PowerPC option to #ifdef's.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
mpi_history.txt Parts list history mpi_history.txt Parts list history
Filename 01.05.10 01.05.09 Filename 01.05.12 01.05.11 01.05.10 01.05.09
---------- -------- -------- ---------- -------- -------- -------- --------
mpi.h 01.05.08 01.05.07 mpi.h 01.05.10 01.05.09 01.05.08 01.05.07
mpi_ioc.h 01.05.09 01.05.08 mpi_ioc.h 01.05.10 01.05.09 01.05.09 01.05.08
mpi_cnfg.h 01.05.09 01.05.08 mpi_cnfg.h 01.05.11 01.05.10 01.05.09 01.05.08
mpi_init.h 01.05.05 01.05.04 mpi_init.h 01.05.06 01.05.06 01.05.05 01.05.04
mpi_targ.h 01.05.05 01.05.04 mpi_targ.h 01.05.05 01.05.05 01.05.05 01.05.04
mpi_fc.h 01.05.01 01.05.01 mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01 mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02 mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02
mpi_tool.h 01.05.03 01.05.03 mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03
mpi_inb.h 01.05.01 01.05.01 mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01
mpi_sas.h 01.05.01 01.05.01 mpi_sas.h 01.05.02 01.05.01 01.05.01 01.05.01
mpi_type.h 01.05.01 01.05.01 mpi_type.h 01.05.02 01.05.01 01.05.01 01.05.01
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03 Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
---------- -------- -------- -------- -------- -------- -------- ---------- -------- -------- -------- -------- -------- --------
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI initiator mode messages and structures * Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000 * Creation Date: June 8, 2000
* *
* mpi_init.h Version: 01.05.05 * mpi_init.h Version: 01.05.06
* *
* Version History * Version History
* --------------- * ---------------
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
* addressing. * addressing.
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines. * 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
* Added four new defines for SEP SlotStatus. * Added four new defines for SEP SlotStatus.
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -290,8 +292,8 @@ typedef struct _MSG_SCSI_IO32_REQUEST ...@@ -290,8 +292,8 @@ typedef struct _MSG_SCSI_IO32_REQUEST
/* SCSI IO 32 MsgFlags bits */ /* SCSI IO 32 MsgFlags bits */
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01) #define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00) #define MPI_SCSIIO32_MSGFLGS_32_SENSE_WIDTH (0x00)
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01) #define MPI_SCSIIO32_MSGFLGS_64_SENSE_WIDTH (0x01)
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02) #define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00) #define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000 * Creation Date: August 11, 2000
* *
* mpi_ioc.h Version: 01.05.09 * mpi_ioc.h Version: 01.05.10
* *
* Version History * Version History
* --------------- * ---------------
...@@ -83,6 +83,10 @@ ...@@ -83,6 +83,10 @@
* Removed IOCFacts Reply EEDP Capability bit. * Removed IOCFacts Reply EEDP Capability bit.
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits. * 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
* Added Max SATA Targets to SAS Discovery Error event. * Added Max SATA Targets to SAS Discovery Error event.
* 08-30-05 01.05.10 Added 4 new events and their event data structures.
* Added new ReasonCode value for SAS Device Status Change
* event.
* Added new family code for FC949E.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -464,6 +468,10 @@ typedef struct _MSG_EVENT_ACK_REPLY ...@@ -464,6 +468,10 @@ typedef struct _MSG_EVENT_ACK_REPLY
#define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011) #define MPI_EVENT_PERSISTENT_TABLE_FULL (0x00000011)
#define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012) #define MPI_EVENT_SAS_PHY_LINK_STATUS (0x00000012)
#define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013) #define MPI_EVENT_SAS_DISCOVERY_ERROR (0x00000013)
#define MPI_EVENT_IR_RESYNC_UPDATE (0x00000014)
#define MPI_EVENT_IR2 (0x00000015)
#define MPI_EVENT_SAS_DISCOVERY (0x00000016)
#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
/* AckRequired field values */ /* AckRequired field values */
...@@ -480,6 +488,29 @@ typedef struct _EVENT_DATA_EVENT_CHANGE ...@@ -480,6 +488,29 @@ typedef struct _EVENT_DATA_EVENT_CHANGE
} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE, } EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t; EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;
/* LogEntryAdded Event data */
/* this structure matches MPI_LOG_0_ENTRY in mpi_cnfg.h */
#define MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH (0x1C)
typedef struct _EVENT_DATA_LOG_ENTRY
{
U32 TimeStamp; /* 00h */
U32 Reserved1; /* 04h */
U16 LogSequence; /* 08h */
U16 LogEntryQualifier; /* 0Ah */
U8 LogData[MPI_EVENT_DATA_LOG_ENTRY_DATA_LENGTH]; /* 0Ch */
} EVENT_DATA_LOG_ENTRY, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY,
MpiEventDataLogEntry_t, MPI_POINTER pMpiEventDataLogEntry_t;
typedef struct _EVENT_DATA_LOG_ENTRY_ADDED
{
U16 LogSequence; /* 00h */
U16 Reserved1; /* 02h */
U32 Reserved2; /* 04h */
EVENT_DATA_LOG_ENTRY LogEntry; /* 08h */
} EVENT_DATA_LOG_ENTRY_ADDED, MPI_POINTER PTR_EVENT_DATA_LOG_ENTRY_ADDED,
MpiEventDataLogEntryAdded_t, MPI_POINTER pMpiEventDataLogEntryAdded_t;
/* SCSI Event data for Port, Bus and Device forms */ /* SCSI Event data for Port, Bus and Device forms */
typedef struct _EVENT_DATA_SCSI typedef struct _EVENT_DATA_SCSI
...@@ -538,6 +569,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE ...@@ -538,6 +569,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
#define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
#define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06) #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED (0x06)
#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) #define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
#define MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
/* SCSI Event data for Queue Full event */ /* SCSI Event data for Queue Full event */
...@@ -579,6 +611,79 @@ typedef struct _EVENT_DATA_RAID ...@@ -579,6 +611,79 @@ typedef struct _EVENT_DATA_RAID
#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A) #define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B) #define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED (0x0B)
/* MPI Integrated RAID Resync Update Event data */
typedef struct _MPI_EVENT_DATA_IR_RESYNC_UPDATE
{
U8 VolumeID; /* 00h */
U8 VolumeBus; /* 01h */
U8 ResyncComplete; /* 02h */
U8 Reserved1; /* 03h */
U32 Reserved2; /* 04h */
} MPI_EVENT_DATA_IR_RESYNC_UPDATE,
MPI_POINTER PTR_MPI_EVENT_DATA_IR_RESYNC_UPDATE,
MpiEventDataIrResyncUpdate_t, MPI_POINTER pMpiEventDataIrResyncUpdate_t;
/* MPI IR2 Event data */
/* MPI_LD_STATE or MPI_PD_STATE */
typedef struct _IR2_STATE_CHANGED
{
U16 PreviousState; /* 00h */
U16 NewState; /* 02h */
} IR2_STATE_CHANGED, MPI_POINTER PTR_IR2_STATE_CHANGED;
typedef struct _IR2_PD_INFO
{
U16 DeviceHandle; /* 00h */
U8 TruncEnclosureHandle; /* 02h */
U8 TruncatedSlot; /* 03h */
} IR2_PD_INFO, MPI_POINTER PTR_IR2_PD_INFO;
typedef union _MPI_IR2_RC_EVENT_DATA
{
IR2_STATE_CHANGED StateChanged;
U32 Lba;
IR2_PD_INFO PdInfo;
} MPI_IR2_RC_EVENT_DATA, MPI_POINTER PTR_MPI_IR2_RC_EVENT_DATA;
typedef struct _MPI_EVENT_DATA_IR2
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U8 ReasonCode; /* 02h */
U8 PhysDiskNum; /* 03h */
MPI_IR2_RC_EVENT_DATA IR2EventData; /* 04h */
} MPI_EVENT_DATA_IR2, MPI_POINTER PTR_MPI_EVENT_DATA_IR2,
MpiEventDataIR2_t, MPI_POINTER pMpiEventDataIR2_t;
/* MPI IR2 Event data ReasonCode values */
#define MPI_EVENT_IR2_RC_LD_STATE_CHANGED (0x01)
#define MPI_EVENT_IR2_RC_PD_STATE_CHANGED (0x02)
#define MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL (0x03)
#define MPI_EVENT_IR2_RC_PD_INSERTED (0x04)
#define MPI_EVENT_IR2_RC_PD_REMOVED (0x05)
#define MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED (0x06)
#define MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR (0x07)
/* defines for logical disk states */
#define MPI_LD_STATE_OPTIMAL (0x00)
#define MPI_LD_STATE_DEGRADED (0x01)
#define MPI_LD_STATE_FAILED (0x02)
#define MPI_LD_STATE_MISSING (0x03)
#define MPI_LD_STATE_OFFLINE (0x04)
/* defines for physical disk states */
#define MPI_PD_STATE_ONLINE (0x00)
#define MPI_PD_STATE_MISSING (0x01)
#define MPI_PD_STATE_NOT_COMPATIBLE (0x02)
#define MPI_PD_STATE_FAILED (0x03)
#define MPI_PD_STATE_INITIALIZING (0x04)
#define MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST (0x05)
#define MPI_PD_STATE_FAILED_AT_HOST_REQUEST (0x06)
#define MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON (0xFF)
/* MPI Link Status Change Event data */ /* MPI Link Status Change Event data */
typedef struct _EVENT_DATA_LINK_STATUS typedef struct _EVENT_DATA_LINK_STATUS
...@@ -660,6 +765,20 @@ typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS ...@@ -660,6 +765,20 @@ typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
#define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08) #define MPI_EVENT_SAS_PLS_LR_RATE_1_5 (0x08)
#define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09) #define MPI_EVENT_SAS_PLS_LR_RATE_3_0 (0x09)
/* SAS Discovery Event data */
typedef struct _EVENT_DATA_SAS_DISCOVERY
{
U32 DiscoveryStatus; /* 00h */
U32 Reserved1; /* 04h */
} EVENT_DATA_SAS_DISCOVERY, MPI_POINTER PTR_EVENT_DATA_SAS_DISCOVERY,
EventDataSasDiscovery_t, MPI_POINTER pEventDataSasDiscovery_t;
#define MPI_EVENT_SAS_DSCVRY_COMPLETE (0x00000000)
#define MPI_EVENT_SAS_DSCVRY_IN_PROGRESS (0x00000001)
#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_MASK (0xFFFF0000)
#define MPI_EVENT_SAS_DSCVRY_PHY_BITS_SHIFT (16)
/* SAS Discovery Errror Event data */ /* SAS Discovery Errror Event data */
typedef struct _EVENT_DATA_DISCOVERY_ERROR typedef struct _EVENT_DATA_DISCOVERY_ERROR
...@@ -869,6 +988,7 @@ typedef struct _MPI_FW_HEADER ...@@ -869,6 +988,7 @@ typedef struct _MPI_FW_HEADER
#define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */ #define MPI_FW_HEADER_PID_FAMILY_919XL_FC (0x0003) /* 919XL and 929XL */
#define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */ #define MPI_FW_HEADER_PID_FAMILY_939X_FC (0x0004) /* 939X and 949X */
#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005) #define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)
#define MPI_FW_HEADER_PID_FAMILY_949E_FC (0x0006)
/* SAS */ /* SAS */
#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001) #define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)
#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002) #define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002)
......
/*
* Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved.
*
* NAME: fc_log.h
* SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips
* DESCRIPTION: Contains the enumerated list of values that may be returned
* in the IOCLogInfo field of a MPI Default Reply Message.
*
* CREATION DATE: 6/02/2000
* ID: $Id: fc_log.h,v 4.6 2001/07/26 14:41:33 sschremm Exp $
*/
/*
* MpiIocLogInfo_t enum
*
* These 32 bit values are used in the IOCLogInfo field of the MPI reply
* messages.
* The value is 0xabcccccc where
* a = The type of log info as per the MPI spec. Since these codes are
* all for Fibre Channel this value will always be 2.
* b = Specifies a subclass of the firmware where
* 0 = FCP Initiator
* 1 = FCP Target
* 2 = LAN
* 3 = MPI Message Layer
* 4 = FC Link
* 5 = Context Manager
* 6 = Invalid Field Offset
* 7 = State Change Info
* all others are reserved for future use
* c = A specific value within the subclass.
*
* NOTE: Any new values should be added to the end of each subclass so that the
* codes remain consistent across firmware releases.
*/
typedef enum _MpiIocLogInfoFc
{
MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,
MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */
MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */
MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */
MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */
MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,
MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
MPI_IOCLOGINFO_FC_TARGET_NO_LOGIN = 0x21000002, /* not sent because we are not logged in to the remote node */
MPI_IOCLOGINFO_FC_TARGET_DOAR_KILLED_BY_LIP = 0x21000003, /* Data Out, Auto Response, not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_DIAR_KILLED_BY_LIP = 0x21000004, /* Data In, Auto Response, not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_DIAR_MISSING_DATA = 0x21000005, /* Data In, Auto Response, missing data frames */
MPI_IOCLOGINFO_FC_TARGET_DONR_KILLED_BY_LIP = 0x21000006, /* Data Out, No Response, not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_WRSP_KILLED_BY_LIP = 0x21000007, /* Auto-response after a write not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_DINR_KILLED_BY_LIP = 0x21000008, /* Data In, No Response, not completed due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_DINR_MISSING_DATA = 0x21000009, /* Data In, No Response, missing data frames */
MPI_IOCLOGINFO_FC_TARGET_MRSP_KILLED_BY_LIP = 0x2100000a, /* Manual Response not sent due to a LIP */
MPI_IOCLOGINFO_FC_TARGET_NO_CLASS_3 = 0x2100000b, /* not sent because remote node does not support Class 3 */
MPI_IOCLOGINFO_FC_TARGET_LOGIN_NOT_VALID = 0x2100000c, /* not sent because login to remote node not validated */
MPI_IOCLOGINFO_FC_TARGET_FROM_OUTBOUND = 0x2100000e, /* cleared from the outbound queue after a logout */
MPI_IOCLOGINFO_FC_TARGET_WAITING_FOR_DATA_IN = 0x2100000f, /* cleared waiting for data after a logout */
MPI_IOCLOGINFO_FC_LAN_BASE = 0x22000000,
MPI_IOCLOGINFO_FC_LAN_TRANS_SGL_MISSING = 0x22000001, /* Transaction Context Sgl Missing */
MPI_IOCLOGINFO_FC_LAN_TRANS_WRONG_PLACE = 0x22000002, /* Transaction Context found before an EOB */
MPI_IOCLOGINFO_FC_LAN_TRANS_RES_BITS_SET = 0x22000003, /* Transaction Context value has reserved bits set */
MPI_IOCLOGINFO_FC_LAN_WRONG_SGL_FLAG = 0x22000004, /* Invalid SGL Flags */
MPI_IOCLOGINFO_FC_MSG_BASE = 0x23000000,
MPI_IOCLOGINFO_FC_LINK_BASE = 0x24000000,
MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */
MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */
MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */
MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,
MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,
MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */
} MpiIocLogInfoFc_t;
/***************************************************************************
* *
* Copyright 2003 LSI Logic Corporation. All rights reserved. *
* *
* This file is confidential and a trade secret of LSI Logic. The *
* receipt of or possession of this file does not convey any rights to *
* reproduce or disclose its contents or to manufacture, use, or sell *
* anything it may describe, in whole, or in part, without the specific *
* written consent of LSI Logic Corporation. *
* *
***************************************************************************
*
* Name: iopiIocLogInfo.h
* Title: SAS Firmware IOP Interface IOC Log Info Definitions
* Programmer: Guy Kendall
* Creation Date: September 24, 2003
*
* Version History
* ---------------
*
* Last Updated
* -------------
* Version %version: 22 %
* Date Updated %date_modified: %
* Programmer %created_by: nperucca %
*
* Date Who Description
* -------- --- -------------------------------------------------------
* 09/24/03 GWK Initial version
*
*
* Description
* ------------
* This include file contains SAS firmware interface IOC Log Info codes
*
*-------------------------------------------------------------------------
*/
#ifndef IOPI_IOCLOGINFO_H_INCLUDED
#define IOPI_IOCLOGINFO_H_INCLUDED
/****************************************************************************/
/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
/* Format: */
/* Bits 31-28: MPI_IOCLOGINFO_TYPE_SAS (3) */
/* Bits 27-24: IOC_LOGINFO_ORIGINATOR: 0=IOP, 1=PL, 2=IR */
/* Bits 23-16: LOGINFO_CODE */
/* Bits 15-0: LOGINFO_CODE Specific */
/****************************************************************************/
/****************************************************************************/
/* IOC_LOGINFO_ORIGINATOR defines */
/****************************************************************************/
#define IOC_LOGINFO_ORIGINATOR_IOP (0x00000000)
#define IOC_LOGINFO_ORIGINATOR_PL (0x01000000)
#define IOC_LOGINFO_ORIGINATOR_IR (0x02000000)
/****************************************************************************/
/* LOGINFO_CODE defines */
/****************************************************************************/
#define IOC_LOGINFO_CODE_MASK (0x00FF0000)
#define IOC_LOGINFO_CODE_SHIFT (16)
/****************************************************************************/
/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */
/****************************************************************************/
#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)
#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
/****************************************************************************/
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
/****************************************************************************/
#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)
#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)
#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)
#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)
#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)
#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)
#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)
#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)
#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
#define PL_LOGINFO_CODE_RESET (0x00110000)
#define PL_LOGINFO_CODE_ABORT (0x00120000)
#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)
#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)
#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)
#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200001) /* Error occured on SMP Read */
#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200002) /* Error occured on SMP Write */
#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200004) /* Encl Mgmt services not available for this WWID */
#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200005) /* Address Mode not suppored */
#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200006) /* Invalid Slot Number in SEP Msg */
#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200007) /* SGPIO not present/enabled */
#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200104) /* SEP stopped or sent bad chksum in Hdr */
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200105) /* SEP returned unknown scsi status */
#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200106) /* SEP returned unknown scsi status */
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x00200107) /* SEP returned bad chksum after STOP */
#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x00200108) /* SEP returned bad chksum after STOP while gettin data*/
/****************************************************************************/
/* IR LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IR */
/****************************************************************************/
#define IR_LOGINFO_CODE_UNUSED1 (0x00010000)
#define IR_LOGINFO_CODE_UNUSED2 (0x00020000)
/****************************************************************************/
/* Defines for convienence */
/****************************************************************************/
#define IOC_LOGINFO_PREFIX_IOP ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IOP)
#define IOC_LOGINFO_PREFIX_PL ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_PL)
#define IOC_LOGINFO_PREFIX_IR ((MPI_IOCLOGINFO_TYPE_SAS << MPI_IOCLOGINFO_TYPE_SHIFT) | IOC_LOGINFO_ORIGINATOR_IR)
#endif /* end of file */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Title: MPI Serial Attached SCSI structures and definitions * Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: August 19, 2004 * Creation Date: August 19, 2004
* *
* mpi_sas.h Version: 01.05.01 * mpi_sas.h Version: 01.05.02
* *
* Version History * Version History
* --------------- * ---------------
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
* Date Version Description * Date Version Description
* -------- -------- ------------------------------------------------------ * -------- -------- ------------------------------------------------------
* 08-19-04 01.05.01 Original release. * 08-19-04 01.05.01 Original release.
* 08-30-05 01.05.02 Added DeviceInfo bit for SEP.
* Added PrimFlags and Primitive field to SAS IO Unit
* Control request, and added a new operation code.
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
...@@ -51,6 +54,7 @@ ...@@ -51,6 +54,7 @@
* Values for the SAS DeviceInfo field used in SAS Device Status Change Event * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
* data and SAS IO Unit Configuration pages. * data and SAS IO Unit Configuration pages.
*/ */
#define MPI_SAS_DEVICE_INFO_SEP (0x00004000)
#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) #define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000)
#define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) #define MPI_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000)
#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) #define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
...@@ -212,20 +216,26 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST ...@@ -212,20 +216,26 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
U8 TargetID; /* 0Ch */ U8 TargetID; /* 0Ch */
U8 Bus; /* 0Dh */ U8 Bus; /* 0Dh */
U8 PhyNum; /* 0Eh */ U8 PhyNum; /* 0Eh */
U8 Reserved4; /* 0Fh */ U8 PrimFlags; /* 0Fh */
U32 Reserved5; /* 10h */ U32 Primitive; /* 10h */
U64 SASAddress; /* 14h */ U64 SASAddress; /* 14h */
U32 Reserved6; /* 1Ch */ U32 Reserved4; /* 1Ch */
} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST, } MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t; SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
/* values for the Operation field */ /* values for the Operation field */
#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01) #define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02) #define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
#define MPI_SAS_OP_PHY_LINK_RESET (0x06) #define MPI_SAS_OP_PHY_LINK_RESET (0x06)
#define MPI_SAS_OP_PHY_HARD_RESET (0x07) #define MPI_SAS_OP_PHY_HARD_RESET (0x07)
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
#define MPI_SAS_OP_MAP_CURRENT (0x09) #define MPI_SAS_OP_MAP_CURRENT (0x09)
#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
/* values for the PrimFlags field */
#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
#define MPI_SAS_PRIMFLAGS_TRIPLE (0x02)
#define MPI_SAS_PRIMFLAGS_REDUNDANT (0x01)
/* SAS IO Unit Control Reply */ /* SAS IO Unit Control Reply */
......
...@@ -148,7 +148,6 @@ static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag); ...@@ -148,7 +148,6 @@ static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int GetLanConfigPages(MPT_ADAPTER *ioc); static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc); static int GetIoUnitPage2(MPT_ADAPTER *ioc);
int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
...@@ -1232,12 +1231,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1232,12 +1231,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((KERN_INFO MYNAM dprintk((KERN_INFO MYNAM
": Not using 64 bit consistent mask\n")); ": Not using 64 bit consistent mask\n"));
ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
if (ioc == NULL) { if (ioc == NULL) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
return -ENOMEM; return -ENOMEM;
} }
memset(ioc, 0, sizeof(MPT_ADAPTER));
ioc->alloc_total = sizeof(MPT_ADAPTER); ioc->alloc_total = sizeof(MPT_ADAPTER);
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
ioc->reply_sz = MPT_REPLY_FRAME_SIZE; ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
...@@ -1245,6 +1243,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1245,6 +1243,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->pcidev = pdev; ioc->pcidev = pdev;
ioc->diagPending = 0; ioc->diagPending = 0;
spin_lock_init(&ioc->diagLock); spin_lock_init(&ioc->diagLock);
spin_lock_init(&ioc->fc_rescan_work_lock);
spin_lock_init(&ioc->fc_rport_lock);
spin_lock_init(&ioc->initializing_hba_lock); spin_lock_init(&ioc->initializing_hba_lock);
/* Initialize the event logging. /* Initialize the event logging.
...@@ -1268,6 +1268,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1268,6 +1268,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
*/ */
INIT_LIST_HEAD(&ioc->configQ); INIT_LIST_HEAD(&ioc->configQ);
/* Initialize the fc rport list head.
*/
INIT_LIST_HEAD(&ioc->fc_rports);
/* Find lookup slot. */ /* Find lookup slot. */
INIT_LIST_HEAD(&ioc->list); INIT_LIST_HEAD(&ioc->list);
ioc->id = mpt_ids++; ioc->id = mpt_ids++;
...@@ -1374,6 +1378,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1374,6 +1378,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->bus_type = FC; ioc->bus_type = FC;
ioc->errata_flag_1064 = 1; ioc->errata_flag_1064 = 1;
} }
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
ioc->prod_name = "LSIFC949E";
ioc->bus_type = FC;
}
else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) { else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
ioc->prod_name = "LSI53C1030"; ioc->prod_name = "LSI53C1030";
ioc->bus_type = SPI; ioc->bus_type = SPI;
...@@ -1622,7 +1630,7 @@ mpt_resume(struct pci_dev *pdev) ...@@ -1622,7 +1630,7 @@ mpt_resume(struct pci_dev *pdev)
pci_enable_device(pdev); pci_enable_device(pdev);
/* enable interrupts */ /* enable interrupts */
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
ioc->active = 1; ioc->active = 1;
/* F/W not running */ /* F/W not running */
...@@ -1715,7 +1723,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1715,7 +1723,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name)); ioc->alt_ioc->name));
CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
ioc->alt_ioc->active = 1; ioc->alt_ioc->active = 1;
} }
...@@ -1831,7 +1839,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1831,7 +1839,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
if (ret == 0) { if (ret == 0) {
/* Enable! (reply interrupt) */ /* Enable! (reply interrupt) */
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM)); CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
ioc->active = 1; ioc->active = 1;
} }
...@@ -1839,7 +1847,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1839,7 +1847,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
/* (re)Enable alt-IOC! (reply interrupt) */ /* (re)Enable alt-IOC! (reply interrupt) */
dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n", dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
ioc->alt_ioc->name)); ioc->alt_ioc->name));
CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM)); CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
ioc->alt_ioc->active = 1; ioc->alt_ioc->active = 1;
} }
...@@ -1880,7 +1888,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) ...@@ -1880,7 +1888,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* (FCPortPage0_t stuff) * (FCPortPage0_t stuff)
*/ */
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
(void) GetFcPortPage0(ioc, ii); (void) mptbase_GetFcPortPage0(ioc, ii);
} }
if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
...@@ -4199,7 +4207,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) ...@@ -4199,7 +4207,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* GetFcPortPage0 - Fetch FCPort config Page0. * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
* @ioc: Pointer to MPT_ADAPTER structure * @ioc: Pointer to MPT_ADAPTER structure
* @portnum: IOC Port number * @portnum: IOC Port number
* *
...@@ -4209,8 +4217,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc) ...@@ -4209,8 +4217,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
* -EAGAIN if no msg frames currently available * -EAGAIN if no msg frames currently available
* -EFAULT for non-successful reply or no reply (timeout) * -EFAULT for non-successful reply or no reply (timeout)
*/ */
static int int
GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
{ {
ConfigPageHeader_t hdr; ConfigPageHeader_t hdr;
CONFIGPARMS cfg; CONFIGPARMS cfg;
...@@ -4220,6 +4228,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) ...@@ -4220,6 +4228,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
int data_sz; int data_sz;
int copy_sz; int copy_sz;
int rc; int rc;
int count = 400;
/* Get FCPort Page 0 header */ /* Get FCPort Page 0 header */
hdr.PageVersion = 0; hdr.PageVersion = 0;
...@@ -4243,6 +4253,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) ...@@ -4243,6 +4253,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
rc = -ENOMEM; rc = -ENOMEM;
ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
if (ppage0_alloc) { if (ppage0_alloc) {
try_again:
memset((u8 *)ppage0_alloc, 0, data_sz); memset((u8 *)ppage0_alloc, 0, data_sz);
cfg.physAddr = page0_dma; cfg.physAddr = page0_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
...@@ -4274,6 +4286,19 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum) ...@@ -4274,6 +4286,19 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount); pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators); pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
/*
* if still doing discovery,
* hang loose a while until finished
*/
if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
if (count-- > 0) {
msleep_interruptible(100);
goto try_again;
}
printk(MYIOC_s_INFO_FMT "Firmware discovery not"
" complete.\n",
ioc->name);
}
} }
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
...@@ -6358,6 +6383,7 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory); ...@@ -6358,6 +6383,7 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory); EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation); EXPORT_SYMBOL(mptbase_sas_persist_operation);
EXPORT_SYMBOL(mpt_alt_ioc_wait); EXPORT_SYMBOL(mpt_alt_ioc_wait);
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
...@@ -76,8 +76,8 @@ ...@@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.03.05" #define MPT_LINUX_VERSION_COMMON "3.03.06"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -413,7 +413,7 @@ typedef struct _MPT_IOCTL { ...@@ -413,7 +413,7 @@ typedef struct _MPT_IOCTL {
u8 status; /* current command status */ u8 status; /* current command status */
u8 reset; /* 1 if bus reset allowed */ u8 reset; /* 1 if bus reset allowed */
u8 target; /* target for reset */ u8 target; /* target for reset */
struct semaphore sem_ioc; struct mutex ioctl_mutex;
} MPT_IOCTL; } MPT_IOCTL;
#define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */ #define MPT_SAS_MGMT_STATUS_RF_VALID 0x02 /* The Reply Frame is VALID */
...@@ -421,7 +421,7 @@ typedef struct _MPT_IOCTL { ...@@ -421,7 +421,7 @@ typedef struct _MPT_IOCTL {
#define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */ #define MPT_SAS_MGMT_STATUS_TM_FAILED 0x40 /* User TM request failed */
typedef struct _MPT_SAS_MGMT { typedef struct _MPT_SAS_MGMT {
struct semaphore mutex; struct mutex mutex;
struct completion done; struct completion done;
u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */ u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
u8 status; /* current command status */ u8 status; /* current command status */
...@@ -499,6 +499,22 @@ typedef struct _RaidCfgData { ...@@ -499,6 +499,22 @@ typedef struct _RaidCfgData {
int isRaid; /* bit field, 1 if RAID */ int isRaid; /* bit field, 1 if RAID */
}RaidCfgData; }RaidCfgData;
#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */
/*
* data allocated for each fc rport device
*/
struct mptfc_rport_info
{
struct list_head list;
struct fc_rport *rport;
VirtDevice *vdev;
FCDevicePage0_t pg0;
u8 flags;
};
/* /*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
*/ */
...@@ -612,7 +628,16 @@ typedef struct _MPT_ADAPTER ...@@ -612,7 +628,16 @@ typedef struct _MPT_ADAPTER
struct list_head list; struct list_head list;
struct net_device *netdev; struct net_device *netdev;
struct list_head sas_topology; struct list_head sas_topology;
struct mutex sas_topology_mutex;
MPT_SAS_MGMT sas_mgmt; MPT_SAS_MGMT sas_mgmt;
int num_ports;
struct list_head fc_rports;
spinlock_t fc_rport_lock; /* list and ri flags */
spinlock_t fc_rescan_work_lock;
int fc_rescan_work_count;
struct work_struct fc_rescan_work;
} MPT_ADAPTER; } MPT_ADAPTER;
/* /*
...@@ -999,6 +1024,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); ...@@ -999,6 +1024,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc); extern int mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
/* /*
......
...@@ -177,10 +177,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) ...@@ -177,10 +177,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock)); dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
if (nonblock) { if (nonblock) {
if (down_trylock(&ioc->ioctl->sem_ioc)) if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))
rc = -EAGAIN; rc = -EAGAIN;
} else { } else {
if (down_interruptible(&ioc->ioctl->sem_ioc)) if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))
rc = -ERESTARTSYS; rc = -ERESTARTSYS;
} }
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc)); dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
...@@ -557,7 +557,7 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -557,7 +557,7 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
else else
ret = -EINVAL; ret = -EINVAL;
up(&iocp->ioctl->sem_ioc); mutex_unlock(&iocp->ioctl->ioctl_mutex);
return ret; return ret;
} }
...@@ -2619,7 +2619,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd, ...@@ -2619,7 +2619,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
up(&iocp->ioctl->sem_ioc); mutex_unlock(&iocp->ioctl->ioctl_mutex);
return ret; return ret;
} }
...@@ -2673,7 +2673,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd, ...@@ -2673,7 +2673,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
*/ */
ret = mptctl_do_mpt_command (karg, &uarg->MF); ret = mptctl_do_mpt_command (karg, &uarg->MF);
up(&iocp->ioctl->sem_ioc); mutex_unlock(&iocp->ioctl->ioctl_mutex);
return ret; return ret;
} }
...@@ -2743,7 +2743,7 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2743,7 +2743,7 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
memset(mem, 0, sz); memset(mem, 0, sz);
ioc->ioctl = (MPT_IOCTL *) mem; ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc; ioc->ioctl->ioc = ioc;
sema_init(&ioc->ioctl->sem_ioc, 1); mutex_init(&ioc->ioctl->ioctl_mutex);
return 0; return 0;
out_fail: out_fail:
......
...@@ -55,12 +55,14 @@ ...@@ -55,12 +55,14 @@
#include <linux/reboot.h> /* notifier code */ #include <linux/reboot.h> /* notifier code */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/sort.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport_fc.h>
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
...@@ -79,19 +81,34 @@ static int mpt_pq_filter = 0; ...@@ -79,19 +81,34 @@ static int mpt_pq_filter = 0;
module_param(mpt_pq_filter, int, 0); module_param(mpt_pq_filter, int, 0);
MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
#define MPTFC_DEV_LOSS_TMO (60)
static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
module_param(mptfc_dev_loss_tmo, int, 0);
MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
" transport to wait for an rport to "
" return following a device loss event."
" Default=60.");
static int mptfcDoneCtx = -1; static int mptfcDoneCtx = -1;
static int mptfcTaskCtx = -1; static int mptfcTaskCtx = -1;
static int mptfcInternalCtx = -1; /* Used only for internal commands */ static int mptfcInternalCtx = -1; /* Used only for internal commands */
int mptfc_slave_alloc(struct scsi_device *device);
static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
void (*done)(struct scsi_cmnd *));
static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
static void __devexit mptfc_remove(struct pci_dev *pdev);
static struct scsi_host_template mptfc_driver_template = { static struct scsi_host_template mptfc_driver_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.proc_name = "mptfc", .proc_name = "mptfc",
.proc_info = mptscsih_proc_info, .proc_info = mptscsih_proc_info,
.name = "MPT FC Host", .name = "MPT FC Host",
.info = mptscsih_info, .info = mptscsih_info,
.queuecommand = mptscsih_qcmd, .queuecommand = mptfc_qcmd,
.target_alloc = mptscsih_target_alloc, .target_alloc = mptscsih_target_alloc,
.slave_alloc = mptscsih_slave_alloc, .slave_alloc = mptfc_slave_alloc,
.slave_configure = mptscsih_slave_configure, .slave_configure = mptscsih_slave_configure,
.target_destroy = mptscsih_target_destroy, .target_destroy = mptscsih_target_destroy,
.slave_destroy = mptscsih_slave_destroy, .slave_destroy = mptscsih_slave_destroy,
...@@ -128,19 +145,478 @@ static struct pci_device_id mptfc_pci_table[] = { ...@@ -128,19 +145,478 @@ static struct pci_device_id mptfc_pci_table[] = {
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */ {0} /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(pci, mptfc_pci_table); MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static struct scsi_transport_template *mptfc_transport_template = NULL;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
struct fc_function_template mptfc_transport_functions = {
.dd_fcrport_size = 8,
.show_host_node_name = 1,
.show_host_port_name = 1,
.show_host_supported_classes = 1,
.show_host_port_id = 1,
.show_rport_supported_classes = 1,
.show_starget_node_name = 1,
.show_starget_port_name = 1,
.show_starget_port_id = 1,
.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
.show_rport_dev_loss_tmo = 1,
};
/* FIXME! values controlling firmware RESCAN event
* need to be set low to allow dev_loss_tmo to
* work as expected. Currently, firmware doesn't
* notify driver of RESCAN event until some number
* of seconds elapse. This value can be set via
* lsiutil.
*/
static void
mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
{
if (timeout > 0)
rport->dev_loss_tmo = timeout;
else
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
}
static int
mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
{
FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
return 0;
if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
return -1;
return 1;
}
if ((*aa)->CurrentBus < (*bb)->CurrentBus)
return -1;
return 1;
}
static int
mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
{
ConfigPageHeader_t hdr;
CONFIGPARMS cfg;
FCDevicePage0_t *ppage0_alloc, *fc;
dma_addr_t page0_dma;
int data_sz;
int ii;
FCDevicePage0_t *p0_array=NULL, *p_p0;
FCDevicePage0_t **pp0_array=NULL, **p_pp0;
int rc = -ENOMEM;
U32 port_id = 0xffffff;
int num_targ = 0;
int max_bus = ioc->facts.MaxBuses;
int max_targ = ioc->facts.MaxDevices;
if (max_bus == 0 || max_targ == 0)
goto out;
data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
if (!p0_array)
goto out;
data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
if (!pp0_array)
goto out;
do {
/* Get FC Device Page 0 header */
hdr.PageVersion = 0;
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
cfg.pageAddr = port_id;
cfg.timeout = 0;
if ((rc = mpt_config(ioc, &cfg)) != 0)
break;
if (hdr.PageLength <= 0)
break;
data_sz = hdr.PageLength * 4;
ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
&page0_dma);
rc = -ENOMEM;
if (!ppage0_alloc)
break;
cfg.physAddr = page0_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
if ((rc = mpt_config(ioc, &cfg)) == 0) {
ppage0_alloc->PortIdentifier =
le32_to_cpu(ppage0_alloc->PortIdentifier);
ppage0_alloc->WWNN.Low =
le32_to_cpu(ppage0_alloc->WWNN.Low);
ppage0_alloc->WWNN.High =
le32_to_cpu(ppage0_alloc->WWNN.High);
ppage0_alloc->WWPN.Low =
le32_to_cpu(ppage0_alloc->WWPN.Low);
ppage0_alloc->WWPN.High =
le32_to_cpu(ppage0_alloc->WWPN.High);
ppage0_alloc->BBCredit =
le16_to_cpu(ppage0_alloc->BBCredit);
ppage0_alloc->MaxRxFrameSize =
le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
port_id = ppage0_alloc->PortIdentifier;
num_targ++;
*p_p0 = *ppage0_alloc; /* save data */
*p_pp0++ = p_p0++; /* save addr */
}
pci_free_consistent(ioc->pcidev, data_sz,
(u8 *) ppage0_alloc, page0_dma);
if (rc != 0)
break;
} while (port_id <= 0xff0000);
if (num_targ) {
/* sort array */
if (num_targ > 1)
sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
mptfc_FcDevPage0_cmp_func, NULL);
/* call caller's func for each targ */
for (ii = 0; ii < num_targ; ii++) {
fc = *(pp0_array+ii);
func(ioc, ioc_port, fc);
}
}
out:
if (pp0_array)
kfree(pp0_array);
if (p0_array)
kfree(p0_array);
return rc;
}
static int
mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
{
/* not currently usable */
if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
return -1;
if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
return -1;
if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
return -1;
/*
* board data structure already normalized to platform endianness
* shifted to avoid unaligned access on 64 bit architecture
*/
rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
rid->port_id = pg0->PortIdentifier;
rid->roles = FC_RPORT_ROLE_UNKNOWN;
rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
return 0;
}
static void
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
{
struct fc_rport_identifiers rport_ids;
struct fc_rport *rport;
struct mptfc_rport_info *ri;
int match = 0;
u64 port_name;
unsigned long flags;
if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
return;
/* scan list looking for a match */
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
list_for_each_entry(ri, &ioc->fc_rports, list) {
port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
if (port_name == rport_ids.port_name) { /* match */
list_move_tail(&ri->list, &ioc->fc_rports);
match = 1;
break;
}
}
if (!match) { /* allocate one */
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
if (!ri)
return;
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
list_add_tail(&ri->list, &ioc->fc_rports);
}
ri->pg0 = *pg0; /* add/update pg0 data */
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
if (rport) {
if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
ri->vdev = NULL;
ri->rport = rport;
*((struct mptfc_rport_info **)rport->dd_data) = ri;
}
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
/*
* if already mapped, remap here. If not mapped,
* slave_alloc will allocate vdev and map
*/
if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
ri->vdev->target_id = ri->pg0.CurrentTargetID;
ri->vdev->bus_id = ri->pg0.CurrentBus;
ri->vdev->vtarget->target_id = ri->vdev->target_id;
ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
}
#ifdef MPT_DEBUG
printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
"rport tid %d, tmo %d\n",
ioc->sh->host_no,
pg0->PortIdentifier,
pg0->WWNN,
pg0->WWPN,
pg0->CurrentTargetID,
ri->rport->scsi_target_id,
ri->rport->dev_loss_tmo);
#endif
} else {
list_del(&ri->list);
kfree(ri);
ri = NULL;
}
}
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
}
/* /*
* mptfc_probe - Installs scsi devices per bus. * OS entry point to allow host driver to alloc memory
* @pdev: Pointer to pci_dev structure * for each scsi device. Called once per device the bus scan.
* * Return non-zero if allocation fails.
* Returns 0 for success, non-zero for failure. * Init memory once per LUN.
*
*/ */
int
mptfc_slave_alloc(struct scsi_device *sdev)
{
MPT_SCSI_HOST *hd;
VirtTarget *vtarget;
VirtDevice *vdev;
struct scsi_target *starget;
struct fc_rport *rport;
struct mptfc_rport_info *ri;
unsigned long flags;
rport = starget_to_rport(scsi_target(sdev));
if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice));
return -ENOMEM;
}
memset(vdev, 0, sizeof(VirtDevice));
spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) {
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
kfree(vdev);
return -ENODEV;
}
sdev->hostdata = vdev;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
if (vtarget->num_luns == 0) {
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
MPT_TARGET_FLAGS_VALID_INQUIRY;
hd->Targets[sdev->id] = vtarget;
}
vtarget->target_id = vdev->target_id;
vtarget->bus_id = vdev->bus_id;
vdev->vtarget = vtarget;
vdev->ioc_id = hd->ioc->id;
vdev->lun = sdev->lun;
vdev->target_id = ri->pg0.CurrentTargetID;
vdev->bus_id = ri->pg0.CurrentBus;
ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
ri->vdev = vdev;
spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
vtarget->num_luns++;
#ifdef MPT_DEBUG
printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
"CurrentTargetID %d, %x %llx %llx\n",
sdev->host->host_no,
vtarget->num_luns,
sdev->id, ri->pg0.CurrentTargetID,
ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN);
#endif
return 0;
}
static int
mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
int err;
err = fc_remote_port_chkready(rport);
if (unlikely(err)) {
SCpnt->result = err;
done(SCpnt);
return 0;
}
return mptscsih_qcmd(SCpnt,done);
}
static void
mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
{
unsigned class = 0, cos = 0;
/* don't know what to do as only one scsi (fc) host was allocated */
if (portnum != 0)
return;
class = ioc->fc_port_page0[portnum].SupportedServiceClass;
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
cos |= FC_COS_CLASS1;
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
cos |= FC_COS_CLASS2;
if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
cos |= FC_COS_CLASS3;
fc_host_node_name(ioc->sh) =
(u64)ioc->fc_port_page0[portnum].WWNN.High << 32
| (u64)ioc->fc_port_page0[portnum].WWNN.Low;
fc_host_port_name(ioc->sh) =
(u64)ioc->fc_port_page0[portnum].WWPN.High << 32
| (u64)ioc->fc_port_page0[portnum].WWPN.Low;
fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
fc_host_supported_classes(ioc->sh) = cos;
fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
}
static void
mptfc_rescan_devices(void *arg)
{
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
int ii;
int work_to_do;
unsigned long flags;
struct mptfc_rport_info *ri;
do {
/* start by tagging all ports as missing */
spin_lock_irqsave(&ioc->fc_rport_lock,flags);
list_for_each_entry(ri, &ioc->fc_rports, list) {
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
}
}
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
/*
* now rescan devices known to adapter,
* will reregister existing rports
*/
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
(void) mptbase_GetFcPortPage0(ioc, ii);
mptfc_init_host_attr(ioc,ii); /* refresh */
mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
}
/* delete devices still missing */
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
list_for_each_entry(ri, &ioc->fc_rports, list) {
/* if newly missing, delete it */
if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
MPT_RPORT_INFO_FLAGS_MISSING))
== (MPT_RPORT_INFO_FLAGS_REGISTERED |
MPT_RPORT_INFO_FLAGS_MISSING)) {
ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
MPT_RPORT_INFO_FLAGS_MISSING);
fc_remote_port_delete(ri->rport);
/*
* remote port not really deleted 'cause
* binding is by WWPN and driver only
* registers FCP_TARGETs
*/
#ifdef MPT_DEBUG
printk ("mptfc_rescan.%d: %llx deleted\n",
ioc->sh->host_no, ri->pg0.WWPN);
#endif
}
}
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
/*
* allow multiple passes as target state
* might have changed during scan
*/
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
if (ioc->fc_rescan_work_count > 2) /* only need one more */
ioc->fc_rescan_work_count = 2;
work_to_do = --ioc->fc_rescan_work_count;
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
} while (work_to_do);
}
static int static int
mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
...@@ -148,17 +624,16 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -148,17 +624,16 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
unsigned long flags; unsigned long flags;
int sz, ii; int ii;
int numSGE = 0; int numSGE = 0;
int scale; int scale;
int ioc_cap; int ioc_cap;
u8 *mem;
int error=0; int error=0;
int r; int r;
if ((r = mpt_attach(pdev,id)) != 0) if ((r = mpt_attach(pdev,id)) != 0)
return r; return r;
ioc = pci_get_drvdata(pdev); ioc = pci_get_drvdata(pdev);
ioc->DoneCtx = mptfcDoneCtx; ioc->DoneCtx = mptfcDoneCtx;
ioc->TaskCtx = mptfcTaskCtx; ioc->TaskCtx = mptfcTaskCtx;
...@@ -194,7 +669,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -194,7 +669,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc); ioc->name, ioc);
return 0; return -ENODEV;
} }
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
...@@ -207,6 +682,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -207,6 +682,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_mptfc_probe; goto out_mptfc_probe;
} }
INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
/* Attach the SCSI Host to the IOC structure /* Attach the SCSI Host to the IOC structure
...@@ -268,36 +745,27 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -268,36 +745,27 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
sz = ioc->req_depth * sizeof(void *); hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
mem = kmalloc(sz, GFP_ATOMIC); if (!hd->ScsiLookup) {
if (mem == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptfc_probe; goto out_mptfc_probe;
} }
memset(mem, 0, sz); dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
hd->ScsiLookup = (struct scsi_cmnd **) mem; ioc->name, hd->ScsiLookup));
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
ioc->name, hd->ScsiLookup, sz));
/* Allocate memory for the device structures. /* Allocate memory for the device structures.
* A non-Null pointer at an offset * A non-Null pointer at an offset
* indicates a device exists. * indicates a device exists.
* max_id = 1 + maximum id (hosts.h) * max_id = 1 + maximum id (hosts.h)
*/ */
sz = sh->max_id * sizeof(void *); hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
mem = kmalloc(sz, GFP_ATOMIC); if (!hd->Targets) {
if (mem == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptfc_probe; goto out_mptfc_probe;
} }
memset(mem, 0, sz); dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
hd->Targets = (VirtTarget **) mem;
dprintk((KERN_INFO
" vdev @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags /* Clear the TM flags
*/ */
...@@ -332,6 +800,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -332,6 +800,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->scandv_wait_done = 0; hd->scandv_wait_done = 0;
hd->last_queue_full = 0; hd->last_queue_full = 0;
sh->transportt = mptfc_transport_template;
error = scsi_add_host (sh, &ioc->pcidev->dev); error = scsi_add_host (sh, &ioc->pcidev->dev);
if(error) { if(error) {
dprintk((KERN_ERR MYNAM dprintk((KERN_ERR MYNAM
...@@ -339,7 +808,11 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -339,7 +808,11 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_mptfc_probe; goto out_mptfc_probe;
} }
scsi_scan_host(sh); for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
mptfc_init_host_attr(ioc,ii);
mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
}
return 0; return 0;
out_mptfc_probe: out_mptfc_probe:
...@@ -352,7 +825,7 @@ static struct pci_driver mptfc_driver = { ...@@ -352,7 +825,7 @@ static struct pci_driver mptfc_driver = {
.name = "mptfc", .name = "mptfc",
.id_table = mptfc_pci_table, .id_table = mptfc_pci_table,
.probe = mptfc_probe, .probe = mptfc_probe,
.remove = __devexit_p(mptscsih_remove), .remove = __devexit_p(mptfc_remove),
.shutdown = mptscsih_shutdown, .shutdown = mptscsih_shutdown,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = mptscsih_suspend, .suspend = mptscsih_suspend,
...@@ -370,9 +843,20 @@ static struct pci_driver mptfc_driver = { ...@@ -370,9 +843,20 @@ static struct pci_driver mptfc_driver = {
static int __init static int __init
mptfc_init(void) mptfc_init(void)
{ {
int error;
show_mptmod_ver(my_NAME, my_VERSION); show_mptmod_ver(my_NAME, my_VERSION);
/* sanity check module parameter */
if (mptfc_dev_loss_tmo == 0)
mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
mptfc_transport_template =
fc_attach_transport(&mptfc_transport_functions);
if (!mptfc_transport_template)
return -ENODEV;
mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
...@@ -387,7 +871,33 @@ mptfc_init(void) ...@@ -387,7 +871,33 @@ mptfc_init(void)
": Registered for IOC reset notifications\n")); ": Registered for IOC reset notifications\n"));
} }
return pci_register_driver(&mptfc_driver); error = pci_register_driver(&mptfc_driver);
if (error) {
fc_release_transport(mptfc_transport_template);
}
return error;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptfc_remove - Removed fc infrastructure for devices
* @pdev: Pointer to pci_dev structure
*
*/
static void __devexit mptfc_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct mptfc_rport_info *p, *n;
fc_remove_host(ioc->sh);
list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
list_del(&p->list);
kfree(p);
}
mptscsih_remove(pdev);
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -400,7 +910,8 @@ static void __exit ...@@ -400,7 +910,8 @@ static void __exit
mptfc_exit(void) mptfc_exit(void)
{ {
pci_unregister_driver(&mptfc_driver); pci_unregister_driver(&mptfc_driver);
fc_release_transport(mptfc_transport_template);
mpt_reset_deregister(mptfcDoneCtx); mpt_reset_deregister(mptfcDoneCtx);
dprintk((KERN_INFO MYNAM dprintk((KERN_INFO MYNAM
": Deregistered for IOC reset notifications\n")); ": Deregistered for IOC reset notifications\n"));
......
...@@ -411,14 +411,12 @@ mpt_lan_open(struct net_device *dev) ...@@ -411,14 +411,12 @@ mpt_lan_open(struct net_device *dev)
goto out; goto out;
priv->mpt_txfidx_tail = -1; priv->mpt_txfidx_tail = -1;
priv->SendCtl = kmalloc(priv->tx_max_out * sizeof(struct BufferControl), priv->SendCtl = kcalloc(priv->tx_max_out, sizeof(struct BufferControl),
GFP_KERNEL); GFP_KERNEL);
if (priv->SendCtl == NULL) if (priv->SendCtl == NULL)
goto out_mpt_txfidx; goto out_mpt_txfidx;
for (i = 0; i < priv->tx_max_out; i++) { for (i = 0; i < priv->tx_max_out; i++)
memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));
priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i; priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
}
dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n")); dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
...@@ -428,15 +426,13 @@ mpt_lan_open(struct net_device *dev) ...@@ -428,15 +426,13 @@ mpt_lan_open(struct net_device *dev)
goto out_SendCtl; goto out_SendCtl;
priv->mpt_rxfidx_tail = -1; priv->mpt_rxfidx_tail = -1;
priv->RcvCtl = kmalloc(priv->max_buckets_out * priv->RcvCtl = kcalloc(priv->max_buckets_out,
sizeof(struct BufferControl), sizeof(struct BufferControl),
GFP_KERNEL); GFP_KERNEL);
if (priv->RcvCtl == NULL) if (priv->RcvCtl == NULL)
goto out_mpt_rxfidx; goto out_mpt_rxfidx;
for (i = 0; i < priv->max_buckets_out; i++) { for (i = 0; i < priv->max_buckets_out; i++)
memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
}
/**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - ")); /**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
/**/ for (i = 0; i < priv->tx_max_out; i++) /**/ for (i = 0; i < priv->tx_max_out; i++)
......
此差异已折叠。
...@@ -893,6 +893,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) ...@@ -893,6 +893,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
* when a lun is disable by mid-layer. * when a lun is disable by mid-layer.
* Do NOT access the referenced scsi_cmnd structure or * Do NOT access the referenced scsi_cmnd structure or
* members. Will cause either a paging or NULL ptr error. * members. Will cause either a paging or NULL ptr error.
* (BUT, BUT, BUT, the code does reference it! - mdr)
* @hd: Pointer to a SCSI HOST structure * @hd: Pointer to a SCSI HOST structure
* @vdevice: per device private data * @vdevice: per device private data
* *
...@@ -2162,10 +2163,9 @@ mptscsih_target_alloc(struct scsi_target *starget) ...@@ -2162,10 +2163,9 @@ mptscsih_target_alloc(struct scsi_target *starget)
{ {
VirtTarget *vtarget; VirtTarget *vtarget;
vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL); vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
if (!vtarget) if (!vtarget)
return -ENOMEM; return -ENOMEM;
memset(vtarget, 0, sizeof(VirtTarget));
starget->hostdata = vtarget; starget->hostdata = vtarget;
return 0; return 0;
} }
...@@ -2185,14 +2185,13 @@ mptscsih_slave_alloc(struct scsi_device *sdev) ...@@ -2185,14 +2185,13 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
VirtDevice *vdev; VirtDevice *vdev;
struct scsi_target *starget; struct scsi_target *starget;
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdev) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice)); hd->ioc->name, sizeof(VirtDevice));
return -ENOMEM; return -ENOMEM;
} }
memset(vdev, 0, sizeof(VirtDevice));
vdev->ioc_id = hd->ioc->id; vdev->ioc_id = hd->ioc->id;
vdev->target_id = sdev->id; vdev->target_id = sdev->id;
vdev->bus_id = sdev->channel; vdev->bus_id = sdev->channel;
...@@ -2559,13 +2558,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2559,13 +2558,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
hd->cmdPtr = NULL; hd->cmdPtr = NULL;
} }
/* 7. Set flag to force DV and re-read IOC Page 3 /* 7. SPI: Set flag to force DV and re-read IOC Page 3
*/ */
if (ioc->bus_type == SPI) { if (ioc->bus_type == SPI) {
ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
ddvtprintk(("Set reload IOC Pg3 Flag\n")); ddvtprintk(("Set reload IOC Pg3 Flag\n"));
} }
/* 7. FC: Rescan for blocked rports which might have returned.
*/
else if (ioc->bus_type == FC) {
int work_count;
unsigned long flags;
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
work_count = ++ioc->fc_rescan_work_count;
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
if (work_count == 1)
schedule_work(&ioc->fc_rescan_work);
}
dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
} }
...@@ -2589,6 +2600,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2589,6 +2600,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
int work_count;
unsigned long flags;
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event)); ioc->name, event));
...@@ -2610,11 +2623,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) ...@@ -2610,11 +2623,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/* FIXME! */ /* FIXME! */
break; break;
case MPI_EVENT_RESCAN: /* 06 */
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
work_count = ++ioc->fc_rescan_work_count;
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
if (work_count == 1)
schedule_work(&ioc->fc_rescan_work);
break;
/* /*
* CHECKME! Don't think we need to do * CHECKME! Don't think we need to do
* anything for these, but... * anything for these, but...
*/ */
case MPI_EVENT_RESCAN: /* 06 */
case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */ case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */ case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
/* /*
...@@ -3952,8 +3972,6 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice) ...@@ -3952,8 +3972,6 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
mptscsih_do_cmd(hd, &iocmd); mptscsih_do_cmd(hd, &iocmd);
} }
/* Search IOC page 3 to determine if this is hidden physical disk
*/
/* Search IOC page 3 to determine if this is hidden physical disk /* Search IOC page 3 to determine if this is hidden physical disk
*/ */
static int static int
......
...@@ -158,11 +158,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -158,11 +158,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
unsigned long flags; unsigned long flags;
int sz, ii; int ii;
int numSGE = 0; int numSGE = 0;
int scale; int scale;
int ioc_cap; int ioc_cap;
u8 *mem;
int error=0; int error=0;
int r; int r;
...@@ -288,36 +287,27 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -288,36 +287,27 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
sz = ioc->req_depth * sizeof(void *); hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
mem = kmalloc(sz, GFP_ATOMIC); if (!hd->ScsiLookup) {
if (mem == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptspi_probe; goto out_mptspi_probe;
} }
memset(mem, 0, sz); dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
hd->ScsiLookup = (struct scsi_cmnd **) mem; ioc->name, hd->ScsiLookup));
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
ioc->name, hd->ScsiLookup, sz));
/* Allocate memory for the device structures. /* Allocate memory for the device structures.
* A non-Null pointer at an offset * A non-Null pointer at an offset
* indicates a device exists. * indicates a device exists.
* max_id = 1 + maximum id (hosts.h) * max_id = 1 + maximum id (hosts.h)
*/ */
sz = sh->max_id * sizeof(void *); hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
mem = kmalloc(sz, GFP_ATOMIC); if (!hd->Targets) {
if (mem == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptspi_probe; goto out_mptspi_probe;
} }
memset(mem, 0, sz); dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
hd->Targets = (VirtTarget **) mem;
dprintk((KERN_INFO
" vdev @ %p, sz=%d\n", hd->Targets, sz));
/* Clear the TM flags /* Clear the TM flags
*/ */
......
...@@ -88,11 +88,6 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) ...@@ -88,11 +88,6 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int i; int i;
if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
printk(KERN_ERR "%s: device already claimed\n", c->name);
return -ENODEV;
}
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
/* Skip I/O spaces */ /* Skip I/O spaces */
if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
...@@ -319,6 +314,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, ...@@ -319,6 +314,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
return rc; return rc;
} }
if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
printk(KERN_ERR "i2o: device already claimed\n");
return -ENODEV;
}
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
pci_name(pdev)); pci_name(pdev));
......
...@@ -1125,6 +1125,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter) ...@@ -1125,6 +1125,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
zfcp_free_low_mem_buffers(adapter); zfcp_free_low_mem_buffers(adapter);
/* free memory of adapter data structure and queues */ /* free memory of adapter data structure and queues */
zfcp_qdio_free_queues(adapter); zfcp_qdio_free_queues(adapter);
kfree(adapter->fc_stats);
kfree(adapter->stats_reset_data);
ZFCP_LOG_TRACE("freeing adapter structure\n"); ZFCP_LOG_TRACE("freeing adapter structure\n");
kfree(adapter); kfree(adapter);
out: out:
......
...@@ -921,7 +921,6 @@ struct zfcp_adapter { ...@@ -921,7 +921,6 @@ struct zfcp_adapter {
u32 physical_s_id; /* local FC port ID */ u32 physical_s_id; /* local FC port ID */
struct ccw_device *ccw_device; /* S/390 ccw device */ struct ccw_device *ccw_device; /* S/390 ccw device */
u8 fc_service_class; u8 fc_service_class;
u32 fc_topology; /* FC topology */
u32 hydra_version; /* Hydra version */ u32 hydra_version; /* Hydra version */
u32 fsf_lic_version; u32 fsf_lic_version;
u32 adapter_features; /* FCP channel features */ u32 adapter_features; /* FCP channel features */
...@@ -978,6 +977,9 @@ struct zfcp_adapter { ...@@ -978,6 +977,9 @@ struct zfcp_adapter {
struct zfcp_adapter_mempool pool; /* Adapter memory pools */ struct zfcp_adapter_mempool pool; /* Adapter memory pools */
struct qdio_initialize qdio_init_data; /* for qdio_establish */ struct qdio_initialize qdio_init_data; /* for qdio_establish */
struct device generic_services; /* directory for WKA ports */ struct device generic_services; /* directory for WKA ports */
struct fc_host_statistics *fc_stats;
struct fsf_qtcb_bottom_port *stats_reset_data;
unsigned long stats_reset;
}; };
/* /*
......
...@@ -2613,7 +2613,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) ...@@ -2613,7 +2613,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
case ZFCP_ERP_STEP_UNINITIALIZED: case ZFCP_ERP_STEP_UNINITIALIZED:
case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
case ZFCP_ERP_STEP_PORT_CLOSING: case ZFCP_ERP_STEP_PORT_CLOSING:
if (adapter->fc_topology == FSF_TOPO_P2P) { if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) {
if (port->wwpn != adapter->peer_wwpn) { if (port->wwpn != adapter->peer_wwpn) {
ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx " ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
"on adapter %s.\nPeer WWPN " "on adapter %s.\nPeer WWPN "
......
...@@ -964,6 +964,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) ...@@ -964,6 +964,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
| ZFCP_STATUS_COMMON_ERP_FAILED); | ZFCP_STATUS_COMMON_ERP_FAILED);
break; break;
case FSF_STATUS_READ_NOTIFICATION_LOST:
ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: "
"adapter %s%s%s%s%s%s%s%s%s\n",
zfcp_get_busid_by_adapter(adapter),
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_INCOMING_ELS) ?
", incoming ELS" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_SENSE_DATA) ?
", sense data" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_LINK_STATUS) ?
", link status change" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_PORT_CLOSED) ?
", port close" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ?
", bit error exception" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_ACT_UPDATED) ?
", ACT update" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_ACT_HARDENED) ?
", ACT hardening" : "",
(status_buffer->status_subtype &
FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ?
", adapter feature change" : "");
if (status_buffer->status_subtype &
FSF_STATUS_READ_SUB_ACT_UPDATED)
zfcp_erp_adapter_access_changed(adapter);
break;
case FSF_STATUS_READ_CFDC_UPDATED: case FSF_STATUS_READ_CFDC_UPDATED:
ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
...@@ -1954,6 +1988,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1954,6 +1988,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req->qtcb->bottom.config.feature_selection = erp_action->fsf_req->qtcb->bottom.config.feature_selection =
FSF_FEATURE_CFDC | FSF_FEATURE_CFDC |
FSF_FEATURE_LUN_SHARING | FSF_FEATURE_LUN_SHARING |
FSF_FEATURE_NOTIFICATION_LOST |
FSF_FEATURE_UPDATE_ALERT; FSF_FEATURE_UPDATE_ALERT;
/* start QDIO request for this FSF request */ /* start QDIO request for this FSF request */
...@@ -2008,27 +2043,30 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) ...@@ -2008,27 +2043,30 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
fc_host_speed(shost) = bottom->fc_link_speed; fc_host_speed(shost) = bottom->fc_link_speed;
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->fc_topology = bottom->fc_topology;
adapter->hydra_version = bottom->adapter_type; adapter->hydra_version = bottom->adapter_type;
if (adapter->physical_wwpn == 0) if (fc_host_permanent_port_name(shost) == -1)
adapter->physical_wwpn = fc_host_port_name(shost); fc_host_permanent_port_name(shost) =
if (adapter->physical_s_id == 0) fc_host_port_name(shost);
adapter->physical_s_id = fc_host_port_id(shost); if (bottom->fc_topology == FSF_TOPO_P2P) {
adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
adapter->peer_wwpn = bottom->plogi_payload.wwpn;
adapter->peer_wwnn = bottom->plogi_payload.wwnn;
fc_host_port_type(shost) = FC_PORTTYPE_PTP;
} else if (bottom->fc_topology == FSF_TOPO_FABRIC)
fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
else if (bottom->fc_topology == FSF_TOPO_AL)
fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
else
fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
} else { } else {
fc_host_node_name(shost) = 0; fc_host_node_name(shost) = 0;
fc_host_port_name(shost) = 0; fc_host_port_name(shost) = 0;
fc_host_port_id(shost) = 0; fc_host_port_id(shost) = 0;
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
adapter->fc_topology = 0; fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
adapter->hydra_version = 0; adapter->hydra_version = 0;
} }
if (adapter->fc_topology == FSF_TOPO_P2P) {
adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
adapter->peer_wwpn = bottom->plogi_payload.wwpn;
adapter->peer_wwnn = bottom->plogi_payload.wwnn;
}
if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
adapter->hardware_version = bottom->hardware_version; adapter->hardware_version = bottom->hardware_version;
memcpy(fc_host_serial_number(shost), bottom->serial_number, memcpy(fc_host_serial_number(shost), bottom->serial_number,
...@@ -2097,8 +2135,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2097,8 +2135,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
return -EIO; return -EIO;
switch (adapter->fc_topology) { switch (fc_host_port_type(adapter->scsi_host)) {
case FSF_TOPO_P2P: case FC_PORTTYPE_PTP:
ZFCP_LOG_NORMAL("Point-to-Point fibrechannel " ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
"configuration detected at adapter %s\n" "configuration detected at adapter %s\n"
"Peer WWNN 0x%016llx, " "Peer WWNN 0x%016llx, "
...@@ -2111,7 +2149,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2111,7 +2149,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 0, debug_text_event(fsf_req->adapter->erp_dbf, 0,
"top-p-to-p"); "top-p-to-p");
break; break;
case FSF_TOPO_AL: case FC_PORTTYPE_NLPORT:
ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
"topology detected at adapter %s " "topology detected at adapter %s "
"unsupported, shutting down adapter\n", "unsupported, shutting down adapter\n",
...@@ -2120,7 +2158,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2120,7 +2158,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
"top-al"); "top-al");
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO; return -EIO;
case FSF_TOPO_FABRIC: case FC_PORTTYPE_NPORT:
ZFCP_LOG_NORMAL("Switched fabric fibrechannel " ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
"network detected at adapter %s.\n", "network detected at adapter %s.\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
...@@ -2133,7 +2171,6 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2133,7 +2171,6 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
"of a type known to the zfcp " "of a type known to the zfcp "
"driver, shutting down adapter\n", "driver, shutting down adapter\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
adapter->fc_topology = FSF_TOPO_ERROR;
debug_text_exception(fsf_req->adapter->erp_dbf, 0, debug_text_exception(fsf_req->adapter->erp_dbf, 0,
"unknown-topo"); "unknown-topo");
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
...@@ -2293,14 +2330,13 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) ...@@ -2293,14 +2330,13 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
data = (struct fsf_qtcb_bottom_port*) fsf_req->data; data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
if (data) if (data)
memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
adapter->physical_wwpn = bottom->wwpn; fc_host_permanent_port_name(shost) = bottom->wwpn;
adapter->physical_s_id = bottom->fc_port_id; else
} else { fc_host_permanent_port_name(shost) =
adapter->physical_wwpn = fc_host_port_name(shost); fc_host_port_name(shost);
adapter->physical_s_id = fc_host_port_id(shost);
}
fc_host_maxframe_size(shost) = bottom->maximum_frame_size; fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
fc_host_supported_speeds(shost) = bottom->supported_speed;
break; break;
case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
......
...@@ -166,6 +166,7 @@ ...@@ -166,6 +166,7 @@
#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004 #define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004
#define FSF_STATUS_READ_LINK_DOWN 0x00000005 #define FSF_STATUS_READ_LINK_DOWN 0x00000005
#define FSF_STATUS_READ_LINK_UP 0x00000006 #define FSF_STATUS_READ_LINK_UP 0x00000006
#define FSF_STATUS_READ_NOTIFICATION_LOST 0x00000009
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A #define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B #define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B
#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C #define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
...@@ -179,6 +180,16 @@ ...@@ -179,6 +180,16 @@
#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001 #define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001
#define FSF_STATUS_READ_SUB_FIRMWARE_UPDATE 0x00000002 #define FSF_STATUS_READ_SUB_FIRMWARE_UPDATE 0x00000002
/* status subtypes for unsolicited status notification lost */
#define FSF_STATUS_READ_SUB_INCOMING_ELS 0x00000001
#define FSF_STATUS_READ_SUB_SENSE_DATA 0x00000002
#define FSF_STATUS_READ_SUB_LINK_STATUS 0x00000004
#define FSF_STATUS_READ_SUB_PORT_CLOSED 0x00000008
#define FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD 0x00000010
#define FSF_STATUS_READ_SUB_ACT_UPDATED 0x00000020
#define FSF_STATUS_READ_SUB_ACT_HARDENED 0x00000040
#define FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT 0x00000080
/* status subtypes for CFDC */ /* status subtypes for CFDC */
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002 #define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F #define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
...@@ -188,7 +199,6 @@ ...@@ -188,7 +199,6 @@
#define FSF_TOPO_P2P 0x00000001 #define FSF_TOPO_P2P 0x00000001
#define FSF_TOPO_FABRIC 0x00000002 #define FSF_TOPO_FABRIC 0x00000002
#define FSF_TOPO_AL 0x00000003 #define FSF_TOPO_AL 0x00000003
#define FSF_TOPO_FABRIC_VIRT 0x00000004
/* data direction for FCP commands */ /* data direction for FCP commands */
#define FSF_DATADIR_WRITE 0x00000001 #define FSF_DATADIR_WRITE 0x00000001
...@@ -211,6 +221,7 @@ ...@@ -211,6 +221,7 @@
/* channel features */ /* channel features */
#define FSF_FEATURE_CFDC 0x00000002 #define FSF_FEATURE_CFDC 0x00000002
#define FSF_FEATURE_LUN_SHARING 0x00000004 #define FSF_FEATURE_LUN_SHARING 0x00000004
#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010 #define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
#define FSF_FEATURE_UPDATE_ALERT 0x00000100 #define FSF_FEATURE_UPDATE_ALERT 0x00000100
......
...@@ -49,8 +49,6 @@ static int zfcp_task_management_function(struct zfcp_unit *, u8, ...@@ -49,8 +49,6 @@ static int zfcp_task_management_function(struct zfcp_unit *, u8,
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t, static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
scsi_lun_t); scsi_lun_t);
static struct zfcp_port *zfcp_port_lookup(struct zfcp_adapter *, int,
scsi_id_t);
static struct device_attribute *zfcp_sysfs_sdev_attrs[]; static struct device_attribute *zfcp_sysfs_sdev_attrs[];
...@@ -406,18 +404,6 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id, ...@@ -406,18 +404,6 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
return retval; return retval;
} }
static struct zfcp_port *
zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
{
struct zfcp_port *port;
list_for_each_entry(port, &adapter->port_list_head, list) {
if (port->rport && (id == port->rport->scsi_target_id))
return port;
}
return (struct zfcp_port *) NULL;
}
/** /**
* zfcp_scsi_eh_abort_handler - abort the specified SCSI command * zfcp_scsi_eh_abort_handler - abort the specified SCSI command
* @scpnt: pointer to scsi_cmnd to be aborted * @scpnt: pointer to scsi_cmnd to be aborted
...@@ -731,70 +717,164 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter) ...@@ -731,70 +717,164 @@ zfcp_fsf_start_scsi_er_timer(struct zfcp_adapter *adapter)
/* /*
* Support functions for FC transport class * Support functions for FC transport class
*/ */
static void static struct fc_host_statistics*
zfcp_get_port_id(struct scsi_target *starget) zfcp_init_fc_host_stats(struct zfcp_adapter *adapter)
{ {
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct fc_host_statistics *fc_stats;
struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
struct zfcp_port *port;
unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags); if (!adapter->fc_stats) {
port = zfcp_port_lookup(adapter, starget->channel, starget->id); fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL);
if (port) if (!fc_stats)
fc_starget_port_id(starget) = port->d_id; return NULL;
else adapter->fc_stats = fc_stats; /* freed in adater_dequeue */
fc_starget_port_id(starget) = -1; }
read_unlock_irqrestore(&zfcp_data.config_lock, flags); memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats));
return adapter->fc_stats;
} }
static void static void
zfcp_get_port_name(struct scsi_target *starget) zfcp_adjust_fc_host_stats(struct fc_host_statistics *fc_stats,
struct fsf_qtcb_bottom_port *data,
struct fsf_qtcb_bottom_port *old)
{ {
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); fc_stats->seconds_since_last_reset = data->seconds_since_last_reset -
struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0]; old->seconds_since_last_reset;
struct zfcp_port *port; fc_stats->tx_frames = data->tx_frames - old->tx_frames;
unsigned long flags; fc_stats->tx_words = data->tx_words - old->tx_words;
fc_stats->rx_frames = data->rx_frames - old->rx_frames;
fc_stats->rx_words = data->rx_words - old->rx_words;
fc_stats->lip_count = data->lip - old->lip;
fc_stats->nos_count = data->nos - old->nos;
fc_stats->error_frames = data->error_frames - old->error_frames;
fc_stats->dumped_frames = data->dumped_frames - old->dumped_frames;
fc_stats->link_failure_count = data->link_failure - old->link_failure;
fc_stats->loss_of_sync_count = data->loss_of_sync - old->loss_of_sync;
fc_stats->loss_of_signal_count = data->loss_of_signal -
old->loss_of_signal;
fc_stats->prim_seq_protocol_err_count = data->psp_error_counts -
old->psp_error_counts;
fc_stats->invalid_tx_word_count = data->invalid_tx_words -
old->invalid_tx_words;
fc_stats->invalid_crc_count = data->invalid_crcs - old->invalid_crcs;
fc_stats->fcp_input_requests = data->input_requests -
old->input_requests;
fc_stats->fcp_output_requests = data->output_requests -
old->output_requests;
fc_stats->fcp_control_requests = data->control_requests -
old->control_requests;
fc_stats->fcp_input_megabytes = data->input_mb - old->input_mb;
fc_stats->fcp_output_megabytes = data->output_mb - old->output_mb;
}
read_lock_irqsave(&zfcp_data.config_lock, flags); static void
port = zfcp_port_lookup(adapter, starget->channel, starget->id); zfcp_set_fc_host_stats(struct fc_host_statistics *fc_stats,
if (port) struct fsf_qtcb_bottom_port *data)
fc_starget_port_name(starget) = port->wwpn; {
else fc_stats->seconds_since_last_reset = data->seconds_since_last_reset;
fc_starget_port_name(starget) = -1; fc_stats->tx_frames = data->tx_frames;
read_unlock_irqrestore(&zfcp_data.config_lock, flags); fc_stats->tx_words = data->tx_words;
fc_stats->rx_frames = data->rx_frames;
fc_stats->rx_words = data->rx_words;
fc_stats->lip_count = data->lip;
fc_stats->nos_count = data->nos;
fc_stats->error_frames = data->error_frames;
fc_stats->dumped_frames = data->dumped_frames;
fc_stats->link_failure_count = data->link_failure;
fc_stats->loss_of_sync_count = data->loss_of_sync;
fc_stats->loss_of_signal_count = data->loss_of_signal;
fc_stats->prim_seq_protocol_err_count = data->psp_error_counts;
fc_stats->invalid_tx_word_count = data->invalid_tx_words;
fc_stats->invalid_crc_count = data->invalid_crcs;
fc_stats->fcp_input_requests = data->input_requests;
fc_stats->fcp_output_requests = data->output_requests;
fc_stats->fcp_control_requests = data->control_requests;
fc_stats->fcp_input_megabytes = data->input_mb;
fc_stats->fcp_output_megabytes = data->output_mb;
}
/**
* zfcp_get_fc_host_stats - provide fc_host_statistics for scsi_transport_fc
*
* assumption: scsi_transport_fc synchronizes calls of
* get_fc_host_stats and reset_fc_host_stats
* (XXX to be checked otherwise introduce locking)
*/
static struct fc_host_statistics *
zfcp_get_fc_host_stats(struct Scsi_Host *shost)
{
struct zfcp_adapter *adapter;
struct fc_host_statistics *fc_stats;
struct fsf_qtcb_bottom_port *data;
int ret;
adapter = (struct zfcp_adapter *)shost->hostdata[0];
fc_stats = zfcp_init_fc_host_stats(adapter);
if (!fc_stats)
return NULL;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return NULL;
memset(data, 0, sizeof(*data));
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data);
if (ret) {
kfree(data);
return NULL; /* XXX return zeroed fc_stats? */
}
if (adapter->stats_reset &&
((jiffies/HZ - adapter->stats_reset) <
data->seconds_since_last_reset)) {
zfcp_adjust_fc_host_stats(fc_stats, data,
adapter->stats_reset_data);
} else
zfcp_set_fc_host_stats(fc_stats, data);
kfree(data);
return fc_stats;
} }
static void static void
zfcp_get_node_name(struct scsi_target *starget) zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
{ {
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct zfcp_adapter *adapter;
struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0]; struct fsf_qtcb_bottom_port *data, *old_data;
struct zfcp_port *port; int ret;
unsigned long flags;
read_lock_irqsave(&zfcp_data.config_lock, flags); adapter = (struct zfcp_adapter *)shost->hostdata[0];
port = zfcp_port_lookup(adapter, starget->channel, starget->id); data = kmalloc(sizeof(*data), GFP_KERNEL);
if (port) if (!data)
fc_starget_node_name(starget) = port->wwnn; return;
else memset(data, 0, sizeof(*data));
fc_starget_node_name(starget) = -1;
read_unlock_irqrestore(&zfcp_data.config_lock, flags); ret = zfcp_fsf_exchange_port_data(NULL, adapter, data);
if (ret == 0) {
adapter->stats_reset = jiffies/HZ;
old_data = adapter->stats_reset_data;
adapter->stats_reset_data = data; /* finally freed in
adater_dequeue */
kfree(old_data);
}
} }
struct fc_function_template zfcp_transport_functions = { struct fc_function_template zfcp_transport_functions = {
.get_starget_port_id = zfcp_get_port_id,
.get_starget_port_name = zfcp_get_port_name,
.get_starget_node_name = zfcp_get_node_name,
.show_starget_port_id = 1, .show_starget_port_id = 1,
.show_starget_port_name = 1, .show_starget_port_name = 1,
.show_starget_node_name = 1, .show_starget_node_name = 1,
.show_rport_supported_classes = 1, .show_rport_supported_classes = 1,
.show_host_node_name = 1, .show_host_node_name = 1,
.show_host_port_name = 1, .show_host_port_name = 1,
.show_host_permanent_port_name = 1,
.show_host_supported_classes = 1, .show_host_supported_classes = 1,
.show_host_supported_speeds = 1,
.show_host_maxframe_size = 1, .show_host_maxframe_size = 1,
.show_host_serial_number = 1, .show_host_serial_number = 1,
.get_fc_host_stats = zfcp_get_fc_host_stats,
.reset_fc_host_stats = zfcp_reset_fc_host_stats,
/* no functions registered for following dynamic attributes but
directly set by LLDD */
.show_host_port_type = 1,
.show_host_speed = 1, .show_host_speed = 1,
.show_host_port_id = 1, .show_host_port_id = 1,
}; };
......
...@@ -33,14 +33,6 @@ ...@@ -33,14 +33,6 @@
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG #define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG
static const char fc_topologies[5][25] = {
"<error>",
"point-to-point",
"fabric",
"arbitrated loop",
"fabric (virt. adapter)"
};
/** /**
* ZFCP_DEFINE_ADAPTER_ATTR * ZFCP_DEFINE_ADAPTER_ATTR
* @_name: name of show attribute * @_name: name of show attribute
...@@ -69,12 +61,8 @@ ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn); ...@@ -69,12 +61,8 @@ ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn);
ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id); ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id);
ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version); ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version); ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
ZFCP_DEFINE_ADAPTER_ATTR(fc_service_class, "%d\n", adapter->fc_service_class);
ZFCP_DEFINE_ADAPTER_ATTR(fc_topology, "%s\n",
fc_topologies[adapter->fc_topology]);
ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n", ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n",
adapter->hardware_version); adapter->hardware_version);
ZFCP_DEFINE_ADAPTER_ATTR(scsi_host_no, "0x%x\n", adapter->scsi_host_no);
ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask
(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)); (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status));
...@@ -259,9 +247,6 @@ static struct attribute *zfcp_adapter_attrs[] = { ...@@ -259,9 +247,6 @@ static struct attribute *zfcp_adapter_attrs[] = {
&dev_attr_physical_s_id.attr, &dev_attr_physical_s_id.attr,
&dev_attr_card_version.attr, &dev_attr_card_version.attr,
&dev_attr_lic_version.attr, &dev_attr_lic_version.attr,
&dev_attr_fc_service_class.attr,
&dev_attr_fc_topology.attr,
&dev_attr_scsi_host_no.attr,
&dev_attr_status.attr, &dev_attr_status.attr,
&dev_attr_hardware_version.attr, &dev_attr_hardware_version.attr,
NULL NULL
......
...@@ -65,8 +65,6 @@ static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_ ...@@ -65,8 +65,6 @@ static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_port_##_name##_show, NULL); static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_port_##_name##_show, NULL);
ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status)); ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status));
ZFCP_DEFINE_PORT_ATTR(wwnn, "0x%016llx\n", port->wwnn);
ZFCP_DEFINE_PORT_ATTR(d_id, "0x%06x\n", port->d_id);
ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask
(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)); (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status));
ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask
...@@ -245,8 +243,6 @@ static struct attribute *zfcp_port_common_attrs[] = { ...@@ -245,8 +243,6 @@ static struct attribute *zfcp_port_common_attrs[] = {
&dev_attr_failed.attr, &dev_attr_failed.attr,
&dev_attr_in_recovery.attr, &dev_attr_in_recovery.attr,
&dev_attr_status.attr, &dev_attr_status.attr,
&dev_attr_wwnn.attr,
&dev_attr_d_id.attr,
&dev_attr_access_denied.attr, &dev_attr_access_denied.attr,
NULL NULL
}; };
......
...@@ -65,7 +65,6 @@ static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, struct device_ ...@@ -65,7 +65,6 @@ static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, struct device_
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_unit_##_name##_show, NULL); static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_unit_##_name##_show, NULL);
ZFCP_DEFINE_UNIT_ATTR(status, "0x%08x\n", atomic_read(&unit->status)); ZFCP_DEFINE_UNIT_ATTR(status, "0x%08x\n", atomic_read(&unit->status));
ZFCP_DEFINE_UNIT_ATTR(scsi_lun, "0x%x\n", unit->scsi_lun);
ZFCP_DEFINE_UNIT_ATTR(in_recovery, "%d\n", atomic_test_mask ZFCP_DEFINE_UNIT_ATTR(in_recovery, "%d\n", atomic_test_mask
(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)); (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status));
ZFCP_DEFINE_UNIT_ATTR(access_denied, "%d\n", atomic_test_mask ZFCP_DEFINE_UNIT_ATTR(access_denied, "%d\n", atomic_test_mask
...@@ -138,7 +137,6 @@ static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_unit_failed_show, ...@@ -138,7 +137,6 @@ static DEVICE_ATTR(failed, S_IWUSR | S_IRUGO, zfcp_sysfs_unit_failed_show,
zfcp_sysfs_unit_failed_store); zfcp_sysfs_unit_failed_store);
static struct attribute *zfcp_unit_attrs[] = { static struct attribute *zfcp_unit_attrs[] = {
&dev_attr_scsi_lun.attr,
&dev_attr_failed.attr, &dev_attr_failed.attr,
&dev_attr_in_recovery.attr, &dev_attr_in_recovery.attr,
&dev_attr_status.attr, &dev_attr_status.attr,
......
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/mutex.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -615,7 +616,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -615,7 +616,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
/* Only let one of these through at a time */ /* Only let one of these through at a time */
if (down_interruptible(&tw_dev->ioctl_sem)) { if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
retval = TW_IOCTL_ERROR_OS_EINTR; retval = TW_IOCTL_ERROR_OS_EINTR;
goto out; goto out;
} }
...@@ -852,7 +853,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -852,7 +853,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
/* Now free ioctl buf memory */ /* Now free ioctl buf memory */
dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle); dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
out2: out2:
up(&tw_dev->ioctl_sem); mutex_unlock(&tw_dev->ioctl_lock);
out: out:
return retval; return retval;
} /* End twa_chrdev_ioctl() */ } /* End twa_chrdev_ioctl() */
...@@ -1182,7 +1183,7 @@ static int twa_initialize_device_extension(TW_Device_Extension *tw_dev) ...@@ -1182,7 +1183,7 @@ static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
tw_dev->error_sequence_id = 1; tw_dev->error_sequence_id = 1;
tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
init_MUTEX(&tw_dev->ioctl_sem); mutex_init(&tw_dev->ioctl_lock);
init_waitqueue_head(&tw_dev->ioctl_wqueue); init_waitqueue_head(&tw_dev->ioctl_wqueue);
retval = 0; retval = 0;
......
...@@ -672,7 +672,7 @@ typedef struct TAG_TW_Device_Extension { ...@@ -672,7 +672,7 @@ typedef struct TAG_TW_Device_Extension {
u32 ioctl_msec; u32 ioctl_msec;
int chrdev_request_id; int chrdev_request_id;
wait_queue_head_t ioctl_wqueue; wait_queue_head_t ioctl_wqueue;
struct semaphore ioctl_sem; struct mutex ioctl_lock;
char aen_clobber; char aen_clobber;
unsigned short working_srl; unsigned short working_srl;
unsigned short working_branch; unsigned short working_branch;
......
...@@ -203,6 +203,7 @@ ...@@ -203,6 +203,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/mutex.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -888,7 +889,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -888,7 +889,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n"); dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
/* Only let one of these through at a time */ /* Only let one of these through at a time */
if (down_interruptible(&tw_dev->ioctl_sem)) if (mutex_lock_interruptible(&tw_dev->ioctl_lock))
return -EINTR; return -EINTR;
/* First copy down the buffer length */ /* First copy down the buffer length */
...@@ -1029,7 +1030,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1029,7 +1030,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
/* Now free ioctl buf memory */ /* Now free ioctl buf memory */
dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
out: out:
up(&tw_dev->ioctl_sem); mutex_unlock(&tw_dev->ioctl_lock);
return retval; return retval;
} /* End tw_chrdev_ioctl() */ } /* End tw_chrdev_ioctl() */
...@@ -1270,7 +1271,7 @@ static int tw_initialize_device_extension(TW_Device_Extension *tw_dev) ...@@ -1270,7 +1271,7 @@ static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
tw_dev->pending_tail = TW_Q_START; tw_dev->pending_tail = TW_Q_START;
tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
init_MUTEX(&tw_dev->ioctl_sem); mutex_init(&tw_dev->ioctl_lock);
init_waitqueue_head(&tw_dev->ioctl_wqueue); init_waitqueue_head(&tw_dev->ioctl_wqueue);
return 0; return 0;
......
...@@ -420,7 +420,7 @@ typedef struct TAG_TW_Device_Extension { ...@@ -420,7 +420,7 @@ typedef struct TAG_TW_Device_Extension {
u32 max_sector_count; u32 max_sector_count;
u32 aen_count; u32 aen_count;
struct Scsi_Host *host; struct Scsi_Host *host;
struct semaphore ioctl_sem; struct mutex ioctl_lock;
unsigned short aen_queue[TW_Q_LENGTH]; unsigned short aen_queue[TW_Q_LENGTH];
unsigned char aen_head; unsigned char aen_head;
unsigned char aen_tail; unsigned char aen_tail;
......
...@@ -2216,6 +2216,7 @@ static int __init BusLogic_init(void) ...@@ -2216,6 +2216,7 @@ static int __init BusLogic_init(void)
HostAdapter->PCI_Address = ProbeInfo->PCI_Address; HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
HostAdapter->Bus = ProbeInfo->Bus; HostAdapter->Bus = ProbeInfo->Bus;
HostAdapter->Device = ProbeInfo->Device; HostAdapter->Device = ProbeInfo->Device;
HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel; HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType]; HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
/* /*
...@@ -2296,7 +2297,7 @@ static int __init BusLogic_init(void) ...@@ -2296,7 +2297,7 @@ static int __init BusLogic_init(void)
scsi_host_put(Host); scsi_host_put(Host);
} else { } else {
BusLogic_InitializeHostStructure(HostAdapter, Host); BusLogic_InitializeHostStructure(HostAdapter, Host);
scsi_add_host(Host, NULL); scsi_add_host(Host, HostAdapter->PCI_Device ? &HostAdapter->PCI_Device->dev : NULL);
scsi_scan_host(Host); scsi_scan_host(Host);
BusLogicHostAdapterCount++; BusLogicHostAdapterCount++;
} }
......
...@@ -80,7 +80,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o ...@@ -80,7 +80,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o
obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o
obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
obj-$(CONFIG_SCSI_LPFC) += lpfc/ obj-$(CONFIG_SCSI_LPFC) += lpfc/
obj-$(CONFIG_SCSI_PAS16) += pas16.o obj-$(CONFIG_SCSI_PAS16) += pas16.o
obj-$(CONFIG_SCSI_SEAGATE) += seagate.o obj-$(CONFIG_SCSI_SEAGATE) += seagate.o
......
...@@ -531,6 +531,13 @@ struct aac_driver_ident ...@@ -531,6 +531,13 @@ struct aac_driver_ident
*/ */
#define AAC_QUIRK_MASTER 0x0008 #define AAC_QUIRK_MASTER 0x0008
/*
* Some adapter firmware perform poorly when it must split up scatter gathers
* in order to deal with the limits of the underlying CHIM. This limit in this
* class of adapters is 17 scatter gather elements.
*/
#define AAC_QUIRK_17SG 0x0010
/* /*
* The adapter interface specs all queues to be located in the same * The adapter interface specs all queues to be located in the same
* physically contigous block. The host structure that defines the * physically contigous block. The host structure that defines the
......
...@@ -85,6 +85,10 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) ...@@ -85,6 +85,10 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
if (size < le16_to_cpu(kfib->header.SenderSize)) if (size < le16_to_cpu(kfib->header.SenderSize))
size = le16_to_cpu(kfib->header.SenderSize); size = le16_to_cpu(kfib->header.SenderSize);
if (size > dev->max_fib_size) { if (size > dev->max_fib_size) {
if (size > 2048) {
retval = -EINVAL;
goto cleanup;
}
/* Highjack the hw_fib */ /* Highjack the hw_fib */
hw_fib = fibptr->hw_fib; hw_fib = fibptr->hw_fib;
hw_fib_pa = fibptr->hw_fib_pa; hw_fib_pa = fibptr->hw_fib_pa;
......
...@@ -200,10 +200,10 @@ static struct aac_driver_ident aac_drivers[] = { ...@@ -200,10 +200,10 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */ { aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2025SA ", 1 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 1 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 1, AAC_QUIRK_17SG }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
{ aac_rx_init, "aacraid", "DELL ", "CERC SR2 ", 1 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ { aac_rx_init, "aacraid", "DELL ", "CERC SR2 ", 1, AAC_QUIRK_17SG }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 1 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 1, AAC_QUIRK_17SG }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA", 1 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA", 1, AAC_QUIRK_17SG }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2026ZCR ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2026ZCR ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2610SA ", 1 }, /* SATA 6Ch (Bearcat) */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2610SA ", 1 }, /* SATA 6Ch (Bearcat) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */
...@@ -574,7 +574,15 @@ static ssize_t aac_show_model(struct class_device *class_dev, ...@@ -574,7 +574,15 @@ static ssize_t aac_show_model(struct class_device *class_dev,
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len; int len;
len = snprintf(buf, PAGE_SIZE, "%s\n", if (dev->supplement_adapter_info.AdapterTypeText[0]) {
char * cp = dev->supplement_adapter_info.AdapterTypeText;
while (*cp && *cp != ' ')
++cp;
while (*cp == ' ')
++cp;
len = snprintf(buf, PAGE_SIZE, "%s\n", cp);
} else
len = snprintf(buf, PAGE_SIZE, "%s\n",
aac_drivers[dev->cardtype].model); aac_drivers[dev->cardtype].model);
return len; return len;
} }
...@@ -585,7 +593,15 @@ static ssize_t aac_show_vendor(struct class_device *class_dev, ...@@ -585,7 +593,15 @@ static ssize_t aac_show_vendor(struct class_device *class_dev,
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata; struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
int len; int len;
len = snprintf(buf, PAGE_SIZE, "%s\n", if (dev->supplement_adapter_info.AdapterTypeText[0]) {
char * cp = dev->supplement_adapter_info.AdapterTypeText;
while (*cp && *cp != ' ')
++cp;
len = snprintf(buf, PAGE_SIZE, "%.*s\n",
(int)(cp - (char *)dev->supplement_adapter_info.AdapterTypeText),
dev->supplement_adapter_info.AdapterTypeText);
} else
len = snprintf(buf, PAGE_SIZE, "%s\n",
aac_drivers[dev->cardtype].vname); aac_drivers[dev->cardtype].vname);
return len; return len;
} }
...@@ -837,6 +853,13 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -837,6 +853,13 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
= (aac->scsi_host_ptr->sg_tablesize * 8) + 112; = (aac->scsi_host_ptr->sg_tablesize * 8) + 112;
} }
if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
(aac->scsi_host_ptr->sg_tablesize > 17)) {
aac->scsi_host_ptr->sg_tablesize = 17;
aac->scsi_host_ptr->max_sectors
= (aac->scsi_host_ptr->sg_tablesize * 8) + 112;
}
/* /*
* Firware printf works only with older firmware. * Firware printf works only with older firmware.
*/ */
......
...@@ -42,13 +42,13 @@ config AIC7XXX_CMDS_PER_DEVICE ...@@ -42,13 +42,13 @@ config AIC7XXX_CMDS_PER_DEVICE
config AIC7XXX_RESET_DELAY_MS config AIC7XXX_RESET_DELAY_MS
int "Initial bus reset delay in milli-seconds" int "Initial bus reset delay in milli-seconds"
depends on SCSI_AIC7XXX depends on SCSI_AIC7XXX
default "15000" default "5000"
---help--- ---help---
The number of milliseconds to delay after an initial bus reset. The number of milliseconds to delay after an initial bus reset.
The bus settle delay following all error recovery actions is The bus settle delay following all error recovery actions is
dictated by the SCSI layer and is not affected by this value. dictated by the SCSI layer and is not affected by this value.
Default: 15000 (15 seconds) Default: 5000 (5 seconds)
config AIC7XXX_PROBE_EISA_VL config AIC7XXX_PROBE_EISA_VL
bool "Probe for EISA and VL AIC7XXX Adapters" bool "Probe for EISA and VL AIC7XXX Adapters"
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -75,8 +75,7 @@ struct scb_platform_data; ...@@ -75,8 +75,7 @@ struct scb_platform_data;
#define INITIATOR_WILDCARD (~0) #define INITIATOR_WILDCARD (~0)
#define SCB_LIST_NULL 0xFF00 #define SCB_LIST_NULL 0xFF00
#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL)) #define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL))
#define QOUTFIFO_ENTRY_VALID 0x8000 #define QOUTFIFO_ENTRY_VALID 0x80
#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))
#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL) #define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
#define SCSIID_TARGET(ahd, scsiid) \ #define SCSIID_TARGET(ahd, scsiid) \
...@@ -1053,6 +1052,13 @@ typedef uint8_t ahd_mode_state; ...@@ -1053,6 +1052,13 @@ typedef uint8_t ahd_mode_state;
typedef void ahd_callback_t (void *); typedef void ahd_callback_t (void *);
struct ahd_completion
{
uint16_t tag;
uint8_t sg_status;
uint8_t valid_tag;
};
struct ahd_softc { struct ahd_softc {
bus_space_tag_t tags[2]; bus_space_tag_t tags[2];
bus_space_handle_t bshs[2]; bus_space_handle_t bshs[2];
...@@ -1062,6 +1068,7 @@ struct ahd_softc { ...@@ -1062,6 +1068,7 @@ struct ahd_softc {
struct scb_data scb_data; struct scb_data scb_data;
struct hardware_scb *next_queued_hscb; struct hardware_scb *next_queued_hscb;
struct map_node *next_queued_hscb_map;
/* /*
* SCBs that have been sent to the controller * SCBs that have been sent to the controller
...@@ -1140,16 +1147,23 @@ struct ahd_softc { ...@@ -1140,16 +1147,23 @@ struct ahd_softc {
ahd_flag flags; ahd_flag flags;
struct seeprom_config *seep_config; struct seeprom_config *seep_config;
/* Values to store in the SEQCTL register for pause and unpause */
uint8_t unpause;
uint8_t pause;
/* Command Queues */ /* Command Queues */
struct ahd_completion *qoutfifo;
uint16_t qoutfifonext; uint16_t qoutfifonext;
uint16_t qoutfifonext_valid_tag; uint16_t qoutfifonext_valid_tag;
uint16_t qinfifonext; uint16_t qinfifonext;
uint16_t qinfifo[AHD_SCB_MAX]; uint16_t qinfifo[AHD_SCB_MAX];
uint16_t *qoutfifo;
/*
* Our qfreeze count. The sequencer compares
* this value with its own counter to determine
* whether to allow selections to occur.
*/
uint16_t qfreeze_cnt;
/* Values to store in the SEQCTL register for pause and unpause */
uint8_t unpause;
uint8_t pause;
/* Critical Section Data */ /* Critical Section Data */
struct cs *critical_sections; struct cs *critical_sections;
...@@ -1197,8 +1211,7 @@ struct ahd_softc { ...@@ -1197,8 +1211,7 @@ struct ahd_softc {
*/ */
bus_dma_tag_t parent_dmat; bus_dma_tag_t parent_dmat;
bus_dma_tag_t shared_data_dmat; bus_dma_tag_t shared_data_dmat;
bus_dmamap_t shared_data_dmamap; struct map_node shared_data_map;
dma_addr_t shared_data_busaddr;
/* Information saved through suspend/resume cycles */ /* Information saved through suspend/resume cycles */
struct ahd_suspend_state suspend_state; struct ahd_suspend_state suspend_state;
...@@ -1296,9 +1309,9 @@ struct ahd_devinfo { ...@@ -1296,9 +1309,9 @@ struct ahd_devinfo {
}; };
/****************************** PCI Structures ********************************/ /****************************** PCI Structures ********************************/
#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ #define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/
#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ #define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */
#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ #define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */
typedef int (ahd_device_setup_t)(struct ahd_softc *); typedef int (ahd_device_setup_t)(struct ahd_softc *);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
* *
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#76 $"
/* /*
* This file is processed by the aic7xxx_asm utility for use in assembling * This file is processed by the aic7xxx_asm utility for use in assembling
...@@ -65,13 +65,6 @@ VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $" ...@@ -65,13 +65,6 @@ VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"
mvi MODE_PTR, MK_MODE(src, dst); \ mvi MODE_PTR, MK_MODE(src, dst); \
} }
#define TOGGLE_DFF_MODE \
if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
call toggle_dff_mode_work_around; \
} else { \
xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1); \
}
#define RESTORE_MODE(mode) \ #define RESTORE_MODE(mode) \
if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \ if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
mov mode call set_mode_work_around; \ mov mode call set_mode_work_around; \
...@@ -1199,7 +1192,7 @@ register TARGPCISTAT { ...@@ -1199,7 +1192,7 @@ register TARGPCISTAT {
/* /*
* LQ Packet In * LQ Packet In
* The last LQ Packet received * The last LQ Packet recieved
*/ */
register LQIN { register LQIN {
address 0x020 address 0x020
...@@ -3542,10 +3535,34 @@ scratch_ram { ...@@ -3542,10 +3535,34 @@ scratch_ram {
COMPLETE_DMA_SCB_HEAD { COMPLETE_DMA_SCB_HEAD {
size 2 size 2
} }
/* Counting semaphore to prevent new select-outs */ /*
* tail of list of SCBs that have
* completed but need to be uploaded
* to the host prior to being completed.
*/
COMPLETE_DMA_SCB_TAIL {
size 2
}
/*
* head of list of SCBs that have
* been uploaded to the host, but cannot
* be completed until the QFREEZE is in
* full effect (i.e. no selections pending).
*/
COMPLETE_ON_QFREEZE_HEAD {
size 2
}
/*
* Counting semaphore to prevent new select-outs
* The queue is frozen so long as the sequencer
* and kernel freeze counts differ.
*/
QFREEZE_COUNT { QFREEZE_COUNT {
size 2 size 2
} }
KERNEL_QFREEZE_COUNT {
size 2
}
/* /*
* Mode to restore on legacy idle loop exit. * Mode to restore on legacy idle loop exit.
*/ */
...@@ -3624,6 +3641,17 @@ scratch_ram { ...@@ -3624,6 +3641,17 @@ scratch_ram {
QOUTFIFO_ENTRY_VALID_TAG { QOUTFIFO_ENTRY_VALID_TAG {
size 1 size 1
} }
/*
* Kernel and sequencer offsets into the queue of
* incoming target mode command descriptors. The
* queue is full when the KERNEL_TQINPOS == TQINPOS.
*/
KERNEL_TQINPOS {
size 1
}
TQINPOS {
size 1
}
/* /*
* Base address of our shared data with the kernel driver in host * Base address of our shared data with the kernel driver in host
* memory. This includes the qoutfifo and target mode * memory. This includes the qoutfifo and target mode
...@@ -3639,17 +3667,6 @@ scratch_ram { ...@@ -3639,17 +3667,6 @@ scratch_ram {
QOUTFIFO_NEXT_ADDR { QOUTFIFO_NEXT_ADDR {
size 4 size 4
} }
/*
* Kernel and sequencer offsets into the queue of
* incoming target mode command descriptors. The
* queue is full when the KERNEL_TQINPOS == TQINPOS.
*/
KERNEL_TQINPOS {
size 1
}
TQINPOS {
size 1
}
ARG_1 { ARG_1 {
size 1 size 1
mask SEND_MSG 0x80 mask SEND_MSG 0x80
...@@ -3951,6 +3968,7 @@ const SG_PREFETCH_ADDR_MASK download ...@@ -3951,6 +3968,7 @@ const SG_PREFETCH_ADDR_MASK download
const SG_SIZEOF download const SG_SIZEOF download
const PKT_OVERRUN_BUFOFFSET download const PKT_OVERRUN_BUFOFFSET download
const SCB_TRANSFER_SIZE download const SCB_TRANSFER_SIZE download
const CACHELINE_MASK download
/* /*
* BIOS SCB offsets * BIOS SCB offsets
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* $FreeBSD$ * $FreeBSD$
*/ */
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $" VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd" PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_" PREFIX = "ahd_"
...@@ -68,13 +68,47 @@ no_error_set: ...@@ -68,13 +68,47 @@ no_error_set:
} }
SET_MODE(M_SCSI, M_SCSI) SET_MODE(M_SCSI, M_SCSI)
test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus; test SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus;
test SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus; test SEQ_FLAGS2, SELECTOUT_QFROZEN jz check_waiting_list;
/*
* If the kernel has caught up with us, thaw the queue.
*/
mov A, KERNEL_QFREEZE_COUNT;
cmp QFREEZE_COUNT, A jne check_frozen_completions;
mov A, KERNEL_QFREEZE_COUNT[1];
cmp QFREEZE_COUNT[1], A jne check_frozen_completions;
and SEQ_FLAGS2, ~SELECTOUT_QFROZEN;
jmp check_waiting_list;
check_frozen_completions:
test SSTAT0, SELDO|SELINGO jnz idle_loop_checkbus;
BEGIN_CRITICAL;
/*
* If we have completions stalled waiting for the qfreeze
* to take effect, move them over to the complete_scb list
* now that no selections are pending.
*/
cmp COMPLETE_ON_QFREEZE_HEAD[1],SCB_LIST_NULL je idle_loop_checkbus;
/*
* Find the end of the qfreeze list. The first element has
* to be treated specially.
*/
bmov SCBPTR, COMPLETE_ON_QFREEZE_HEAD, 2;
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je join_lists;
/*
* Now the normal loop.
*/
bmov SCBPTR, SCB_NEXT_COMPLETE, 2;
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL jne . - 1;
join_lists:
bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
bmov COMPLETE_SCB_HEAD, COMPLETE_ON_QFREEZE_HEAD, 2;
mvi COMPLETE_ON_QFREEZE_HEAD[1], SCB_LIST_NULL;
jmp idle_loop_checkbus;
check_waiting_list:
cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus; cmp WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus;
/* /*
* ENSELO is cleared by a SELDO, so we must test for SELDO * ENSELO is cleared by a SELDO, so we must test for SELDO
* one last time. * one last time.
*/ */
BEGIN_CRITICAL;
test SSTAT0, SELDO jnz select_out; test SSTAT0, SELDO jnz select_out;
END_CRITICAL; END_CRITICAL;
call start_selection; call start_selection;
...@@ -90,6 +124,13 @@ idle_loop_check_nonpackreq: ...@@ -90,6 +124,13 @@ idle_loop_check_nonpackreq:
test SSTAT2, NONPACKREQ jz . + 2; test SSTAT2, NONPACKREQ jz . + 2;
call unexpected_nonpkt_phase_find_ctxt; call unexpected_nonpkt_phase_find_ctxt;
if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) { if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
/*
* On Rev A. hardware, the busy LED is only
* turned on automaically during selections
* and re-selections. Make the LED status
* more useful by forcing it to be on so
* long as one of our data FIFOs is active.
*/
and A, FIFO0FREE|FIFO1FREE, DFFSTAT; and A, FIFO0FREE|FIFO1FREE, DFFSTAT;
cmp A, FIFO0FREE|FIFO1FREE jne . + 3; cmp A, FIFO0FREE|FIFO1FREE jne . + 3;
and SBLKCTL, ~DIAGLEDEN|DIAGLEDON; and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
...@@ -101,9 +142,9 @@ idle_loop_check_nonpackreq: ...@@ -101,9 +142,9 @@ idle_loop_check_nonpackreq:
call idle_loop_cchan; call idle_loop_cchan;
jmp idle_loop; jmp idle_loop;
BEGIN_CRITICAL;
idle_loop_gsfifo: idle_loop_gsfifo:
SET_MODE(M_SCSI, M_SCSI) SET_MODE(M_SCSI, M_SCSI)
BEGIN_CRITICAL;
idle_loop_gsfifo_in_scsi_mode: idle_loop_gsfifo_in_scsi_mode:
test LQISTAT2, LQIGSAVAIL jz return; test LQISTAT2, LQIGSAVAIL jz return;
/* /*
...@@ -152,11 +193,15 @@ END_CRITICAL; ...@@ -152,11 +193,15 @@ END_CRITICAL;
idle_loop_service_fifos: idle_loop_service_fifos:
SET_MODE(M_DFF0, M_DFF0) SET_MODE(M_DFF0, M_DFF0)
BEGIN_CRITICAL;
test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo; test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;
call longjmp; call longjmp;
END_CRITICAL;
idle_loop_next_fifo: idle_loop_next_fifo:
SET_MODE(M_DFF1, M_DFF1) SET_MODE(M_DFF1, M_DFF1)
BEGIN_CRITICAL;
test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp; test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp;
END_CRITICAL;
return: return:
ret; ret;
...@@ -170,7 +215,6 @@ BEGIN_CRITICAL; ...@@ -170,7 +215,6 @@ BEGIN_CRITICAL;
test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle; test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog; test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;
test CCSCBCTL, CCSCBDONE jz return; test CCSCBCTL, CCSCBDONE jz return;
END_CRITICAL;
/* FALLTHROUGH */ /* FALLTHROUGH */
scbdma_tohost_done: scbdma_tohost_done:
test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone; test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
...@@ -180,26 +224,18 @@ scbdma_tohost_done: ...@@ -180,26 +224,18 @@ scbdma_tohost_done:
* bad SCSI status (currently only for underruns), we * bad SCSI status (currently only for underruns), we
* queue the SCB for normal completion. Otherwise, we * queue the SCB for normal completion. Otherwise, we
* wait until any select-out activity has halted, and * wait until any select-out activity has halted, and
* then notify the host so that the transaction can be * then queue the completion.
* dealt with.
*/ */
test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;
and CCSCBCTL, ~(CCARREN|CCSCBEN); and CCSCBCTL, ~(CCARREN|CCSCBEN);
bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2; bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL jne . + 2;
mvi COMPLETE_DMA_SCB_TAIL[1], SCB_LIST_NULL;
test SCB_SCSI_STATUS, 0xff jz scbdma_queue_completion;
bmov SCB_NEXT_COMPLETE, COMPLETE_ON_QFREEZE_HEAD, 2;
bmov COMPLETE_ON_QFREEZE_HEAD, SCBPTR, 2 ret;
scbdma_queue_completion:
bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
scbdma_notify_host:
SET_MODE(M_SCSI, M_SCSI)
test SCSISEQ0, ENSELO jnz return;
test SSTAT0, (SELDO|SELINGO) jnz return;
SET_MODE(M_CCHAN, M_CCHAN)
/*
* Remove SCB and notify host.
*/
and CCSCBCTL, ~(CCARREN|CCSCBEN);
bmov COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;
SET_SEQINTCODE(BAD_SCB_STATUS)
ret;
fill_qoutfifo_dmadone: fill_qoutfifo_dmadone:
and CCSCBCTL, ~(CCARREN|CCSCBEN); and CCSCBCTL, ~(CCARREN|CCSCBEN);
call qoutfifo_updated; call qoutfifo_updated;
...@@ -208,6 +244,7 @@ fill_qoutfifo_dmadone: ...@@ -208,6 +244,7 @@ fill_qoutfifo_dmadone:
test QOFF_CTLSTA, SDSCB_ROLLOVR jz return; test QOFF_CTLSTA, SDSCB_ROLLOVR jz return;
bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4; bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4;
xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret; xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;
END_CRITICAL;
qoutfifo_updated: qoutfifo_updated:
/* /*
...@@ -324,14 +361,15 @@ fill_qoutfifo: ...@@ -324,14 +361,15 @@ fill_qoutfifo:
* Keep track of the SCBs we are dmaing just * Keep track of the SCBs we are dmaing just
* in case the DMA fails or is aborted. * in case the DMA fails or is aborted.
*/ */
mov A, QOUTFIFO_ENTRY_VALID_TAG;
bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2; bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;
mvi CCSCBCTL, CCSCBRESET; mvi CCSCBCTL, CCSCBRESET;
bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4; bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;
mov A, QOUTFIFO_NEXT_ADDR;
bmov SCBPTR, COMPLETE_SCB_HEAD, 2; bmov SCBPTR, COMPLETE_SCB_HEAD, 2;
fill_qoutfifo_loop: fill_qoutfifo_loop:
mov CCSCBRAM, SCBPTR; bmov CCSCBRAM, SCBPTR, 2;
or CCSCBRAM, A, SCBPTR[1]; mov CCSCBRAM, SCB_SGPTR[0];
mov CCSCBRAM, QOUTFIFO_ENTRY_VALID_TAG;
mov NONE, SDSCB_QOFF; mov NONE, SDSCB_QOFF;
inc INT_COALESCING_CMDCOUNT; inc INT_COALESCING_CMDCOUNT;
add CMDS_PENDING, -1; add CMDS_PENDING, -1;
...@@ -339,6 +377,18 @@ fill_qoutfifo_loop: ...@@ -339,6 +377,18 @@ fill_qoutfifo_loop:
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done; cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done; cmp CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done;
test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done; test QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done;
/*
* Don't cross an ADB or Cachline boundary when DMA'ing
* completion entries. In PCI mode, at least in 32/33
* configurations, the SCB DMA engine may lose its place
* in the data-stream should the target force a retry on
* something other than an 8byte aligned boundary. In
* PCI-X mode, we do this to avoid split transactions since
* many chipsets seem to be unable to format proper split
* completions to continue the data transfer.
*/
add SINDEX, A, CCSCBADDR;
test SINDEX, CACHELINE_MASK jz fill_qoutfifo_done;
bmov SCBPTR, SCB_NEXT_COMPLETE, 2; bmov SCBPTR, SCB_NEXT_COMPLETE, 2;
jmp fill_qoutfifo_loop; jmp fill_qoutfifo_loop;
fill_qoutfifo_done: fill_qoutfifo_done:
...@@ -354,7 +404,6 @@ dma_complete_scb: ...@@ -354,7 +404,6 @@ dma_complete_scb:
bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2; bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;
bmov SCBHADDR, SCB_BUSADDR, 4; bmov SCBHADDR, SCB_BUSADDR, 4;
mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb; mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb;
END_CRITICAL;
/* /*
* Either post or fetch an SCB from host memory. The caller * Either post or fetch an SCB from host memory. The caller
...@@ -371,9 +420,19 @@ dma_scb: ...@@ -371,9 +420,19 @@ dma_scb:
mvi SCBHCNT, SCB_TRANSFER_SIZE; mvi SCBHCNT, SCB_TRANSFER_SIZE;
mov CCSCBCTL, SINDEX ret; mov CCSCBCTL, SINDEX ret;
BEGIN_CRITICAL;
setjmp: setjmp:
bmov LONGJMP_ADDR, STACK, 2 ret; /*
* At least on the A, a return in the same
* instruction as the bmov results in a return
* to the caller, not to the new address at the
* top of the stack. Since we want the latter
* (we use setjmp to register a handler from an
* interrupt context but not invoke that handler
* until we return to our idle loop), use a
* separate ret instruction.
*/
bmov LONGJMP_ADDR, STACK, 2;
ret;
setjmp_inline: setjmp_inline:
bmov LONGJMP_ADDR, STACK, 2; bmov LONGJMP_ADDR, STACK, 2;
longjmp: longjmp:
...@@ -392,11 +451,6 @@ set_mode_work_around: ...@@ -392,11 +451,6 @@ set_mode_work_around:
mvi SEQINTCTL, INTVEC1DSL; mvi SEQINTCTL, INTVEC1DSL;
mov MODE_PTR, SINDEX; mov MODE_PTR, SINDEX;
clr SEQINTCTL ret; clr SEQINTCTL ret;
toggle_dff_mode_work_around:
mvi SEQINTCTL, INTVEC1DSL;
xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
clr SEQINTCTL ret;
} }
...@@ -490,6 +544,21 @@ allocate_fifo1: ...@@ -490,6 +544,21 @@ allocate_fifo1:
SET_SRC_MODE M_SCSI; SET_SRC_MODE M_SCSI;
SET_DST_MODE M_SCSI; SET_DST_MODE M_SCSI;
select_in: select_in:
if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
/*
* On Rev A. hardware, the busy LED is only
* turned on automaically during selections
* and re-selections. Make the LED status
* more useful by forcing it to be on from
* the point of selection until our idle
* loop determines that neither of our FIFOs
* are busy. This handles the non-packetized
* case nicely as we will not return to the
* idle loop until the busfree at the end of
* each transaction.
*/
or SBLKCTL, DIAGLEDEN|DIAGLEDON;
}
if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) { if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {
/* /*
* Test to ensure that the bus has not * Test to ensure that the bus has not
...@@ -528,6 +597,21 @@ SET_SRC_MODE M_SCSI; ...@@ -528,6 +597,21 @@ SET_SRC_MODE M_SCSI;
SET_DST_MODE M_SCSI; SET_DST_MODE M_SCSI;
select_out: select_out:
BEGIN_CRITICAL; BEGIN_CRITICAL;
if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
/*
* On Rev A. hardware, the busy LED is only
* turned on automaically during selections
* and re-selections. Make the LED status
* more useful by forcing it to be on from
* the point of re-selection until our idle
* loop determines that neither of our FIFOs
* are busy. This handles the non-packetized
* case nicely as we will not return to the
* idle loop until the busfree at the end of
* each transaction.
*/
or SBLKCTL, DIAGLEDEN|DIAGLEDON;
}
/* Clear out all SCBs that have been successfully sent. */ /* Clear out all SCBs that have been successfully sent. */
if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) { if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {
/* /*
...@@ -1000,15 +1084,9 @@ not_found_ITloop: ...@@ -1000,15 +1084,9 @@ not_found_ITloop:
/* /*
* We received a "command complete" message. Put the SCB on the complete * We received a "command complete" message. Put the SCB on the complete
* queue and trigger a completion interrupt via the idle loop. Before doing * queue and trigger a completion interrupt via the idle loop. Before doing
* so, check to see if there * so, check to see if there is a residual or the status byte is something
* is a residual or the status byte is something other than STATUS_GOOD (0). * other than STATUS_GOOD (0). In either of these conditions, we upload the
* In either of these conditions, we upload the SCB back to the host so it can * SCB back to the host so it can process this information.
* process this information. In the case of a non zero status byte, we
* additionally interrupt the kernel driver synchronously, allowing it to
* decide if sense should be retrieved. If the kernel driver wishes to request
* sense, it will fill the kernel SCB with a request sense command, requeue
* it to the QINFIFO and tell us not to post to the QOUTFIFO by setting
* RETURN_1 to SEND_SENSE.
*/ */
mesgin_complete: mesgin_complete:
...@@ -1053,6 +1131,7 @@ complete_nomsg: ...@@ -1053,6 +1131,7 @@ complete_nomsg:
call queue_scb_completion; call queue_scb_completion;
jmp await_busfree; jmp await_busfree;
BEGIN_CRITICAL;
freeze_queue: freeze_queue:
/* Cancel any pending select-out. */ /* Cancel any pending select-out. */
test SSTAT0, SELDO|SELINGO jnz . + 2; test SSTAT0, SELDO|SELINGO jnz . + 2;
...@@ -1063,6 +1142,7 @@ freeze_queue: ...@@ -1063,6 +1142,7 @@ freeze_queue:
adc QFREEZE_COUNT[1], A; adc QFREEZE_COUNT[1], A;
or SEQ_FLAGS2, SELECTOUT_QFROZEN; or SEQ_FLAGS2, SELECTOUT_QFROZEN;
mov A, ACCUM_SAVE ret; mov A, ACCUM_SAVE ret;
END_CRITICAL;
/* /*
* Complete the current FIFO's SCB if data for this same * Complete the current FIFO's SCB if data for this same
...@@ -1085,8 +1165,10 @@ queue_scb_completion: ...@@ -1085,8 +1165,10 @@ queue_scb_completion:
test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */
test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
complete: complete:
BEGIN_CRITICAL;
bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2; bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret; bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
END_CRITICAL;
bad_status: bad_status:
cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb; cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;
call freeze_queue; call freeze_queue;
...@@ -1097,9 +1179,18 @@ upload_scb: ...@@ -1097,9 +1179,18 @@ upload_scb:
* it on the host. * it on the host.
*/ */
bmov SCB_TAG, SCBPTR, 2; bmov SCB_TAG, SCBPTR, 2;
bmov SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2; BEGIN_CRITICAL;
or SCB_SGPTR, SG_STATUS_VALID;
mvi SCB_NEXT_COMPLETE[1], SCB_LIST_NULL;
cmp COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne add_dma_scb_tail;
bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2; bmov COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;
or SCB_SGPTR, SG_STATUS_VALID ret; bmov COMPLETE_DMA_SCB_TAIL, SCBPTR, 2 ret;
add_dma_scb_tail:
bmov REG0, SCBPTR, 2;
bmov SCBPTR, COMPLETE_DMA_SCB_TAIL, 2;
bmov SCB_NEXT_COMPLETE, REG0, 2;
bmov COMPLETE_DMA_SCB_TAIL, REG0, 2 ret;
END_CRITICAL;
/* /*
* Is it a disconnect message? Set a flag in the SCB to remind us * Is it a disconnect message? Set a flag in the SCB to remind us
...@@ -1146,8 +1237,18 @@ SET_DST_MODE M_DFF1; ...@@ -1146,8 +1237,18 @@ SET_DST_MODE M_DFF1;
await_busfree_clrchn: await_busfree_clrchn:
mvi DFFSXFRCTL, CLRCHN; mvi DFFSXFRCTL, CLRCHN;
await_busfree_not_m_dff: await_busfree_not_m_dff:
call clear_target_state; /* clear target specific flags */
mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;
test SSTAT1,REQINIT|BUSFREE jz .; test SSTAT1,REQINIT|BUSFREE jz .;
/*
* We only set BUSFREE status once either a new
* phase has been detected or we are really
* BUSFREE. This allows the driver to know
* that we are active on the bus even though
* no identified transaction exists should a
* timeout occur while awaiting busfree.
*/
mvi LASTPHASE, P_BUSFREE;
test SSTAT1, BUSFREE jnz idle_loop; test SSTAT1, BUSFREE jnz idle_loop;
SET_SEQINTCODE(MISSED_BUSFREE) SET_SEQINTCODE(MISSED_BUSFREE)
...@@ -1202,11 +1303,6 @@ msgin_rdptrs_get_fifo: ...@@ -1202,11 +1303,6 @@ msgin_rdptrs_get_fifo:
call allocate_fifo; call allocate_fifo;
jmp mesgin_done; jmp mesgin_done;
clear_target_state:
mvi LASTPHASE, P_BUSFREE;
/* clear target specific flags */
mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;
phase_lock: phase_lock:
if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) { if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {
/* /*
...@@ -1297,6 +1393,47 @@ service_fifo: ...@@ -1297,6 +1393,47 @@ service_fifo:
/* Are we actively fetching segments? */ /* Are we actively fetching segments? */
test CCSGCTL, CCSGENACK jnz return; test CCSGCTL, CCSGENACK jnz return;
/*
* Should the other FIFO get the S/G cache first? If
* both FIFOs have been allocated since we last checked
* any FIFO, it is important that we service a FIFO
* that is not actively on the bus first. This guarantees
* that a FIFO will be freed to handle snapshot requests for
* any FIFO that is still on the bus. Chips with RTI do not
* perform snapshots, so don't bother with this test there.
*/
if ((ahd->features & AHD_RTI) == 0) {
/*
* If we're not still receiving SCSI data,
* it is safe to allocate the S/G cache to
* this FIFO.
*/
test DFCNTRL, SCSIEN jz idle_sgfetch_start;
/*
* Switch to the other FIFO. Non-RTI chips
* also have the "set mode" bug, so we must
* disable interrupts during the switch.
*/
mvi SEQINTCTL, INTVEC1DSL;
xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
/*
* If the other FIFO needs loading, then it
* must not have claimed the S/G cache yet
* (SG_CACHE_AVAIL would have been cleared in
* the orginal FIFO mode and we test this above).
* Return to the idle loop so we can process the
* FIFO not currently on the bus first.
*/
test SG_STATE, LOADING_NEEDED jz idle_sgfetch_okay;
clr SEQINTCTL ret;
idle_sgfetch_okay:
xor MODE_PTR, MK_MODE(M_DFF1, M_DFF1);
clr SEQINTCTL;
}
idle_sgfetch_start:
/* /*
* We fetch a "cacheline aligned" and sized amount of data * We fetch a "cacheline aligned" and sized amount of data
* so we don't end up referencing a non-existant page. * so we don't end up referencing a non-existant page.
...@@ -1308,7 +1445,7 @@ service_fifo: ...@@ -1308,7 +1445,7 @@ service_fifo:
mvi SGHCNT, SG_PREFETCH_CNT; mvi SGHCNT, SG_PREFETCH_CNT;
if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) { if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) {
/* /*
* Need two instruction between "touches" of SGHADDR. * Need two instructions between "touches" of SGHADDR.
*/ */
nop; nop;
} }
...@@ -1658,7 +1795,7 @@ export seq_isr: ...@@ -1658,7 +1795,7 @@ export seq_isr:
* savepointer in the current FIFO. We do this so that * savepointer in the current FIFO. We do this so that
* a pending CTXTDONE or SAVEPTR is visible in the active * a pending CTXTDONE or SAVEPTR is visible in the active
* FIFO. This status is the only way we can detect if we * FIFO. This status is the only way we can detect if we
* have lost the race (e.g. host paused us) and our attepts * have lost the race (e.g. host paused us) and our attempts
* to disable the channel occurred after all REQs were * to disable the channel occurred after all REQs were
* already seen and acked (REQINIT never comes true). * already seen and acked (REQINIT never comes true).
*/ */
...@@ -1667,7 +1804,7 @@ export seq_isr: ...@@ -1667,7 +1804,7 @@ export seq_isr:
test DFCNTRL, DIRECTION jz interrupt_return; test DFCNTRL, DIRECTION jz interrupt_return;
and DFCNTRL, ~SCSIEN; and DFCNTRL, ~SCSIEN;
snapshot_wait_data_valid: snapshot_wait_data_valid:
test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid; test SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz interrupt_return;
test SSTAT1, REQINIT jz snapshot_wait_data_valid; test SSTAT1, REQINIT jz snapshot_wait_data_valid;
snapshot_data_valid: snapshot_data_valid:
or DFCNTRL, SCSIEN; or DFCNTRL, SCSIEN;
...@@ -1834,7 +1971,6 @@ pkt_saveptrs_check_status: ...@@ -1834,7 +1971,6 @@ pkt_saveptrs_check_status:
dec SCB_FIFO_USE_COUNT; dec SCB_FIFO_USE_COUNT;
test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle; test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
mvi DFFSXFRCTL, CLRCHN ret; mvi DFFSXFRCTL, CLRCHN ret;
END_CRITICAL;
/* /*
* LAST_SEG_DONE status has been seen in the current FIFO. * LAST_SEG_DONE status has been seen in the current FIFO.
...@@ -1843,7 +1979,6 @@ END_CRITICAL; ...@@ -1843,7 +1979,6 @@ END_CRITICAL;
* Check for overrun and see if we can complete this command. * Check for overrun and see if we can complete this command.
*/ */
pkt_last_seg_done: pkt_last_seg_done:
BEGIN_CRITICAL;
/* /*
* Mark transfer as completed. * Mark transfer as completed.
*/ */
......
此差异已折叠。
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $
* *
* $FreeBSD$ * $FreeBSD$
*/ */
...@@ -522,12 +522,21 @@ do { \ ...@@ -522,12 +522,21 @@ do { \
static __inline uint16_t static __inline uint16_t
ahd_inw(struct ahd_softc *ahd, u_int port) ahd_inw(struct ahd_softc *ahd, u_int port)
{ {
/*
* Read high byte first as some registers increment
* or have other side effects when the low byte is
* read.
*/
return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));
} }
static __inline void static __inline void
ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) ahd_outw(struct ahd_softc *ahd, u_int port, u_int value)
{ {
/*
* Write low byte first to accomodate registers
* such as PRGMCNT where the order maters.
*/
ahd_outb(ahd, port, value & 0xFF); ahd_outb(ahd, port, value & 0xFF);
ahd_outb(ahd, port+1, (value >> 8) & 0xFF); ahd_outb(ahd, port+1, (value >> 8) & 0xFF);
} }
...@@ -684,7 +693,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) ...@@ -684,7 +693,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
* Razor #528 * Razor #528
*/ */
value = ahd_inb(ahd, offset); value = ahd_inb(ahd, offset);
if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0) if ((ahd->bugs & AHD_PCIX_SCBRAM_RD_BUG) != 0)
ahd_inb(ahd, MODE_PTR); ahd_inb(ahd, MODE_PTR);
return (value); return (value);
} }
...@@ -727,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) ...@@ -727,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_int tag)
static __inline void static __inline void
ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
{ {
struct hardware_scb *q_hscb; struct hardware_scb *q_hscb;
struct map_node *q_hscb_map;
uint32_t saved_hscb_busaddr; uint32_t saved_hscb_busaddr;
/* /*
...@@ -743,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) ...@@ -743,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
* locate the correct SCB by SCB_TAG. * locate the correct SCB by SCB_TAG.
*/ */
q_hscb = ahd->next_queued_hscb; q_hscb = ahd->next_queued_hscb;
q_hscb_map = ahd->next_queued_hscb_map;
saved_hscb_busaddr = q_hscb->hscb_busaddr; saved_hscb_busaddr = q_hscb->hscb_busaddr;
memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
q_hscb->hscb_busaddr = saved_hscb_busaddr; q_hscb->hscb_busaddr = saved_hscb_busaddr;
...@@ -750,7 +761,9 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) ...@@ -750,7 +761,9 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
/* Now swap HSCB pointers. */ /* Now swap HSCB pointers. */
ahd->next_queued_hscb = scb->hscb; ahd->next_queued_hscb = scb->hscb;
ahd->next_queued_hscb_map = scb->hscb_map;
scb->hscb = q_hscb; scb->hscb = q_hscb;
scb->hscb_map = q_hscb_map;
/* Now define the mapping from tag to SCB in the scbindex */ /* Now define the mapping from tag to SCB in the scbindex */
ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb;
...@@ -824,8 +837,9 @@ static __inline int ahd_intr(struct ahd_softc *ahd); ...@@ -824,8 +837,9 @@ static __inline int ahd_intr(struct ahd_softc *ahd);
static __inline void static __inline void
ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)
{ {
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
/*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); /*offset*/0,
/*len*/AHD_SCB_MAX * sizeof(struct ahd_completion), op);
} }
static __inline void static __inline void
...@@ -834,7 +848,7 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) ...@@ -834,7 +848,7 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd, int op)
#ifdef AHD_TARGET_MODE #ifdef AHD_TARGET_MODE
if ((ahd->flags & AHD_TARGETROLE) != 0) { if ((ahd->flags & AHD_TARGETROLE) != 0) {
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
ahd->shared_data_dmamap, ahd->shared_data_map.dmamap,
ahd_targetcmd_offset(ahd, 0), ahd_targetcmd_offset(ahd, 0),
sizeof(struct target_cmd) * AHD_TMODE_CMDS, sizeof(struct target_cmd) * AHD_TMODE_CMDS,
op); op);
...@@ -854,17 +868,17 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) ...@@ -854,17 +868,17 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd)
u_int retval; u_int retval;
retval = 0; retval = 0;
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
/*offset*/ahd->qoutfifonext, /*len*/2, /*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo),
BUS_DMASYNC_POSTREAD); /*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD);
if ((ahd->qoutfifo[ahd->qoutfifonext] if (ahd->qoutfifo[ahd->qoutfifonext].valid_tag
& QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) == ahd->qoutfifonext_valid_tag)
retval |= AHD_RUN_QOUTFIFO; retval |= AHD_RUN_QOUTFIFO;
#ifdef AHD_TARGET_MODE #ifdef AHD_TARGET_MODE
if ((ahd->flags & AHD_TARGETROLE) != 0 if ((ahd->flags & AHD_TARGETROLE) != 0
&& (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) {
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
ahd->shared_data_dmamap, ahd->shared_data_map.dmamap,
ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), ahd_targetcmd_offset(ahd, ahd->tqinfifofnext),
/*len*/sizeof(struct target_cmd), /*len*/sizeof(struct target_cmd),
BUS_DMASYNC_POSTREAD); BUS_DMASYNC_POSTREAD);
......
...@@ -1468,6 +1468,30 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, ...@@ -1468,6 +1468,30 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
if ((tstate->auto_negotiate & mask) != 0) { if ((tstate->auto_negotiate & mask) != 0) {
scb->flags |= SCB_AUTO_NEGOTIATE; scb->flags |= SCB_AUTO_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE; scb->hscb->control |= MK_MESSAGE;
} else if (cmd->cmnd[0] == INQUIRY
&& (tinfo->curr.offset != 0
|| tinfo->curr.width != MSG_EXT_WDTR_BUS_8_BIT
|| tinfo->curr.ppr_options != 0)
&& (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)==0) {
/*
* The SCSI spec requires inquiry
* commands to complete without
* reporting unit attention conditions.
* Because of this, an inquiry command
* that occurs just after a device is
* reset will result in a data phase
* with mismatched negotiated rates.
* The core already forces a renegotiation
* for reset events that are visible to
* our controller or that we initiate,
* but a third party device reset or a
* hot-plug insertion can still cause this
* issue. Therefore, we force a re-negotiation
* for every inquiry command unless we
* are async.
*/
scb->flags |= SCB_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE;
} }
if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
...@@ -2058,6 +2082,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ...@@ -2058,6 +2082,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
int paused; int paused;
int wait; int wait;
int disconnected; int disconnected;
int found;
ahd_mode_state saved_modes; ahd_mode_state saved_modes;
unsigned long flags; unsigned long flags;
...@@ -2176,7 +2201,8 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ...@@ -2176,7 +2201,8 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
last_phase = ahd_inb(ahd, LASTPHASE); last_phase = ahd_inb(ahd, LASTPHASE);
saved_scbptr = ahd_get_scbptr(ahd); saved_scbptr = ahd_get_scbptr(ahd);
active_scbptr = saved_scbptr; active_scbptr = saved_scbptr;
if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { if (disconnected && ((last_phase != P_BUSFREE) ||
(ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)) {
struct scb *bus_scb; struct scb *bus_scb;
bus_scb = ahd_lookup_scb(ahd, active_scbptr); bus_scb = ahd_lookup_scb(ahd, active_scbptr);
...@@ -2194,28 +2220,41 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ...@@ -2194,28 +2220,41 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
* bus or is in the disconnected state. * bus or is in the disconnected state.
*/ */
saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
if (last_phase != P_BUSFREE if (SCB_GET_TAG(pending_scb) == active_scbptr
&& (SCB_GET_TAG(pending_scb) == active_scbptr
|| (flag == SCB_DEVICE_RESET || (flag == SCB_DEVICE_RESET
&& SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd)))) { && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd))) {
/* /*
* We're active on the bus, so assert ATN * We're active on the bus, so assert ATN
* and hope that the target responds. * and hope that the target responds.
*/ */
pending_scb = ahd_lookup_scb(ahd, active_scbptr); pending_scb = ahd_lookup_scb(ahd, active_scbptr);
pending_scb->flags |= SCB_RECOVERY_SCB|flag; pending_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET;
ahd_outb(ahd, MSG_OUT, HOST_MSG); ahd_outb(ahd, MSG_OUT, HOST_MSG);
ahd_outb(ahd, SCSISIGO, last_phase|ATNO); ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n"); scmd_printk(KERN_INFO, cmd, "BDR message in message buffer\n");
wait = TRUE; wait = TRUE;
} else if (last_phase != P_BUSFREE
&& ahd_inb(ahd, SCSIPHASE) == 0) {
/*
* SCB is not identified, there
* is no pending REQ, and the sequencer
* has not seen a busfree. Looks like
* a stuck connection waiting to
* go busfree. Reset the bus.
*/
found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
/*Initiate Reset*/TRUE);
printf("%s: Issued Channel %c Bus Reset. "
"%d SCBs aborted\n", ahd_name(ahd),
cmd->device->channel + 'A', found);
} else if (disconnected) { } else if (disconnected) {
/* /*
* Actually re-queue this SCB in an attempt * Actually re-queue this SCB in an attempt
* to select the device before it reconnects. * to select the device before it reconnects.
*/ */
pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; pending_scb->flags |= SCB_RECOVERY_SCB|flag;
ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb)); ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
pending_scb->hscb->cdb_len = 0; pending_scb->hscb->cdb_len = 0;
pending_scb->hscb->task_attribute = 0; pending_scb->hscb->task_attribute = 0;
...@@ -2296,16 +2335,17 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ...@@ -2296,16 +2335,17 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
timer.expires = jiffies + (5 * HZ); timer.expires = jiffies + (5 * HZ);
timer.function = ahd_linux_sem_timeout; timer.function = ahd_linux_sem_timeout;
add_timer(&timer); add_timer(&timer);
printf("Recovery code sleeping\n"); printf("%s: Recovery code sleeping\n", ahd_name(ahd));
down(&ahd->platform_data->eh_sem); down(&ahd->platform_data->eh_sem);
printf("Recovery code awake\n"); printf("%s: Recovery code awake\n", ahd_name(ahd));
ret = del_timer_sync(&timer); ret = del_timer_sync(&timer);
if (ret == 0) { if (ret == 0) {
printf("Timer Expired\n"); printf("%s: Timer Expired (active %d)\n",
ahd_name(ahd), dev->active);
retval = FAILED; retval = FAILED;
} }
} }
ahd_unlock(ahd, &flags); ahd_unlock(ahd, &flags);
return (retval); return (retval);
} }
......
...@@ -252,7 +252,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) ...@@ -252,7 +252,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
/***************************** SMP support ************************************/ /***************************** SMP support ************************************/
#include <linux/spinlock.h> #include <linux/spinlock.h>
#define AIC79XX_DRIVER_VERSION "1.3.11" #define AIC79XX_DRIVER_VERSION "3.0"
/*************************** Device Data Structures ***************************/ /*************************** Device Data Structures ***************************/
/* /*
......
...@@ -38,9 +38,7 @@ ...@@ -38,9 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $ * $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $
*
* $FreeBSD$
*/ */
#ifdef __linux__ #ifdef __linux__
...@@ -114,6 +112,13 @@ struct ahd_pci_identity ahd_pci_ident_table [] = ...@@ -114,6 +112,13 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 29320ALP Ultra320 SCSI adapter", "Adaptec 29320ALP Ultra320 SCSI adapter",
ahd_aic7901_setup ahd_aic7901_setup
}, },
/* aic7901A based controllers */
{
ID_AHA_29320LP,
ID_ALL_MASK,
"Adaptec 29320LP Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
/* aic7902 based controllers */ /* aic7902 based controllers */
{ {
ID_AHA_29320, ID_AHA_29320,
...@@ -127,12 +132,6 @@ struct ahd_pci_identity ahd_pci_ident_table [] = ...@@ -127,12 +132,6 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 29320B Ultra320 SCSI adapter", "Adaptec 29320B Ultra320 SCSI adapter",
ahd_aic7902_setup ahd_aic7902_setup
}, },
{
ID_AHA_29320LP,
ID_ALL_MASK,
"Adaptec 29320LP Ultra320 SCSI adapter",
ahd_aic7901A_setup
},
{ {
ID_AHA_39320, ID_AHA_39320,
ID_ALL_MASK, ID_ALL_MASK,
...@@ -145,6 +144,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] = ...@@ -145,6 +144,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
"Adaptec 39320 Ultra320 SCSI adapter", "Adaptec 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup ahd_aic7902_setup
}, },
{
ID_AHA_39320_B_DELL,
ID_ALL_MASK,
"Adaptec (Dell OEM) 39320 Ultra320 SCSI adapter",
ahd_aic7902_setup
},
{ {
ID_AHA_39320A, ID_AHA_39320A,
ID_ALL_MASK, ID_ALL_MASK,
...@@ -668,6 +673,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control) ...@@ -668,6 +673,7 @@ ahd_configure_termination(struct ahd_softc *ahd, u_int adapter_control)
* Now set the termination based on what we found. * Now set the termination based on what we found.
*/ */
sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN; sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
ahd->flags &= ~AHD_TERM_ENB_A;
if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) { if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
ahd->flags |= AHD_TERM_ENB_A; ahd->flags |= AHD_TERM_ENB_A;
sxfrctl1 |= STPWEN; sxfrctl1 |= STPWEN;
......
...@@ -53,14 +53,15 @@ ...@@ -53,14 +53,15 @@
#define ID_AHA_29320ALP 0x8017900500449005ull #define ID_AHA_29320ALP 0x8017900500449005ull
#define ID_AIC7901A 0x801E9005FFFF9005ull #define ID_AIC7901A 0x801E9005FFFF9005ull
#define ID_AHA_29320 0x8012900500429005ull
#define ID_AHA_29320B 0x8013900500439005ull
#define ID_AHA_29320LP 0x8014900500449005ull #define ID_AHA_29320LP 0x8014900500449005ull
#define ID_AIC7902 0x801F9005FFFF9005ull #define ID_AIC7902 0x801F9005FFFF9005ull
#define ID_AIC7902_B 0x801D9005FFFF9005ull #define ID_AIC7902_B 0x801D9005FFFF9005ull
#define ID_AHA_39320 0x8010900500409005ull #define ID_AHA_39320 0x8010900500409005ull
#define ID_AHA_29320 0x8012900500429005ull
#define ID_AHA_29320B 0x8013900500439005ull
#define ID_AHA_39320_B 0x8015900500409005ull #define ID_AHA_39320_B 0x8015900500409005ull
#define ID_AHA_39320_B_DELL 0x8015900501681028ull
#define ID_AHA_39320A 0x8016900500409005ull #define ID_AHA_39320A 0x8016900500409005ull
#define ID_AHA_39320D 0x8011900500419005ull #define ID_AHA_39320D 0x8011900500419005ull
#define ID_AHA_39320D_B 0x801C900500419005ull #define ID_AHA_39320D_B 0x801C900500419005ull
......
...@@ -375,7 +375,7 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, ...@@ -375,7 +375,7 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
struct scsi_cmnd *cmd); struct scsi_cmnd *cmd);
static void ahc_linux_sem_timeout(u_long arg); static void ahc_linux_sem_timeout(u_long arg);
static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
static void ahc_linux_release_simq(u_long arg); static void ahc_linux_release_simq(struct ahc_softc *ahc);
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
...@@ -1073,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa ...@@ -1073,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
return (ENOMEM); return (ENOMEM);
*((struct ahc_softc **)host->hostdata) = ahc; *((struct ahc_softc **)host->hostdata) = ahc;
ahc_lock(ahc, &s);
ahc->platform_data->host = host; ahc->platform_data->host = host;
host->can_queue = AHC_MAX_QUEUE; host->can_queue = AHC_MAX_QUEUE;
host->cmd_per_lun = 2; host->cmd_per_lun = 2;
...@@ -1084,7 +1083,9 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa ...@@ -1084,7 +1083,9 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
host->max_lun = AHC_NUM_LUNS; host->max_lun = AHC_NUM_LUNS;
host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0; host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
host->sg_tablesize = AHC_NSEG; host->sg_tablesize = AHC_NSEG;
ahc_lock(ahc, &s);
ahc_set_unit(ahc, ahc_linux_unit++); ahc_set_unit(ahc, ahc_linux_unit++);
ahc_unlock(ahc, &s);
sprintf(buf, "scsi%d", host->host_no); sprintf(buf, "scsi%d", host->host_no);
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT); new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
if (new_name != NULL) { if (new_name != NULL) {
...@@ -1094,7 +1095,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa ...@@ -1094,7 +1095,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
host->unique_id = ahc->unit; host->unique_id = ahc->unit;
ahc_linux_initialize_scsi_bus(ahc); ahc_linux_initialize_scsi_bus(ahc);
ahc_intr_enable(ahc, TRUE); ahc_intr_enable(ahc, TRUE);
ahc_unlock(ahc, &s);
host->transportt = ahc_linux_transport_template; host->transportt = ahc_linux_transport_template;
...@@ -1120,10 +1120,13 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) ...@@ -1120,10 +1120,13 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
{ {
int i; int i;
int numtarg; int numtarg;
unsigned long s;
i = 0; i = 0;
numtarg = 0; numtarg = 0;
ahc_lock(ahc, &s);
if (aic7xxx_no_reset != 0) if (aic7xxx_no_reset != 0)
ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B); ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
...@@ -1170,16 +1173,12 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) ...@@ -1170,16 +1173,12 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
ahc_update_neg_request(ahc, &devinfo, tstate, ahc_update_neg_request(ahc, &devinfo, tstate,
tinfo, AHC_NEG_ALWAYS); tinfo, AHC_NEG_ALWAYS);
} }
ahc_unlock(ahc, &s);
/* Give the bus some time to recover */ /* Give the bus some time to recover */
if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) { if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
ahc_linux_freeze_simq(ahc); ahc_linux_freeze_simq(ahc);
init_timer(&ahc->platform_data->reset_timer); msleep(AIC7XXX_RESET_DELAY);
ahc->platform_data->reset_timer.data = (u_long)ahc; ahc_linux_release_simq(ahc);
ahc->platform_data->reset_timer.expires =
jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
ahc->platform_data->reset_timer.function =
ahc_linux_release_simq;
add_timer(&ahc->platform_data->reset_timer);
} }
} }
...@@ -2059,6 +2058,9 @@ ahc_linux_sem_timeout(u_long arg) ...@@ -2059,6 +2058,9 @@ ahc_linux_sem_timeout(u_long arg)
static void static void
ahc_linux_freeze_simq(struct ahc_softc *ahc) ahc_linux_freeze_simq(struct ahc_softc *ahc)
{ {
unsigned long s;
ahc_lock(ahc, &s);
ahc->platform_data->qfrozen++; ahc->platform_data->qfrozen++;
if (ahc->platform_data->qfrozen == 1) { if (ahc->platform_data->qfrozen == 1) {
scsi_block_requests(ahc->platform_data->host); scsi_block_requests(ahc->platform_data->host);
...@@ -2068,17 +2070,15 @@ ahc_linux_freeze_simq(struct ahc_softc *ahc) ...@@ -2068,17 +2070,15 @@ ahc_linux_freeze_simq(struct ahc_softc *ahc)
CAM_LUN_WILDCARD, SCB_LIST_NULL, CAM_LUN_WILDCARD, SCB_LIST_NULL,
ROLE_INITIATOR, CAM_REQUEUE_REQ); ROLE_INITIATOR, CAM_REQUEUE_REQ);
} }
ahc_unlock(ahc, &s);
} }
static void static void
ahc_linux_release_simq(u_long arg) ahc_linux_release_simq(struct ahc_softc *ahc)
{ {
struct ahc_softc *ahc;
u_long s; u_long s;
int unblock_reqs; int unblock_reqs;
ahc = (struct ahc_softc *)arg;
unblock_reqs = 0; unblock_reqs = 0;
ahc_lock(ahc, &s); ahc_lock(ahc, &s);
if (ahc->platform_data->qfrozen > 0) if (ahc->platform_data->qfrozen > 0)
......
...@@ -223,9 +223,6 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t); ...@@ -223,9 +223,6 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
*/ */
#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op) #define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
/************************** Timer DataStructures ******************************/
typedef struct timer_list ahc_timer_t;
/********************************** Includes **********************************/ /********************************** Includes **********************************/
#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT #ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
#define AIC_DEBUG_REGISTERS 1 #define AIC_DEBUG_REGISTERS 1
...@@ -235,30 +232,9 @@ typedef struct timer_list ahc_timer_t; ...@@ -235,30 +232,9 @@ typedef struct timer_list ahc_timer_t;
#include "aic7xxx.h" #include "aic7xxx.h"
/***************************** Timer Facilities *******************************/ /***************************** Timer Facilities *******************************/
#define ahc_timer_init init_timer
#define ahc_timer_stop del_timer_sync
typedef void ahc_linux_callback_t (u_long);
static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
ahc_callback_t *func, void *arg);
static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
static __inline void
ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
{
struct ahc_softc *ahc;
ahc = (struct ahc_softc *)arg;
del_timer(timer);
timer->data = (u_long)arg;
timer->expires = jiffies + (usec * HZ)/1000000;
timer->function = (ahc_linux_callback_t*)func;
add_timer(timer);
}
static __inline void static __inline void
ahc_scb_timer_reset(struct scb *scb, u_int usec) ahc_scb_timer_reset(struct scb *scb, u_int usec)
{ {
mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
} }
/***************************** SMP support ************************************/ /***************************** SMP support ************************************/
...@@ -393,7 +369,6 @@ struct ahc_platform_data { ...@@ -393,7 +369,6 @@ struct ahc_platform_data {
spinlock_t spin_lock; spinlock_t spin_lock;
u_int qfrozen; u_int qfrozen;
struct timer_list reset_timer;
struct semaphore eh_sem; struct semaphore eh_sem;
struct Scsi_Host *host; /* pointer to scsi host */ struct Scsi_Host *host; /* pointer to scsi host */
#define AHC_LINUX_NOIRQ ((uint32_t)~0) #define AHC_LINUX_NOIRQ ((uint32_t)~0)
......
...@@ -39,9 +39,7 @@ ...@@ -39,9 +39,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES. * POSSIBILITY OF SUCH DAMAGES.
* *
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#79 $
*
* $FreeBSD$
*/ */
#ifdef __linux__ #ifdef __linux__
...@@ -393,6 +391,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ...@@ -393,6 +391,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
"Adaptec aic7892 Ultra160 SCSI adapter (ARO)", "Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
ahc_aic7892_setup ahc_aic7892_setup
}, },
{
ID_AHA_2915_30LP,
ID_ALL_MASK,
"Adaptec 2915/30LP Ultra160 SCSI adapter",
ahc_aic7892_setup
},
/* aic7895 based controllers */ /* aic7895 based controllers */
{ {
ID_AHA_2940U_DUAL, ID_AHA_2940U_DUAL,
...@@ -1193,9 +1197,19 @@ ahc_pci_test_register_access(struct ahc_softc *ahc) ...@@ -1193,9 +1197,19 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
* use for this test. * use for this test.
*/ */
hcntrl = ahc_inb(ahc, HCNTRL); hcntrl = ahc_inb(ahc, HCNTRL);
if (hcntrl == 0xFF) if (hcntrl == 0xFF)
goto fail; goto fail;
if ((hcntrl & CHIPRST) != 0) {
/*
* The chip has not been initialized since
* PCI/EISA/VLB bus reset. Don't trust
* "left over BIOS data".
*/
ahc->flags |= AHC_NO_BIOS_INIT;
}
/* /*
* Next create a situation where write combining * Next create a situation where write combining
* or read prefetching could be initiated by the * or read prefetching could be initiated by the
...@@ -1307,6 +1321,10 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1) ...@@ -1307,6 +1321,10 @@ check_extport(struct ahc_softc *ahc, u_int *sxfrctl1)
sd.sd_chip = C56_66; sd.sd_chip = C56_66;
} }
ahc_release_seeprom(&sd); ahc_release_seeprom(&sd);
/* Remember the SEEPROM type for later */
if (sd.sd_chip == C56_66)
ahc->flags |= AHC_LARGE_SEEPROM;
} }
if (!have_seeprom) { if (!have_seeprom) {
......
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
#define ID_AHA_29160C 0x0080900562209005ull #define ID_AHA_29160C 0x0080900562209005ull
#define ID_AHA_29160B 0x00809005E2209005ull #define ID_AHA_29160B 0x00809005E2209005ull
#define ID_AHA_19160B 0x0081900562A19005ull #define ID_AHA_19160B 0x0081900562A19005ull
#define ID_AHA_2915_30LP 0x0082900502109005ull
#define ID_AIC7896 0x005F9005FFFF9005ull #define ID_AIC7896 0x005F9005FFFF9005ull
#define ID_AIC7896_ARO 0x00539005FFFF9005ull #define ID_AIC7896_ARO 0x00539005FFFF9005ull
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/chio.h> /* here are all the ioctls */ #include <linux/chio.h> /* here are all the ioctls */
#include <linux/mutex.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
...@@ -111,7 +112,7 @@ typedef struct { ...@@ -111,7 +112,7 @@ typedef struct {
u_int counts[CH_TYPES]; u_int counts[CH_TYPES];
u_int unit_attention; u_int unit_attention;
u_int voltags; u_int voltags;
struct semaphore lock; struct mutex lock;
} scsi_changer; } scsi_changer;
static LIST_HEAD(ch_devlist); static LIST_HEAD(ch_devlist);
...@@ -565,7 +566,7 @@ static int ch_gstatus(scsi_changer *ch, int type, unsigned char __user *dest) ...@@ -565,7 +566,7 @@ static int ch_gstatus(scsi_changer *ch, int type, unsigned char __user *dest)
u_char data[16]; u_char data[16];
unsigned int i; unsigned int i;
down(&ch->lock); mutex_lock(&ch->lock);
for (i = 0; i < ch->counts[type]; i++) { for (i = 0; i < ch->counts[type]; i++) {
if (0 != ch_read_element_status if (0 != ch_read_element_status
(ch, ch->firsts[type]+i,data)) { (ch, ch->firsts[type]+i,data)) {
...@@ -582,7 +583,7 @@ static int ch_gstatus(scsi_changer *ch, int type, unsigned char __user *dest) ...@@ -582,7 +583,7 @@ static int ch_gstatus(scsi_changer *ch, int type, unsigned char __user *dest)
if (0 != retval) if (0 != retval)
break; break;
} }
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -687,11 +688,11 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -687,11 +688,11 @@ static int ch_ioctl(struct inode * inode, struct file * file,
dprintk("CHIOPOSITION: invalid parameter\n"); dprintk("CHIOPOSITION: invalid parameter\n");
return -EBADSLT; return -EBADSLT;
} }
down(&ch->lock); mutex_lock(&ch->lock);
retval = ch_position(ch,0, retval = ch_position(ch,0,
ch->firsts[pos.cp_type] + pos.cp_unit, ch->firsts[pos.cp_type] + pos.cp_unit,
pos.cp_flags & CP_INVERT); pos.cp_flags & CP_INVERT);
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -708,12 +709,12 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -708,12 +709,12 @@ static int ch_ioctl(struct inode * inode, struct file * file,
return -EBADSLT; return -EBADSLT;
} }
down(&ch->lock); mutex_lock(&ch->lock);
retval = ch_move(ch,0, retval = ch_move(ch,0,
ch->firsts[mv.cm_fromtype] + mv.cm_fromunit, ch->firsts[mv.cm_fromtype] + mv.cm_fromunit,
ch->firsts[mv.cm_totype] + mv.cm_tounit, ch->firsts[mv.cm_totype] + mv.cm_tounit,
mv.cm_flags & CM_INVERT); mv.cm_flags & CM_INVERT);
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -731,14 +732,14 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -731,14 +732,14 @@ static int ch_ioctl(struct inode * inode, struct file * file,
return -EBADSLT; return -EBADSLT;
} }
down(&ch->lock); mutex_lock(&ch->lock);
retval = ch_exchange retval = ch_exchange
(ch,0, (ch,0,
ch->firsts[mv.ce_srctype] + mv.ce_srcunit, ch->firsts[mv.ce_srctype] + mv.ce_srcunit,
ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit, ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit,
ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit, ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit,
mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2); mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2);
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -772,7 +773,7 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -772,7 +773,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
down(&ch->lock); mutex_lock(&ch->lock);
voltag_retry: voltag_retry:
memset(cmd,0,sizeof(cmd)); memset(cmd,0,sizeof(cmd));
...@@ -823,7 +824,7 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -823,7 +824,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
goto voltag_retry; goto voltag_retry;
} }
kfree(buffer); kfree(buffer);
up(&ch->lock); mutex_unlock(&ch->lock);
if (copy_to_user(argp, &cge, sizeof (cge))) if (copy_to_user(argp, &cge, sizeof (cge)))
return -EFAULT; return -EFAULT;
...@@ -832,9 +833,9 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -832,9 +833,9 @@ static int ch_ioctl(struct inode * inode, struct file * file,
case CHIOINITELEM: case CHIOINITELEM:
{ {
down(&ch->lock); mutex_lock(&ch->lock);
retval = ch_init_elem(ch); retval = ch_init_elem(ch);
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -851,12 +852,12 @@ static int ch_ioctl(struct inode * inode, struct file * file, ...@@ -851,12 +852,12 @@ static int ch_ioctl(struct inode * inode, struct file * file,
return -EBADSLT; return -EBADSLT;
} }
elem = ch->firsts[csv.csv_type] + csv.csv_unit; elem = ch->firsts[csv.csv_type] + csv.csv_unit;
down(&ch->lock); mutex_lock(&ch->lock);
retval = ch_set_voltag(ch, elem, retval = ch_set_voltag(ch, elem,
csv.csv_flags & CSV_AVOLTAG, csv.csv_flags & CSV_AVOLTAG,
csv.csv_flags & CSV_CLEARTAG, csv.csv_flags & CSV_CLEARTAG,
csv.csv_voltag); csv.csv_voltag);
up(&ch->lock); mutex_unlock(&ch->lock);
return retval; return retval;
} }
...@@ -929,7 +930,7 @@ static int ch_probe(struct device *dev) ...@@ -929,7 +930,7 @@ static int ch_probe(struct device *dev)
memset(ch,0,sizeof(*ch)); memset(ch,0,sizeof(*ch));
ch->minor = ch_devcount; ch->minor = ch_devcount;
sprintf(ch->name,"ch%d",ch->minor); sprintf(ch->name,"ch%d",ch->minor);
init_MUTEX(&ch->lock); mutex_init(&ch->lock);
ch->device = sd; ch->device = sd;
ch_readconfig(ch); ch_readconfig(ch);
if (init) if (init)
......
此差异已折叠。
...@@ -156,16 +156,16 @@ EXPORT_SYMBOL(scsi_host_set_state); ...@@ -156,16 +156,16 @@ EXPORT_SYMBOL(scsi_host_set_state);
void scsi_remove_host(struct Scsi_Host *shost) void scsi_remove_host(struct Scsi_Host *shost)
{ {
unsigned long flags; unsigned long flags;
down(&shost->scan_mutex); mutex_lock(&shost->scan_mutex);
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
if (scsi_host_set_state(shost, SHOST_CANCEL)) if (scsi_host_set_state(shost, SHOST_CANCEL))
if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) { if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
up(&shost->scan_mutex); mutex_unlock(&shost->scan_mutex);
return; return;
} }
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
up(&shost->scan_mutex); mutex_unlock(&shost->scan_mutex);
scsi_forget_host(shost); scsi_forget_host(shost);
scsi_proc_host_rm(shost); scsi_proc_host_rm(shost);
...@@ -320,7 +320,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) ...@@ -320,7 +320,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
INIT_LIST_HEAD(&shost->starved_list); INIT_LIST_HEAD(&shost->starved_list);
init_waitqueue_head(&shost->host_wait); init_waitqueue_head(&shost->host_wait);
init_MUTEX(&shost->scan_mutex); mutex_init(&shost->scan_mutex);
shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */ shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */
shost->dma_channel = 0xff; shost->dma_channel = 0xff;
......
...@@ -1319,6 +1319,9 @@ ips_slave_configure(struct scsi_device * SDptr) ...@@ -1319,6 +1319,9 @@ ips_slave_configure(struct scsi_device * SDptr)
min = ha->max_cmds - 1; min = ha->max_cmds - 1;
scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min); scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
} }
SDptr->skip_ms_page_8 = 1;
SDptr->skip_ms_page_3f = 1;
return 0; return 0;
} }
#endif #endif
......
此差异已折叠。
...@@ -158,7 +158,7 @@ struct iscsi_conn { ...@@ -158,7 +158,7 @@ struct iscsi_conn {
struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
struct kfifo *xmitqueue; /* data-path cmd queue */ struct kfifo *xmitqueue; /* data-path cmd queue */
struct work_struct xmitwork; /* per-conn. xmit workqueue */ struct work_struct xmitwork; /* per-conn. xmit workqueue */
struct semaphore xmitsema; /* serializes connection xmit, struct mutex xmitmutex; /* serializes connection xmit,
* access to kfifos: * * access to kfifos: *
* xmitqueue, writequeue, * * xmitqueue, writequeue, *
* immqueue, mgmtqueue */ * immqueue, mgmtqueue */
...@@ -191,6 +191,8 @@ struct iscsi_conn { ...@@ -191,6 +191,8 @@ struct iscsi_conn {
uint32_t sendpage_failures_cnt; uint32_t sendpage_failures_cnt;
uint32_t discontiguous_hdr_cnt; uint32_t discontiguous_hdr_cnt;
uint32_t eh_abort_cnt; uint32_t eh_abort_cnt;
ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
}; };
struct iscsi_session { struct iscsi_session {
...@@ -240,8 +242,8 @@ struct iscsi_session { ...@@ -240,8 +242,8 @@ struct iscsi_session {
struct iscsi_buf { struct iscsi_buf {
struct scatterlist sg; struct scatterlist sg;
struct kvec iov;
unsigned int sent; unsigned int sent;
char use_sendmsg;
}; };
struct iscsi_data_task { struct iscsi_data_task {
......
...@@ -150,7 +150,7 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba) ...@@ -150,7 +150,7 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba)
return psb; return psb;
} }
struct lpfc_scsi_buf* static struct lpfc_scsi_buf*
lpfc_get_scsi_buf(struct lpfc_hba * phba) lpfc_get_scsi_buf(struct lpfc_hba * phba)
{ {
struct lpfc_scsi_buf * lpfc_cmd = NULL; struct lpfc_scsi_buf * lpfc_cmd = NULL;
......
...@@ -4479,7 +4479,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) ...@@ -4479,7 +4479,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
* serialized. This is so because we want to reserve maximum number of * serialized. This is so because we want to reserve maximum number of
* available command ids for the I/O commands. * available command ids for the I/O commands.
*/ */
down(&adapter->int_mtx); mutex_lock(&adapter->int_mtx);
scb = &adapter->int_scb; scb = &adapter->int_scb;
memset(scb, 0, sizeof(scb_t)); memset(scb, 0, sizeof(scb_t));
...@@ -4527,7 +4527,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) ...@@ -4527,7 +4527,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
mc->cmd, mc->opcode, mc->subopcode, scmd->result); mc->cmd, mc->opcode, mc->subopcode, scmd->result);
} }
up(&adapter->int_mtx); mutex_unlock(&adapter->int_mtx);
return rval; return rval;
} }
...@@ -4866,7 +4866,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -4866,7 +4866,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
adapter->has_64bit_addr = 0; adapter->has_64bit_addr = 0;
} }
init_MUTEX(&adapter->int_mtx); mutex_init(&adapter->int_mtx);
init_completion(&adapter->int_waitq); init_completion(&adapter->int_waitq);
adapter->this_id = DEFAULT_INITIATOR_ID; adapter->this_id = DEFAULT_INITIATOR_ID;
......
此差异已折叠。
此差异已折叠。
...@@ -3,7 +3,7 @@ EXTRA_CFLAGS += -DUNIQUE_FW_NAME ...@@ -3,7 +3,7 @@ EXTRA_CFLAGS += -DUNIQUE_FW_NAME
qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o
obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
qla2100-y := ql2100.o ql2100_fw.o qla2100-y := ql2100.o ql2100_fw.o
qla2200-y := ql2200.o ql2200_fw.o qla2200-y := ql2200.o ql2200_fw.o
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册