Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
This commit is contained in:
@@ -0,0 +1,108 @@
|
|||||||
|
AACRAID Driver for Linux (take two)
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
-------------------------
|
||||||
|
The aacraid driver adds support for Adaptec (http://www.adaptec.com)
|
||||||
|
RAID controllers. This is a major rewrite from the original
|
||||||
|
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
|
||||||
|
the original).
|
||||||
|
|
||||||
|
Supported Cards/Chipsets
|
||||||
|
-------------------------
|
||||||
|
PCI ID (pci.ids) OEM Product
|
||||||
|
9005:0285:9005:028a Adaptec 2020ZCR (Skyhawk)
|
||||||
|
9005:0285:9005:028e Adaptec 2020SA (Skyhawk)
|
||||||
|
9005:0285:9005:028b Adaptec 2025ZCR (Terminator)
|
||||||
|
9005:0285:9005:028f Adaptec 2025SA (Terminator)
|
||||||
|
9005:0285:9005:0286 Adaptec 2120S (Crusader)
|
||||||
|
9005:0286:9005:028d Adaptec 2130S (Lancer)
|
||||||
|
9005:0285:9005:0285 Adaptec 2200S (Vulcan)
|
||||||
|
9005:0285:9005:0287 Adaptec 2200S (Vulcan-2m)
|
||||||
|
9005:0286:9005:028c Adaptec 2230S (Lancer)
|
||||||
|
9005:0286:9005:028c Adaptec 2230SLP (Lancer)
|
||||||
|
9005:0285:9005:0296 Adaptec 2240S (SabreExpress)
|
||||||
|
9005:0285:9005:0290 Adaptec 2410SA (Jaguar)
|
||||||
|
9005:0285:9005:0293 Adaptec 21610SA (Corsair-16)
|
||||||
|
9005:0285:103c:3227 Adaptec 2610SA (Bearcat)
|
||||||
|
9005:0285:9005:0292 Adaptec 2810SA (Corsair-8)
|
||||||
|
9005:0285:9005:0294 Adaptec Prowler
|
||||||
|
9005:0286:9005:029d Adaptec 2420SA (Intruder)
|
||||||
|
9005:0286:9005:029c Adaptec 2620SA (Intruder)
|
||||||
|
9005:0286:9005:029b Adaptec 2820SA (Intruder)
|
||||||
|
9005:0286:9005:02a7 Adaptec 2830SA (Skyray)
|
||||||
|
9005:0286:9005:02a8 Adaptec 2430SA (Skyray)
|
||||||
|
9005:0285:9005:0288 Adaptec 3230S (Harrier)
|
||||||
|
9005:0285:9005:0289 Adaptec 3240S (Tornado)
|
||||||
|
9005:0285:9005:0298 Adaptec 4000SAS (BlackBird)
|
||||||
|
9005:0285:9005:0297 Adaptec 4005SAS (AvonPark)
|
||||||
|
9005:0285:9005:0299 Adaptec 4800SAS (Marauder-X)
|
||||||
|
9005:0285:9005:029a Adaptec 4805SAS (Marauder-E)
|
||||||
|
9005:0286:9005:02a2 Adaptec 4810SAS (Hurricane)
|
||||||
|
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
||||||
|
1011:0046:9005:0365 Adaptec 5400S (Mustang)
|
||||||
|
9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
|
||||||
|
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
|
||||||
|
-------------------------
|
||||||
|
Alan Cox <alan@redhat.com>
|
||||||
|
Christoph Hellwig <hch@infradead.org> (updates for new-style PCI probing and SCSI host registration,
|
||||||
|
small cleanups/fixes)
|
||||||
|
Matt Domsch <matt_domsch@dell.com> (revision ioctl, adapter messages)
|
||||||
|
Deanna Bonds (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
|
||||||
|
added new ioctls, changed scsi interface to use new error handler,
|
||||||
|
increased the number of fibs and outstanding commands to a container)
|
||||||
|
|
||||||
|
(fixed 64bit and 64G memory model, changed confusing naming convention
|
||||||
|
where fibs that go to the hardware are consistently called hw_fibs and
|
||||||
|
not just fibs like the name of the driver tracking structure)
|
||||||
|
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
|
||||||
|
|
||||||
|
Original Driver
|
||||||
|
-------------------------
|
||||||
|
Adaptec Unix OEM Product Group
|
||||||
|
|
||||||
|
Mailing List
|
||||||
|
-------------------------
|
||||||
|
linux-scsi@vger.kernel.org (Interested parties troll here)
|
||||||
|
Also note this is very different to Brian's original driver
|
||||||
|
so don't expect him to support it.
|
||||||
|
Adaptec does support this driver. Contact Adaptec tech support or
|
||||||
|
aacraid@adaptec.com
|
||||||
|
|
||||||
|
Original by Brian Boerner February 2001
|
||||||
|
Rewritten by Alan Cox, November 2001
|
||||||
@@ -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 @@
|
|||||||
* 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 @@
|
|||||||
* 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 @@
|
|||||||
/* 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
|
|||||||
#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
|
|||||||
#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 @@
|
|||||||
* 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 @@
|
|||||||
* 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
|
|||||||
#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
|
|||||||
#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
|
|||||||
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
|
|||||||
} 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
|
|||||||
} 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
|
|||||||
#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
|
|||||||
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
|
|||||||
} 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
|
|||||||
#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
|
|||||||
#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
|
|||||||
|
|
||||||
#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
|
|||||||
} 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
|
|||||||
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
|
|||||||
#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
|
|||||||
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
|
|||||||
} 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
|
|||||||
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
|
|||||||
#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
|
|||||||
} 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 @@
|
|||||||
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
|
|||||||
* 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
|
|||||||
* 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
|
|||||||
* 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
|
|||||||
* 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
|
|||||||
|
|
||||||
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
|
|||||||
* 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 @@
|
|||||||
* 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 @@
|
|||||||
* 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
|
|||||||
|
|
||||||
/* 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 @@
|
|||||||
* 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 @@
|
|||||||
* 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
|
|||||||
#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
|
|||||||
} 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
|
|||||||
#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
|
|||||||
#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
|
|||||||
#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
|
|||||||
#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)
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* 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 @@
|
|||||||
* 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 @@
|
|||||||
* 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 @@
|
|||||||
* 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
|
|||||||
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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* (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)
|
|||||||
|
|
||||||
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)
|
|||||||
/* (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)
|
|||||||
* (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)
|
|||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
* -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
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 @@
|
|||||||
#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 {
|
|||||||
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 {
|
|||||||
#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 {
|
|||||||
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
|
|||||||
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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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:
|
||||||
|
|||||||
+546
-35
@@ -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;
|
|||||||
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[] = {
|
|||||||
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 = {
|
||||||
* mptfc_probe - Installs scsi devices per bus.
|
.dd_fcrport_size = 8,
|
||||||
* @pdev: Pointer to pci_dev structure
|
.show_host_node_name = 1,
|
||||||
*
|
.show_host_port_name = 1,
|
||||||
* Returns 0 for success, non-zero for failure.
|
.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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OS entry point to allow host driver to alloc memory
|
||||||
|
* for each scsi device. Called once per device the bus scan.
|
||||||
|
* Return non-zero if allocation fails.
|
||||||
|
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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 = {
|
|||||||
.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 = {
|
|||||||
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)
|
|||||||
": 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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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++)
|
||||||
|
|||||||
+346
-58
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||||
* (mailto:mpt_linux_developer@lsil.com)
|
* (mailto:mpt_linux_developer@lsil.com)
|
||||||
* Copyright (c) 2005 Dell
|
* Copyright (c) 2005-2006 Dell
|
||||||
*/
|
*/
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/*
|
||||||
@@ -86,6 +86,24 @@ static int mptsasInternalCtx = -1; /* Used only for internal commands */
|
|||||||
static int mptsasMgmtCtx = -1;
|
static int mptsasMgmtCtx = -1;
|
||||||
|
|
||||||
|
|
||||||
|
enum mptsas_hotplug_action {
|
||||||
|
MPTSAS_ADD_DEVICE,
|
||||||
|
MPTSAS_DEL_DEVICE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mptsas_hotplug_event {
|
||||||
|
struct work_struct work;
|
||||||
|
MPT_ADAPTER *ioc;
|
||||||
|
enum mptsas_hotplug_action event_type;
|
||||||
|
u64 sas_address;
|
||||||
|
u32 channel;
|
||||||
|
u32 id;
|
||||||
|
u32 device_info;
|
||||||
|
u16 handle;
|
||||||
|
u16 parent_handle;
|
||||||
|
u8 phy_id;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SAS topology structures
|
* SAS topology structures
|
||||||
*
|
*
|
||||||
@@ -99,8 +117,8 @@ struct mptsas_devinfo {
|
|||||||
u8 phy_id; /* phy number of parent device */
|
u8 phy_id; /* phy number of parent device */
|
||||||
u8 port_id; /* sas physical port this device
|
u8 port_id; /* sas physical port this device
|
||||||
is assoc'd with */
|
is assoc'd with */
|
||||||
u8 target; /* logical target id of this device */
|
u8 id; /* logical target id of this device */
|
||||||
u8 bus; /* logical bus number of this device */
|
u8 channel; /* logical bus number of this device */
|
||||||
u64 sas_address; /* WWN of this device,
|
u64 sas_address; /* WWN of this device,
|
||||||
SATA is assigned by HBA,expander */
|
SATA is assigned by HBA,expander */
|
||||||
u32 device_info; /* bitfield detailed info about this device */
|
u32 device_info; /* bitfield detailed info about this device */
|
||||||
@@ -114,6 +132,7 @@ struct mptsas_phyinfo {
|
|||||||
u8 programmed_link_rate; /* programmed max/min phy link rate */
|
u8 programmed_link_rate; /* programmed max/min phy link rate */
|
||||||
struct mptsas_devinfo identify; /* point to phy device info */
|
struct mptsas_devinfo identify; /* point to phy device info */
|
||||||
struct mptsas_devinfo attached; /* point to attached device info */
|
struct mptsas_devinfo attached; /* point to attached device info */
|
||||||
|
struct sas_phy *phy;
|
||||||
struct sas_rphy *rphy;
|
struct sas_rphy *rphy;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -239,13 +258,12 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
|||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
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;
|
||||||
sdev->hostdata = vdev;
|
sdev->hostdata = vdev;
|
||||||
starget = scsi_target(sdev);
|
starget = scsi_target(sdev);
|
||||||
@@ -256,19 +274,32 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
|||||||
hd->Targets[sdev->id] = vtarget;
|
hd->Targets[sdev->id] = vtarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAID volumes placed beyond the last expected port.
|
||||||
|
*/
|
||||||
|
if (sdev->channel == hd->ioc->num_ports) {
|
||||||
|
vdev->target_id = sdev->id;
|
||||||
|
vdev->bus_id = 0;
|
||||||
|
vdev->lun = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
|
rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
|
||||||
|
mutex_lock(&hd->ioc->sas_topology_mutex);
|
||||||
list_for_each_entry(p, &hd->ioc->sas_topology, list) {
|
list_for_each_entry(p, &hd->ioc->sas_topology, list) {
|
||||||
for (i = 0; i < p->num_phys; i++) {
|
for (i = 0; i < p->num_phys; i++) {
|
||||||
if (p->phy_info[i].attached.sas_address ==
|
if (p->phy_info[i].attached.sas_address ==
|
||||||
rphy->identify.sas_address) {
|
rphy->identify.sas_address) {
|
||||||
vdev->target_id =
|
vdev->target_id =
|
||||||
p->phy_info[i].attached.target;
|
p->phy_info[i].attached.id;
|
||||||
vdev->bus_id = p->phy_info[i].attached.bus;
|
vdev->bus_id = p->phy_info[i].attached.channel;
|
||||||
vdev->lun = sdev->lun;
|
vdev->lun = sdev->lun;
|
||||||
|
mutex_unlock(&hd->ioc->sas_topology_mutex);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&hd->ioc->sas_topology_mutex);
|
||||||
|
|
||||||
printk("No matching SAS device found!!\n");
|
printk("No matching SAS device found!!\n");
|
||||||
kfree(vdev);
|
kfree(vdev);
|
||||||
@@ -282,6 +313,42 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mptsas_slave_destroy(struct scsi_device *sdev)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *host = sdev->host;
|
||||||
|
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
|
||||||
|
struct sas_rphy *rphy;
|
||||||
|
struct mptsas_portinfo *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle hotplug removal case.
|
||||||
|
* We need to clear out attached data structure.
|
||||||
|
*/
|
||||||
|
rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
|
||||||
|
|
||||||
|
mutex_lock(&hd->ioc->sas_topology_mutex);
|
||||||
|
list_for_each_entry(p, &hd->ioc->sas_topology, list) {
|
||||||
|
for (i = 0; i < p->num_phys; i++) {
|
||||||
|
if (p->phy_info[i].attached.sas_address ==
|
||||||
|
rphy->identify.sas_address) {
|
||||||
|
memset(&p->phy_info[i].attached, 0,
|
||||||
|
sizeof(struct mptsas_devinfo));
|
||||||
|
p->phy_info[i].rphy = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&hd->ioc->sas_topology_mutex);
|
||||||
|
/*
|
||||||
|
* TODO: Issue target reset to flush firmware outstanding commands.
|
||||||
|
*/
|
||||||
|
mptscsih_slave_destroy(sdev);
|
||||||
|
}
|
||||||
|
|
||||||
static struct scsi_host_template mptsas_driver_template = {
|
static struct scsi_host_template mptsas_driver_template = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.proc_name = "mptsas",
|
.proc_name = "mptsas",
|
||||||
@@ -293,7 +360,7 @@ static struct scsi_host_template mptsas_driver_template = {
|
|||||||
.slave_alloc = mptsas_slave_alloc,
|
.slave_alloc = mptsas_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 = mptsas_slave_destroy,
|
||||||
.change_queue_depth = mptscsih_change_queue_depth,
|
.change_queue_depth = mptscsih_change_queue_depth,
|
||||||
.eh_abort_handler = mptscsih_abort,
|
.eh_abort_handler = mptscsih_abort,
|
||||||
.eh_device_reset_handler = mptscsih_dev_reset,
|
.eh_device_reset_handler = mptscsih_dev_reset,
|
||||||
@@ -399,7 +466,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
|
|||||||
if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
|
if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
if (down_interruptible(&ioc->sas_mgmt.mutex))
|
if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
|
mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
|
||||||
@@ -450,7 +517,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
|
|||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
up(&ioc->sas_mgmt.mutex);
|
mutex_unlock(&ioc->sas_mgmt.mutex);
|
||||||
out:
|
out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -649,8 +716,8 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
|
|||||||
device_info->handle = le16_to_cpu(buffer->DevHandle);
|
device_info->handle = le16_to_cpu(buffer->DevHandle);
|
||||||
device_info->phy_id = buffer->PhyNum;
|
device_info->phy_id = buffer->PhyNum;
|
||||||
device_info->port_id = buffer->PhysicalPort;
|
device_info->port_id = buffer->PhysicalPort;
|
||||||
device_info->target = buffer->TargetID;
|
device_info->id = buffer->TargetID;
|
||||||
device_info->bus = buffer->Bus;
|
device_info->channel = buffer->Bus;
|
||||||
memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
|
memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
|
||||||
device_info->sas_address = le64_to_cpu(sas_address);
|
device_info->sas_address = le64_to_cpu(sas_address);
|
||||||
device_info->device_info =
|
device_info->device_info =
|
||||||
@@ -858,36 +925,36 @@ mptsas_parse_device_info(struct sas_identify *identify,
|
|||||||
static int mptsas_probe_one_phy(struct device *dev,
|
static int mptsas_probe_one_phy(struct device *dev,
|
||||||
struct mptsas_phyinfo *phy_info, int index, int local)
|
struct mptsas_phyinfo *phy_info, int index, int local)
|
||||||
{
|
{
|
||||||
struct sas_phy *port;
|
struct sas_phy *phy;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
port = sas_phy_alloc(dev, index);
|
phy = sas_phy_alloc(dev, index);
|
||||||
if (!port)
|
if (!phy)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
port->port_identifier = phy_info->port_id;
|
phy->port_identifier = phy_info->port_id;
|
||||||
mptsas_parse_device_info(&port->identify, &phy_info->identify);
|
mptsas_parse_device_info(&phy->identify, &phy_info->identify);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set Negotiated link rate.
|
* Set Negotiated link rate.
|
||||||
*/
|
*/
|
||||||
switch (phy_info->negotiated_link_rate) {
|
switch (phy_info->negotiated_link_rate) {
|
||||||
case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
|
case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
|
||||||
port->negotiated_linkrate = SAS_PHY_DISABLED;
|
phy->negotiated_linkrate = SAS_PHY_DISABLED;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
|
case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
|
||||||
port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
|
phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_IOUNIT0_RATE_1_5:
|
case MPI_SAS_IOUNIT0_RATE_1_5:
|
||||||
port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_IOUNIT0_RATE_3_0:
|
case MPI_SAS_IOUNIT0_RATE_3_0:
|
||||||
port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
|
case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
|
||||||
case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
|
case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
|
phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,10 +963,10 @@ static int mptsas_probe_one_phy(struct device *dev,
|
|||||||
*/
|
*/
|
||||||
switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
|
switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
|
||||||
case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
|
case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
|
||||||
port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
|
phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
|
case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
|
||||||
port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
|
phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -911,10 +978,10 @@ static int mptsas_probe_one_phy(struct device *dev,
|
|||||||
switch (phy_info->programmed_link_rate &
|
switch (phy_info->programmed_link_rate &
|
||||||
MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
|
MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
|
||||||
case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
|
case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
|
||||||
port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
|
case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
|
||||||
port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -925,10 +992,10 @@ static int mptsas_probe_one_phy(struct device *dev,
|
|||||||
*/
|
*/
|
||||||
switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
|
switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
|
||||||
case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
|
case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
|
||||||
port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
|
phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
|
case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
|
||||||
port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
|
phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -940,28 +1007,29 @@ static int mptsas_probe_one_phy(struct device *dev,
|
|||||||
switch (phy_info->programmed_link_rate &
|
switch (phy_info->programmed_link_rate &
|
||||||
MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
|
MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
|
||||||
case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
|
case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
|
||||||
port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
|
||||||
break;
|
break;
|
||||||
case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
|
case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
|
||||||
port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local)
|
if (local)
|
||||||
port->local_attached = 1;
|
phy->local_attached = 1;
|
||||||
|
|
||||||
error = sas_phy_add(port);
|
error = sas_phy_add(phy);
|
||||||
if (error) {
|
if (error) {
|
||||||
sas_phy_free(port);
|
sas_phy_free(phy);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
phy_info->phy = phy;
|
||||||
|
|
||||||
if (phy_info->attached.handle) {
|
if (phy_info->attached.handle) {
|
||||||
struct sas_rphy *rphy;
|
struct sas_rphy *rphy;
|
||||||
|
|
||||||
rphy = sas_rphy_alloc(port);
|
rphy = sas_rphy_alloc(phy);
|
||||||
if (!rphy)
|
if (!rphy)
|
||||||
return 0; /* non-fatal: an rphy can be added later */
|
return 0; /* non-fatal: an rphy can be added later */
|
||||||
|
|
||||||
@@ -985,16 +1053,19 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
|
|||||||
u32 handle = 0xFFFF;
|
u32 handle = 0xFFFF;
|
||||||
int error = -ENOMEM, i;
|
int error = -ENOMEM, i;
|
||||||
|
|
||||||
port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
|
port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
|
||||||
if (!port_info)
|
if (!port_info)
|
||||||
goto out;
|
goto out;
|
||||||
memset(port_info, 0, sizeof(*port_info));
|
|
||||||
|
|
||||||
error = mptsas_sas_io_unit_pg0(ioc, port_info);
|
error = mptsas_sas_io_unit_pg0(ioc, port_info);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_free_port_info;
|
goto out_free_port_info;
|
||||||
|
|
||||||
|
ioc->num_ports = port_info->num_phys;
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
list_add_tail(&port_info->list, &ioc->sas_topology);
|
list_add_tail(&port_info->list, &ioc->sas_topology);
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
for (i = 0; i < port_info->num_phys; i++) {
|
for (i = 0; i < port_info->num_phys; i++) {
|
||||||
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
|
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
|
||||||
(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
|
(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
|
||||||
@@ -1034,10 +1105,9 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
|||||||
struct mptsas_portinfo *port_info, *p;
|
struct mptsas_portinfo *port_info, *p;
|
||||||
int error = -ENOMEM, i, j;
|
int error = -ENOMEM, i, j;
|
||||||
|
|
||||||
port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
|
port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
|
||||||
if (!port_info)
|
if (!port_info)
|
||||||
goto out;
|
goto out;
|
||||||
memset(port_info, 0, sizeof(*port_info));
|
|
||||||
|
|
||||||
error = mptsas_sas_expander_pg0(ioc, port_info,
|
error = mptsas_sas_expander_pg0(ioc, port_info,
|
||||||
(MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
|
(MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
|
||||||
@@ -1047,7 +1117,10 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
|||||||
|
|
||||||
*handle = port_info->handle;
|
*handle = port_info->handle;
|
||||||
|
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
list_add_tail(&port_info->list, &ioc->sas_topology);
|
list_add_tail(&port_info->list, &ioc->sas_topology);
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
for (i = 0; i < port_info->num_phys; i++) {
|
for (i = 0; i < port_info->num_phys; i++) {
|
||||||
struct device *parent;
|
struct device *parent;
|
||||||
|
|
||||||
@@ -1079,6 +1152,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
|||||||
* HBA phys.
|
* HBA phys.
|
||||||
*/
|
*/
|
||||||
parent = &ioc->sh->shost_gendev;
|
parent = &ioc->sh->shost_gendev;
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
list_for_each_entry(p, &ioc->sas_topology, list) {
|
list_for_each_entry(p, &ioc->sas_topology, list) {
|
||||||
for (j = 0; j < p->num_phys; j++) {
|
for (j = 0; j < p->num_phys; j++) {
|
||||||
if (port_info->phy_info[i].identify.handle ==
|
if (port_info->phy_info[i].identify.handle ==
|
||||||
@@ -1086,6 +1160,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
|||||||
parent = &p->phy_info[j].rphy->dev;
|
parent = &p->phy_info[j].rphy->dev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
mptsas_probe_one_phy(parent, &port_info->phy_info[i],
|
mptsas_probe_one_phy(parent, &port_info->phy_info[i],
|
||||||
*index, 0);
|
*index, 0);
|
||||||
@@ -1111,6 +1186,211 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct mptsas_phyinfo *
|
||||||
|
mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id)
|
||||||
|
{
|
||||||
|
struct mptsas_portinfo *port_info;
|
||||||
|
struct mptsas_devinfo device_info;
|
||||||
|
struct mptsas_phyinfo *phy_info = NULL;
|
||||||
|
int i, error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the parent sas_address
|
||||||
|
*/
|
||||||
|
error = mptsas_sas_device_pg0(ioc, &device_info,
|
||||||
|
(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
|
||||||
|
MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
|
||||||
|
parent_handle);
|
||||||
|
if (error) {
|
||||||
|
printk("mptsas: failed to retrieve device page\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The phy_info structures are never deallocated during lifetime of
|
||||||
|
* a host, so the code below is safe without additional refcounting.
|
||||||
|
*/
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
|
list_for_each_entry(port_info, &ioc->sas_topology, list) {
|
||||||
|
for (i = 0; i < port_info->num_phys; i++) {
|
||||||
|
if (port_info->phy_info[i].identify.sas_address ==
|
||||||
|
device_info.sas_address &&
|
||||||
|
port_info->phy_info[i].phy_id == phy_id) {
|
||||||
|
phy_info = &port_info->phy_info[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
|
return phy_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mptsas_phyinfo *
|
||||||
|
mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
|
||||||
|
{
|
||||||
|
struct mptsas_portinfo *port_info;
|
||||||
|
struct mptsas_phyinfo *phy_info = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The phy_info structures are never deallocated during lifetime of
|
||||||
|
* a host, so the code below is safe without additional refcounting.
|
||||||
|
*/
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
|
list_for_each_entry(port_info, &ioc->sas_topology, list) {
|
||||||
|
for (i = 0; i < port_info->num_phys; i++) {
|
||||||
|
if (port_info->phy_info[i].attached.handle == handle) {
|
||||||
|
phy_info = &port_info->phy_info[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
|
return phy_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mptsas_hotplug_work(void *arg)
|
||||||
|
{
|
||||||
|
struct mptsas_hotplug_event *ev = arg;
|
||||||
|
MPT_ADAPTER *ioc = ev->ioc;
|
||||||
|
struct mptsas_phyinfo *phy_info;
|
||||||
|
struct sas_rphy *rphy;
|
||||||
|
char *ds = NULL;
|
||||||
|
|
||||||
|
if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
|
||||||
|
ds = "ssp";
|
||||||
|
if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
|
||||||
|
ds = "stp";
|
||||||
|
if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
|
||||||
|
ds = "sata";
|
||||||
|
|
||||||
|
switch (ev->event_type) {
|
||||||
|
case MPTSAS_DEL_DEVICE:
|
||||||
|
printk(MYIOC_s_INFO_FMT
|
||||||
|
"removing %s device, channel %d, id %d, phy %d\n",
|
||||||
|
ioc->name, ds, ev->channel, ev->id, ev->phy_id);
|
||||||
|
|
||||||
|
phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle);
|
||||||
|
if (!phy_info) {
|
||||||
|
printk("mptsas: remove event for non-existant PHY.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phy_info->rphy) {
|
||||||
|
sas_rphy_delete(phy_info->rphy);
|
||||||
|
phy_info->rphy = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPTSAS_ADD_DEVICE:
|
||||||
|
printk(MYIOC_s_INFO_FMT
|
||||||
|
"attaching %s device, channel %d, id %d, phy %d\n",
|
||||||
|
ioc->name, ds, ev->channel, ev->id, ev->phy_id);
|
||||||
|
|
||||||
|
phy_info = mptsas_find_phyinfo_by_parent(ioc,
|
||||||
|
ev->parent_handle, ev->phy_id);
|
||||||
|
if (!phy_info) {
|
||||||
|
printk("mptsas: add event for non-existant PHY.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phy_info->rphy) {
|
||||||
|
printk("mptsas: trying to add existing device.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill attached info */
|
||||||
|
phy_info->attached.handle = ev->handle;
|
||||||
|
phy_info->attached.phy_id = ev->phy_id;
|
||||||
|
phy_info->attached.port_id = phy_info->identify.port_id;
|
||||||
|
phy_info->attached.id = ev->id;
|
||||||
|
phy_info->attached.channel = ev->channel;
|
||||||
|
phy_info->attached.sas_address = ev->sas_address;
|
||||||
|
phy_info->attached.device_info = ev->device_info;
|
||||||
|
|
||||||
|
rphy = sas_rphy_alloc(phy_info->phy);
|
||||||
|
if (!rphy)
|
||||||
|
break; /* non-fatal: an rphy can be added later */
|
||||||
|
|
||||||
|
mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
|
||||||
|
if (sas_rphy_add(rphy)) {
|
||||||
|
sas_rphy_free(rphy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
phy_info->rphy = rphy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mptscsih_send_sas_event(MPT_ADAPTER *ioc,
|
||||||
|
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
|
||||||
|
{
|
||||||
|
struct mptsas_hotplug_event *ev;
|
||||||
|
u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
|
||||||
|
__le64 sas_address;
|
||||||
|
|
||||||
|
if ((device_info &
|
||||||
|
(MPI_SAS_DEVICE_INFO_SSP_TARGET |
|
||||||
|
MPI_SAS_DEVICE_INFO_STP_TARGET |
|
||||||
|
MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((sas_event_data->ReasonCode &
|
||||||
|
(MPI_EVENT_SAS_DEV_STAT_RC_ADDED |
|
||||||
|
MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING)) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
|
||||||
|
if (!ev) {
|
||||||
|
printk(KERN_WARNING "mptsas: lost hotplug event\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INIT_WORK(&ev->work, mptsas_hotplug_work, ev);
|
||||||
|
ev->ioc = ioc;
|
||||||
|
ev->handle = le16_to_cpu(sas_event_data->DevHandle);
|
||||||
|
ev->parent_handle = le16_to_cpu(sas_event_data->ParentDevHandle);
|
||||||
|
ev->channel = sas_event_data->Bus;
|
||||||
|
ev->id = sas_event_data->TargetID;
|
||||||
|
ev->phy_id = sas_event_data->PhyNum;
|
||||||
|
memcpy(&sas_address, &sas_event_data->SASAddress, sizeof(__le64));
|
||||||
|
ev->sas_address = le64_to_cpu(sas_address);
|
||||||
|
ev->device_info = device_info;
|
||||||
|
|
||||||
|
if (sas_event_data->ReasonCode & MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
|
||||||
|
ev->event_type = MPTSAS_ADD_DEVICE;
|
||||||
|
else
|
||||||
|
ev->event_type = MPTSAS_DEL_DEVICE;
|
||||||
|
|
||||||
|
schedule_work(&ev->work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
|
||||||
|
{
|
||||||
|
u8 event = le32_to_cpu(reply->Event) & 0xFF;
|
||||||
|
|
||||||
|
if (!ioc->sh)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
|
||||||
|
mptscsih_send_sas_event(ioc,
|
||||||
|
(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
|
||||||
|
return 1; /* currently means nothing really */
|
||||||
|
|
||||||
|
default:
|
||||||
|
return mptscsih_event_process(ioc, reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
@@ -1118,11 +1398,10 @@ mptsas_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;
|
||||||
|
|
||||||
@@ -1203,7 +1482,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
sh->unique_id = ioc->id;
|
sh->unique_id = ioc->id;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ioc->sas_topology);
|
INIT_LIST_HEAD(&ioc->sas_topology);
|
||||||
init_MUTEX(&ioc->sas_mgmt.mutex);
|
mutex_init(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
|
mutex_init(&ioc->sas_mgmt.mutex);
|
||||||
init_completion(&ioc->sas_mgmt.done);
|
init_completion(&ioc->sas_mgmt.done);
|
||||||
|
|
||||||
/* Verify that we won't exceed the maximum
|
/* Verify that we won't exceed the maximum
|
||||||
@@ -1244,36 +1525,27 @@ mptsas_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_mptsas_probe;
|
goto out_mptsas_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_mptsas_probe;
|
goto out_mptsas_probe;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(mem, 0, sz);
|
dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
|
||||||
hd->Targets = (VirtTarget **) mem;
|
|
||||||
|
|
||||||
dprintk((KERN_INFO
|
|
||||||
" vtarget @ %p, sz=%d\n", hd->Targets, sz));
|
|
||||||
|
|
||||||
/* Clear the TM flags
|
/* Clear the TM flags
|
||||||
*/
|
*/
|
||||||
@@ -1324,6 +1596,20 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
|
|
||||||
mptsas_scan_sas_topology(ioc);
|
mptsas_scan_sas_topology(ioc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reporting RAID volumes.
|
||||||
|
*/
|
||||||
|
if (!ioc->raid_data.pIocPg2)
|
||||||
|
return 0;
|
||||||
|
if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
|
||||||
|
return 0;
|
||||||
|
for (ii=0;ii<ioc->raid_data.pIocPg2->NumActiveVolumes;ii++) {
|
||||||
|
scsi_add_device(sh,
|
||||||
|
ioc->num_ports,
|
||||||
|
ioc->raid_data.pIocPg2->RaidVolume[ii].VolumeID,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_mptsas_probe:
|
out_mptsas_probe:
|
||||||
@@ -1339,10 +1625,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
sas_remove_host(ioc->sh);
|
sas_remove_host(ioc->sh);
|
||||||
|
|
||||||
|
mutex_lock(&ioc->sas_topology_mutex);
|
||||||
list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
|
list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
|
||||||
list_del(&p->list);
|
list_del(&p->list);
|
||||||
kfree(p);
|
kfree(p);
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&ioc->sas_topology_mutex);
|
||||||
|
|
||||||
mptscsih_remove(pdev);
|
mptscsih_remove(pdev);
|
||||||
}
|
}
|
||||||
@@ -1393,7 +1681,7 @@ mptsas_init(void)
|
|||||||
mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
|
mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
|
||||||
mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
|
mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
|
||||||
|
|
||||||
if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
|
if (mpt_event_register(mptsasDoneCtx, mptsas_event_process) == 0) {
|
||||||
devtprintk((KERN_INFO MYNAM
|
devtprintk((KERN_INFO MYNAM
|
||||||
": Registered for IOC event notifications\n"));
|
": Registered for IOC event notifications\n"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
| 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
"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)
|
|||||||
"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)
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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 @@
|
|||||||
#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 @@
|
|||||||
/* 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
|
||||||
|
|||||||
+135
-55
@@ -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,
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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;
|
||||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
fc_stats->rx_words = data->rx_words - old->rx_words;
|
||||||
port = zfcp_port_lookup(adapter, starget->channel, starget->id);
|
fc_stats->lip_count = data->lip - old->lip;
|
||||||
if (port)
|
fc_stats->nos_count = data->nos - old->nos;
|
||||||
fc_starget_port_name(starget) = port->wwpn;
|
fc_stats->error_frames = data->error_frames - old->error_frames;
|
||||||
else
|
fc_stats->dumped_frames = data->dumped_frames - old->dumped_frames;
|
||||||
fc_starget_port_name(starget) = -1;
|
fc_stats->link_failure_count = data->link_failure - old->link_failure;
|
||||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zfcp_get_node_name(struct scsi_target *starget)
|
zfcp_set_fc_host_stats(struct fc_host_statistics *fc_stats,
|
||||||
|
struct fsf_qtcb_bottom_port *data)
|
||||||
{
|
{
|
||||||
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];
|
fc_stats->tx_frames = data->tx_frames;
|
||||||
struct zfcp_port *port;
|
fc_stats->tx_words = data->tx_words;
|
||||||
unsigned long flags;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
/**
|
||||||
port = zfcp_port_lookup(adapter, starget->channel, starget->id);
|
* zfcp_get_fc_host_stats - provide fc_host_statistics for scsi_transport_fc
|
||||||
if (port)
|
*
|
||||||
fc_starget_node_name(starget) = port->wwnn;
|
* assumption: scsi_transport_fc synchronizes calls of
|
||||||
else
|
* get_fc_host_stats and reset_fc_host_stats
|
||||||
fc_starget_node_name(starget) = -1;
|
* (XXX to be checked otherwise introduce locking)
|
||||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
*/
|
||||||
|
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
|
||||||
|
zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
|
||||||
|
{
|
||||||
|
struct zfcp_adapter *adapter;
|
||||||
|
struct fsf_qtcb_bottom_port *data, *old_data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
adapter = (struct zfcp_adapter *)shost->hostdata[0];
|
||||||
|
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return;
|
||||||
|
memset(data, 0, sizeof(*data));
|
||||||
|
|
||||||
|
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 @@
|
|||||||
|
|
||||||
#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);
|
|||||||
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[] = {
|
|||||||
&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_
|
|||||||
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[] = {
|
|||||||
&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_
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
#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
|
|||||||
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 @@ out3:
|
|||||||
/* 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)
|
|||||||
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 {
|
|||||||
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 @@
|
|||||||
#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
|
|||||||
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 @@ out2:
|
|||||||
/* 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)
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
AACRAID Driver for Linux (take two)
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
-------------------------
|
|
||||||
The aacraid driver adds support for Adaptec (http://www.adaptec.com)
|
|
||||||
RAID controllers. This is a major rewrite from the original
|
|
||||||
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
|
|
||||||
the original).
|
|
||||||
|
|
||||||
Supported Cards/Chipsets
|
|
||||||
-------------------------
|
|
||||||
Adaptec 2020S
|
|
||||||
Adaptec 2025S
|
|
||||||
Adaptec 2120S
|
|
||||||
Adaptec 2130S
|
|
||||||
Adaptec 2200S
|
|
||||||
Adaptec 2230S
|
|
||||||
Adaptec 2240S
|
|
||||||
Adaptec 2410SA
|
|
||||||
Adaptec 2610SA
|
|
||||||
Adaptec 2810SA
|
|
||||||
Adaptec 21610SA
|
|
||||||
Adaptec 3230S
|
|
||||||
Adaptec 3240S
|
|
||||||
Adaptec 4000SAS
|
|
||||||
Adaptec 4005SAS
|
|
||||||
Adaptec 4800SAS
|
|
||||||
Adaptec 4805SAS
|
|
||||||
Adaptec 5400S
|
|
||||||
Dell PERC 2 Quad Channel
|
|
||||||
Dell PERC 2/Si
|
|
||||||
Dell PERC 3/Si
|
|
||||||
Dell PERC 3/Di
|
|
||||||
Dell CERC 2
|
|
||||||
HP NetRAID-4M
|
|
||||||
Legend S220
|
|
||||||
Legend S230
|
|
||||||
IBM ServeRAID 8i
|
|
||||||
ICP 9014R0
|
|
||||||
ICP 9024R0
|
|
||||||
ICP 9047MA
|
|
||||||
ICP 9087MA
|
|
||||||
ICP 9085LI
|
|
||||||
ICP 5085AU
|
|
||||||
|
|
||||||
People
|
|
||||||
-------------------------
|
|
||||||
Alan Cox <alan@redhat.com>
|
|
||||||
Christoph Hellwig <hch@infradead.org> (updates for new-style PCI probing and SCSI host registration,
|
|
||||||
small cleanups/fixes)
|
|
||||||
Matt Domsch <matt_domsch@dell.com> (revision ioctl, adapter messages)
|
|
||||||
Deanna Bonds (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
|
|
||||||
added new ioctls, changed scsi interface to use new error handler,
|
|
||||||
increased the number of fibs and outstanding commands to a container)
|
|
||||||
|
|
||||||
(fixed 64bit and 64G memory model, changed confusing naming convention
|
|
||||||
where fibs that go to the hardware are consistently called hw_fibs and
|
|
||||||
not just fibs like the name of the driver tracking structure)
|
|
||||||
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
|
|
||||||
|
|
||||||
Original Driver
|
|
||||||
-------------------------
|
|
||||||
Adaptec Unix OEM Product Group
|
|
||||||
|
|
||||||
Mailing List
|
|
||||||
-------------------------
|
|
||||||
linux-scsi@vger.kernel.org (Interested parties troll here)
|
|
||||||
Also note this is very different to Brian's original driver
|
|
||||||
so don't expect him to support it.
|
|
||||||
Adaptec does support this driver. Contact either tech support or Mark Salyzyn.
|
|
||||||
|
|
||||||
Original by Brian Boerner February 2001
|
|
||||||
Rewritten by Alan Cox, November 2001
|
|
||||||
@@ -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)
|
|||||||
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[] = {
|
|||||||
{ 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
= (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
|
|||||||
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 @@
|
|||||||
* 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;
|
|||||||
#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;
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
*/
|
*/
|
||||||
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 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/****************************** 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 @@
|
|||||||
*
|
*
|
||||||
* $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 $"
|
|||||||
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 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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
|
|||||||
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 @@
|
|||||||
* $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:
|
|||||||
}
|
}
|
||||||
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:
|
|||||||
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:
|
|||||||
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;
|
|||||||
|
|
||||||
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;
|
|||||||
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:
|
|||||||
* 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:
|
|||||||
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:
|
|||||||
* 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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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;
|
|||||||
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:
|
|||||||
/*
|
/*
|
||||||
* 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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
* 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;
|
|||||||
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:
|
|||||||
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:
|
|||||||
/* 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:
|
|||||||
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:
|
|||||||
* 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:
|
|||||||
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:
|
|||||||
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;
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+418
-365
File diff suppressed because it is too large
Load Diff
@@ -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 { \
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
|
|
||||||
/* 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);
|
|||||||
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)
|
|||||||
#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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
* 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 @@ done:
|
|||||||
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)
|
|||||||
/***************************** 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 @@
|
|||||||
* 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 [] =
|
|||||||
"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 [] =
|
|||||||
"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 [] =
|
|||||||
"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)
|
|||||||
* 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 @@
|
|||||||
#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
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
* DO NOT EDIT - This file is automatically generated
|
* DO NOT EDIT - This file is automatically generated
|
||||||
* from the following source files:
|
* from the following source files:
|
||||||
*
|
*
|
||||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
|
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#118 $
|
||||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
|
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#75 $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "aic79xx_osm.h"
|
#include "aic79xx_osm.h"
|
||||||
@@ -172,21 +172,6 @@ ahd_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x0b, regvalue, cur_col, wrap));
|
0x0b, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = {
|
|
||||||
{ "CLRSEQ_SPLTINT", 0x01, 0x01 },
|
|
||||||
{ "CLRSEQ_PCIINT", 0x02, 0x02 },
|
|
||||||
{ "CLRSEQ_SCSIINT", 0x04, 0x04 },
|
|
||||||
{ "CLRSEQ_SEQINT", 0x08, 0x08 },
|
|
||||||
{ "CLRSEQ_SWTMRTO", 0x10, 0x10 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT",
|
|
||||||
0x0c, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = {
|
static ahd_reg_parse_entry_t SEQINTSTAT_parse_table[] = {
|
||||||
{ "SEQ_SPLTINT", 0x01, 0x01 },
|
{ "SEQ_SPLTINT", 0x01, 0x01 },
|
||||||
{ "SEQ_PCIINT", 0x02, 0x02 },
|
{ "SEQ_PCIINT", 0x02, 0x02 },
|
||||||
@@ -202,6 +187,21 @@ ahd_seqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x0c, regvalue, cur_col, wrap));
|
0x0c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t CLRSEQINTSTAT_parse_table[] = {
|
||||||
|
{ "CLRSEQ_SPLTINT", 0x01, 0x01 },
|
||||||
|
{ "CLRSEQ_PCIINT", 0x02, 0x02 },
|
||||||
|
{ "CLRSEQ_SCSIINT", 0x04, 0x04 },
|
||||||
|
{ "CLRSEQ_SEQINT", 0x08, 0x08 },
|
||||||
|
{ "CLRSEQ_SWTMRTO", 0x10, 0x10 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_clrseqintstat_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(CLRSEQINTSTAT_parse_table, 5, "CLRSEQINTSTAT",
|
||||||
|
0x0c, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_swtimer_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -670,16 +670,16 @@ ahd_sxfrctl0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "BUSINITID",
|
return (ahd_print_register(NULL, 0, "DLCOUNT",
|
||||||
0x3c, regvalue, cur_col, wrap));
|
0x3c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_dlcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_businitid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "DLCOUNT",
|
return (ahd_print_register(NULL, 0, "BUSINITID",
|
||||||
0x3c, regvalue, cur_col, wrap));
|
0x3c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,21 +859,6 @@ ahd_selid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x49, regvalue, cur_col, wrap));
|
0x49, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = {
|
|
||||||
{ "SELWIDE", 0x02, 0x02 },
|
|
||||||
{ "ENAB20", 0x04, 0x04 },
|
|
||||||
{ "ENAB40", 0x08, 0x08 },
|
|
||||||
{ "DIAGLEDON", 0x40, 0x40 },
|
|
||||||
{ "DIAGLEDEN", 0x80, 0x80 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL",
|
|
||||||
0x4a, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = {
|
static ahd_reg_parse_entry_t OPTIONMODE_parse_table[] = {
|
||||||
{ "AUTO_MSGOUT_DE", 0x02, 0x02 },
|
{ "AUTO_MSGOUT_DE", 0x02, 0x02 },
|
||||||
{ "ENDGFORMCHK", 0x04, 0x04 },
|
{ "ENDGFORMCHK", 0x04, 0x04 },
|
||||||
@@ -891,22 +876,19 @@ ahd_optionmode_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x4a, regvalue, cur_col, wrap));
|
0x4a, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SSTAT0_parse_table[] = {
|
static ahd_reg_parse_entry_t SBLKCTL_parse_table[] = {
|
||||||
{ "ARBDO", 0x01, 0x01 },
|
{ "SELWIDE", 0x02, 0x02 },
|
||||||
{ "SPIORDY", 0x02, 0x02 },
|
{ "ENAB20", 0x04, 0x04 },
|
||||||
{ "OVERRUN", 0x04, 0x04 },
|
{ "ENAB40", 0x08, 0x08 },
|
||||||
{ "IOERR", 0x08, 0x08 },
|
{ "DIAGLEDON", 0x40, 0x40 },
|
||||||
{ "SELINGO", 0x10, 0x10 },
|
{ "DIAGLEDEN", 0x80, 0x80 }
|
||||||
{ "SELDI", 0x20, 0x20 },
|
|
||||||
{ "SELDO", 0x40, 0x40 },
|
|
||||||
{ "TARGET", 0x80, 0x80 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_sblkctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0",
|
return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL",
|
||||||
0x4b, regvalue, cur_col, wrap));
|
0x4a, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = {
|
static ahd_reg_parse_entry_t CLRSINT0_parse_table[] = {
|
||||||
@@ -926,6 +908,24 @@ ahd_clrsint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x4b, regvalue, cur_col, wrap));
|
0x4b, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t SSTAT0_parse_table[] = {
|
||||||
|
{ "ARBDO", 0x01, 0x01 },
|
||||||
|
{ "SPIORDY", 0x02, 0x02 },
|
||||||
|
{ "OVERRUN", 0x04, 0x04 },
|
||||||
|
{ "IOERR", 0x08, 0x08 },
|
||||||
|
{ "SELINGO", 0x10, 0x10 },
|
||||||
|
{ "SELDI", 0x20, 0x20 },
|
||||||
|
{ "SELDO", 0x40, 0x40 },
|
||||||
|
{ "TARGET", 0x80, 0x80 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_sstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(SSTAT0_parse_table, 8, "SSTAT0",
|
||||||
|
0x4b, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SIMODE0_parse_table[] = {
|
static ahd_reg_parse_entry_t SIMODE0_parse_table[] = {
|
||||||
{ "ENARBDO", 0x01, 0x01 },
|
{ "ENARBDO", 0x01, 0x01 },
|
||||||
{ "ENSPIORDY", 0x02, 0x02 },
|
{ "ENSPIORDY", 0x02, 0x02 },
|
||||||
@@ -998,6 +998,19 @@ ahd_sstat2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x4d, regvalue, cur_col, wrap));
|
0x4d, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t SIMODE2_parse_table[] = {
|
||||||
|
{ "ENDMADONE", 0x01, 0x01 },
|
||||||
|
{ "ENSDONE", 0x02, 0x02 },
|
||||||
|
{ "ENWIDE_RES", 0x04, 0x04 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2",
|
||||||
|
0x4d, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = {
|
static ahd_reg_parse_entry_t CLRSINT2_parse_table[] = {
|
||||||
{ "CLRDMADONE", 0x01, 0x01 },
|
{ "CLRDMADONE", 0x01, 0x01 },
|
||||||
{ "CLRSDONE", 0x02, 0x02 },
|
{ "CLRSDONE", 0x02, 0x02 },
|
||||||
@@ -1012,19 +1025,6 @@ ahd_clrsint2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x4d, regvalue, cur_col, wrap));
|
0x4d, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SIMODE2_parse_table[] = {
|
|
||||||
{ "ENDMADONE", 0x01, 0x01 },
|
|
||||||
{ "ENSDONE", 0x02, 0x02 },
|
|
||||||
{ "ENWIDE_RES", 0x04, 0x04 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_simode2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(SIMODE2_parse_table, 3, "SIMODE2",
|
|
||||||
0x4d, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = {
|
static ahd_reg_parse_entry_t PERRDIAG_parse_table[] = {
|
||||||
{ "DTERR", 0x01, 0x01 },
|
{ "DTERR", 0x01, 0x01 },
|
||||||
{ "DGFORMERR", 0x02, 0x02 },
|
{ "DGFORMERR", 0x02, 0x02 },
|
||||||
@@ -1220,21 +1220,6 @@ ahd_clrsint3_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x53, regvalue, cur_col, wrap));
|
0x53, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = {
|
|
||||||
{ "ENLQOTCRC", 0x01, 0x01 },
|
|
||||||
{ "ENLQOATNPKT", 0x02, 0x02 },
|
|
||||||
{ "ENLQOATNLQ", 0x04, 0x04 },
|
|
||||||
{ "ENLQOSTOPT2", 0x08, 0x08 },
|
|
||||||
{ "ENLQOTARGSCBPERR", 0x10, 0x10 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0",
|
|
||||||
0x54, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = {
|
static ahd_reg_parse_entry_t LQOSTAT0_parse_table[] = {
|
||||||
{ "LQOTCRC", 0x01, 0x01 },
|
{ "LQOTCRC", 0x01, 0x01 },
|
||||||
{ "LQOATNPKT", 0x02, 0x02 },
|
{ "LQOATNPKT", 0x02, 0x02 },
|
||||||
@@ -1265,6 +1250,36 @@ ahd_clrlqoint0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x54, regvalue, cur_col, wrap));
|
0x54, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t LQOMODE0_parse_table[] = {
|
||||||
|
{ "ENLQOTCRC", 0x01, 0x01 },
|
||||||
|
{ "ENLQOATNPKT", 0x02, 0x02 },
|
||||||
|
{ "ENLQOATNLQ", 0x04, 0x04 },
|
||||||
|
{ "ENLQOSTOPT2", 0x08, 0x08 },
|
||||||
|
{ "ENLQOTARGSCBPERR", 0x10, 0x10 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_lqomode0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(LQOMODE0_parse_table, 5, "LQOMODE0",
|
||||||
|
0x54, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = {
|
||||||
|
{ "ENLQOPHACHGINPKT", 0x01, 0x01 },
|
||||||
|
{ "ENLQOBUSFREE", 0x02, 0x02 },
|
||||||
|
{ "ENLQOBADQAS", 0x04, 0x04 },
|
||||||
|
{ "ENLQOSTOPI2", 0x08, 0x08 },
|
||||||
|
{ "ENLQOINITSCBPERR", 0x10, 0x10 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1",
|
||||||
|
0x55, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = {
|
static ahd_reg_parse_entry_t LQOSTAT1_parse_table[] = {
|
||||||
{ "LQOPHACHGINPKT", 0x01, 0x01 },
|
{ "LQOPHACHGINPKT", 0x01, 0x01 },
|
||||||
{ "LQOBUSFREE", 0x02, 0x02 },
|
{ "LQOBUSFREE", 0x02, 0x02 },
|
||||||
@@ -1295,21 +1310,6 @@ ahd_clrlqoint1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x55, regvalue, cur_col, wrap));
|
0x55, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LQOMODE1_parse_table[] = {
|
|
||||||
{ "ENLQOPHACHGINPKT", 0x01, 0x01 },
|
|
||||||
{ "ENLQOBUSFREE", 0x02, 0x02 },
|
|
||||||
{ "ENLQOBADQAS", 0x04, 0x04 },
|
|
||||||
{ "ENLQOSTOPI2", 0x08, 0x08 },
|
|
||||||
{ "ENLQOINITSCBPERR", 0x10, 0x10 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_lqomode1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(LQOMODE1_parse_table, 5, "LQOMODE1",
|
|
||||||
0x55, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = {
|
static ahd_reg_parse_entry_t LQOSTAT2_parse_table[] = {
|
||||||
{ "LQOSTOP0", 0x01, 0x01 },
|
{ "LQOSTOP0", 0x01, 0x01 },
|
||||||
{ "LQOPHACHGOUTPKT", 0x02, 0x02 },
|
{ "LQOPHACHGOUTPKT", 0x02, 0x02 },
|
||||||
@@ -1594,6 +1594,13 @@ ahd_annexcol_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x65, regvalue, cur_col, wrap));
|
0x65, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "ANNEXDAT",
|
||||||
|
0x66, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = {
|
static ahd_reg_parse_entry_t SCSCHKN_parse_table[] = {
|
||||||
{ "LSTSGCLRDIS", 0x01, 0x01 },
|
{ "LSTSGCLRDIS", 0x01, 0x01 },
|
||||||
{ "SHVALIDSTDIS", 0x02, 0x02 },
|
{ "SHVALIDSTDIS", 0x02, 0x02 },
|
||||||
@@ -1611,13 +1618,6 @@ ahd_scschkn_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x66, regvalue, cur_col, wrap));
|
0x66, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ahd_annexdat_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "ANNEXDAT",
|
|
||||||
0x66, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_iownid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -1728,16 +1728,16 @@ ahd_pll400ctl1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "PLL400CNT0",
|
return (ahd_print_register(NULL, 0, "UNFAIRNESS",
|
||||||
0x6e, regvalue, cur_col, wrap));
|
0x6e, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_unfairness_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_pll400cnt0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "UNFAIRNESS",
|
return (ahd_print_register(NULL, 0, "PLL400CNT0",
|
||||||
0x6e, regvalue, cur_col, wrap));
|
0x6e, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1787,13 +1787,6 @@ ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x7a, regvalue, cur_col, wrap));
|
0x7a, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "SGHADDR",
|
|
||||||
0x7c, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -1802,10 +1795,10 @@ ahd_scbhaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_sghaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "SGHCNT",
|
return (ahd_print_register(NULL, 0, "SGHADDR",
|
||||||
0x84, regvalue, cur_col, wrap));
|
0x7c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -1815,6 +1808,13 @@ ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x84, regvalue, cur_col, wrap));
|
0x84, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_sghcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "SGHCNT",
|
||||||
|
0x84, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = {
|
static ahd_reg_parse_entry_t DFF_THRSH_parse_table[] = {
|
||||||
{ "WR_DFTHRSH_MIN", 0x00, 0x70 },
|
{ "WR_DFTHRSH_MIN", 0x00, 0x70 },
|
||||||
{ "RD_DFTHRSH_MIN", 0x00, 0x07 },
|
{ "RD_DFTHRSH_MIN", 0x00, 0x07 },
|
||||||
@@ -1950,17 +1950,6 @@ ahd_nsenable_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x91, regvalue, cur_col, wrap));
|
0x91, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = {
|
|
||||||
{ "CBNUM", 0xff, 0xff }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1",
|
|
||||||
0x91, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = {
|
static ahd_reg_parse_entry_t CMCRXMSG1_parse_table[] = {
|
||||||
{ "CBNUM", 0xff, 0xff }
|
{ "CBNUM", 0xff, 0xff }
|
||||||
};
|
};
|
||||||
@@ -1972,6 +1961,17 @@ ahd_cmcrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x91, regvalue, cur_col, wrap));
|
0x91, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t DCHRXMSG1_parse_table[] = {
|
||||||
|
{ "CBNUM", 0xff, 0xff }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_dchrxmsg1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(DCHRXMSG1_parse_table, 1, "DCHRXMSG1",
|
||||||
|
0x91, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = {
|
static ahd_reg_parse_entry_t DCHRXMSG2_parse_table[] = {
|
||||||
{ "MINDEX", 0xff, 0xff }
|
{ "MINDEX", 0xff, 0xff }
|
||||||
};
|
};
|
||||||
@@ -1983,17 +1983,6 @@ ahd_dchrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x92, regvalue, cur_col, wrap));
|
0x92, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = {
|
|
||||||
{ "MINDEX", 0xff, 0xff }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2",
|
|
||||||
0x92, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = {
|
static ahd_reg_parse_entry_t CMCRXMSG2_parse_table[] = {
|
||||||
{ "MINDEX", 0xff, 0xff }
|
{ "MINDEX", 0xff, 0xff }
|
||||||
};
|
};
|
||||||
@@ -2012,6 +2001,17 @@ ahd_ost_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x92, regvalue, cur_col, wrap));
|
0x92, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t OVLYRXMSG2_parse_table[] = {
|
||||||
|
{ "MINDEX", 0xff, 0xff }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_ovlyrxmsg2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(OVLYRXMSG2_parse_table, 1, "OVLYRXMSG2",
|
||||||
|
0x92, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = {
|
static ahd_reg_parse_entry_t DCHRXMSG3_parse_table[] = {
|
||||||
{ "MCLASS", 0x0f, 0x0f }
|
{ "MCLASS", 0x0f, 0x0f }
|
||||||
};
|
};
|
||||||
@@ -2023,6 +2023,17 @@ ahd_dchrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x93, regvalue, cur_col, wrap));
|
0x93, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = {
|
||||||
|
{ "MCLASS", 0x0f, 0x0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3",
|
||||||
|
0x93, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = {
|
static ahd_reg_parse_entry_t CMCRXMSG3_parse_table[] = {
|
||||||
{ "MCLASS", 0x0f, 0x0f }
|
{ "MCLASS", 0x0f, 0x0f }
|
||||||
};
|
};
|
||||||
@@ -2051,17 +2062,6 @@ ahd_pcixctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x93, regvalue, cur_col, wrap));
|
0x93, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t OVLYRXMSG3_parse_table[] = {
|
|
||||||
{ "MCLASS", 0x0f, 0x0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_ovlyrxmsg3_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(OVLYRXMSG3_parse_table, 1, "OVLYRXMSG3",
|
|
||||||
0x93, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -2070,16 +2070,16 @@ ahd_ovlyseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "CMCSEQBCNT",
|
return (ahd_print_register(NULL, 0, "DCHSEQBCNT",
|
||||||
0x94, regvalue, cur_col, wrap));
|
0x94, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_dchseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_cmcseqbcnt_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "DCHSEQBCNT",
|
return (ahd_print_register(NULL, 0, "CMCSEQBCNT",
|
||||||
0x94, regvalue, cur_col, wrap));
|
0x94, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2101,24 +2101,6 @@ ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x96, regvalue, cur_col, wrap));
|
0x96, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = {
|
|
||||||
{ "RXSPLTRSP", 0x01, 0x01 },
|
|
||||||
{ "RXSCEMSG", 0x02, 0x02 },
|
|
||||||
{ "RXOVRUN", 0x04, 0x04 },
|
|
||||||
{ "CNTNOTCMPLT", 0x08, 0x08 },
|
|
||||||
{ "SCDATBUCKET", 0x10, 0x10 },
|
|
||||||
{ "SCADERR", 0x20, 0x20 },
|
|
||||||
{ "SCBCERR", 0x40, 0x40 },
|
|
||||||
{ "STAETERM", 0x80, 0x80 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0",
|
|
||||||
0x96, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = {
|
static ahd_reg_parse_entry_t DCHSPLTSTAT0_parse_table[] = {
|
||||||
{ "RXSPLTRSP", 0x01, 0x01 },
|
{ "RXSPLTRSP", 0x01, 0x01 },
|
||||||
{ "RXSCEMSG", 0x02, 0x02 },
|
{ "RXSCEMSG", 0x02, 0x02 },
|
||||||
@@ -2137,15 +2119,22 @@ ahd_dchspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x96, regvalue, cur_col, wrap));
|
0x96, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = {
|
static ahd_reg_parse_entry_t OVLYSPLTSTAT0_parse_table[] = {
|
||||||
{ "RXDATABUCKET", 0x01, 0x01 }
|
{ "RXSPLTRSP", 0x01, 0x01 },
|
||||||
|
{ "RXSCEMSG", 0x02, 0x02 },
|
||||||
|
{ "RXOVRUN", 0x04, 0x04 },
|
||||||
|
{ "CNTNOTCMPLT", 0x08, 0x08 },
|
||||||
|
{ "SCDATBUCKET", 0x10, 0x10 },
|
||||||
|
{ "SCADERR", 0x20, 0x20 },
|
||||||
|
{ "SCBCERR", 0x40, 0x40 },
|
||||||
|
{ "STAETERM", 0x80, 0x80 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_ovlyspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1",
|
return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0",
|
||||||
0x97, regvalue, cur_col, wrap));
|
0x96, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = {
|
static ahd_reg_parse_entry_t CMCSPLTSTAT1_parse_table[] = {
|
||||||
@@ -2170,6 +2159,17 @@ ahd_ovlyspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x97, regvalue, cur_col, wrap));
|
0x97, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = {
|
||||||
|
{ "RXDATABUCKET", 0x01, 0x01 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_dchspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(DCHSPLTSTAT1_parse_table, 1, "DCHSPLTSTAT1",
|
||||||
|
0x97, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = {
|
static ahd_reg_parse_entry_t SGRXMSG0_parse_table[] = {
|
||||||
{ "CFNUM", 0x07, 0x07 },
|
{ "CFNUM", 0x07, 0x07 },
|
||||||
{ "CDNUM", 0xf8, 0xf8 }
|
{ "CDNUM", 0xf8, 0xf8 }
|
||||||
@@ -2320,6 +2320,17 @@ ahd_sgspltstat0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x9e, regvalue, cur_col, wrap));
|
0x9e, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = {
|
||||||
|
{ "RXDATABUCKET", 0x01, 0x01 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1",
|
||||||
|
0x9f, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SFUNCT_parse_table[] = {
|
static ahd_reg_parse_entry_t SFUNCT_parse_table[] = {
|
||||||
{ "TEST_NUM", 0x0f, 0x0f },
|
{ "TEST_NUM", 0x0f, 0x0f },
|
||||||
{ "TEST_GROUP", 0xf0, 0xf0 }
|
{ "TEST_GROUP", 0xf0, 0xf0 }
|
||||||
@@ -2332,17 +2343,6 @@ ahd_sfunct_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x9f, regvalue, cur_col, wrap));
|
0x9f, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SGSPLTSTAT1_parse_table[] = {
|
|
||||||
{ "RXDATABUCKET", 0x01, 0x01 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_sgspltstat1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(SGSPLTSTAT1_parse_table, 1, "SGSPLTSTAT1",
|
|
||||||
0x9f, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = {
|
static ahd_reg_parse_entry_t DF0PCISTAT_parse_table[] = {
|
||||||
{ "DPR", 0x01, 0x01 },
|
{ "DPR", 0x01, 0x01 },
|
||||||
{ "TWATERR", 0x02, 0x02 },
|
{ "TWATERR", 0x02, 0x02 },
|
||||||
@@ -2537,16 +2537,16 @@ ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "CCSCBADDR",
|
return (ahd_print_register(NULL, 0, "CCSCBADR_BK",
|
||||||
0xac, regvalue, cur_col, wrap));
|
0xac, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_ccscbadr_bk_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_ccscbaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "CCSCBADR_BK",
|
return (ahd_print_register(NULL, 0, "CCSCBADDR",
|
||||||
0xac, regvalue, cur_col, wrap));
|
0xac, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2566,22 +2566,6 @@ ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xad, regvalue, cur_col, wrap));
|
0xad, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = {
|
|
||||||
{ "CCSGRESET", 0x01, 0x01 },
|
|
||||||
{ "SG_FETCH_REQ", 0x02, 0x02 },
|
|
||||||
{ "CCSGENACK", 0x08, 0x08 },
|
|
||||||
{ "SG_CACHE_AVAIL", 0x10, 0x10 },
|
|
||||||
{ "CCSGDONE", 0x80, 0x80 },
|
|
||||||
{ "CCSGEN", 0x0c, 0x0c }
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL",
|
|
||||||
0xad, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = {
|
static ahd_reg_parse_entry_t CCSCBCTL_parse_table[] = {
|
||||||
{ "CCSCBRESET", 0x01, 0x01 },
|
{ "CCSCBRESET", 0x01, 0x01 },
|
||||||
{ "CCSCBDIR", 0x04, 0x04 },
|
{ "CCSCBDIR", 0x04, 0x04 },
|
||||||
@@ -2598,6 +2582,22 @@ ahd_ccscbctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xad, regvalue, cur_col, wrap));
|
0xad, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ahd_reg_parse_entry_t CCSGCTL_parse_table[] = {
|
||||||
|
{ "CCSGRESET", 0x01, 0x01 },
|
||||||
|
{ "SG_FETCH_REQ", 0x02, 0x02 },
|
||||||
|
{ "CCSGENACK", 0x08, 0x08 },
|
||||||
|
{ "SG_CACHE_AVAIL", 0x10, 0x10 },
|
||||||
|
{ "CCSGDONE", 0x80, 0x80 },
|
||||||
|
{ "CCSGEN", 0x0c, 0x0c }
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_ccsgctl_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(CCSGCTL_parse_table, 6, "CCSGCTL",
|
||||||
|
0xad, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_ccsgram_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -2840,13 +2840,6 @@ ahd_wrtbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xc7, regvalue, cur_col, wrap));
|
0xc7, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "DFPTRS",
|
|
||||||
0xc8, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -2855,10 +2848,10 @@ ahd_rcvrbiascalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_dfptrs_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "DFBKPTR",
|
return (ahd_print_register(NULL, 0, "DFPTRS",
|
||||||
0xc9, regvalue, cur_col, wrap));
|
0xc8, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -2868,6 +2861,13 @@ ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xc9, regvalue, cur_col, wrap));
|
0xc9, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_dfbkptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "DFBKPTR",
|
||||||
|
0xc9, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = {
|
static ahd_reg_parse_entry_t DFDBCTL_parse_table[] = {
|
||||||
{ "DFF_RAMBIST_EN", 0x01, 0x01 },
|
{ "DFF_RAMBIST_EN", 0x01, 0x01 },
|
||||||
{ "DFF_RAMBIST_DONE", 0x02, 0x02 },
|
{ "DFF_RAMBIST_DONE", 0x02, 0x02 },
|
||||||
@@ -3001,6 +3001,13 @@ ahd_dindex_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xe4, regvalue, cur_col, wrap));
|
0xe4, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "BRKADDR0",
|
||||||
|
0xe6, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = {
|
static ahd_reg_parse_entry_t BRKADDR1_parse_table[] = {
|
||||||
{ "BRKDIS", 0x80, 0x80 }
|
{ "BRKDIS", 0x80, 0x80 }
|
||||||
};
|
};
|
||||||
@@ -3012,13 +3019,6 @@ ahd_brkaddr1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xe6, regvalue, cur_col, wrap));
|
0xe6, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ahd_brkaddr0_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "BRKADDR0",
|
|
||||||
0xe6, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_allones_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -3068,13 +3068,6 @@ ahd_stack_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xf2, regvalue, cur_col, wrap));
|
0xf2, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "CURADDR",
|
|
||||||
0xf4, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -3083,10 +3076,10 @@ ahd_intvec1_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_curaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INTVEC2_ADDR",
|
return (ahd_print_register(NULL, 0, "CURADDR",
|
||||||
0xf6, regvalue, cur_col, wrap));
|
0xf4, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -3096,6 +3089,13 @@ ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0xf6, regvalue, cur_col, wrap));
|
0xf6, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_intvec2_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "INTVEC2_ADDR",
|
||||||
|
0xf6, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_longjmp_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
@@ -3173,25 +3173,46 @@ ahd_complete_dma_scb_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|||||||
0x12c, regvalue, cur_col, wrap));
|
0x12c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_complete_dma_scb_tail_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "COMPLETE_DMA_SCB_TAIL",
|
||||||
|
0x12e, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_complete_on_qfreeze_head_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "COMPLETE_ON_QFREEZE_HEAD",
|
||||||
|
0x130, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "QFREEZE_COUNT",
|
return (ahd_print_register(NULL, 0, "QFREEZE_COUNT",
|
||||||
0x12e, regvalue, cur_col, wrap));
|
0x132, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_kernel_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "KERNEL_QFREEZE_COUNT",
|
||||||
|
0x134, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "SAVED_MODE",
|
return (ahd_print_register(NULL, 0, "SAVED_MODE",
|
||||||
0x130, regvalue, cur_col, wrap));
|
0x136, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "MSG_OUT",
|
return (ahd_print_register(NULL, 0, "MSG_OUT",
|
||||||
0x131, regvalue, cur_col, wrap));
|
0x137, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = {
|
static ahd_reg_parse_entry_t DMAPARAMS_parse_table[] = {
|
||||||
@@ -3211,7 +3232,7 @@ int
|
|||||||
ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
|
return (ahd_print_register(DMAPARAMS_parse_table, 10, "DMAPARAMS",
|
||||||
0x132, regvalue, cur_col, wrap));
|
0x138, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
|
static ahd_reg_parse_entry_t SEQ_FLAGS_parse_table[] = {
|
||||||
@@ -3230,21 +3251,21 @@ int
|
|||||||
ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_seq_flags_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
|
return (ahd_print_register(SEQ_FLAGS_parse_table, 9, "SEQ_FLAGS",
|
||||||
0x133, regvalue, cur_col, wrap));
|
0x139, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "SAVED_SCSIID",
|
return (ahd_print_register(NULL, 0, "SAVED_SCSIID",
|
||||||
0x134, regvalue, cur_col, wrap));
|
0x13a, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "SAVED_LUN",
|
return (ahd_print_register(NULL, 0, "SAVED_LUN",
|
||||||
0x135, regvalue, cur_col, wrap));
|
0x13b, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = {
|
static ahd_reg_parse_entry_t LASTPHASE_parse_table[] = {
|
||||||
@@ -3267,42 +3288,42 @@ int
|
|||||||
ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
|
return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
|
||||||
0x136, regvalue, cur_col, wrap));
|
0x13c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_qoutfifo_entry_valid_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG",
|
return (ahd_print_register(NULL, 0, "QOUTFIFO_ENTRY_VALID_TAG",
|
||||||
0x137, regvalue, cur_col, wrap));
|
0x13d, regvalue, cur_col, wrap));
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR",
|
|
||||||
0x138, regvalue, cur_col, wrap));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
|
||||||
{
|
|
||||||
return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR",
|
|
||||||
0x13c, regvalue, cur_col, wrap));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS",
|
return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS",
|
||||||
0x140, regvalue, cur_col, wrap));
|
0x13e, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "TQINPOS",
|
return (ahd_print_register(NULL, 0, "TQINPOS",
|
||||||
0x141, regvalue, cur_col, wrap));
|
0x13f, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_shared_data_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "SHARED_DATA_ADDR",
|
||||||
|
0x140, regvalue, cur_col, wrap));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ahd_qoutfifo_next_addr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
|
{
|
||||||
|
return (ahd_print_register(NULL, 0, "QOUTFIFO_NEXT_ADDR",
|
||||||
|
0x144, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t ARG_1_parse_table[] = {
|
static ahd_reg_parse_entry_t ARG_1_parse_table[] = {
|
||||||
@@ -3320,21 +3341,21 @@ int
|
|||||||
ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_arg_1_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1",
|
return (ahd_print_register(ARG_1_parse_table, 8, "ARG_1",
|
||||||
0x142, regvalue, cur_col, wrap));
|
0x148, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "ARG_2",
|
return (ahd_print_register(NULL, 0, "ARG_2",
|
||||||
0x143, regvalue, cur_col, wrap));
|
0x149, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "LAST_MSG",
|
return (ahd_print_register(NULL, 0, "LAST_MSG",
|
||||||
0x144, regvalue, cur_col, wrap));
|
0x14a, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
|
static ahd_reg_parse_entry_t SCSISEQ_TEMPLATE_parse_table[] = {
|
||||||
@@ -3350,14 +3371,14 @@ int
|
|||||||
ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_scsiseq_template_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
|
return (ahd_print_register(SCSISEQ_TEMPLATE_parse_table, 6, "SCSISEQ_TEMPLATE",
|
||||||
0x145, regvalue, cur_col, wrap));
|
0x14b, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INITIATOR_TAG",
|
return (ahd_print_register(NULL, 0, "INITIATOR_TAG",
|
||||||
0x146, regvalue, cur_col, wrap));
|
0x14c, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
|
static ahd_reg_parse_entry_t SEQ_FLAGS2_parse_table[] = {
|
||||||
@@ -3369,63 +3390,63 @@ int
|
|||||||
ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_seq_flags2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
|
return (ahd_print_register(SEQ_FLAGS2_parse_table, 2, "SEQ_FLAGS2",
|
||||||
0x147, regvalue, cur_col, wrap));
|
0x14d, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR",
|
return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR",
|
||||||
0x148, regvalue, cur_col, wrap));
|
0x14e, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
|
return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
|
||||||
0x14a, regvalue, cur_col, wrap));
|
0x150, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
|
return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
|
||||||
0x14c, regvalue, cur_col, wrap));
|
0x152, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
|
return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
|
||||||
0x14d, regvalue, cur_col, wrap));
|
0x153, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "CMDS_PENDING",
|
return (ahd_print_register(NULL, 0, "CMDS_PENDING",
|
||||||
0x14e, regvalue, cur_col, wrap));
|
0x154, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
|
return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
|
||||||
0x150, regvalue, cur_col, wrap));
|
0x156, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX",
|
return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX",
|
||||||
0x151, regvalue, cur_col, wrap));
|
0x157, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||||
{
|
{
|
||||||
return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE",
|
return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE",
|
||||||
0x152, regvalue, cur_col, wrap));
|
0x158, regvalue, cur_col, wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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);
|
|||||||
*/
|
*/
|
||||||
#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;
|
|||||||
#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 {
|
|||||||
|
|
||||||
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 @@
|
|||||||
* 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 [] =
|
|||||||
"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)
|
|||||||
* 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)
|
|||||||
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 @@
|
|||||||
#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
|
||||||
|
|||||||
+17
-16
@@ -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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
||||||
|
|||||||
+24
-21
@@ -61,6 +61,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
|
|||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <asm/processor.h> /* for boot_cpu_data */
|
#include <asm/processor.h> /* for boot_cpu_data */
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
@@ -106,7 +107,7 @@ static dpt_sig_S DPTI_sig = {
|
|||||||
*============================================================================
|
*============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static DECLARE_MUTEX(adpt_configuration_lock);
|
static DEFINE_MUTEX(adpt_configuration_lock);
|
||||||
|
|
||||||
static struct i2o_sys_tbl *sys_tbl = NULL;
|
static struct i2o_sys_tbl *sys_tbl = NULL;
|
||||||
static int sys_tbl_ind = 0;
|
static int sys_tbl_ind = 0;
|
||||||
@@ -537,13 +538,13 @@ static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, of
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Find HBA (host bus adapter) we are looking for
|
// Find HBA (host bus adapter) we are looking for
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||||
if (pHba->host == host) {
|
if (pHba->host == host) {
|
||||||
break; /* found adapter */
|
break; /* found adapter */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
if (pHba == NULL) {
|
if (pHba == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -898,6 +899,12 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
|||||||
if(pci_enable_device(pDev)) {
|
if(pci_enable_device(pDev)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pci_request_regions(pDev, "dpt_i2o")) {
|
||||||
|
PERROR("dpti: adpt_config_hba: pci request region failed\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
pci_set_master(pDev);
|
pci_set_master(pDev);
|
||||||
if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
|
if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
|
||||||
pci_set_dma_mask(pDev, 0xffffffffULL))
|
pci_set_dma_mask(pDev, 0xffffffffULL))
|
||||||
@@ -923,10 +930,6 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
|||||||
raptorFlag = TRUE;
|
raptorFlag = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_request_regions(pDev, "dpt_i2o")) {
|
|
||||||
PERROR("dpti: adpt_config_hba: pci request region failed\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
|
base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
|
||||||
if (!base_addr_virt) {
|
if (!base_addr_virt) {
|
||||||
pci_release_regions(pDev);
|
pci_release_regions(pDev);
|
||||||
@@ -958,7 +961,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
|||||||
}
|
}
|
||||||
memset(pHba, 0, sizeof(adpt_hba));
|
memset(pHba, 0, sizeof(adpt_hba));
|
||||||
|
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
|
|
||||||
if(hba_chain != NULL){
|
if(hba_chain != NULL){
|
||||||
for(p = hba_chain; p->next; p = p->next);
|
for(p = hba_chain; p->next; p = p->next);
|
||||||
@@ -971,7 +974,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
|
|||||||
sprintf(pHba->name, "dpti%d", hba_count);
|
sprintf(pHba->name, "dpti%d", hba_count);
|
||||||
hba_count++;
|
hba_count++;
|
||||||
|
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
|
|
||||||
pHba->pDev = pDev;
|
pHba->pDev = pDev;
|
||||||
pHba->base_addr_phys = base_addr0_phys;
|
pHba->base_addr_phys = base_addr0_phys;
|
||||||
@@ -1027,7 +1030,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
|||||||
struct adpt_device* pNext;
|
struct adpt_device* pNext;
|
||||||
|
|
||||||
|
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
// scsi_unregister calls our adpt_release which
|
// scsi_unregister calls our adpt_release which
|
||||||
// does a quiese
|
// does a quiese
|
||||||
if(pHba->host){
|
if(pHba->host){
|
||||||
@@ -1046,7 +1049,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hba_count--;
|
hba_count--;
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
|
|
||||||
iounmap(pHba->base_addr_virt);
|
iounmap(pHba->base_addr_virt);
|
||||||
pci_release_regions(pHba->pDev);
|
pci_release_regions(pHba->pDev);
|
||||||
@@ -1549,7 +1552,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
|
|||||||
|
|
||||||
static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
|
static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
|
||||||
{
|
{
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
d->controller=pHba;
|
d->controller=pHba;
|
||||||
d->owner=NULL;
|
d->owner=NULL;
|
||||||
d->next=pHba->devices;
|
d->next=pHba->devices;
|
||||||
@@ -1560,7 +1563,7 @@ static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
|
|||||||
pHba->devices=d;
|
pHba->devices=d;
|
||||||
*d->dev_name = 0;
|
*d->dev_name = 0;
|
||||||
|
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1575,24 +1578,24 @@ static int adpt_open(struct inode *inode, struct file *file)
|
|||||||
if (minor >= hba_count) {
|
if (minor >= hba_count) {
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||||
if (pHba->unit == minor) {
|
if (pHba->unit == minor) {
|
||||||
break; /* found adapter */
|
break; /* found adapter */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pHba == NULL) {
|
if (pHba == NULL) {
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(pHba->in_use){
|
// if(pHba->in_use){
|
||||||
// up(&adpt_configuration_lock);
|
// mutex_unlock(&adpt_configuration_lock);
|
||||||
// return -EBUSY;
|
// return -EBUSY;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pHba->in_use = 1;
|
pHba->in_use = 1;
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1606,13 +1609,13 @@ static int adpt_close(struct inode *inode, struct file *file)
|
|||||||
if (minor >= hba_count) {
|
if (minor >= hba_count) {
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||||
if (pHba->unit == minor) {
|
if (pHba->unit == minor) {
|
||||||
break; /* found adapter */
|
break; /* found adapter */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
if (pHba == NULL) {
|
if (pHba == NULL) {
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
@@ -1910,13 +1913,13 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
|
|||||||
if (minor >= DPTI_MAX_HBA){
|
if (minor >= DPTI_MAX_HBA){
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
down(&adpt_configuration_lock);
|
mutex_lock(&adpt_configuration_lock);
|
||||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||||
if (pHba->unit == minor) {
|
if (pHba->unit == minor) {
|
||||||
break; /* found adapter */
|
break; /* found adapter */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&adpt_configuration_lock);
|
mutex_unlock(&adpt_configuration_lock);
|
||||||
if(pHba == NULL){
|
if(pHba == NULL){
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|||||||
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)
|
|||||||
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
|
||||||
|
|||||||
+147
-156
@@ -33,6 +33,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/kfifo.h>
|
#include <linux/kfifo.h>
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
@@ -86,35 +87,32 @@ iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size)
|
|||||||
{
|
{
|
||||||
sg_init_one(&ibuf->sg, (u8 *)vbuf, size);
|
sg_init_one(&ibuf->sg, (u8 *)vbuf, size);
|
||||||
ibuf->sent = 0;
|
ibuf->sent = 0;
|
||||||
|
ibuf->use_sendmsg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
|
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
|
||||||
{
|
{
|
||||||
ibuf->sg.page = (void*)vbuf;
|
ibuf->sg.page = virt_to_page(vbuf);
|
||||||
ibuf->sg.offset = (unsigned int)-1;
|
ibuf->sg.offset = offset_in_page(vbuf);
|
||||||
ibuf->sg.length = size;
|
ibuf->sg.length = size;
|
||||||
ibuf->sent = 0;
|
ibuf->sent = 0;
|
||||||
}
|
ibuf->use_sendmsg = 1;
|
||||||
|
|
||||||
static inline void*
|
|
||||||
iscsi_buf_iov_base(struct iscsi_buf *ibuf)
|
|
||||||
{
|
|
||||||
return (char*)ibuf->sg.page + ibuf->sent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
|
iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
|
||||||
{
|
{
|
||||||
|
ibuf->sg.page = sg->page;
|
||||||
|
ibuf->sg.offset = sg->offset;
|
||||||
|
ibuf->sg.length = sg->length;
|
||||||
/*
|
/*
|
||||||
* Fastpath: sg element fits into single page
|
* Fastpath: sg element fits into single page
|
||||||
*/
|
*/
|
||||||
if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) {
|
if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
|
||||||
ibuf->sg.page = sg->page;
|
ibuf->use_sendmsg = 0;
|
||||||
ibuf->sg.offset = sg->offset;
|
else
|
||||||
ibuf->sg.length = sg->length;
|
ibuf->use_sendmsg = 1;
|
||||||
} else
|
|
||||||
iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length);
|
|
||||||
ibuf->sent = 0;
|
ibuf->sent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +354,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
struct scsi_cmnd *sc = ctask->sc;
|
struct scsi_cmnd *sc = ctask->sc;
|
||||||
|
|
||||||
conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
|
conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
|
||||||
if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) {
|
if (rhdr->flags & ISCSI_FLAG_DATA_UNDERFLOW) {
|
||||||
int res_count = be32_to_cpu(rhdr->residual_count);
|
int res_count = be32_to_cpu(rhdr->residual_count);
|
||||||
|
|
||||||
if (res_count > 0 &&
|
if (res_count > 0 &&
|
||||||
@@ -366,9 +364,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
} else
|
} else
|
||||||
sc->result = (DID_BAD_TARGET << 16) |
|
sc->result = (DID_BAD_TARGET << 16) |
|
||||||
rhdr->cmd_status;
|
rhdr->cmd_status;
|
||||||
} else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
|
} else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) {
|
||||||
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
|
|
||||||
else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
|
|
||||||
sc->resid = be32_to_cpu(rhdr->residual_count);
|
sc->resid = be32_to_cpu(rhdr->residual_count);
|
||||||
sc->result = (DID_OK << 16) | rhdr->cmd_status;
|
sc->result = (DID_OK << 16) | rhdr->cmd_status;
|
||||||
} else
|
} else
|
||||||
@@ -529,7 +525,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
__kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
__kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*));
|
||||||
__kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*));
|
__kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*));
|
||||||
|
|
||||||
schedule_work(&conn->xmitwork);
|
scsi_queue_work(session->host, &conn->xmitwork);
|
||||||
conn->r2t_pdus_cnt++;
|
conn->r2t_pdus_cnt++;
|
||||||
spin_unlock(&session->lock);
|
spin_unlock(&session->lock);
|
||||||
|
|
||||||
@@ -686,7 +682,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
|||||||
switch(conn->in.opcode) {
|
switch(conn->in.opcode) {
|
||||||
case ISCSI_OP_LOGIN_RSP:
|
case ISCSI_OP_LOGIN_RSP:
|
||||||
case ISCSI_OP_TEXT_RSP:
|
case ISCSI_OP_TEXT_RSP:
|
||||||
case ISCSI_OP_LOGOUT_RSP:
|
case ISCSI_OP_LOGOUT_RSP:
|
||||||
rc = iscsi_check_assign_cmdsn(session,
|
rc = iscsi_check_assign_cmdsn(session,
|
||||||
(struct iscsi_nopin*)hdr);
|
(struct iscsi_nopin*)hdr);
|
||||||
if (rc)
|
if (rc)
|
||||||
@@ -727,12 +723,12 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
|||||||
}
|
}
|
||||||
spin_unlock(&session->lock);
|
spin_unlock(&session->lock);
|
||||||
break;
|
break;
|
||||||
case ISCSI_OP_NOOP_IN:
|
case ISCSI_OP_NOOP_IN:
|
||||||
if (hdr->ttt != ISCSI_RESERVED_TAG) {
|
if (hdr->ttt != ISCSI_RESERVED_TAG) {
|
||||||
rc = ISCSI_ERR_PROTO;
|
rc = ISCSI_ERR_PROTO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rc = iscsi_check_assign_cmdsn(session,
|
rc = iscsi_check_assign_cmdsn(session,
|
||||||
(struct iscsi_nopin*)hdr);
|
(struct iscsi_nopin*)hdr);
|
||||||
if (rc)
|
if (rc)
|
||||||
break;
|
break;
|
||||||
@@ -767,7 +763,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
|||||||
if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
|
if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
|
||||||
rc = iscsi_recv_pdu(iscsi_handle(conn),
|
rc = iscsi_recv_pdu(iscsi_handle(conn),
|
||||||
hdr, NULL, 0);
|
hdr, NULL, 0);
|
||||||
} else
|
} else
|
||||||
rc = ISCSI_ERR_PROTO;
|
rc = ISCSI_ERR_PROTO;
|
||||||
break;
|
break;
|
||||||
case ISCSI_OP_REJECT:
|
case ISCSI_OP_REJECT:
|
||||||
@@ -929,7 +925,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
|
|||||||
sc->request_bufflen, ctask->data_offset);
|
sc->request_bufflen, ctask->data_offset);
|
||||||
if (rc == -EAGAIN)
|
if (rc == -EAGAIN)
|
||||||
return rc;
|
return rc;
|
||||||
if (conn->datadgst_en)
|
if (conn->datadgst_en)
|
||||||
iscsi_recv_digest_update(conn, sc->request_buffer, i);
|
iscsi_recv_digest_update(conn, sc->request_buffer, i);
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -1024,7 +1020,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
|
|||||||
conn->in.hdr = &conn->hdr;
|
conn->in.hdr = &conn->hdr;
|
||||||
conn->senselen = (conn->data[0] << 8) | conn->data[1];
|
conn->senselen = (conn->data[0] << 8) | conn->data[1];
|
||||||
rc = iscsi_cmd_rsp(conn, conn->in.ctask);
|
rc = iscsi_cmd_rsp(conn, conn->in.ctask);
|
||||||
if (!rc && conn->datadgst_en)
|
if (!rc && conn->datadgst_en)
|
||||||
iscsi_recv_digest_update(conn, conn->data,
|
iscsi_recv_digest_update(conn, conn->data,
|
||||||
conn->in.datalen);
|
conn->in.datalen);
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1047,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
|
|||||||
rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
|
rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
|
||||||
conn->data, conn->in.datalen);
|
conn->data, conn->in.datalen);
|
||||||
|
|
||||||
if (!rc && conn->datadgst_en &&
|
if (!rc && conn->datadgst_en &&
|
||||||
conn->in.opcode != ISCSI_OP_LOGIN_RSP)
|
conn->in.opcode != ISCSI_OP_LOGIN_RSP)
|
||||||
iscsi_recv_digest_update(conn, conn->data,
|
iscsi_recv_digest_update(conn, conn->data,
|
||||||
conn->in.datalen);
|
conn->in.datalen);
|
||||||
@@ -1271,7 +1267,7 @@ iscsi_write_space(struct sock *sk)
|
|||||||
conn->old_write_space(sk);
|
conn->old_write_space(sk);
|
||||||
debug_tcp("iscsi_write_space: cid %d\n", conn->id);
|
debug_tcp("iscsi_write_space: cid %d\n", conn->id);
|
||||||
clear_bit(SUSPEND_BIT, &conn->suspend_tx);
|
clear_bit(SUSPEND_BIT, &conn->suspend_tx);
|
||||||
schedule_work(&conn->xmitwork);
|
scsi_queue_work(conn->session->host, &conn->xmitwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1312,35 +1308,25 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
|
|||||||
* @buf: buffer to write from
|
* @buf: buffer to write from
|
||||||
* @size: actual size to write
|
* @size: actual size to write
|
||||||
* @flags: socket's flags
|
* @flags: socket's flags
|
||||||
*
|
|
||||||
* Notes:
|
|
||||||
* depending on buffer will use tcp_sendpage() or tcp_sendmsg().
|
|
||||||
* buf->sg.offset == -1 tells us that buffer is non S/G and forces
|
|
||||||
* to use tcp_sendmsg().
|
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
|
iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
|
||||||
{
|
{
|
||||||
int res;
|
struct socket *sk = conn->sock;
|
||||||
|
int offset = buf->sg.offset + buf->sent;
|
||||||
|
|
||||||
if ((int)buf->sg.offset >= 0) {
|
/*
|
||||||
int offset = buf->sg.offset + buf->sent;
|
* if we got use_sg=0 or are sending something we kmallocd
|
||||||
|
* then we did not have to do kmap (kmap returns page_address)
|
||||||
/* tcp_sendpage */
|
*
|
||||||
res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags);
|
* if we got use_sg > 0, but had to drop down, we do not
|
||||||
} else {
|
* set clustering so this should only happen for that
|
||||||
struct msghdr msg;
|
* slab case.
|
||||||
|
*/
|
||||||
buf->iov.iov_base = iscsi_buf_iov_base(buf);
|
if (buf->use_sendmsg)
|
||||||
buf->iov.iov_len = size;
|
return sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
|
||||||
|
else
|
||||||
memset(&msg, 0, sizeof(struct msghdr));
|
return conn->sendpage(sk, buf->sg.page, offset, size, flags);
|
||||||
|
|
||||||
/* tcp_sendmsg */
|
|
||||||
res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1355,7 +1341,6 @@ iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
|
|||||||
static inline int
|
static inline int
|
||||||
iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
|
iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
|
||||||
{
|
{
|
||||||
struct socket *sk = conn->sock;
|
|
||||||
int flags = 0; /* MSG_DONTWAIT; */
|
int flags = 0; /* MSG_DONTWAIT; */
|
||||||
int res, size;
|
int res, size;
|
||||||
|
|
||||||
@@ -1364,7 +1349,7 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
|
|||||||
if (buf->sent + size != buf->sg.length || datalen)
|
if (buf->sent + size != buf->sg.length || datalen)
|
||||||
flags |= MSG_MORE;
|
flags |= MSG_MORE;
|
||||||
|
|
||||||
res = iscsi_send(sk, buf, size, flags);
|
res = iscsi_send(conn, buf, size, flags);
|
||||||
debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
|
debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
conn->txdata_octets += res;
|
conn->txdata_octets += res;
|
||||||
@@ -1395,7 +1380,6 @@ static inline int
|
|||||||
iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
|
iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
|
||||||
int *count, int *sent)
|
int *count, int *sent)
|
||||||
{
|
{
|
||||||
struct socket *sk = conn->sock;
|
|
||||||
int flags = 0; /* MSG_DONTWAIT; */
|
int flags = 0; /* MSG_DONTWAIT; */
|
||||||
int res, size;
|
int res, size;
|
||||||
|
|
||||||
@@ -1406,7 +1390,7 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
|
|||||||
if (buf->sent + size != buf->sg.length || *count != size)
|
if (buf->sent + size != buf->sg.length || *count != size)
|
||||||
flags |= MSG_MORE;
|
flags |= MSG_MORE;
|
||||||
|
|
||||||
res = iscsi_send(sk, buf, size, flags);
|
res = iscsi_send(conn, buf, size, flags);
|
||||||
debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
|
debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n",
|
||||||
size, buf->sent, *count, *sent, res);
|
size, buf->sent, *count, *sent, res);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
@@ -1434,19 +1418,6 @@ iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
ctask->digest_count = 4;
|
ctask->digest_count = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
iscsi_buf_data_digest_update(struct iscsi_conn *conn, struct iscsi_buf *buf)
|
|
||||||
{
|
|
||||||
struct scatterlist sg;
|
|
||||||
|
|
||||||
if (buf->sg.offset != -1)
|
|
||||||
crypto_digest_update(conn->data_tx_tfm, &buf->sg, 1);
|
|
||||||
else {
|
|
||||||
sg_init_one(&sg, (char *)buf->sg.page, buf->sg.length);
|
|
||||||
crypto_digest_update(conn->data_tx_tfm, &sg, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
|
iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
|
||||||
struct iscsi_buf *buf, uint32_t *digest, int final)
|
struct iscsi_buf *buf, uint32_t *digest, int final)
|
||||||
@@ -1680,7 +1651,7 @@ iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
|
|||||||
zero_data(ctask->hdr.dlength);
|
zero_data(ctask->hdr.dlength);
|
||||||
}
|
}
|
||||||
|
|
||||||
iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
|
iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
|
||||||
sizeof(struct iscsi_hdr));
|
sizeof(struct iscsi_hdr));
|
||||||
conn->scsicmd_pdus_cnt++;
|
conn->scsicmd_pdus_cnt++;
|
||||||
}
|
}
|
||||||
@@ -1746,7 +1717,7 @@ static inline int
|
|||||||
handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||||
{
|
{
|
||||||
ctask->xmstate &= ~XMSTATE_R_HDR;
|
ctask->xmstate &= ~XMSTATE_R_HDR;
|
||||||
if (conn->hdrdgst_en)
|
if (conn->hdrdgst_en)
|
||||||
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
||||||
if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
|
if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
|
||||||
BUG_ON(ctask->xmstate != XMSTATE_IDLE);
|
BUG_ON(ctask->xmstate != XMSTATE_IDLE);
|
||||||
@@ -1760,7 +1731,7 @@ static inline int
|
|||||||
handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||||
{
|
{
|
||||||
ctask->xmstate &= ~XMSTATE_W_HDR;
|
ctask->xmstate &= ~XMSTATE_W_HDR;
|
||||||
if (conn->hdrdgst_en)
|
if (conn->hdrdgst_en)
|
||||||
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
||||||
if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
|
if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
|
||||||
ctask->xmstate |= XMSTATE_W_HDR;
|
ctask->xmstate |= XMSTATE_W_HDR;
|
||||||
@@ -1809,7 +1780,8 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
if (conn->datadgst_en)
|
if (conn->datadgst_en)
|
||||||
iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
|
crypto_digest_update(conn->data_tx_tfm,
|
||||||
|
&ctask->sendbuf.sg, 1);
|
||||||
|
|
||||||
if (!ctask->imm_count)
|
if (!ctask->imm_count)
|
||||||
break;
|
break;
|
||||||
@@ -1894,7 +1866,8 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
* so pass it
|
* so pass it
|
||||||
*/
|
*/
|
||||||
if (conn->datadgst_en && ctask->sent - start > 0)
|
if (conn->datadgst_en && ctask->sent - start > 0)
|
||||||
iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
|
crypto_digest_update(conn->data_tx_tfm,
|
||||||
|
&ctask->sendbuf.sg, 1);
|
||||||
|
|
||||||
if (!ctask->data_count)
|
if (!ctask->data_count)
|
||||||
break;
|
break;
|
||||||
@@ -1972,7 +1945,7 @@ solicit_again:
|
|||||||
|
|
||||||
BUG_ON(r2t->data_count < 0);
|
BUG_ON(r2t->data_count < 0);
|
||||||
if (conn->datadgst_en)
|
if (conn->datadgst_en)
|
||||||
iscsi_buf_data_digest_update(conn, &r2t->sendbuf);
|
crypto_digest_update(conn->data_tx_tfm, &r2t->sendbuf.sg, 1);
|
||||||
|
|
||||||
if (r2t->data_count) {
|
if (r2t->data_count) {
|
||||||
BUG_ON(ctask->sc->use_sg == 0);
|
BUG_ON(ctask->sc->use_sg == 0);
|
||||||
@@ -2054,7 +2027,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (conn->datadgst_en) {
|
if (conn->datadgst_en) {
|
||||||
iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
|
crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1);
|
||||||
/* imm data? */
|
/* imm data? */
|
||||||
if (!dtask) {
|
if (!dtask) {
|
||||||
if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
|
if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
|
||||||
@@ -2148,7 +2121,7 @@ unsolicit_head_again:
|
|||||||
solicit_head_again:
|
solicit_head_again:
|
||||||
r2t = ctask->r2t;
|
r2t = ctask->r2t;
|
||||||
if (conn->hdrdgst_en)
|
if (conn->hdrdgst_en)
|
||||||
iscsi_hdr_digest(conn, &r2t->headbuf,
|
iscsi_hdr_digest(conn, &r2t->headbuf,
|
||||||
(u8*)r2t->dtask->hdrext);
|
(u8*)r2t->dtask->hdrext);
|
||||||
if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
|
if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
|
||||||
ctask->xmstate &= ~XMSTATE_SOL_DATA;
|
ctask->xmstate &= ~XMSTATE_SOL_DATA;
|
||||||
@@ -2300,10 +2273,10 @@ iscsi_xmitworker(void *data)
|
|||||||
/*
|
/*
|
||||||
* serialize Xmit worker on a per-connection basis.
|
* serialize Xmit worker on a per-connection basis.
|
||||||
*/
|
*/
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
if (iscsi_data_xmit(conn))
|
if (iscsi_data_xmit(conn))
|
||||||
schedule_work(&conn->xmitwork);
|
scsi_queue_work(conn->session->host, &conn->xmitwork);
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FAILURE_BAD_HOST 1
|
#define FAILURE_BAD_HOST 1
|
||||||
@@ -2367,15 +2340,7 @@ iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
|
|||||||
session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
|
session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
|
||||||
spin_unlock(&session->lock);
|
spin_unlock(&session->lock);
|
||||||
|
|
||||||
if (!in_interrupt() && !down_trylock(&conn->xmitsema)) {
|
scsi_queue_work(host, &conn->xmitwork);
|
||||||
spin_unlock_irq(host->host_lock);
|
|
||||||
if (iscsi_data_xmit(conn))
|
|
||||||
schedule_work(&conn->xmitwork);
|
|
||||||
up(&conn->xmitsema);
|
|
||||||
spin_lock_irq(host->host_lock);
|
|
||||||
} else
|
|
||||||
schedule_work(&conn->xmitwork);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
reject:
|
reject:
|
||||||
@@ -2462,17 +2427,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
|
|||||||
kfree(items);
|
kfree(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
static iscsi_connh_t
|
static struct iscsi_cls_conn *
|
||||||
iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
|
iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
|
||||||
{
|
{
|
||||||
struct iscsi_session *session = iscsi_ptr(sessionh);
|
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||||
struct iscsi_conn *conn = NULL;
|
struct iscsi_conn *conn;
|
||||||
|
struct iscsi_cls_conn *cls_conn;
|
||||||
|
|
||||||
|
cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata),
|
||||||
|
conn_idx);
|
||||||
|
if (!cls_conn)
|
||||||
|
return NULL;
|
||||||
|
conn = cls_conn->dd_data;
|
||||||
|
|
||||||
conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
|
|
||||||
if (conn == NULL)
|
|
||||||
goto conn_alloc_fail;
|
|
||||||
memset(conn, 0, sizeof(struct iscsi_conn));
|
memset(conn, 0, sizeof(struct iscsi_conn));
|
||||||
|
|
||||||
conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
|
conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
|
||||||
conn->in_progress = IN_PROGRESS_WAIT_HEADER;
|
conn->in_progress = IN_PROGRESS_WAIT_HEADER;
|
||||||
conn->id = conn_idx;
|
conn->id = conn_idx;
|
||||||
@@ -2531,10 +2499,10 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
|
|||||||
goto max_recv_dlenght_alloc_fail;
|
goto max_recv_dlenght_alloc_fail;
|
||||||
|
|
||||||
init_timer(&conn->tmabort_timer);
|
init_timer(&conn->tmabort_timer);
|
||||||
init_MUTEX(&conn->xmitsema);
|
mutex_init(&conn->xmitmutex);
|
||||||
init_waitqueue_head(&conn->ehwait);
|
init_waitqueue_head(&conn->ehwait);
|
||||||
|
|
||||||
return iscsi_handle(conn);
|
return cls_conn;
|
||||||
|
|
||||||
max_recv_dlenght_alloc_fail:
|
max_recv_dlenght_alloc_fail:
|
||||||
spin_lock_bh(&session->lock);
|
spin_lock_bh(&session->lock);
|
||||||
@@ -2550,18 +2518,18 @@ immqueue_alloc_fail:
|
|||||||
writequeue_alloc_fail:
|
writequeue_alloc_fail:
|
||||||
kfifo_free(conn->xmitqueue);
|
kfifo_free(conn->xmitqueue);
|
||||||
xmitqueue_alloc_fail:
|
xmitqueue_alloc_fail:
|
||||||
kfree(conn);
|
iscsi_destroy_conn(cls_conn);
|
||||||
conn_alloc_fail:
|
return NULL;
|
||||||
return iscsi_handle(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iscsi_conn_destroy(iscsi_connh_t connh)
|
iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn)
|
||||||
{
|
{
|
||||||
struct iscsi_conn *conn = iscsi_ptr(connh);
|
struct iscsi_conn *conn = cls_conn->dd_data;
|
||||||
struct iscsi_session *session = conn->session;
|
struct iscsi_session *session = conn->session;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
set_bit(SUSPEND_BIT, &conn->suspend_tx);
|
set_bit(SUSPEND_BIT, &conn->suspend_tx);
|
||||||
if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
|
if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
|
||||||
struct sock *sk = conn->sock->sk;
|
struct sock *sk = conn->sock->sk;
|
||||||
@@ -2592,19 +2560,19 @@ iscsi_conn_destroy(iscsi_connh_t connh)
|
|||||||
}
|
}
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
|
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Block until all in-progress commands for this connection
|
* Block until all in-progress commands for this connection
|
||||||
* time out or fail.
|
* time out or fail.
|
||||||
*/
|
*/
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spin_lock_bh(&conn->lock);
|
spin_lock_irqsave(session->host->host_lock, flags);
|
||||||
if (!session->host->host_busy) { /* OK for ERL == 0 */
|
if (!session->host->host_busy) { /* OK for ERL == 0 */
|
||||||
spin_unlock_bh(&conn->lock);
|
spin_unlock_irqrestore(session->host->host_lock, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&conn->lock);
|
spin_unlock_irqrestore(session->host->host_lock, flags);
|
||||||
msleep_interruptible(500);
|
msleep_interruptible(500);
|
||||||
printk("conn_destroy(): host_busy %d host_failed %d\n",
|
printk("conn_destroy(): host_busy %d host_failed %d\n",
|
||||||
session->host->host_busy, session->host->host_failed);
|
session->host->host_busy, session->host->host_failed);
|
||||||
@@ -2652,7 +2620,8 @@ iscsi_conn_destroy(iscsi_connh_t connh)
|
|||||||
kfifo_free(conn->writequeue);
|
kfifo_free(conn->writequeue);
|
||||||
kfifo_free(conn->immqueue);
|
kfifo_free(conn->immqueue);
|
||||||
kfifo_free(conn->mgmtqueue);
|
kfifo_free(conn->mgmtqueue);
|
||||||
kfree(conn);
|
|
||||||
|
iscsi_destroy_conn(cls_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2713,6 +2682,8 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
|
|||||||
*/
|
*/
|
||||||
iscsi_conn_set_callbacks(conn);
|
iscsi_conn_set_callbacks(conn);
|
||||||
|
|
||||||
|
conn->sendpage = conn->sock->ops->sendpage;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set receive state machine into initial state
|
* set receive state machine into initial state
|
||||||
*/
|
*/
|
||||||
@@ -2796,7 +2767,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
|
|||||||
set_bit(SUSPEND_BIT, &conn->suspend_rx);
|
set_bit(SUSPEND_BIT, &conn->suspend_rx);
|
||||||
write_unlock_bh(&sk->sk_callback_lock);
|
write_unlock_bh(&sk->sk_callback_lock);
|
||||||
|
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
|
|
||||||
spin_lock_irqsave(session->host->host_lock, flags);
|
spin_lock_irqsave(session->host->host_lock, flags);
|
||||||
spin_lock(&session->lock);
|
spin_lock(&session->lock);
|
||||||
@@ -2878,7 +2849,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
|
|||||||
conn->datadgst_en = 0;
|
conn->datadgst_en = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2963,8 +2934,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
|
|||||||
else
|
else
|
||||||
__kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
|
__kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
|
||||||
|
|
||||||
schedule_work(&conn->xmitwork);
|
scsi_queue_work(session->host, &conn->xmitwork);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3029,12 +2999,12 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
|||||||
* 1) connection-level failure;
|
* 1) connection-level failure;
|
||||||
* 2) recovery due protocol error;
|
* 2) recovery due protocol error;
|
||||||
*/
|
*/
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
spin_lock_bh(&session->lock);
|
spin_lock_bh(&session->lock);
|
||||||
if (session->state != ISCSI_STATE_LOGGED_IN) {
|
if (session->state != ISCSI_STATE_LOGGED_IN) {
|
||||||
if (session->state == ISCSI_STATE_TERMINATE) {
|
if (session->state == ISCSI_STATE_TERMINATE) {
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
@@ -3052,7 +3022,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
|||||||
* 2) session was re-open during time out of ctask.
|
* 2) session was re-open during time out of ctask.
|
||||||
*/
|
*/
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
conn->tmabort_state = TMABORT_INITIAL;
|
conn->tmabort_state = TMABORT_INITIAL;
|
||||||
@@ -3107,7 +3077,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
|||||||
conn->tmabort_state == TMABORT_SUCCESS) {
|
conn->tmabort_state == TMABORT_SUCCESS) {
|
||||||
conn->tmabort_state = TMABORT_INITIAL;
|
conn->tmabort_state = TMABORT_INITIAL;
|
||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
conn->tmabort_state = TMABORT_INITIAL;
|
conn->tmabort_state = TMABORT_INITIAL;
|
||||||
@@ -3116,7 +3086,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
|||||||
spin_unlock_bh(&session->lock);
|
spin_unlock_bh(&session->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3182,7 +3152,7 @@ failed:
|
|||||||
exit:
|
exit:
|
||||||
del_timer_sync(&conn->tmabort_timer);
|
del_timer_sync(&conn->tmabort_timer);
|
||||||
|
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
if (conn->sock) {
|
if (conn->sock) {
|
||||||
struct sock *sk = conn->sock->sk;
|
struct sock *sk = conn->sock->sk;
|
||||||
|
|
||||||
@@ -3190,7 +3160,7 @@ exit:
|
|||||||
iscsi_ctask_cleanup(conn, ctask);
|
iscsi_ctask_cleanup(conn, ctask);
|
||||||
write_unlock_bh(&sk->sk_callback_lock);
|
write_unlock_bh(&sk->sk_callback_lock);
|
||||||
}
|
}
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3281,17 +3251,23 @@ static struct scsi_host_template iscsi_sht = {
|
|||||||
.this_id = -1,
|
.this_id = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static iscsi_sessionh_t
|
static struct iscsi_transport iscsi_tcp_transport;
|
||||||
iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
|
|
||||||
|
static struct Scsi_Host *
|
||||||
|
iscsi_session_create(struct scsi_transport_template *scsit,
|
||||||
|
uint32_t initial_cmdsn)
|
||||||
{
|
{
|
||||||
int cmd_i;
|
struct Scsi_Host *shost;
|
||||||
struct iscsi_session *session;
|
struct iscsi_session *session;
|
||||||
|
int cmd_i;
|
||||||
|
|
||||||
session = iscsi_hostdata(host->hostdata);
|
shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport);
|
||||||
|
if (!shost)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
session = iscsi_hostdata(shost->hostdata);
|
||||||
memset(session, 0, sizeof(struct iscsi_session));
|
memset(session, 0, sizeof(struct iscsi_session));
|
||||||
|
session->host = shost;
|
||||||
session->host = host;
|
|
||||||
session->id = host->host_no;
|
|
||||||
session->state = ISCSI_STATE_LOGGED_IN;
|
session->state = ISCSI_STATE_LOGGED_IN;
|
||||||
session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
|
session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX;
|
||||||
session->cmds_max = ISCSI_XMIT_CMDS_MAX;
|
session->cmds_max = ISCSI_XMIT_CMDS_MAX;
|
||||||
@@ -3335,7 +3311,7 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
|
|||||||
if (iscsi_r2tpool_alloc(session))
|
if (iscsi_r2tpool_alloc(session))
|
||||||
goto r2tpool_alloc_fail;
|
goto r2tpool_alloc_fail;
|
||||||
|
|
||||||
return iscsi_handle(session);
|
return shost;
|
||||||
|
|
||||||
r2tpool_alloc_fail:
|
r2tpool_alloc_fail:
|
||||||
for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
|
for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
|
||||||
@@ -3345,15 +3321,15 @@ immdata_alloc_fail:
|
|||||||
mgmtpool_alloc_fail:
|
mgmtpool_alloc_fail:
|
||||||
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
||||||
cmdpool_alloc_fail:
|
cmdpool_alloc_fail:
|
||||||
return iscsi_handle(NULL);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iscsi_session_destroy(iscsi_sessionh_t sessionh)
|
iscsi_session_destroy(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
|
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||||
int cmd_i;
|
int cmd_i;
|
||||||
struct iscsi_data_task *dtask, *n;
|
struct iscsi_data_task *dtask, *n;
|
||||||
struct iscsi_session *session = iscsi_ptr(sessionh);
|
|
||||||
|
|
||||||
for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
|
for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
|
||||||
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
|
struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
|
||||||
@@ -3369,6 +3345,8 @@ iscsi_session_destroy(iscsi_sessionh_t sessionh)
|
|||||||
iscsi_r2tpool_free(session);
|
iscsi_r2tpool_free(session);
|
||||||
iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
|
iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
|
||||||
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
||||||
|
|
||||||
|
iscsi_transport_destroy_session(shost);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -3467,6 +3445,8 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
|
|||||||
if (conn->data_rx_tfm)
|
if (conn->data_rx_tfm)
|
||||||
crypto_free_tfm(conn->data_rx_tfm);
|
crypto_free_tfm(conn->data_rx_tfm);
|
||||||
}
|
}
|
||||||
|
conn->sendpage = conn->datadgst_en ?
|
||||||
|
sock_no_sendpage : conn->sock->ops->sendpage;
|
||||||
break;
|
break;
|
||||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||||
session->initial_r2t_en = value;
|
session->initial_r2t_en = value;
|
||||||
@@ -3515,25 +3495,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
|
iscsi_session_get_param(struct Scsi_Host *shost,
|
||||||
uint32_t *value)
|
enum iscsi_param param, uint32_t *value)
|
||||||
{
|
{
|
||||||
struct iscsi_conn *conn = iscsi_ptr(connh);
|
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||||
struct iscsi_session *session = conn->session;
|
|
||||||
|
|
||||||
switch(param) {
|
switch(param) {
|
||||||
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
|
||||||
*value = conn->max_recv_dlength;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
|
||||||
*value = conn->max_xmit_dlength;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_HDRDGST_EN:
|
|
||||||
*value = conn->hdrdgst_en;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_DATADGST_EN:
|
|
||||||
*value = conn->datadgst_en;
|
|
||||||
break;
|
|
||||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||||
*value = session->initial_r2t_en;
|
*value = session->initial_r2t_en;
|
||||||
break;
|
break;
|
||||||
@@ -3571,6 +3538,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value)
|
||||||
|
{
|
||||||
|
struct iscsi_conn *conn = data;
|
||||||
|
|
||||||
|
switch(param) {
|
||||||
|
case ISCSI_PARAM_MAX_RECV_DLENGTH:
|
||||||
|
*value = conn->max_recv_dlength;
|
||||||
|
break;
|
||||||
|
case ISCSI_PARAM_MAX_XMIT_DLENGTH:
|
||||||
|
*value = conn->max_xmit_dlength;
|
||||||
|
break;
|
||||||
|
case ISCSI_PARAM_HDRDGST_EN:
|
||||||
|
*value = conn->hdrdgst_en;
|
||||||
|
break;
|
||||||
|
case ISCSI_PARAM_DATADGST_EN:
|
||||||
|
*value = conn->datadgst_en;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ISCSI_ERR_PARAM_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
|
iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats)
|
||||||
{
|
{
|
||||||
@@ -3601,9 +3593,9 @@ iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data,
|
|||||||
struct iscsi_conn *conn = iscsi_ptr(connh);
|
struct iscsi_conn *conn = iscsi_ptr(connh);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
down(&conn->xmitsema);
|
mutex_lock(&conn->xmitmutex);
|
||||||
rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
|
rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
|
||||||
up(&conn->xmitsema);
|
mutex_unlock(&conn->xmitmutex);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -3615,6 +3607,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
|||||||
| CAP_DATADGST,
|
| CAP_DATADGST,
|
||||||
.host_template = &iscsi_sht,
|
.host_template = &iscsi_sht,
|
||||||
.hostdata_size = sizeof(struct iscsi_session),
|
.hostdata_size = sizeof(struct iscsi_session),
|
||||||
|
.conndata_size = sizeof(struct iscsi_conn),
|
||||||
.max_conn = 1,
|
.max_conn = 1,
|
||||||
.max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
|
.max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
|
||||||
.create_session = iscsi_session_create,
|
.create_session = iscsi_session_create,
|
||||||
@@ -3623,7 +3616,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
|||||||
.bind_conn = iscsi_conn_bind,
|
.bind_conn = iscsi_conn_bind,
|
||||||
.destroy_conn = iscsi_conn_destroy,
|
.destroy_conn = iscsi_conn_destroy,
|
||||||
.set_param = iscsi_conn_set_param,
|
.set_param = iscsi_conn_set_param,
|
||||||
.get_param = iscsi_conn_get_param,
|
.get_conn_param = iscsi_conn_get_param,
|
||||||
|
.get_session_param = iscsi_session_get_param,
|
||||||
.start_conn = iscsi_conn_start,
|
.start_conn = iscsi_conn_start,
|
||||||
.stop_conn = iscsi_conn_stop,
|
.stop_conn = iscsi_conn_stop,
|
||||||
.send_pdu = iscsi_conn_send_pdu,
|
.send_pdu = iscsi_conn_send_pdu,
|
||||||
@@ -3633,8 +3627,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
|||||||
static int __init
|
static int __init
|
||||||
iscsi_tcp_init(void)
|
iscsi_tcp_init(void)
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
|
|
||||||
if (iscsi_max_lun < 1) {
|
if (iscsi_max_lun < 1) {
|
||||||
printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
|
printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -3647,11 +3639,10 @@ iscsi_tcp_init(void)
|
|||||||
if (!taskcache)
|
if (!taskcache)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
error = iscsi_register_transport(&iscsi_tcp_transport);
|
if (!iscsi_register_transport(&iscsi_tcp_transport))
|
||||||
if (error)
|
|
||||||
kmem_cache_destroy(taskcache);
|
kmem_cache_destroy(taskcache);
|
||||||
|
|
||||||
return error;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit
|
static void __exit
|
||||||
|
|||||||
@@ -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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define __MEGARAID_H__
|
#define __MEGARAID_H__
|
||||||
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#define MEGARAID_VERSION \
|
#define MEGARAID_VERSION \
|
||||||
"v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"
|
"v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"
|
||||||
@@ -889,7 +889,7 @@ typedef struct {
|
|||||||
|
|
||||||
scb_t int_scb;
|
scb_t int_scb;
|
||||||
Scsi_Cmnd int_scmd;
|
Scsi_Cmnd int_scmd;
|
||||||
struct semaphore int_mtx; /* To synchronize the internal
|
struct mutex int_mtx; /* To synchronize the internal
|
||||||
commands */
|
commands */
|
||||||
struct completion int_waitq; /* wait queue for internal
|
struct completion int_waitq; /* wait queue for internal
|
||||||
cmds */
|
cmds */
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
@@ -72,7 +73,7 @@ MODULE_DEVICE_TABLE(pci, megasas_pci_table);
|
|||||||
static int megasas_mgmt_majorno;
|
static int megasas_mgmt_majorno;
|
||||||
static struct megasas_mgmt_info megasas_mgmt_info;
|
static struct megasas_mgmt_info megasas_mgmt_info;
|
||||||
static struct fasync_struct *megasas_async_queue;
|
static struct fasync_struct *megasas_async_queue;
|
||||||
static DECLARE_MUTEX(megasas_async_queue_mutex);
|
static DEFINE_MUTEX(megasas_async_queue_mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* megasas_get_cmd - Get a command from the free pool
|
* megasas_get_cmd - Get a command from the free pool
|
||||||
@@ -2362,11 +2363,11 @@ static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
down(&megasas_async_queue_mutex);
|
mutex_lock(&megasas_async_queue_mutex);
|
||||||
|
|
||||||
rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
|
rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
|
||||||
|
|
||||||
up(&megasas_async_queue_mutex);
|
mutex_unlock(&megasas_async_queue_mutex);
|
||||||
|
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
/* For sanity check when we get ioctl */
|
/* For sanity check when we get ioctl */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
config SCSI_QLA2XXX
|
config SCSI_QLA_FC
|
||||||
tristate "QLogic QLA2XXX Fibre Channel Support"
|
tristate "QLogic QLA2XXX Fibre Channel Support"
|
||||||
depends on PCI && SCSI
|
depends on PCI && SCSI
|
||||||
select SCSI_FC_ATTRS
|
select SCSI_FC_ATTRS
|
||||||
@@ -22,49 +22,57 @@ config SCSI_QLA2XXX
|
|||||||
Upon request, the driver caches the firmware image until
|
Upon request, the driver caches the firmware image until
|
||||||
the driver is unloaded.
|
the driver is unloaded.
|
||||||
|
|
||||||
|
Firmware images can be retrieved from:
|
||||||
|
|
||||||
|
ftp://ftp.qlogic.com/outgoing/linux/firmware/
|
||||||
|
|
||||||
NOTE: The original method of building firmware-loader
|
NOTE: The original method of building firmware-loader
|
||||||
modules has been deprecated as the firmware-images will
|
modules has been deprecated as the firmware-images will
|
||||||
be removed from the kernel sources.
|
be removed from the kernel sources.
|
||||||
|
|
||||||
config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
bool " Use firmware-loader modules (DEPRECATED)"
|
bool " Use firmware-loader modules (DEPRECATED)"
|
||||||
depends on SCSI_QLA2XXX
|
depends on SCSI_QLA_FC
|
||||||
|
help
|
||||||
|
This option offers you the deprecated firmware-loader
|
||||||
|
modules that have been obsoleted by the usage of the
|
||||||
|
Firmware Loader interface in the qla2xxx driver.
|
||||||
|
|
||||||
config SCSI_QLA21XX
|
config SCSI_QLA21XX
|
||||||
tristate " Build QLogic ISP2100 firmware-module"
|
tristate " Build QLogic ISP2100 firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 21xx (ISP2100) host adapter family.
|
This driver supports the QLogic 21xx (ISP2100) host adapter family.
|
||||||
|
|
||||||
config SCSI_QLA22XX
|
config SCSI_QLA22XX
|
||||||
tristate " Build QLogic ISP2200 firmware-module"
|
tristate " Build QLogic ISP2200 firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
||||||
|
|
||||||
config SCSI_QLA2300
|
config SCSI_QLA2300
|
||||||
tristate " Build QLogic ISP2300 firmware-module"
|
tristate " Build QLogic ISP2300 firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
|
This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
|
||||||
adapter family.
|
adapter family.
|
||||||
|
|
||||||
config SCSI_QLA2322
|
config SCSI_QLA2322
|
||||||
tristate " Build QLogic ISP2322 firmware-module"
|
tristate " Build QLogic ISP2322 firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 2322 (ISP2322) host adapter family.
|
This driver supports the QLogic 2322 (ISP2322) host adapter family.
|
||||||
|
|
||||||
config SCSI_QLA6312
|
config SCSI_QLA6312
|
||||||
tristate " Build QLogic ISP63xx firmware-module"
|
tristate " Build QLogic ISP63xx firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
|
This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
|
||||||
adapter family.
|
adapter family.
|
||||||
|
|
||||||
config SCSI_QLA24XX
|
config SCSI_QLA24XX
|
||||||
tristate " Build QLogic ISP24xx firmware-module"
|
tristate " Build QLogic ISP24xx firmware-module"
|
||||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||||
---help---
|
---help---
|
||||||
This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
|
This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
|
||||||
adapter family.
|
adapter family.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -541,7 +541,7 @@ struct fc_function_template qla2xxx_transport_functions = {
|
|||||||
void
|
void
|
||||||
qla2x00_init_host_attr(scsi_qla_host_t *ha)
|
qla2x00_init_host_attr(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
fc_host_node_name(ha->host) = wwn_to_u64(ha->init_cb->node_name);
|
fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
|
||||||
fc_host_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
|
fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
|
||||||
fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
|
fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1003,10 +1003,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
|
|||||||
fw = (struct qla24xx_fw_dump *) ha->fw_dump24;
|
fw = (struct qla24xx_fw_dump *) ha->fw_dump24;
|
||||||
|
|
||||||
rval = QLA_SUCCESS;
|
rval = QLA_SUCCESS;
|
||||||
fw->hccr = RD_REG_DWORD(®->hccr);
|
fw->host_status = RD_REG_DWORD(®->host_status);
|
||||||
|
|
||||||
/* Pause RISC. */
|
/* Pause RISC. */
|
||||||
if ((fw->hccr & HCCRX_RISC_PAUSE) == 0) {
|
if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) {
|
||||||
WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET |
|
WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET |
|
||||||
HCCRX_CLR_HOST_INT);
|
HCCRX_CLR_HOST_INT);
|
||||||
RD_REG_DWORD(®->hccr); /* PCI Posting. */
|
RD_REG_DWORD(®->hccr); /* PCI Posting. */
|
||||||
@@ -1021,16 +1021,54 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable interrupts. */
|
|
||||||
WRT_REG_DWORD(®->ictrl, 0);
|
|
||||||
RD_REG_DWORD(®->ictrl);
|
|
||||||
|
|
||||||
if (rval == QLA_SUCCESS) {
|
if (rval == QLA_SUCCESS) {
|
||||||
/* Host interface registers. */
|
/* Host interface registers. */
|
||||||
dmp_reg = (uint32_t __iomem *)(reg + 0);
|
dmp_reg = (uint32_t __iomem *)(reg + 0);
|
||||||
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
|
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
|
||||||
fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++);
|
fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++);
|
||||||
|
|
||||||
|
/* Disable interrupts. */
|
||||||
|
WRT_REG_DWORD(®->ictrl, 0);
|
||||||
|
RD_REG_DWORD(®->ictrl);
|
||||||
|
|
||||||
|
/* Shadow registers. */
|
||||||
|
WRT_REG_DWORD(®->iobase_addr, 0x0F70);
|
||||||
|
RD_REG_DWORD(®->iobase_addr);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0000000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0100000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0200000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0300000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0400000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0500000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
||||||
|
WRT_REG_DWORD(dmp_reg, 0xB0600000);
|
||||||
|
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
||||||
|
fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg);
|
||||||
|
|
||||||
/* Mailbox registers. */
|
/* Mailbox registers. */
|
||||||
mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
|
mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
|
||||||
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
|
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
|
||||||
@@ -1308,43 +1346,6 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
|
|||||||
for (cnt = 0; cnt < 16; cnt++)
|
for (cnt = 0; cnt < 16; cnt++)
|
||||||
*iter_reg++ = RD_REG_DWORD(dmp_reg++);
|
*iter_reg++ = RD_REG_DWORD(dmp_reg++);
|
||||||
|
|
||||||
WRT_REG_DWORD(®->iobase_addr, 0x0F70);
|
|
||||||
RD_REG_DWORD(®->iobase_addr);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0000000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0100000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0200000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0300000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0400000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0500000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
|
|
||||||
WRT_REG_DWORD(dmp_reg, 0xB0600000);
|
|
||||||
dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
|
|
||||||
fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg);
|
|
||||||
|
|
||||||
/* Local memory controller registers. */
|
/* Local memory controller registers. */
|
||||||
iter_reg = fw->lmc_reg;
|
iter_reg = fw->lmc_reg;
|
||||||
WRT_REG_DWORD(®->iobase_addr, 0x3000);
|
WRT_REG_DWORD(®->iobase_addr, 0x3000);
|
||||||
@@ -1677,7 +1678,7 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
|
|||||||
ha->fw_major_version, ha->fw_minor_version,
|
ha->fw_major_version, ha->fw_minor_version,
|
||||||
ha->fw_subminor_version, ha->fw_attributes);
|
ha->fw_subminor_version, ha->fw_attributes);
|
||||||
|
|
||||||
qla_uprintf(&uiter, "\nHCCR Register\n%04x\n", fw->hccr);
|
qla_uprintf(&uiter, "\nR2H Status Register\n%04x\n", fw->host_status);
|
||||||
|
|
||||||
qla_uprintf(&uiter, "\nHost Interface Registers");
|
qla_uprintf(&uiter, "\nHost Interface Registers");
|
||||||
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) {
|
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) {
|
||||||
@@ -1687,6 +1688,14 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
|
|||||||
qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]);
|
qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qla_uprintf(&uiter, "\n\nShadow Registers");
|
||||||
|
for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) {
|
||||||
|
if (cnt % 8 == 0)
|
||||||
|
qla_uprintf(&uiter, "\n");
|
||||||
|
|
||||||
|
qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]);
|
||||||
|
}
|
||||||
|
|
||||||
qla_uprintf(&uiter, "\n\nMailbox Registers");
|
qla_uprintf(&uiter, "\n\nMailbox Registers");
|
||||||
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) {
|
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) {
|
||||||
if (cnt % 8 == 0)
|
if (cnt % 8 == 0)
|
||||||
@@ -1855,14 +1864,6 @@ qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
|
|||||||
qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]);
|
qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
qla_uprintf(&uiter, "\n\nShadow Registers");
|
|
||||||
for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) {
|
|
||||||
if (cnt % 8 == 0)
|
|
||||||
qla_uprintf(&uiter, "\n");
|
|
||||||
|
|
||||||
qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]);
|
|
||||||
}
|
|
||||||
|
|
||||||
qla_uprintf(&uiter, "\n\nLMC Registers");
|
qla_uprintf(&uiter, "\n\nLMC Registers");
|
||||||
for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) {
|
for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) {
|
||||||
if (cnt % 8 == 0)
|
if (cnt % 8 == 0)
|
||||||
|
|||||||
@@ -227,8 +227,9 @@ struct qla2100_fw_dump {
|
|||||||
#define FW_DUMP_SIZE_24XX 0x2B0000
|
#define FW_DUMP_SIZE_24XX 0x2B0000
|
||||||
|
|
||||||
struct qla24xx_fw_dump {
|
struct qla24xx_fw_dump {
|
||||||
uint32_t hccr;
|
uint32_t host_status;
|
||||||
uint32_t host_reg[32];
|
uint32_t host_reg[32];
|
||||||
|
uint32_t shadow_reg[7];
|
||||||
uint16_t mailbox_reg[32];
|
uint16_t mailbox_reg[32];
|
||||||
uint32_t xseq_gp_reg[128];
|
uint32_t xseq_gp_reg[128];
|
||||||
uint32_t xseq_0_reg[16];
|
uint32_t xseq_0_reg[16];
|
||||||
@@ -250,7 +251,6 @@ struct qla24xx_fw_dump {
|
|||||||
uint32_t rcvt0_data_dma_reg[32];
|
uint32_t rcvt0_data_dma_reg[32];
|
||||||
uint32_t rcvt1_data_dma_reg[32];
|
uint32_t rcvt1_data_dma_reg[32];
|
||||||
uint32_t risc_gp_reg[128];
|
uint32_t risc_gp_reg[128];
|
||||||
uint32_t shadow_reg[7];
|
|
||||||
uint32_t lmc_reg[112];
|
uint32_t lmc_reg[112];
|
||||||
uint32_t fpm_hdw_reg[192];
|
uint32_t fpm_hdw_reg[192];
|
||||||
uint32_t fb_hdw_reg[176];
|
uint32_t fb_hdw_reg[176];
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ extern int qlport_down_retry;
|
|||||||
extern int ql2xplogiabsentdevice;
|
extern int ql2xplogiabsentdevice;
|
||||||
extern int ql2xloginretrycount;
|
extern int ql2xloginretrycount;
|
||||||
extern int ql2xfdmienable;
|
extern int ql2xfdmienable;
|
||||||
|
extern int ql2xprocessrscn;
|
||||||
|
|
||||||
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
|
extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
|
||||||
|
|
||||||
@@ -96,10 +97,7 @@ int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
|
|||||||
* Global Function Prototypes in qla_mbx.c source file.
|
* Global Function Prototypes in qla_mbx.c source file.
|
||||||
*/
|
*/
|
||||||
extern int
|
extern int
|
||||||
qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t);
|
qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
|
||||||
|
|
||||||
extern int
|
|
||||||
qla2x00_load_ram_ext(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
|
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
|
||||||
|
|||||||
@@ -538,6 +538,7 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
|
|||||||
ct_req->req.rff_id.port_id[1] = ha->d_id.b.area;
|
ct_req->req.rff_id.port_id[1] = ha->d_id.b.area;
|
||||||
ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa;
|
ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa;
|
||||||
|
|
||||||
|
ct_req->req.rff_id.fc4_feature = BIT_1;
|
||||||
ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
|
ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
|
||||||
|
|
||||||
/* Execute MS IOCB */
|
/* Execute MS IOCB */
|
||||||
@@ -1529,9 +1530,9 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
|||||||
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
|
eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
|
||||||
eiter->len = __constant_cpu_to_be16(4 + 4);
|
eiter->len = __constant_cpu_to_be16(4 + 4);
|
||||||
if (IS_QLA25XX(ha))
|
if (IS_QLA25XX(ha))
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(4);
|
|
||||||
else if (IS_QLA24XX(ha))
|
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(8);
|
eiter->a.sup_speed = __constant_cpu_to_be32(8);
|
||||||
|
else if (IS_QLA24XX(ha))
|
||||||
|
eiter->a.sup_speed = __constant_cpu_to_be32(4);
|
||||||
else if (IS_QLA23XX(ha))
|
else if (IS_QLA23XX(ha))
|
||||||
eiter->a.sup_speed = __constant_cpu_to_be32(2);
|
eiter->a.sup_speed = __constant_cpu_to_be32(2);
|
||||||
else
|
else
|
||||||
@@ -1553,9 +1554,6 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
|||||||
eiter->a.cur_speed = __constant_cpu_to_be32(2);
|
eiter->a.cur_speed = __constant_cpu_to_be32(2);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
eiter->a.cur_speed = __constant_cpu_to_be32(8);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
eiter->a.cur_speed = __constant_cpu_to_be32(4);
|
eiter->a.cur_speed = __constant_cpu_to_be32(4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1014,11 +1014,13 @@ qla24xx_update_fw_options(scsi_qla_host_t *ha)
|
|||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
/* Update Serial Link options. */
|
/* Update Serial Link options. */
|
||||||
if ((ha->fw_seriallink_options24[0] & BIT_0) == 0)
|
if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rval = qla2x00_set_serdes_params(ha, ha->fw_seriallink_options24[1],
|
rval = qla2x00_set_serdes_params(ha,
|
||||||
ha->fw_seriallink_options24[2], ha->fw_seriallink_options24[3]);
|
le16_to_cpu(ha->fw_seriallink_options24[1]),
|
||||||
|
le16_to_cpu(ha->fw_seriallink_options24[2]),
|
||||||
|
le16_to_cpu(ha->fw_seriallink_options24[3]));
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
qla_printk(KERN_WARNING, ha,
|
qla_printk(KERN_WARNING, ha,
|
||||||
"Unable to update Serial Link options (%x).\n", rval);
|
"Unable to update Serial Link options (%x).\n", rval);
|
||||||
@@ -1939,6 +1941,9 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
|
|||||||
"information -- get_port_database=%x, "
|
"information -- get_port_database=%x, "
|
||||||
"loop_id=0x%04x\n",
|
"loop_id=0x%04x\n",
|
||||||
ha->host_no, rval2, new_fcport->loop_id));
|
ha->host_no, rval2, new_fcport->loop_id));
|
||||||
|
DEBUG2(printk("scsi(%ld): Scheduling resync...\n",
|
||||||
|
ha->host_no));
|
||||||
|
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2648,7 +2653,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
|
|||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
if (ql2xprocessrscn &&
|
||||||
|
!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
||||||
!IS_QLA6312(ha) && !IS_QLA6322(ha) &&
|
!IS_QLA6312(ha) && !IS_QLA6322(ha) &&
|
||||||
!IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
!IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
||||||
ha->flags.init_done) {
|
ha->flags.init_done) {
|
||||||
@@ -3402,6 +3408,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
|||||||
ha->node_name = icb->node_name;
|
ha->node_name = icb->node_name;
|
||||||
ha->port_name = icb->port_name;
|
ha->port_name = icb->port_name;
|
||||||
|
|
||||||
|
icb->execution_throttle = __constant_cpu_to_le16(0xFFFF);
|
||||||
|
|
||||||
ha->retry_count = le16_to_cpu(nv->login_retry_count);
|
ha->retry_count = le16_to_cpu(nv->login_retry_count);
|
||||||
|
|
||||||
/* Set minimum login_timeout to 4 seconds. */
|
/* Set minimum login_timeout to 4 seconds. */
|
||||||
@@ -3667,8 +3675,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
|
|||||||
for (i = 0; i < dlen; i++)
|
for (i = 0; i < dlen; i++)
|
||||||
dcode[i] = swab32(dcode[i]);
|
dcode[i] = swab32(dcode[i]);
|
||||||
|
|
||||||
rval = qla2x00_load_ram_ext(ha, ha->request_dma,
|
rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
|
||||||
risc_addr, dlen);
|
dlen);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
||||||
"segment %d of firmware\n", ha->host_no,
|
"segment %d of firmware\n", ha->host_no,
|
||||||
@@ -3868,8 +3876,8 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
|
|||||||
for (i = 0; i < dlen; i++)
|
for (i = 0; i < dlen; i++)
|
||||||
dcode[i] = swab32(fwcode[i]);
|
dcode[i] = swab32(fwcode[i]);
|
||||||
|
|
||||||
rval = qla2x00_load_ram_ext(ha, ha->request_dma,
|
rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
|
||||||
risc_addr, dlen);
|
dlen);
|
||||||
if (rval) {
|
if (rval) {
|
||||||
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
||||||
"segment %d of firmware\n", ha->host_no,
|
"segment %d of firmware\n", ha->host_no,
|
||||||
|
|||||||
@@ -519,7 +519,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
|
|||||||
* us, create a new entry in our rscn fcports list and handle
|
* us, create a new entry in our rscn fcports list and handle
|
||||||
* the event like an RSCN.
|
* the event like an RSCN.
|
||||||
*/
|
*/
|
||||||
if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
|
if (ql2xprocessrscn &&
|
||||||
|
!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
|
||||||
!IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
!IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
||||||
ha->flags.init_done && mb[1] != 0xffff &&
|
ha->flags.init_done && mb[1] != 0xffff &&
|
||||||
((ha->operating_mode == P2P && mb[1] != 0) ||
|
((ha->operating_mode == P2P && mb[1] != 0) ||
|
||||||
@@ -963,15 +964,16 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CS_DATA_UNDERRUN:
|
case CS_DATA_UNDERRUN:
|
||||||
DEBUG2(printk(KERN_INFO
|
|
||||||
"scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
|
|
||||||
ha->host_no, cp->device->id, cp->device->lun, comp_status,
|
|
||||||
scsi_status));
|
|
||||||
|
|
||||||
resid = resid_len;
|
resid = resid_len;
|
||||||
if (scsi_status & SS_RESIDUAL_UNDER) {
|
if (scsi_status & SS_RESIDUAL_UNDER) {
|
||||||
cp->resid = resid;
|
cp->resid = resid;
|
||||||
CMD_RESID_LEN(cp) = resid;
|
CMD_RESID_LEN(cp) = resid;
|
||||||
|
} else {
|
||||||
|
DEBUG2(printk(KERN_INFO
|
||||||
|
"scsi(%ld:%d:%d) UNDERRUN status detected "
|
||||||
|
"0x%x-0x%x.\n", ha->host_no, cp->device->id,
|
||||||
|
cp->device->lun, comp_status, scsi_status));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -196,7 +196,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||||||
/* Check for pending interrupts. */
|
/* Check for pending interrupts. */
|
||||||
qla2x00_poll(ha);
|
qla2x00_poll(ha);
|
||||||
|
|
||||||
udelay(10); /* v4.27 */
|
if (command != MBC_LOAD_RISC_RAM_EXTENDED &&
|
||||||
|
!ha->flags.mbox_int)
|
||||||
|
msleep(10);
|
||||||
} /* while */
|
} /* while */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,98 +327,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* qla2x00_load_ram
|
|
||||||
* Load adapter RAM using DMA.
|
|
||||||
*
|
|
||||||
* Input:
|
|
||||||
* ha = adapter block pointer.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* qla2x00 local function return status code.
|
|
||||||
*
|
|
||||||
* Context:
|
|
||||||
* Kernel context.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr,
|
qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
|
||||||
uint16_t risc_code_size)
|
uint32_t risc_code_size)
|
||||||
{
|
|
||||||
int rval;
|
|
||||||
mbx_cmd_t mc;
|
|
||||||
mbx_cmd_t *mcp = &mc;
|
|
||||||
uint32_t req_len;
|
|
||||||
dma_addr_t nml_dma;
|
|
||||||
uint32_t nml_len;
|
|
||||||
uint32_t normalized;
|
|
||||||
|
|
||||||
DEBUG11(printk("qla2x00_load_ram(%ld): entered.\n",
|
|
||||||
ha->host_no);)
|
|
||||||
|
|
||||||
req_len = risc_code_size;
|
|
||||||
nml_dma = 0;
|
|
||||||
nml_len = 0;
|
|
||||||
|
|
||||||
normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
|
|
||||||
&nml_len);
|
|
||||||
|
|
||||||
/* Load first segment */
|
|
||||||
mcp->mb[0] = MBC_LOAD_RISC_RAM;
|
|
||||||
mcp->mb[1] = risc_addr;
|
|
||||||
mcp->mb[2] = MSW(req_dma);
|
|
||||||
mcp->mb[3] = LSW(req_dma);
|
|
||||||
mcp->mb[4] = (uint16_t)req_len;
|
|
||||||
mcp->mb[6] = MSW(MSD(req_dma));
|
|
||||||
mcp->mb[7] = LSW(MSD(req_dma));
|
|
||||||
mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
|
||||||
mcp->in_mb = MBX_0;
|
|
||||||
mcp->tov = 30;
|
|
||||||
mcp->flags = 0;
|
|
||||||
rval = qla2x00_mailbox_command(ha, mcp);
|
|
||||||
|
|
||||||
/* Load second segment - if necessary */
|
|
||||||
if (normalized && (rval == QLA_SUCCESS)) {
|
|
||||||
mcp->mb[0] = MBC_LOAD_RISC_RAM;
|
|
||||||
mcp->mb[1] = risc_addr + (uint16_t)req_len;
|
|
||||||
mcp->mb[2] = MSW(nml_dma);
|
|
||||||
mcp->mb[3] = LSW(nml_dma);
|
|
||||||
mcp->mb[4] = (uint16_t)nml_len;
|
|
||||||
mcp->mb[6] = MSW(MSD(nml_dma));
|
|
||||||
mcp->mb[7] = LSW(MSD(nml_dma));
|
|
||||||
mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
|
||||||
mcp->in_mb = MBX_0;
|
|
||||||
mcp->tov = 30;
|
|
||||||
mcp->flags = 0;
|
|
||||||
rval = qla2x00_mailbox_command(ha, mcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rval == QLA_SUCCESS) {
|
|
||||||
/* Empty */
|
|
||||||
DEBUG11(printk("qla2x00_load_ram(%ld): done.\n", ha->host_no);)
|
|
||||||
} else {
|
|
||||||
/* Empty */
|
|
||||||
DEBUG2_3_11(printk("qla2x00_load_ram(%ld): failed. rval=%x "
|
|
||||||
"mb[0]=%x.\n", ha->host_no, rval, mcp->mb[0]);)
|
|
||||||
}
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* qla2x00_load_ram_ext
|
|
||||||
* Load adapter extended RAM using DMA.
|
|
||||||
*
|
|
||||||
* Input:
|
|
||||||
* ha = adapter block pointer.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* qla2x00 local function return status code.
|
|
||||||
*
|
|
||||||
* Context:
|
|
||||||
* Kernel context.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
|
|
||||||
uint32_t risc_addr, uint32_t risc_code_size)
|
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
mbx_cmd_t mc;
|
mbx_cmd_t mc;
|
||||||
@@ -424,14 +337,20 @@ qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
|
|||||||
|
|
||||||
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
|
||||||
|
|
||||||
mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
|
if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
||||||
|
mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
|
||||||
|
mcp->mb[8] = MSW(risc_addr);
|
||||||
|
mcp->out_mb = MBX_8|MBX_0;
|
||||||
|
} else {
|
||||||
|
mcp->mb[0] = MBC_LOAD_RISC_RAM;
|
||||||
|
mcp->out_mb = MBX_0;
|
||||||
|
}
|
||||||
mcp->mb[1] = LSW(risc_addr);
|
mcp->mb[1] = LSW(risc_addr);
|
||||||
mcp->mb[2] = MSW(req_dma);
|
mcp->mb[2] = MSW(req_dma);
|
||||||
mcp->mb[3] = LSW(req_dma);
|
mcp->mb[3] = LSW(req_dma);
|
||||||
mcp->mb[6] = MSW(MSD(req_dma));
|
mcp->mb[6] = MSW(MSD(req_dma));
|
||||||
mcp->mb[7] = LSW(MSD(req_dma));
|
mcp->mb[7] = LSW(MSD(req_dma));
|
||||||
mcp->mb[8] = MSW(risc_addr);
|
mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
|
||||||
mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
|
||||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
||||||
mcp->mb[4] = MSW(risc_code_size);
|
mcp->mb[4] = MSW(risc_code_size);
|
||||||
mcp->mb[5] = LSW(risc_code_size);
|
mcp->mb[5] = LSW(risc_code_size);
|
||||||
|
|||||||
@@ -71,6 +71,12 @@ MODULE_PARM_DESC(ql2xfdmienable,
|
|||||||
"Enables FDMI registratons "
|
"Enables FDMI registratons "
|
||||||
"Default is 0 - no FDMI. 1 - perfom FDMI.");
|
"Default is 0 - no FDMI. 1 - perfom FDMI.");
|
||||||
|
|
||||||
|
int ql2xprocessrscn;
|
||||||
|
module_param(ql2xprocessrscn, int, S_IRUGO|S_IRUSR);
|
||||||
|
MODULE_PARM_DESC(ql2xprocessrscn,
|
||||||
|
"Option to enable port RSCN handling via a series of less"
|
||||||
|
"fabric intrusive ADISCs and PLOGIs.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCSI host template entry points
|
* SCSI host template entry points
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -573,6 +573,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
|
|||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
/* Enable flash write-protection. */
|
||||||
|
qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c);
|
||||||
|
|
||||||
/* Disable flash write. */
|
/* Disable flash write. */
|
||||||
WRT_REG_DWORD(®->ctrl_status,
|
WRT_REG_DWORD(®->ctrl_status,
|
||||||
RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE);
|
RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE);
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
/*
|
/*
|
||||||
* Driver version
|
* Driver version
|
||||||
*/
|
*/
|
||||||
#define QLA2XXX_VERSION "8.01.03-k"
|
#define QLA2XXX_VERSION "8.01.04-k"
|
||||||
|
|
||||||
#define QLA_DRIVER_MAJOR_VER 8
|
#define QLA_DRIVER_MAJOR_VER 8
|
||||||
#define QLA_DRIVER_MINOR_VER 1
|
#define QLA_DRIVER_MINOR_VER 1
|
||||||
#define QLA_DRIVER_PATCH_VER 3
|
#define QLA_DRIVER_PATCH_VER 4
|
||||||
#define QLA_DRIVER_BETA_VER 0
|
#define QLA_DRIVER_BETA_VER 0
|
||||||
|
|||||||
@@ -148,9 +148,11 @@ static struct {
|
|||||||
{ RAID_LEVEL_LINEAR, "linear" },
|
{ RAID_LEVEL_LINEAR, "linear" },
|
||||||
{ RAID_LEVEL_0, "raid0" },
|
{ RAID_LEVEL_0, "raid0" },
|
||||||
{ RAID_LEVEL_1, "raid1" },
|
{ RAID_LEVEL_1, "raid1" },
|
||||||
|
{ RAID_LEVEL_10, "raid10" },
|
||||||
{ RAID_LEVEL_3, "raid3" },
|
{ RAID_LEVEL_3, "raid3" },
|
||||||
{ RAID_LEVEL_4, "raid4" },
|
{ RAID_LEVEL_4, "raid4" },
|
||||||
{ RAID_LEVEL_5, "raid5" },
|
{ RAID_LEVEL_5, "raid5" },
|
||||||
|
{ RAID_LEVEL_50, "raid50" },
|
||||||
{ RAID_LEVEL_6, "raid6" },
|
{ RAID_LEVEL_6, "raid6" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+7
-6
@@ -55,6 +55,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_cmnd.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
@@ -209,7 +210,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
|
|||||||
.gfp_mask = __GFP_DMA,
|
.gfp_mask = __GFP_DMA,
|
||||||
};
|
};
|
||||||
|
|
||||||
static DECLARE_MUTEX(host_cmd_pool_mutex);
|
static DEFINE_MUTEX(host_cmd_pool_mutex);
|
||||||
|
|
||||||
static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
|
static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost,
|
||||||
gfp_t gfp_mask)
|
gfp_t gfp_mask)
|
||||||
@@ -330,7 +331,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
|||||||
* Select a command slab for this host and create it if not
|
* Select a command slab for this host and create it if not
|
||||||
* yet existant.
|
* yet existant.
|
||||||
*/
|
*/
|
||||||
down(&host_cmd_pool_mutex);
|
mutex_lock(&host_cmd_pool_mutex);
|
||||||
pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
|
pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool);
|
||||||
if (!pool->users) {
|
if (!pool->users) {
|
||||||
pool->slab = kmem_cache_create(pool->name,
|
pool->slab = kmem_cache_create(pool->name,
|
||||||
@@ -342,7 +343,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
|||||||
|
|
||||||
pool->users++;
|
pool->users++;
|
||||||
shost->cmd_pool = pool;
|
shost->cmd_pool = pool;
|
||||||
up(&host_cmd_pool_mutex);
|
mutex_unlock(&host_cmd_pool_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get one backup command for this host.
|
* Get one backup command for this host.
|
||||||
@@ -359,7 +360,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
|||||||
kmem_cache_destroy(pool->slab);
|
kmem_cache_destroy(pool->slab);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
fail:
|
fail:
|
||||||
up(&host_cmd_pool_mutex);
|
mutex_unlock(&host_cmd_pool_mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -381,10 +382,10 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost)
|
|||||||
kmem_cache_free(shost->cmd_pool->slab, cmd);
|
kmem_cache_free(shost->cmd_pool->slab, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
down(&host_cmd_pool_mutex);
|
mutex_lock(&host_cmd_pool_mutex);
|
||||||
if (!--shost->cmd_pool->users)
|
if (!--shost->cmd_pool->users)
|
||||||
kmem_cache_destroy(shost->cmd_pool->slab);
|
kmem_cache_destroy(shost->cmd_pool->slab);
|
||||||
up(&host_cmd_pool_mutex);
|
mutex_unlock(&host_cmd_pool_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SCSI_LOGGING
|
#ifdef CONFIG_SCSI_LOGGING
|
||||||
|
|||||||
@@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_generic_done(struct scsi_cmnd *cmd)
|
static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
BUG_ON(!blk_pc_request(cmd->request));
|
BUG_ON(!blk_pc_request(cmd->request));
|
||||||
/*
|
/*
|
||||||
@@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd)
|
|||||||
scsi_io_completion(cmd, cmd->bufflen, 0);
|
scsi_io_completion(cmd, cmd->bufflen, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
|
static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
struct request *req = cmd->request;
|
struct request *req = cmd->request;
|
||||||
|
|
||||||
@@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
|
|||||||
cmd->transfersize = req->data_len;
|
cmd->transfersize = req->data_len;
|
||||||
cmd->allowed = req->retries;
|
cmd->allowed = req->retries;
|
||||||
cmd->timeout_per_command = req->timeout;
|
cmd->timeout_per_command = req->timeout;
|
||||||
|
cmd->done = scsi_blk_pc_done;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
|
|
||||||
|
|
||||||
static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
||||||
{
|
{
|
||||||
@@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
|||||||
* happening now.
|
* happening now.
|
||||||
*/
|
*/
|
||||||
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
|
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
|
||||||
struct scsi_driver *drv;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1371,16 +1370,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
|||||||
/*
|
/*
|
||||||
* Initialize the actual SCSI command for this request.
|
* Initialize the actual SCSI command for this request.
|
||||||
*/
|
*/
|
||||||
if (req->rq_disk) {
|
if (req->flags & REQ_BLOCK_PC) {
|
||||||
|
scsi_setup_blk_pc_cmnd(cmd);
|
||||||
|
} else if (req->rq_disk) {
|
||||||
|
struct scsi_driver *drv;
|
||||||
|
|
||||||
drv = *(struct scsi_driver **)req->rq_disk->private_data;
|
drv = *(struct scsi_driver **)req->rq_disk->private_data;
|
||||||
if (unlikely(!drv->init_command(cmd))) {
|
if (unlikely(!drv->init_command(cmd))) {
|
||||||
scsi_release_buffers(cmd);
|
scsi_release_buffers(cmd);
|
||||||
scsi_put_command(cmd);
|
scsi_put_command(cmd);
|
||||||
goto kill;
|
goto kill;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
scsi_setup_blk_pc_cmnd(cmd);
|
|
||||||
cmd->done = scsi_generic_done;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,6 @@ struct Scsi_Host;
|
|||||||
#define SCSI_SENSE_VALID(scmd) \
|
#define SCSI_SENSE_VALID(scmd) \
|
||||||
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
|
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
|
||||||
|
|
||||||
/*
|
|
||||||
* Special value for scanning to specify scanning or rescanning of all
|
|
||||||
* possible channels, (target) ids, or luns on a given shost.
|
|
||||||
*/
|
|
||||||
#define SCAN_WILD_CARD ~0
|
|
||||||
|
|
||||||
/* hosts.c */
|
/* hosts.c */
|
||||||
extern int scsi_init_hosts(void);
|
extern int scsi_init_hosts(void);
|
||||||
extern void scsi_exit_hosts(void);
|
extern void scsi_exit_hosts(void);
|
||||||
|
|||||||
@@ -25,11 +25,13 @@
|
|||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
|
#include <scsi/scsi_transport.h>
|
||||||
|
|
||||||
#include "scsi_priv.h"
|
#include "scsi_priv.h"
|
||||||
#include "scsi_logging.h"
|
#include "scsi_logging.h"
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
static struct proc_dir_entry *proc_scsi;
|
static struct proc_dir_entry *proc_scsi;
|
||||||
|
|
||||||
/* Protect sht->present and sht->proc_dir */
|
/* Protect sht->present and sht->proc_dir */
|
||||||
static DECLARE_MUTEX(global_host_template_sem);
|
static DEFINE_MUTEX(global_host_template_mutex);
|
||||||
|
|
||||||
static int proc_scsi_read(char *buffer, char **start, off_t offset,
|
static int proc_scsi_read(char *buffer, char **start, off_t offset,
|
||||||
int length, int *eof, void *data)
|
int length, int *eof, void *data)
|
||||||
@@ -83,7 +85,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
|
|||||||
if (!sht->proc_info)
|
if (!sht->proc_info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
down(&global_host_template_sem);
|
mutex_lock(&global_host_template_mutex);
|
||||||
if (!sht->present++) {
|
if (!sht->present++) {
|
||||||
sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
|
sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
|
||||||
if (!sht->proc_dir)
|
if (!sht->proc_dir)
|
||||||
@@ -92,7 +94,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
|
|||||||
else
|
else
|
||||||
sht->proc_dir->owner = sht->module;
|
sht->proc_dir->owner = sht->module;
|
||||||
}
|
}
|
||||||
up(&global_host_template_sem);
|
mutex_unlock(&global_host_template_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
|
void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
|
||||||
@@ -100,12 +102,12 @@ void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
|
|||||||
if (!sht->proc_info)
|
if (!sht->proc_info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
down(&global_host_template_sem);
|
mutex_lock(&global_host_template_mutex);
|
||||||
if (!--sht->present && sht->proc_dir) {
|
if (!--sht->present && sht->proc_dir) {
|
||||||
remove_proc_entry(sht->proc_name, proc_scsi);
|
remove_proc_entry(sht->proc_name, proc_scsi);
|
||||||
sht->proc_dir = NULL;
|
sht->proc_dir = NULL;
|
||||||
}
|
}
|
||||||
up(&global_host_template_sem);
|
mutex_unlock(&global_host_template_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scsi_proc_host_add(struct Scsi_Host *shost)
|
void scsi_proc_host_add(struct Scsi_Host *shost)
|
||||||
@@ -199,7 +201,10 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
|
|||||||
if (IS_ERR(shost))
|
if (IS_ERR(shost))
|
||||||
return PTR_ERR(shost);
|
return PTR_ERR(shost);
|
||||||
|
|
||||||
error = scsi_scan_host_selected(shost, channel, id, lun, 1);
|
if (shost->transportt->user_scan)
|
||||||
|
error = shost->transportt->user_scan(shost, channel, id, lun);
|
||||||
|
else
|
||||||
|
error = scsi_scan_host_selected(shost, channel, id, lun, 1);
|
||||||
scsi_host_put(shost);
|
scsi_host_put(shost);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-22
@@ -334,19 +334,6 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
|
|||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
struct scsi_target *found_target;
|
struct scsi_target *found_target;
|
||||||
|
|
||||||
/*
|
|
||||||
* Obtain the real parent from the transport. The transport
|
|
||||||
* is allowed to fail (no error) if there is nothing at that
|
|
||||||
* target id.
|
|
||||||
*/
|
|
||||||
if (shost->transportt->target_parent) {
|
|
||||||
spin_lock_irqsave(shost->host_lock, flags);
|
|
||||||
parent = shost->transportt->target_parent(shost, channel, id);
|
|
||||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
|
||||||
if (!parent)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
starget = kmalloc(size, GFP_KERNEL);
|
starget = kmalloc(size, GFP_KERNEL);
|
||||||
if (!starget) {
|
if (!starget) {
|
||||||
printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
|
printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
|
||||||
@@ -1283,20 +1270,21 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
|
|||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
struct device *parent = &shost->shost_gendev;
|
struct device *parent = &shost->shost_gendev;
|
||||||
int res;
|
int res;
|
||||||
struct scsi_target *starget = scsi_alloc_target(parent, channel, id);
|
struct scsi_target *starget;
|
||||||
|
|
||||||
|
starget = scsi_alloc_target(parent, channel, id);
|
||||||
if (!starget)
|
if (!starget)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
get_device(&starget->dev);
|
get_device(&starget->dev);
|
||||||
down(&shost->scan_mutex);
|
mutex_lock(&shost->scan_mutex);
|
||||||
if (scsi_host_scan_allowed(shost)) {
|
if (scsi_host_scan_allowed(shost)) {
|
||||||
res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
|
res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
|
||||||
hostdata);
|
hostdata);
|
||||||
if (res != SCSI_SCAN_LUN_PRESENT)
|
if (res != SCSI_SCAN_LUN_PRESENT)
|
||||||
sdev = ERR_PTR(-ENODEV);
|
sdev = ERR_PTR(-ENODEV);
|
||||||
}
|
}
|
||||||
up(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
scsi_target_reap(starget);
|
scsi_target_reap(starget);
|
||||||
put_device(&starget->dev);
|
put_device(&starget->dev);
|
||||||
|
|
||||||
@@ -1404,10 +1392,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
|
|||||||
{
|
{
|
||||||
struct Scsi_Host *shost = dev_to_shost(parent);
|
struct Scsi_Host *shost = dev_to_shost(parent);
|
||||||
|
|
||||||
down(&shost->scan_mutex);
|
mutex_lock(&shost->scan_mutex);
|
||||||
if (scsi_host_scan_allowed(shost))
|
if (scsi_host_scan_allowed(shost))
|
||||||
__scsi_scan_target(parent, channel, id, lun, rescan);
|
__scsi_scan_target(parent, channel, id, lun, rescan);
|
||||||
up(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_scan_target);
|
EXPORT_SYMBOL(scsi_scan_target);
|
||||||
|
|
||||||
@@ -1454,7 +1442,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
|||||||
((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
|
((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
down(&shost->scan_mutex);
|
mutex_lock(&shost->scan_mutex);
|
||||||
if (scsi_host_scan_allowed(shost)) {
|
if (scsi_host_scan_allowed(shost)) {
|
||||||
if (channel == SCAN_WILD_CARD)
|
if (channel == SCAN_WILD_CARD)
|
||||||
for (channel = 0; channel <= shost->max_channel;
|
for (channel = 0; channel <= shost->max_channel;
|
||||||
@@ -1464,7 +1452,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
|||||||
else
|
else
|
||||||
scsi_scan_channel(shost, channel, id, lun, rescan);
|
scsi_scan_channel(shost, channel, id, lun, rescan);
|
||||||
}
|
}
|
||||||
up(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1522,7 +1510,7 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
|
|||||||
struct scsi_device *sdev = NULL;
|
struct scsi_device *sdev = NULL;
|
||||||
struct scsi_target *starget;
|
struct scsi_target *starget;
|
||||||
|
|
||||||
down(&shost->scan_mutex);
|
mutex_lock(&shost->scan_mutex);
|
||||||
if (!scsi_host_scan_allowed(shost))
|
if (!scsi_host_scan_allowed(shost))
|
||||||
goto out;
|
goto out;
|
||||||
starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
|
starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
|
||||||
@@ -1536,7 +1524,7 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
|
|||||||
}
|
}
|
||||||
put_device(&starget->dev);
|
put_device(&starget->dev);
|
||||||
out:
|
out:
|
||||||
up(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
return sdev;
|
return sdev;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_get_host_dev);
|
EXPORT_SYMBOL(scsi_get_host_dev);
|
||||||
|
|||||||
@@ -106,7 +106,10 @@ static int scsi_scan(struct Scsi_Host *shost, const char *str)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (check_set(&lun, s3))
|
if (check_set(&lun, s3))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
res = scsi_scan_host_selected(shost, channel, id, lun, 1);
|
if (shost->transportt->user_scan)
|
||||||
|
res = shost->transportt->user_scan(shost, channel, id, lun);
|
||||||
|
else
|
||||||
|
res = scsi_scan_host_selected(shost, channel, id, lun, 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,9 +748,9 @@ void scsi_remove_device(struct scsi_device *sdev)
|
|||||||
{
|
{
|
||||||
struct Scsi_Host *shost = sdev->host;
|
struct Scsi_Host *shost = sdev->host;
|
||||||
|
|
||||||
down(&shost->scan_mutex);
|
mutex_lock(&shost->scan_mutex);
|
||||||
__scsi_remove_device(sdev);
|
__scsi_remove_device(sdev);
|
||||||
up(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_remove_device);
|
EXPORT_SYMBOL(scsi_remove_device);
|
||||||
|
|
||||||
|
|||||||
@@ -295,6 +295,7 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
|
|||||||
*/
|
*/
|
||||||
fc_host_node_name(shost) = -1;
|
fc_host_node_name(shost) = -1;
|
||||||
fc_host_port_name(shost) = -1;
|
fc_host_port_name(shost) = -1;
|
||||||
|
fc_host_permanent_port_name(shost) = -1;
|
||||||
fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED;
|
fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED;
|
||||||
memset(fc_host_supported_fc4s(shost), 0,
|
memset(fc_host_supported_fc4s(shost), 0,
|
||||||
sizeof(fc_host_supported_fc4s(shost)));
|
sizeof(fc_host_supported_fc4s(shost)));
|
||||||
@@ -795,6 +796,8 @@ static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO,
|
|||||||
|
|
||||||
fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
|
fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
|
||||||
fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
|
fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
|
||||||
|
fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
|
||||||
|
unsigned long long);
|
||||||
fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
|
fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
|
||||||
fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
|
fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
|
||||||
fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
|
fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
|
||||||
@@ -1090,17 +1093,23 @@ static int fc_rport_match(struct attribute_container *cont,
|
|||||||
/*
|
/*
|
||||||
* Must be called with shost->host_lock held
|
* Must be called with shost->host_lock held
|
||||||
*/
|
*/
|
||||||
static struct device *fc_target_parent(struct Scsi_Host *shost,
|
static int fc_user_scan(struct Scsi_Host *shost, uint channel,
|
||||||
int channel, uint id)
|
uint id, uint lun)
|
||||||
{
|
{
|
||||||
struct fc_rport *rport;
|
struct fc_rport *rport;
|
||||||
|
|
||||||
list_for_each_entry(rport, &fc_host_rports(shost), peers)
|
list_for_each_entry(rport, &fc_host_rports(shost), peers) {
|
||||||
if ((rport->channel == channel) &&
|
if (rport->scsi_target_id == -1)
|
||||||
(rport->scsi_target_id == id))
|
continue;
|
||||||
return &rport->dev;
|
|
||||||
|
|
||||||
return NULL;
|
if ((channel == SCAN_WILD_CARD || channel == rport->channel) &&
|
||||||
|
(id == SCAN_WILD_CARD || id == rport->scsi_target_id)) {
|
||||||
|
scsi_scan_target(&rport->dev, rport->channel,
|
||||||
|
rport->scsi_target_id, lun, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct scsi_transport_template *
|
struct scsi_transport_template *
|
||||||
@@ -1139,7 +1148,7 @@ fc_attach_transport(struct fc_function_template *ft)
|
|||||||
/* Transport uses the shost workq for scsi scanning */
|
/* Transport uses the shost workq for scsi scanning */
|
||||||
i->t.create_work_queue = 1;
|
i->t.create_work_queue = 1;
|
||||||
|
|
||||||
i->t.target_parent = fc_target_parent;
|
i->t.user_scan = fc_user_scan;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup SCSI Target Attributes.
|
* Setup SCSI Target Attributes.
|
||||||
@@ -1160,6 +1169,7 @@ fc_attach_transport(struct fc_function_template *ft)
|
|||||||
count=0;
|
count=0;
|
||||||
SETUP_HOST_ATTRIBUTE_RD(node_name);
|
SETUP_HOST_ATTRIBUTE_RD(node_name);
|
||||||
SETUP_HOST_ATTRIBUTE_RD(port_name);
|
SETUP_HOST_ATTRIBUTE_RD(port_name);
|
||||||
|
SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
|
||||||
SETUP_HOST_ATTRIBUTE_RD(supported_classes);
|
SETUP_HOST_ATTRIBUTE_RD(supported_classes);
|
||||||
SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
|
SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
|
||||||
SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
|
SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
|
||||||
|
|||||||
+474
-437
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
|
||||||
|
#include <scsi/scsi.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_transport.h>
|
#include <scsi/scsi_transport.h>
|
||||||
@@ -62,7 +63,7 @@ struct sas_internal {
|
|||||||
|
|
||||||
struct sas_host_attrs {
|
struct sas_host_attrs {
|
||||||
struct list_head rphy_list;
|
struct list_head rphy_list;
|
||||||
spinlock_t lock;
|
struct mutex lock;
|
||||||
u32 next_target_id;
|
u32 next_target_id;
|
||||||
};
|
};
|
||||||
#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data)
|
#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data)
|
||||||
@@ -165,7 +166,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
|
|||||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sas_host->rphy_list);
|
INIT_LIST_HEAD(&sas_host->rphy_list);
|
||||||
spin_lock_init(&sas_host->lock);
|
mutex_init(&sas_host->lock);
|
||||||
sas_host->next_target_id = 0;
|
sas_host->next_target_id = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -626,7 +627,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
|
|||||||
transport_add_device(&rphy->dev);
|
transport_add_device(&rphy->dev);
|
||||||
transport_configure_device(&rphy->dev);
|
transport_configure_device(&rphy->dev);
|
||||||
|
|
||||||
spin_lock(&sas_host->lock);
|
mutex_lock(&sas_host->lock);
|
||||||
list_add_tail(&rphy->list, &sas_host->rphy_list);
|
list_add_tail(&rphy->list, &sas_host->rphy_list);
|
||||||
if (identify->device_type == SAS_END_DEVICE &&
|
if (identify->device_type == SAS_END_DEVICE &&
|
||||||
(identify->target_port_protocols &
|
(identify->target_port_protocols &
|
||||||
@@ -634,10 +635,10 @@ int sas_rphy_add(struct sas_rphy *rphy)
|
|||||||
rphy->scsi_target_id = sas_host->next_target_id++;
|
rphy->scsi_target_id = sas_host->next_target_id++;
|
||||||
else
|
else
|
||||||
rphy->scsi_target_id = -1;
|
rphy->scsi_target_id = -1;
|
||||||
spin_unlock(&sas_host->lock);
|
mutex_unlock(&sas_host->lock);
|
||||||
|
|
||||||
if (rphy->scsi_target_id != -1) {
|
if (rphy->scsi_target_id != -1) {
|
||||||
scsi_scan_target(&rphy->dev, parent->number,
|
scsi_scan_target(&rphy->dev, parent->port_identifier,
|
||||||
rphy->scsi_target_id, ~0, 0);
|
rphy->scsi_target_id, ~0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,9 +662,9 @@ void sas_rphy_free(struct sas_rphy *rphy)
|
|||||||
struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
|
struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
|
||||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||||
|
|
||||||
spin_lock(&sas_host->lock);
|
mutex_lock(&sas_host->lock);
|
||||||
list_del(&rphy->list);
|
list_del(&rphy->list);
|
||||||
spin_unlock(&sas_host->lock);
|
mutex_unlock(&sas_host->lock);
|
||||||
|
|
||||||
transport_destroy_device(&rphy->dev);
|
transport_destroy_device(&rphy->dev);
|
||||||
put_device(rphy->dev.parent);
|
put_device(rphy->dev.parent);
|
||||||
@@ -687,15 +688,27 @@ sas_rphy_delete(struct sas_rphy *rphy)
|
|||||||
struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
|
struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
|
||||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||||
|
|
||||||
scsi_remove_target(dev);
|
switch (rphy->identify.device_type) {
|
||||||
|
case SAS_END_DEVICE:
|
||||||
|
scsi_remove_target(dev);
|
||||||
|
break;
|
||||||
|
case SAS_EDGE_EXPANDER_DEVICE:
|
||||||
|
case SAS_FANOUT_EXPANDER_DEVICE:
|
||||||
|
device_for_each_child(dev, NULL, do_sas_phy_delete);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
transport_remove_device(dev);
|
transport_remove_device(dev);
|
||||||
device_del(dev);
|
device_del(dev);
|
||||||
transport_destroy_device(dev);
|
transport_destroy_device(dev);
|
||||||
|
|
||||||
spin_lock(&sas_host->lock);
|
mutex_lock(&sas_host->lock);
|
||||||
list_del(&rphy->list);
|
list_del(&rphy->list);
|
||||||
spin_unlock(&sas_host->lock);
|
mutex_unlock(&sas_host->lock);
|
||||||
|
|
||||||
|
parent->rphy = NULL;
|
||||||
|
|
||||||
put_device(&parent->dev);
|
put_device(&parent->dev);
|
||||||
}
|
}
|
||||||
@@ -719,23 +732,28 @@ EXPORT_SYMBOL(scsi_is_sas_rphy);
|
|||||||
* SCSI scan helper
|
* SCSI scan helper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct device *sas_target_parent(struct Scsi_Host *shost,
|
static int sas_user_scan(struct Scsi_Host *shost, uint channel,
|
||||||
int channel, uint id)
|
uint id, uint lun)
|
||||||
{
|
{
|
||||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||||
struct sas_rphy *rphy;
|
struct sas_rphy *rphy;
|
||||||
struct device *dev = NULL;
|
|
||||||
|
|
||||||
spin_lock(&sas_host->lock);
|
mutex_lock(&sas_host->lock);
|
||||||
list_for_each_entry(rphy, &sas_host->rphy_list, list) {
|
list_for_each_entry(rphy, &sas_host->rphy_list, list) {
|
||||||
struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
|
struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
|
||||||
if (parent->number == channel &&
|
|
||||||
rphy->scsi_target_id == id)
|
|
||||||
dev = &rphy->dev;
|
|
||||||
}
|
|
||||||
spin_unlock(&sas_host->lock);
|
|
||||||
|
|
||||||
return dev;
|
if (rphy->scsi_target_id == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) &&
|
||||||
|
(id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
|
||||||
|
scsi_scan_target(&rphy->dev, parent->port_identifier,
|
||||||
|
rphy->scsi_target_id, lun, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&sas_host->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -780,7 +798,7 @@ sas_attach_transport(struct sas_function_template *ft)
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset(i, 0, sizeof(struct sas_internal));
|
memset(i, 0, sizeof(struct sas_internal));
|
||||||
|
|
||||||
i->t.target_parent = sas_target_parent;
|
i->t.user_scan = sas_user_scan;
|
||||||
|
|
||||||
i->t.host_attrs.ac.attrs = &i->host_attrs[0];
|
i->t.host_attrs.ac.attrs = &i->host_attrs[0];
|
||||||
i->t.host_attrs.ac.class = &sas_host_class.class;
|
i->t.host_attrs.ac.class = &sas_host_class.class;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <asm/semaphore.h>
|
#include <linux/mutex.h>
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
#include "scsi_priv.h"
|
#include "scsi_priv.h"
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
/* Private data accessors (keep these out of the header file) */
|
/* Private data accessors (keep these out of the header file) */
|
||||||
#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
|
#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
|
||||||
#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem)
|
#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
|
||||||
|
|
||||||
struct spi_internal {
|
struct spi_internal {
|
||||||
struct scsi_transport_template t;
|
struct scsi_transport_template t;
|
||||||
@@ -242,7 +242,7 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
|
|||||||
spi_hold_mcs(starget) = 0;
|
spi_hold_mcs(starget) = 0;
|
||||||
spi_dv_pending(starget) = 0;
|
spi_dv_pending(starget) = 0;
|
||||||
spi_initial_dv(starget) = 0;
|
spi_initial_dv(starget) = 0;
|
||||||
init_MUTEX(&spi_dv_sem(starget));
|
mutex_init(&spi_dv_mutex(starget));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -915,7 +915,7 @@ spi_dv_device(struct scsi_device *sdev)
|
|||||||
scsi_target_quiesce(starget);
|
scsi_target_quiesce(starget);
|
||||||
|
|
||||||
spi_dv_pending(starget) = 1;
|
spi_dv_pending(starget) = 1;
|
||||||
down(&spi_dv_sem(starget));
|
mutex_lock(&spi_dv_mutex(starget));
|
||||||
|
|
||||||
starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n");
|
starget_printk(KERN_INFO, starget, "Beginning Domain Validation\n");
|
||||||
|
|
||||||
@@ -923,7 +923,7 @@ spi_dv_device(struct scsi_device *sdev)
|
|||||||
|
|
||||||
starget_printk(KERN_INFO, starget, "Ending Domain Validation\n");
|
starget_printk(KERN_INFO, starget, "Ending Domain Validation\n");
|
||||||
|
|
||||||
up(&spi_dv_sem(starget));
|
mutex_unlock(&spi_dv_mutex(starget));
|
||||||
spi_dv_pending(starget) = 0;
|
spi_dv_pending(starget) = 0;
|
||||||
|
|
||||||
scsi_target_resume(starget);
|
scsi_target_resume(starget);
|
||||||
@@ -1075,7 +1075,7 @@ static const char * const extended_msgs[] = {
|
|||||||
/* 0x04 */ "Parallel Protocol Request"
|
/* 0x04 */ "Parallel Protocol Request"
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_nego(const unsigned char *msg, int per, int off, int width)
|
static void print_nego(const unsigned char *msg, int per, int off, int width)
|
||||||
{
|
{
|
||||||
if (per) {
|
if (per) {
|
||||||
char buf[20];
|
char buf[20];
|
||||||
|
|||||||
+16
-47
@@ -49,6 +49,7 @@
|
|||||||
#include <linux/blkpg.h>
|
#include <linux/blkpg.h>
|
||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
@@ -111,7 +112,7 @@ static DEFINE_SPINLOCK(sd_index_lock);
|
|||||||
/* This semaphore is used to mediate the 0->1 reference get in the
|
/* This semaphore is used to mediate the 0->1 reference get in the
|
||||||
* face of object destruction (i.e. we can't allow a get on an
|
* face of object destruction (i.e. we can't allow a get on an
|
||||||
* object after last put) */
|
* object after last put) */
|
||||||
static DECLARE_MUTEX(sd_ref_sem);
|
static DEFINE_MUTEX(sd_ref_mutex);
|
||||||
|
|
||||||
static int sd_revalidate_disk(struct gendisk *disk);
|
static int sd_revalidate_disk(struct gendisk *disk);
|
||||||
static void sd_rw_intr(struct scsi_cmnd * SCpnt);
|
static void sd_rw_intr(struct scsi_cmnd * SCpnt);
|
||||||
@@ -193,9 +194,9 @@ static struct scsi_disk *scsi_disk_get(struct gendisk *disk)
|
|||||||
{
|
{
|
||||||
struct scsi_disk *sdkp;
|
struct scsi_disk *sdkp;
|
||||||
|
|
||||||
down(&sd_ref_sem);
|
mutex_lock(&sd_ref_mutex);
|
||||||
sdkp = __scsi_disk_get(disk);
|
sdkp = __scsi_disk_get(disk);
|
||||||
up(&sd_ref_sem);
|
mutex_unlock(&sd_ref_mutex);
|
||||||
return sdkp;
|
return sdkp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,11 +204,11 @@ static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct scsi_disk *sdkp;
|
struct scsi_disk *sdkp;
|
||||||
|
|
||||||
down(&sd_ref_sem);
|
mutex_lock(&sd_ref_mutex);
|
||||||
sdkp = dev_get_drvdata(dev);
|
sdkp = dev_get_drvdata(dev);
|
||||||
if (sdkp)
|
if (sdkp)
|
||||||
sdkp = __scsi_disk_get(sdkp->disk);
|
sdkp = __scsi_disk_get(sdkp->disk);
|
||||||
up(&sd_ref_sem);
|
mutex_unlock(&sd_ref_mutex);
|
||||||
return sdkp;
|
return sdkp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,10 +216,10 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
|
|||||||
{
|
{
|
||||||
struct scsi_device *sdev = sdkp->device;
|
struct scsi_device *sdev = sdkp->device;
|
||||||
|
|
||||||
down(&sd_ref_sem);
|
mutex_lock(&sd_ref_mutex);
|
||||||
kref_put(&sdkp->kref, scsi_disk_release);
|
kref_put(&sdkp->kref, scsi_disk_release);
|
||||||
scsi_device_put(sdev);
|
scsi_device_put(sdev);
|
||||||
up(&sd_ref_sem);
|
mutex_unlock(&sd_ref_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,34 +232,12 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
|
|||||||
**/
|
**/
|
||||||
static int sd_init_command(struct scsi_cmnd * SCpnt)
|
static int sd_init_command(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
unsigned int this_count, timeout;
|
|
||||||
struct gendisk *disk;
|
|
||||||
sector_t block;
|
|
||||||
struct scsi_device *sdp = SCpnt->device;
|
struct scsi_device *sdp = SCpnt->device;
|
||||||
struct request *rq = SCpnt->request;
|
struct request *rq = SCpnt->request;
|
||||||
|
struct gendisk *disk = rq->rq_disk;
|
||||||
timeout = sdp->timeout;
|
sector_t block = rq->sector;
|
||||||
|
unsigned int this_count = SCpnt->request_bufflen >> 9;
|
||||||
/*
|
unsigned int timeout = sdp->timeout;
|
||||||
* SG_IO from block layer already setup, just copy cdb basically
|
|
||||||
*/
|
|
||||||
if (blk_pc_request(rq)) {
|
|
||||||
scsi_setup_blk_pc_cmnd(SCpnt);
|
|
||||||
if (rq->timeout)
|
|
||||||
timeout = rq->timeout;
|
|
||||||
|
|
||||||
goto queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* we only do REQ_CMD and REQ_BLOCK_PC
|
|
||||||
*/
|
|
||||||
if (!blk_fs_request(rq))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
disk = rq->rq_disk;
|
|
||||||
block = rq->sector;
|
|
||||||
this_count = SCpnt->request_bufflen >> 9;
|
|
||||||
|
|
||||||
SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
|
SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
|
||||||
"count=%d\n", disk->disk_name,
|
"count=%d\n", disk->disk_name,
|
||||||
@@ -401,8 +380,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
|
|||||||
SCpnt->transfersize = sdp->sector_size;
|
SCpnt->transfersize = sdp->sector_size;
|
||||||
SCpnt->underflow = this_count << 9;
|
SCpnt->underflow = this_count << 9;
|
||||||
SCpnt->allowed = SD_MAX_RETRIES;
|
SCpnt->allowed = SD_MAX_RETRIES;
|
||||||
|
|
||||||
queue:
|
|
||||||
SCpnt->timeout_per_command = timeout;
|
SCpnt->timeout_per_command = timeout;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -836,15 +813,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
|
|||||||
relatively rare error condition, no care is taken to avoid
|
relatively rare error condition, no care is taken to avoid
|
||||||
unnecessary additional work such as memcpy's that could be avoided.
|
unnecessary additional work such as memcpy's that could be avoided.
|
||||||
*/
|
*/
|
||||||
|
if (driver_byte(result) != 0 &&
|
||||||
/*
|
|
||||||
* If SG_IO from block layer then set good_bytes to stop retries;
|
|
||||||
* else if errors, check them, and if necessary prepare for
|
|
||||||
* (partial) retries.
|
|
||||||
*/
|
|
||||||
if (blk_pc_request(SCpnt->request))
|
|
||||||
good_bytes = this_count;
|
|
||||||
else if (driver_byte(result) != 0 &&
|
|
||||||
sense_valid && !sense_deferred) {
|
sense_valid && !sense_deferred) {
|
||||||
switch (sshdr.sense_key) {
|
switch (sshdr.sense_key) {
|
||||||
case MEDIUM_ERROR:
|
case MEDIUM_ERROR:
|
||||||
@@ -1635,10 +1604,10 @@ static int sd_remove(struct device *dev)
|
|||||||
del_gendisk(sdkp->disk);
|
del_gendisk(sdkp->disk);
|
||||||
sd_shutdown(dev);
|
sd_shutdown(dev);
|
||||||
|
|
||||||
down(&sd_ref_sem);
|
mutex_lock(&sd_ref_mutex);
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
kref_put(&sdkp->kref, scsi_disk_release);
|
kref_put(&sdkp->kref, scsi_disk_release);
|
||||||
up(&sd_ref_sem);
|
mutex_unlock(&sd_ref_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1647,7 +1616,7 @@ static int sd_remove(struct device *dev)
|
|||||||
* scsi_disk_release - Called to free the scsi_disk structure
|
* scsi_disk_release - Called to free the scsi_disk structure
|
||||||
* @kref: pointer to embedded kref
|
* @kref: pointer to embedded kref
|
||||||
*
|
*
|
||||||
* sd_ref_sem must be held entering this routine. Because it is
|
* sd_ref_mutex must be held entering this routine. Because it is
|
||||||
* called on last put, you should always use the scsi_disk_get()
|
* called on last put, you should always use the scsi_disk_get()
|
||||||
* scsi_disk_put() helpers which manipulate the semaphore directly
|
* scsi_disk_put() helpers which manipulate the semaphore directly
|
||||||
* and never do a direct kref_put().
|
* and never do a direct kref_put().
|
||||||
|
|||||||
+12
-31
@@ -44,6 +44,7 @@
|
|||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
@@ -90,7 +91,7 @@ static DEFINE_SPINLOCK(sr_index_lock);
|
|||||||
/* This semaphore is used to mediate the 0->1 reference get in the
|
/* This semaphore is used to mediate the 0->1 reference get in the
|
||||||
* face of object destruction (i.e. we can't allow a get on an
|
* face of object destruction (i.e. we can't allow a get on an
|
||||||
* object after last put) */
|
* object after last put) */
|
||||||
static DECLARE_MUTEX(sr_ref_sem);
|
static DEFINE_MUTEX(sr_ref_mutex);
|
||||||
|
|
||||||
static int sr_open(struct cdrom_device_info *, int);
|
static int sr_open(struct cdrom_device_info *, int);
|
||||||
static void sr_release(struct cdrom_device_info *);
|
static void sr_release(struct cdrom_device_info *);
|
||||||
@@ -133,7 +134,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
|
|||||||
{
|
{
|
||||||
struct scsi_cd *cd = NULL;
|
struct scsi_cd *cd = NULL;
|
||||||
|
|
||||||
down(&sr_ref_sem);
|
mutex_lock(&sr_ref_mutex);
|
||||||
if (disk->private_data == NULL)
|
if (disk->private_data == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
cd = scsi_cd(disk);
|
cd = scsi_cd(disk);
|
||||||
@@ -146,7 +147,7 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
|
|||||||
kref_put(&cd->kref, sr_kref_release);
|
kref_put(&cd->kref, sr_kref_release);
|
||||||
cd = NULL;
|
cd = NULL;
|
||||||
out:
|
out:
|
||||||
up(&sr_ref_sem);
|
mutex_unlock(&sr_ref_mutex);
|
||||||
return cd;
|
return cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,10 +155,10 @@ static inline void scsi_cd_put(struct scsi_cd *cd)
|
|||||||
{
|
{
|
||||||
struct scsi_device *sdev = cd->device;
|
struct scsi_device *sdev = cd->device;
|
||||||
|
|
||||||
down(&sr_ref_sem);
|
mutex_lock(&sr_ref_mutex);
|
||||||
kref_put(&cd->kref, sr_kref_release);
|
kref_put(&cd->kref, sr_kref_release);
|
||||||
scsi_device_put(sdev);
|
scsi_device_put(sdev);
|
||||||
up(&sr_ref_sem);
|
mutex_unlock(&sr_ref_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -237,8 +238,6 @@ static void rw_intr(struct scsi_cmnd * SCpnt)
|
|||||||
case ILLEGAL_REQUEST:
|
case ILLEGAL_REQUEST:
|
||||||
if (!(SCpnt->sense_buffer[0] & 0x90))
|
if (!(SCpnt->sense_buffer[0] & 0x90))
|
||||||
break;
|
break;
|
||||||
if (!blk_fs_request(SCpnt->request))
|
|
||||||
break;
|
|
||||||
error_sector = (SCpnt->sense_buffer[3] << 24) |
|
error_sector = (SCpnt->sense_buffer[3] << 24) |
|
||||||
(SCpnt->sense_buffer[4] << 16) |
|
(SCpnt->sense_buffer[4] << 16) |
|
||||||
(SCpnt->sense_buffer[5] << 8) |
|
(SCpnt->sense_buffer[5] << 8) |
|
||||||
@@ -316,23 +315,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* these are already setup, just copy cdb basically
|
|
||||||
*/
|
|
||||||
if (SCpnt->request->flags & REQ_BLOCK_PC) {
|
|
||||||
scsi_setup_blk_pc_cmnd(SCpnt);
|
|
||||||
|
|
||||||
if (SCpnt->timeout_per_command)
|
|
||||||
timeout = SCpnt->timeout_per_command;
|
|
||||||
|
|
||||||
goto queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(SCpnt->request->flags & REQ_CMD)) {
|
|
||||||
blk_dump_rq_flags(SCpnt->request, "sr unsup command");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we do lazy blocksize switching (when reading XA sectors,
|
* we do lazy blocksize switching (when reading XA sectors,
|
||||||
* see CDROMREADMODE2 ioctl)
|
* see CDROMREADMODE2 ioctl)
|
||||||
@@ -421,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
|||||||
*/
|
*/
|
||||||
SCpnt->transfersize = cd->device->sector_size;
|
SCpnt->transfersize = cd->device->sector_size;
|
||||||
SCpnt->underflow = this_count << 9;
|
SCpnt->underflow = this_count << 9;
|
||||||
|
|
||||||
queue:
|
|
||||||
SCpnt->allowed = MAX_RETRIES;
|
SCpnt->allowed = MAX_RETRIES;
|
||||||
SCpnt->timeout_per_command = timeout;
|
SCpnt->timeout_per_command = timeout;
|
||||||
|
|
||||||
@@ -762,8 +742,9 @@ static void get_capabilities(struct scsi_cd *cd)
|
|||||||
/* failed, drive doesn't have capabilities mode page */
|
/* failed, drive doesn't have capabilities mode page */
|
||||||
cd->cdi.speed = 1;
|
cd->cdi.speed = 1;
|
||||||
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
||||||
CDC_DVD | CDC_DVD_RAM |
|
CDC_DVD | CDC_DVD_RAM |
|
||||||
CDC_SELECT_DISC | CDC_SELECT_SPEED);
|
CDC_SELECT_DISC | CDC_SELECT_SPEED |
|
||||||
|
CDC_MRW | CDC_MRW_W | CDC_RAM);
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
printk("%s: scsi-1 drive\n", cd->cdi.name);
|
printk("%s: scsi-1 drive\n", cd->cdi.name);
|
||||||
return;
|
return;
|
||||||
@@ -845,7 +826,7 @@ static int sr_packet(struct cdrom_device_info *cdi,
|
|||||||
* sr_kref_release - Called to free the scsi_cd structure
|
* sr_kref_release - Called to free the scsi_cd structure
|
||||||
* @kref: pointer to embedded kref
|
* @kref: pointer to embedded kref
|
||||||
*
|
*
|
||||||
* sr_ref_sem must be held entering this routine. Because it is
|
* sr_ref_mutex must be held entering this routine. Because it is
|
||||||
* called on last put, you should always use the scsi_cd_get()
|
* called on last put, you should always use the scsi_cd_get()
|
||||||
* scsi_cd_put() helpers which manipulate the semaphore directly
|
* scsi_cd_put() helpers which manipulate the semaphore directly
|
||||||
* and never do a direct kref_put().
|
* and never do a direct kref_put().
|
||||||
@@ -874,9 +855,9 @@ static int sr_remove(struct device *dev)
|
|||||||
|
|
||||||
del_gendisk(cd->disk);
|
del_gendisk(cd->disk);
|
||||||
|
|
||||||
down(&sr_ref_sem);
|
mutex_lock(&sr_ref_mutex);
|
||||||
kref_put(&cd->kref, sr_kref_release);
|
kref_put(&cd->kref, sr_kref_release);
|
||||||
up(&sr_ref_sem);
|
mutex_unlock(&sr_ref_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+111
-91
@@ -31,6 +31,79 @@ static int xa_test = 0;
|
|||||||
|
|
||||||
module_param(xa_test, int, S_IRUGO | S_IWUSR);
|
module_param(xa_test, int, S_IRUGO | S_IWUSR);
|
||||||
|
|
||||||
|
/* primitive to determine whether we need to have GFP_DMA set based on
|
||||||
|
* the status of the unchecked_isa_dma flag in the host structure */
|
||||||
|
#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)
|
||||||
|
|
||||||
|
|
||||||
|
static int sr_read_tochdr(struct cdrom_device_info *cdi,
|
||||||
|
struct cdrom_tochdr *tochdr)
|
||||||
|
{
|
||||||
|
struct scsi_cd *cd = cdi->handle;
|
||||||
|
struct packet_command cgc;
|
||||||
|
int result;
|
||||||
|
unsigned char *buffer;
|
||||||
|
|
||||||
|
buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
|
||||||
|
if (!buffer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memset(&cgc, 0, sizeof(struct packet_command));
|
||||||
|
cgc.timeout = IOCTL_TIMEOUT;
|
||||||
|
cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
|
||||||
|
cgc.cmd[8] = 12; /* LSB of length */
|
||||||
|
cgc.buffer = buffer;
|
||||||
|
cgc.buflen = 12;
|
||||||
|
cgc.quiet = 1;
|
||||||
|
cgc.data_direction = DMA_FROM_DEVICE;
|
||||||
|
|
||||||
|
result = sr_do_ioctl(cd, &cgc);
|
||||||
|
|
||||||
|
tochdr->cdth_trk0 = buffer[2];
|
||||||
|
tochdr->cdth_trk1 = buffer[3];
|
||||||
|
|
||||||
|
kfree(buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sr_read_tocentry(struct cdrom_device_info *cdi,
|
||||||
|
struct cdrom_tocentry *tocentry)
|
||||||
|
{
|
||||||
|
struct scsi_cd *cd = cdi->handle;
|
||||||
|
struct packet_command cgc;
|
||||||
|
int result;
|
||||||
|
unsigned char *buffer;
|
||||||
|
|
||||||
|
buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
|
||||||
|
if (!buffer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memset(&cgc, 0, sizeof(struct packet_command));
|
||||||
|
cgc.timeout = IOCTL_TIMEOUT;
|
||||||
|
cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
|
||||||
|
cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;
|
||||||
|
cgc.cmd[6] = tocentry->cdte_track;
|
||||||
|
cgc.cmd[8] = 12; /* LSB of length */
|
||||||
|
cgc.buffer = buffer;
|
||||||
|
cgc.buflen = 12;
|
||||||
|
cgc.data_direction = DMA_FROM_DEVICE;
|
||||||
|
|
||||||
|
result = sr_do_ioctl(cd, &cgc);
|
||||||
|
|
||||||
|
tocentry->cdte_ctrl = buffer[5] & 0xf;
|
||||||
|
tocentry->cdte_adr = buffer[5] >> 4;
|
||||||
|
tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
|
||||||
|
if (tocentry->cdte_format == CDROM_MSF) {
|
||||||
|
tocentry->cdte_addr.msf.minute = buffer[9];
|
||||||
|
tocentry->cdte_addr.msf.second = buffer[10];
|
||||||
|
tocentry->cdte_addr.msf.frame = buffer[11];
|
||||||
|
} else
|
||||||
|
tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
|
||||||
|
+ buffer[10]) << 8) + buffer[11];
|
||||||
|
|
||||||
|
kfree(buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#define IOCTL_RETRIES 3
|
#define IOCTL_RETRIES 3
|
||||||
|
|
||||||
@@ -45,7 +118,8 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
|
|||||||
struct packet_command cgc;
|
struct packet_command cgc;
|
||||||
int ntracks, ret;
|
int ntracks, ret;
|
||||||
|
|
||||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr)))
|
ret = sr_read_tochdr(cdi, &tochdr);
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
|
ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
|
||||||
@@ -60,9 +134,11 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
|
|||||||
trk1_te.cdte_track = ti->cdti_trk1;
|
trk1_te.cdte_track = ti->cdti_trk1;
|
||||||
trk1_te.cdte_format = CDROM_MSF;
|
trk1_te.cdte_format = CDROM_MSF;
|
||||||
|
|
||||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk0_te)))
|
ret = sr_read_tocentry(cdi, &trk0_te);
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk1_te)))
|
ret = sr_read_tocentry(cdi, &trk1_te);
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memset(&cgc, 0, sizeof(struct packet_command));
|
memset(&cgc, 0, sizeof(struct packet_command));
|
||||||
@@ -78,6 +154,30 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
|
|||||||
return sr_do_ioctl(cdi->handle, &cgc);
|
return sr_do_ioctl(cdi->handle, &cgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sr_play_trkind(struct cdrom_device_info *cdi,
|
||||||
|
struct cdrom_ti *ti)
|
||||||
|
|
||||||
|
{
|
||||||
|
struct scsi_cd *cd = cdi->handle;
|
||||||
|
struct packet_command cgc;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
memset(&cgc, 0, sizeof(struct packet_command));
|
||||||
|
cgc.timeout = IOCTL_TIMEOUT;
|
||||||
|
cgc.cmd[0] = GPCMD_PLAYAUDIO_TI;
|
||||||
|
cgc.cmd[4] = ti->cdti_trk0;
|
||||||
|
cgc.cmd[5] = ti->cdti_ind0;
|
||||||
|
cgc.cmd[7] = ti->cdti_trk1;
|
||||||
|
cgc.cmd[8] = ti->cdti_ind1;
|
||||||
|
cgc.data_direction = DMA_NONE;
|
||||||
|
|
||||||
|
result = sr_do_ioctl(cd, &cgc);
|
||||||
|
if (result == -EDRIVE_CANT_DO_THIS)
|
||||||
|
result = sr_fake_playtrkind(cdi, ti);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* We do our own retries because we want to know what the specific
|
/* We do our own retries because we want to know what the specific
|
||||||
error code is. Normally the UNIT_ATTENTION code will automatically
|
error code is. Normally the UNIT_ATTENTION code will automatically
|
||||||
clear after one error */
|
clear after one error */
|
||||||
@@ -229,13 +329,14 @@ int sr_disk_status(struct cdrom_device_info *cdi)
|
|||||||
int i, rc, have_datatracks = 0;
|
int i, rc, have_datatracks = 0;
|
||||||
|
|
||||||
/* look for data tracks */
|
/* look for data tracks */
|
||||||
if (0 != (rc = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &toc_h)))
|
rc = sr_read_tochdr(cdi, &toc_h);
|
||||||
|
if (rc)
|
||||||
return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;
|
return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;
|
||||||
|
|
||||||
for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {
|
for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {
|
||||||
toc_e.cdte_track = i;
|
toc_e.cdte_track = i;
|
||||||
toc_e.cdte_format = CDROM_LBA;
|
toc_e.cdte_format = CDROM_LBA;
|
||||||
if (sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &toc_e))
|
if (sr_read_tocentry(cdi, &toc_e))
|
||||||
return CDS_NO_INFO;
|
return CDS_NO_INFO;
|
||||||
if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {
|
if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {
|
||||||
have_datatracks = 1;
|
have_datatracks = 1;
|
||||||
@@ -262,10 +363,6 @@ int sr_get_last_session(struct cdrom_device_info *cdi,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* primitive to determine whether we need to have GFP_DMA set based on
|
|
||||||
* the status of the unchecked_isa_dma flag in the host structure */
|
|
||||||
#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0)
|
|
||||||
|
|
||||||
int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
|
int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
|
||||||
{
|
{
|
||||||
Scsi_CD *cd = cdi->handle;
|
Scsi_CD *cd = cdi->handle;
|
||||||
@@ -329,93 +426,16 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed)
|
|||||||
|
|
||||||
int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
|
int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
Scsi_CD *cd = cdi->handle;
|
|
||||||
struct packet_command cgc;
|
|
||||||
int result;
|
|
||||||
unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
|
|
||||||
|
|
||||||
if (!buffer)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memset(&cgc, 0, sizeof(struct packet_command));
|
|
||||||
cgc.timeout = IOCTL_TIMEOUT;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CDROMREADTOCHDR:
|
case CDROMREADTOCHDR:
|
||||||
{
|
return sr_read_tochdr(cdi, arg);
|
||||||
struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
|
|
||||||
|
|
||||||
cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
|
|
||||||
cgc.cmd[8] = 12; /* LSB of length */
|
|
||||||
cgc.buffer = buffer;
|
|
||||||
cgc.buflen = 12;
|
|
||||||
cgc.quiet = 1;
|
|
||||||
cgc.data_direction = DMA_FROM_DEVICE;
|
|
||||||
|
|
||||||
result = sr_do_ioctl(cd, &cgc);
|
|
||||||
|
|
||||||
tochdr->cdth_trk0 = buffer[2];
|
|
||||||
tochdr->cdth_trk1 = buffer[3];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CDROMREADTOCENTRY:
|
case CDROMREADTOCENTRY:
|
||||||
{
|
return sr_read_tocentry(cdi, arg);
|
||||||
struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg;
|
case CDROMPLAYTRKIND:
|
||||||
|
return sr_play_trkind(cdi, arg);
|
||||||
cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
|
|
||||||
cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0;
|
|
||||||
cgc.cmd[6] = tocentry->cdte_track;
|
|
||||||
cgc.cmd[8] = 12; /* LSB of length */
|
|
||||||
cgc.buffer = buffer;
|
|
||||||
cgc.buflen = 12;
|
|
||||||
cgc.data_direction = DMA_FROM_DEVICE;
|
|
||||||
|
|
||||||
result = sr_do_ioctl(cd, &cgc);
|
|
||||||
|
|
||||||
tocentry->cdte_ctrl = buffer[5] & 0xf;
|
|
||||||
tocentry->cdte_adr = buffer[5] >> 4;
|
|
||||||
tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
|
|
||||||
if (tocentry->cdte_format == CDROM_MSF) {
|
|
||||||
tocentry->cdte_addr.msf.minute = buffer[9];
|
|
||||||
tocentry->cdte_addr.msf.second = buffer[10];
|
|
||||||
tocentry->cdte_addr.msf.frame = buffer[11];
|
|
||||||
} else
|
|
||||||
tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
|
|
||||||
+ buffer[10]) << 8) + buffer[11];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CDROMPLAYTRKIND: {
|
|
||||||
struct cdrom_ti* ti = (struct cdrom_ti*)arg;
|
|
||||||
|
|
||||||
cgc.cmd[0] = GPCMD_PLAYAUDIO_TI;
|
|
||||||
cgc.cmd[4] = ti->cdti_trk0;
|
|
||||||
cgc.cmd[5] = ti->cdti_ind0;
|
|
||||||
cgc.cmd[7] = ti->cdti_trk1;
|
|
||||||
cgc.cmd[8] = ti->cdti_ind1;
|
|
||||||
cgc.data_direction = DMA_NONE;
|
|
||||||
|
|
||||||
result = sr_do_ioctl(cd, &cgc);
|
|
||||||
if (result == -EDRIVE_CANT_DO_THIS)
|
|
||||||
result = sr_fake_playtrkind(cdi, ti);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
result = -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (result)
|
|
||||||
printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kfree(buffer);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
|
|||||||
+9
-33
@@ -38,6 +38,7 @@ static const char *verstr = "20050830";
|
|||||||
#include <linux/devfs_fs_kernel.h>
|
#include <linux/devfs_fs_kernel.h>
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
@@ -193,7 +194,6 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
|
|||||||
|
|
||||||
static int st_probe(struct device *);
|
static int st_probe(struct device *);
|
||||||
static int st_remove(struct device *);
|
static int st_remove(struct device *);
|
||||||
static int st_init_command(struct scsi_cmnd *);
|
|
||||||
|
|
||||||
static void do_create_driverfs_files(void);
|
static void do_create_driverfs_files(void);
|
||||||
static void do_remove_driverfs_files(void);
|
static void do_remove_driverfs_files(void);
|
||||||
@@ -206,7 +206,6 @@ static struct scsi_driver st_template = {
|
|||||||
.probe = st_probe,
|
.probe = st_probe,
|
||||||
.remove = st_remove,
|
.remove = st_remove,
|
||||||
},
|
},
|
||||||
.init_command = st_init_command,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int st_compression(struct scsi_tape *, int);
|
static int st_compression(struct scsi_tape *, int);
|
||||||
@@ -220,7 +219,7 @@ static void scsi_tape_release(struct kref *);
|
|||||||
|
|
||||||
#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
|
#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
|
||||||
|
|
||||||
static DECLARE_MUTEX(st_ref_sem);
|
static DEFINE_MUTEX(st_ref_mutex);
|
||||||
|
|
||||||
|
|
||||||
#include "osst_detect.h"
|
#include "osst_detect.h"
|
||||||
@@ -237,7 +236,7 @@ static struct scsi_tape *scsi_tape_get(int dev)
|
|||||||
{
|
{
|
||||||
struct scsi_tape *STp = NULL;
|
struct scsi_tape *STp = NULL;
|
||||||
|
|
||||||
down(&st_ref_sem);
|
mutex_lock(&st_ref_mutex);
|
||||||
write_lock(&st_dev_arr_lock);
|
write_lock(&st_dev_arr_lock);
|
||||||
|
|
||||||
if (dev < st_dev_max && scsi_tapes != NULL)
|
if (dev < st_dev_max && scsi_tapes != NULL)
|
||||||
@@ -259,7 +258,7 @@ out_put:
|
|||||||
STp = NULL;
|
STp = NULL;
|
||||||
out:
|
out:
|
||||||
write_unlock(&st_dev_arr_lock);
|
write_unlock(&st_dev_arr_lock);
|
||||||
up(&st_ref_sem);
|
mutex_unlock(&st_ref_mutex);
|
||||||
return STp;
|
return STp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,10 +266,10 @@ static void scsi_tape_put(struct scsi_tape *STp)
|
|||||||
{
|
{
|
||||||
struct scsi_device *sdev = STp->device;
|
struct scsi_device *sdev = STp->device;
|
||||||
|
|
||||||
down(&st_ref_sem);
|
mutex_lock(&st_ref_mutex);
|
||||||
kref_put(&STp->kref, scsi_tape_release);
|
kref_put(&STp->kref, scsi_tape_release);
|
||||||
scsi_device_put(sdev);
|
scsi_device_put(sdev);
|
||||||
up(&st_ref_sem);
|
mutex_unlock(&st_ref_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct st_reject_data {
|
struct st_reject_data {
|
||||||
@@ -4141,9 +4140,9 @@ static int st_remove(struct device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
down(&st_ref_sem);
|
mutex_lock(&st_ref_mutex);
|
||||||
kref_put(&tpnt->kref, scsi_tape_release);
|
kref_put(&tpnt->kref, scsi_tape_release);
|
||||||
up(&st_ref_sem);
|
mutex_unlock(&st_ref_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4156,7 +4155,7 @@ static int st_remove(struct device *dev)
|
|||||||
* scsi_tape_release - Called to free the Scsi_Tape structure
|
* scsi_tape_release - Called to free the Scsi_Tape structure
|
||||||
* @kref: pointer to embedded kref
|
* @kref: pointer to embedded kref
|
||||||
*
|
*
|
||||||
* st_ref_sem must be held entering this routine. Because it is
|
* st_ref_mutex must be held entering this routine. Because it is
|
||||||
* called on last put, you should always use the scsi_tape_get()
|
* called on last put, you should always use the scsi_tape_get()
|
||||||
* scsi_tape_put() helpers which manipulate the semaphore directly
|
* scsi_tape_put() helpers which manipulate the semaphore directly
|
||||||
* and never do a direct kref_put().
|
* and never do a direct kref_put().
|
||||||
@@ -4180,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void st_intr(struct scsi_cmnd *SCpnt)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The caller should be checking the request's errors
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
scsi_io_completion(SCpnt, SCpnt->bufflen, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* st_init_command: only called via the scsi_cmd_ioctl (block SG_IO)
|
|
||||||
* interface for REQ_BLOCK_PC commands.
|
|
||||||
*/
|
|
||||||
static int st_init_command(struct scsi_cmnd *SCpnt)
|
|
||||||
{
|
|
||||||
if (!(SCpnt->request->flags & REQ_BLOCK_PC))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
scsi_setup_blk_pc_cmnd(SCpnt);
|
|
||||||
SCpnt->done = st_intr;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init init_st(void)
|
static int __init init_st(void)
|
||||||
{
|
{
|
||||||
validate_options();
|
validate_options();
|
||||||
|
|||||||
@@ -181,6 +181,7 @@
|
|||||||
#define PCI_DEVICE_ID_LSI_FC929X 0x0626
|
#define PCI_DEVICE_ID_LSI_FC929X 0x0626
|
||||||
#define PCI_DEVICE_ID_LSI_FC939X 0x0642
|
#define PCI_DEVICE_ID_LSI_FC939X 0x0642
|
||||||
#define PCI_DEVICE_ID_LSI_FC949X 0x0640
|
#define PCI_DEVICE_ID_LSI_FC949X 0x0640
|
||||||
|
#define PCI_DEVICE_ID_LSI_FC949ES 0x0646
|
||||||
#define PCI_DEVICE_ID_LSI_FC919X 0x0628
|
#define PCI_DEVICE_ID_LSI_FC919X 0x0628
|
||||||
#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
|
#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
|
||||||
#define PCI_DEVICE_ID_LSI_61C102 0x0901
|
#define PCI_DEVICE_ID_LSI_61C102 0x0901
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ enum raid_level {
|
|||||||
RAID_LEVEL_LINEAR,
|
RAID_LEVEL_LINEAR,
|
||||||
RAID_LEVEL_0,
|
RAID_LEVEL_0,
|
||||||
RAID_LEVEL_1,
|
RAID_LEVEL_1,
|
||||||
|
RAID_LEVEL_10,
|
||||||
RAID_LEVEL_3,
|
RAID_LEVEL_3,
|
||||||
RAID_LEVEL_4,
|
RAID_LEVEL_4,
|
||||||
RAID_LEVEL_5,
|
RAID_LEVEL_5,
|
||||||
|
RAID_LEVEL_50,
|
||||||
RAID_LEVEL_6,
|
RAID_LEVEL_6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,12 @@ typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */
|
|||||||
|
|
||||||
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
|
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
|
||||||
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
|
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
|
||||||
|
#define hostdata_session(_hostdata) (iscsi_ptr(*(unsigned long *)_hostdata))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iscsi_hostdata - get LLD hostdata from scsi_host
|
||||||
|
* @_hostdata: pointer to scsi host's hostdata
|
||||||
|
**/
|
||||||
#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
|
#define iscsi_hostdata(_hostdata) ((void*)_hostdata + sizeof(unsigned long))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ extern const unsigned char scsi_command_size[8];
|
|||||||
#define MAX_SCSI_DEVICE_CODE 15
|
#define MAX_SCSI_DEVICE_CODE 15
|
||||||
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
|
extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special value for scanning to specify scanning or rescanning of all
|
||||||
|
* possible channels, (target) ids, or luns on a given shost.
|
||||||
|
*/
|
||||||
|
#define SCAN_WILD_CARD ~0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCSI opcodes
|
* SCSI opcodes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -151,6 +151,5 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
|
|||||||
extern void scsi_put_command(struct scsi_cmnd *);
|
extern void scsi_put_command(struct scsi_cmnd *);
|
||||||
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
|
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
|
||||||
extern void scsi_finish_command(struct scsi_cmnd *cmd);
|
extern void scsi_finish_command(struct scsi_cmnd *cmd);
|
||||||
extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd);
|
|
||||||
|
|
||||||
#endif /* _SCSI_SCSI_CMND_H */
|
#endif /* _SCSI_SCSI_CMND_H */
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
struct block_device;
|
struct block_device;
|
||||||
struct completion;
|
struct completion;
|
||||||
@@ -469,7 +470,7 @@ struct Scsi_Host {
|
|||||||
spinlock_t default_lock;
|
spinlock_t default_lock;
|
||||||
spinlock_t *host_lock;
|
spinlock_t *host_lock;
|
||||||
|
|
||||||
struct semaphore scan_mutex;/* serialize scanning activity */
|
struct mutex scan_mutex;/* serialize scanning activity */
|
||||||
|
|
||||||
struct list_head eh_cmd_q;
|
struct list_head eh_cmd_q;
|
||||||
struct task_struct * ehandler; /* Error recovery thread. */
|
struct task_struct * ehandler; /* Error recovery thread. */
|
||||||
|
|||||||
@@ -30,12 +30,9 @@ struct scsi_transport_template {
|
|||||||
struct transport_container device_attrs;
|
struct transport_container device_attrs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If set, call target_parent prior to allocating a scsi_target,
|
* If set, called from sysfs and legacy procfs rescanning code.
|
||||||
* so we get the appropriate parent for the target. This function
|
|
||||||
* is required for transports like FC and iSCSI that do not put the
|
|
||||||
* scsi_target under scsi_host.
|
|
||||||
*/
|
*/
|
||||||
struct device *(*target_parent)(struct Scsi_Host *, int, uint);
|
int (*user_scan)(struct Scsi_Host *, uint, uint, uint);
|
||||||
|
|
||||||
/* The size of the specific transport attribute structure (a
|
/* The size of the specific transport attribute structure (a
|
||||||
* space of this size will be left at the end of the
|
* space of this size will be left at the end of the
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user