mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 02:34:01 +08:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
This commit is contained in:
commit
12dbf3fc4d
108
Documentation/scsi/aacraid.txt
Normal file
108
Documentation/scsi/aacraid.txt
Normal file
@ -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"
|
||||
depends on PCI && SCSI
|
||||
select FUSION
|
||||
select SCSI_FC_ATTRS
|
||||
---help---
|
||||
SCSI HOST support for a Fiber Channel host adapters.
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Title: MPI Message independent structures and definitions
|
||||
* Creation Date: July 27, 2000
|
||||
*
|
||||
* mpi.h Version: 01.05.08
|
||||
* mpi.h Version: 01.05.10
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -74,6 +74,8 @@
|
||||
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
|
||||
* TargetAssistExtended requests.
|
||||
* 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 */
|
||||
|
||||
/* 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_UNIT_MASK (0xFF00)
|
||||
#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_TOO_MUCH_WRITE_DATA (0x006E)
|
||||
#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) */
|
||||
@ -745,7 +749,7 @@ typedef struct _MSG_DEFAULT_REPLY
|
||||
#define MPI_IOCSTATUS_LAN_CANCELED (0x0087)
|
||||
|
||||
/****************************************************************************/
|
||||
/* Serial Attached SCSI values */
|
||||
/* Serial Attached SCSI values */
|
||||
/****************************************************************************/
|
||||
|
||||
#define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090)
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Title: MPI Config message, structures, and Pages
|
||||
* Creation Date: July 27, 2000
|
||||
*
|
||||
* mpi_cnfg.h Version: 01.05.09
|
||||
* mpi_cnfg.h Version: 01.05.11
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -249,6 +249,23 @@
|
||||
* Added OwnerDevHandle and Flags field to SAS PHY Page 0.
|
||||
* Added IOC GPIO Flags define to SAS Enclosure Page 0.
|
||||
* 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_FC939X (0x0642)
|
||||
#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
|
||||
#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646)
|
||||
#define MPI_MANUFACTPAGE_DEVICEID_FC949E (0x0646)
|
||||
/* SCSI */
|
||||
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
|
||||
#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_SAS1068 (0x0054)
|
||||
#define MPI_MANUFACTPAGE_DEVID_SAS1068E (0x0058)
|
||||
#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0060)
|
||||
#define MPI_MANUFACTPAGE_DEVID_SAS1078 (0x0062)
|
||||
|
||||
|
||||
typedef struct _CONFIG_PAGE_MANUFACTURING_0
|
||||
@ -602,9 +619,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
|
||||
U32 IMVolumeSettings; /* 50h */
|
||||
U32 Reserved3; /* 54h */
|
||||
U32 Reserved4; /* 58h */
|
||||
U8 ISDataScrubRate; /* 5Ch */
|
||||
U8 ISResyncRate; /* 5Dh */
|
||||
U16 Reserved5; /* 5Eh */
|
||||
U32 Reserved5; /* 5Ch */
|
||||
U8 IMEDataScrubRate; /* 60h */
|
||||
U8 IMEResyncRate; /* 61h */
|
||||
U16 Reserved6; /* 62h */
|
||||
@ -616,9 +631,14 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
|
||||
} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
|
||||
ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
|
||||
|
||||
#define MPI_MANUFACTURING4_PAGEVERSION (0x02)
|
||||
#define MPI_MANUFACTURING4_PAGEVERSION (0x03)
|
||||
|
||||
/* 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)
|
||||
|
||||
|
||||
@ -669,7 +689,7 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
|
||||
} CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
|
||||
IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
|
||||
|
||||
#define MPI_IOUNITPAGE1_PAGEVERSION (0x01)
|
||||
#define MPI_IOUNITPAGE1_PAGEVERSION (0x02)
|
||||
|
||||
/* IO Unit Page 1 Flags defines */
|
||||
#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_FORCE_32 (0x00000080)
|
||||
#define MPI_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE (0x00000100)
|
||||
|
||||
#define MPI_IOUNITPAGE1_SATA_WRITE_CACHE_DISABLE (0x00000200)
|
||||
|
||||
typedef struct _MPI_ADAPTER_INFO
|
||||
{
|
||||
@ -968,7 +988,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U32 DeviceSettings; /* 10h */
|
||||
U16 NumberOfDevices; /* 14h */
|
||||
U16 Reserved2; /* 16h */
|
||||
U8 ExpanderSpinup; /* 16h */
|
||||
U8 Reserved2; /* 17h */
|
||||
U16 IOTimeoutBlockDevicesNonRM; /* 18h */
|
||||
U16 IOTimeoutSequential; /* 1Ah */
|
||||
U16 IOTimeoutOther; /* 1Ch */
|
||||
@ -976,7 +997,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
|
||||
} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
|
||||
BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
|
||||
|
||||
#define MPI_BIOSPAGE1_PAGEVERSION (0x02)
|
||||
#define MPI_BIOSPAGE1_PAGEVERSION (0x03)
|
||||
|
||||
/* values for the BiosOptions field */
|
||||
#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
|
||||
@ -985,8 +1006,15 @@ typedef struct _CONFIG_PAGE_BIOS_1
|
||||
#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
|
||||
|
||||
/* 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_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_ENCLOSURE_SLOT_BOOT (0x00000000)
|
||||
#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_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
|
||||
{
|
||||
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_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 \
|
||||
)
|
||||
#define MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK (0x00FF0000)
|
||||
#define MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET (16)
|
||||
#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 \
|
||||
)
|
||||
#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,
|
||||
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
|
||||
|
||||
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04)
|
||||
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x05)
|
||||
|
||||
/* values for SAS IO Unit Page 1 ControlFlags */
|
||||
#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_1_5_MAX (0x2000)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800)
|
||||
#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_1_5_MAX (0x2000)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH (0x0800)
|
||||
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT (0x0600)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
|
||||
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY (0x0002)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_POSTPONE_SATA_INIT (0x0100)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED (0x0010)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH (0x0008)
|
||||
#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL (0x0004)
|
||||
#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 */
|
||||
#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_AUTO_PORT_CONFIG (0x01)
|
||||
#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_AUTO_PORT_CONFIG (0x01)
|
||||
|
||||
/* values for SAS IO Unit Page 0 PhyFlags */
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04)
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02)
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01)
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE (0x04)
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT (0x02)
|
||||
#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT (0x01)
|
||||
|
||||
/* values for SAS IO Unit Page 0 MaxMinLinkRate */
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0)
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80)
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09)
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_MASK (0xF0)
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_1_5 (0x80)
|
||||
#define MPI_SAS_IOUNIT1_MAX_RATE_3_0 (0x90)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_MASK (0x0F)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_1_5 (0x08)
|
||||
#define MPI_SAS_IOUNIT1_MIN_RATE_3_0 (0x09)
|
||||
|
||||
/* 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
|
||||
{
|
||||
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
|
||||
U32 Reserved1; /* 08h */
|
||||
U8 NumDevsPerEnclosure; /* 08h */
|
||||
U8 Reserved1; /* 09h */
|
||||
U16 Reserved2; /* 0Ah */
|
||||
U16 MaxPersistentIDs; /* 0Ch */
|
||||
U16 NumPersistentIDsUsed; /* 0Eh */
|
||||
U8 Status; /* 10h */
|
||||
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,
|
||||
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 */
|
||||
#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_DIRECT_ATTACH_PHYS_MAP (0x01)
|
||||
#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_DA_STARTING_SLOT (0x20)
|
||||
@ -2473,7 +2510,7 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
|
||||
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
|
||||
U8 PhysicalPort; /* 08h */
|
||||
U8 Reserved1; /* 09h */
|
||||
U16 Reserved2; /* 0Ah */
|
||||
U16 EnclosureHandle; /* 0Ah */
|
||||
U64 SASAddress; /* 0Ch */
|
||||
U32 DiscoveryStatus; /* 14h */
|
||||
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,
|
||||
SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
|
||||
|
||||
#define MPI_SASEXPANDER0_PAGEVERSION (0x02)
|
||||
#define MPI_SASEXPANDER0_PAGEVERSION (0x03)
|
||||
|
||||
/* values for SAS Expander Page 0 DiscoveryStatus field */
|
||||
#define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001)
|
||||
@ -2527,9 +2564,9 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER_1
|
||||
U8 NegotiatedLinkRate; /* 1Fh */
|
||||
U8 PhyIdentifier; /* 20h */
|
||||
U8 AttachedPhyIdentifier; /* 21h */
|
||||
U8 NumTableEntriesProg; /* 22h */
|
||||
U8 Reserved3; /* 22h */
|
||||
U8 DiscoveryInfo; /* 23h */
|
||||
U32 Reserved3; /* 24h */
|
||||
U32 Reserved4; /* 24h */
|
||||
} CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1,
|
||||
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)
|
||||
#endif
|
||||
|
||||
#define MPI_LOG_0_LOG_DATA_LENGTH (20)
|
||||
#define MPI_LOG_0_LOG_DATA_LENGTH (0x1C)
|
||||
|
||||
typedef struct _MPI_LOG_0_ENTRY
|
||||
{
|
||||
U64 WWID; /* 00h */
|
||||
U32 TimeStamp; /* 08h */
|
||||
U32 Reserved1; /* 0Ch */
|
||||
U16 LogSequence; /* 10h */
|
||||
U16 LogEntryQualifier; /* 12h */
|
||||
U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 14h */
|
||||
U32 TimeStamp; /* 00h */
|
||||
U32 Reserved1; /* 04h */
|
||||
U16 LogSequence; /* 08h */
|
||||
U16 LogEntryQualifier; /* 0Ah */
|
||||
U8 LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 0Ch */
|
||||
} MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY,
|
||||
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,
|
||||
LogPage0_t, MPI_POINTER pLogPage0_t;
|
||||
|
||||
#define MPI_LOG_0_PAGEVERSION (0x00)
|
||||
#define MPI_LOG_0_PAGEVERSION (0x01)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -6,25 +6,25 @@
|
||||
Copyright (c) 2000-2005 LSI Logic Corporation.
|
||||
|
||||
---------------------------------------
|
||||
Header Set Release Version: 01.05.10
|
||||
Header Set Release Date: 03-11-05
|
||||
Header Set Release Version: 01.05.12
|
||||
Header Set Release Date: 08-30-05
|
||||
---------------------------------------
|
||||
|
||||
Filename Current version Prior version
|
||||
---------- --------------- -------------
|
||||
mpi.h 01.05.08 01.05.07
|
||||
mpi_ioc.h 01.05.09 01.05.08
|
||||
mpi_cnfg.h 01.05.09 01.05.08
|
||||
mpi_init.h 01.05.05 01.05.04
|
||||
mpi_targ.h 01.05.05 01.05.04
|
||||
mpi.h 01.05.10 01.05.09
|
||||
mpi_ioc.h 01.05.10 01.05.09
|
||||
mpi_cnfg.h 01.05.11 01.05.10
|
||||
mpi_init.h 01.05.06 01.05.06
|
||||
mpi_targ.h 01.05.05 01.05.05
|
||||
mpi_fc.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_tool.h 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.01 01.05.01
|
||||
mpi_history.txt 01.05.09 01.05.09
|
||||
mpi_sas.h 01.05.02 01.05.01
|
||||
mpi_type.h 01.05.02 01.05.01
|
||||
mpi_history.txt 01.05.12 01.05.11
|
||||
|
||||
|
||||
* Date Version Description
|
||||
@ -91,6 +91,8 @@ mpi.h
|
||||
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
|
||||
* TargetAssistExtended requests.
|
||||
* 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
|
||||
@ -164,6 +166,10 @@ mpi_ioc.h
|
||||
* Removed IOCFacts Reply EEDP Capability bit.
|
||||
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
|
||||
* 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
|
||||
@ -402,6 +408,23 @@ mpi_cnfg.h
|
||||
* Added OwnerDevHandle and Flags field to SAS PHY Page 0.
|
||||
* Added IOC GPIO Flags define to SAS Enclosure Page 0.
|
||||
* 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
|
||||
@ -442,6 +465,8 @@ mpi_init.h
|
||||
* addressing.
|
||||
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
|
||||
* 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
|
||||
@ -582,6 +607,9 @@ mpi_inb.h
|
||||
|
||||
mpi_sas.h
|
||||
* 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
|
||||
@ -592,24 +620,25 @@ mpi_type.h
|
||||
* 08-08-01 01.02.01 Original release for v1.2 work.
|
||||
* 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-30-05 01.05.02 Added PowerPC option to #ifdef's.
|
||||
* --------------------------------------------------------------------------
|
||||
|
||||
mpi_history.txt Parts list history
|
||||
|
||||
Filename 01.05.10 01.05.09
|
||||
---------- -------- --------
|
||||
mpi.h 01.05.08 01.05.07
|
||||
mpi_ioc.h 01.05.09 01.05.08
|
||||
mpi_cnfg.h 01.05.09 01.05.08
|
||||
mpi_init.h 01.05.05 01.05.04
|
||||
mpi_targ.h 01.05.05 01.05.04
|
||||
mpi_fc.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_tool.h 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01
|
||||
mpi_sas.h 01.05.01 01.05.01
|
||||
mpi_type.h 01.05.01 01.05.01
|
||||
Filename 01.05.12 01.05.11 01.05.10 01.05.09
|
||||
---------- -------- -------- -------- --------
|
||||
mpi.h 01.05.10 01.05.09 01.05.08 01.05.07
|
||||
mpi_ioc.h 01.05.10 01.05.09 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.06 01.05.06 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 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 01.05.02 01.05.02
|
||||
mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03
|
||||
mpi_inb.h 01.05.01 01.05.01 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.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
|
||||
---------- -------- -------- -------- -------- -------- --------
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Title: MPI initiator mode messages and structures
|
||||
* Creation Date: June 8, 2000
|
||||
*
|
||||
* mpi_init.h Version: 01.05.05
|
||||
* mpi_init.h Version: 01.05.06
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -50,6 +50,8 @@
|
||||
* addressing.
|
||||
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
|
||||
* 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 */
|
||||
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
|
||||
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00)
|
||||
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01)
|
||||
#define MPI_SCSIIO32_MSGFLGS_32_SENSE_WIDTH (0x00)
|
||||
#define MPI_SCSIIO32_MSGFLGS_64_SENSE_WIDTH (0x01)
|
||||
|
||||
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
|
||||
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
|
||||
* Creation Date: August 11, 2000
|
||||
*
|
||||
* mpi_ioc.h Version: 01.05.09
|
||||
* mpi_ioc.h Version: 01.05.10
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -83,6 +83,10 @@
|
||||
* Removed IOCFacts Reply EEDP Capability bit.
|
||||
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
|
||||
* 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_SAS_PHY_LINK_STATUS (0x00000012)
|
||||
#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 */
|
||||
|
||||
@ -480,6 +488,29 @@ typedef struct _EVENT_DATA_EVENT_CHANGE
|
||||
} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
|
||||
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 */
|
||||
|
||||
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_NO_PERSIST_ADDED (0x06)
|
||||
#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 */
|
||||
@ -579,6 +611,79 @@ typedef struct _EVENT_DATA_RAID
|
||||
#define MPI_EVENT_RAID_RC_SMART_DATA (0x0A)
|
||||
#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 */
|
||||
|
||||
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_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 */
|
||||
|
||||
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_939X_FC (0x0004) /* 939X and 949X */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_959_FC (0x0005)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_949E_FC (0x0006)
|
||||
/* SAS */
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1064_SAS (0x0001)
|
||||
#define MPI_FW_HEADER_PID_FAMILY_1068_SAS (0x0002)
|
||||
|
89
drivers/message/fusion/lsi/mpi_log_fc.h
Normal file
89
drivers/message/fusion/lsi/mpi_log_fc.h
Normal file
@ -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;
|
162
drivers/message/fusion/lsi/mpi_log_sas.h
Normal file
162
drivers/message/fusion/lsi/mpi_log_sas.h
Normal file
@ -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
|
||||
* Creation Date: August 19, 2004
|
||||
*
|
||||
* mpi_sas.h Version: 01.05.01
|
||||
* mpi_sas.h Version: 01.05.02
|
||||
*
|
||||
* Version History
|
||||
* ---------------
|
||||
@ -14,6 +14,9 @@
|
||||
* Date Version Description
|
||||
* -------- -------- ------------------------------------------------------
|
||||
* 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
|
||||
* 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_LSI_DEVICE (0x00001000)
|
||||
#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800)
|
||||
@ -212,20 +216,26 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
|
||||
U8 TargetID; /* 0Ch */
|
||||
U8 Bus; /* 0Dh */
|
||||
U8 PhyNum; /* 0Eh */
|
||||
U8 Reserved4; /* 0Fh */
|
||||
U32 Reserved5; /* 10h */
|
||||
U8 PrimFlags; /* 0Fh */
|
||||
U32 Primitive; /* 10h */
|
||||
U64 SASAddress; /* 14h */
|
||||
U32 Reserved6; /* 1Ch */
|
||||
U32 Reserved4; /* 1Ch */
|
||||
} MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
|
||||
SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
|
||||
|
||||
/* values for the Operation field */
|
||||
#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
|
||||
#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
|
||||
#define MPI_SAS_OP_PHY_LINK_RESET (0x06)
|
||||
#define MPI_SAS_OP_PHY_HARD_RESET (0x07)
|
||||
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
|
||||
#define MPI_SAS_OP_MAP_CURRENT (0x09)
|
||||
#define MPI_SAS_OP_CLEAR_NOT_PRESENT (0x01)
|
||||
#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT (0x02)
|
||||
#define MPI_SAS_OP_PHY_LINK_RESET (0x06)
|
||||
#define MPI_SAS_OP_PHY_HARD_RESET (0x07)
|
||||
#define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08)
|
||||
#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 */
|
||||
|
@ -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 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
|
||||
static int GetLanConfigPages(MPT_ADAPTER *ioc);
|
||||
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
|
||||
static int GetIoUnitPage2(MPT_ADAPTER *ioc);
|
||||
int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
|
||||
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
|
||||
": Not using 64 bit consistent mask\n"));
|
||||
|
||||
ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
|
||||
ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
|
||||
if (ioc == NULL) {
|
||||
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(ioc, 0, sizeof(MPT_ADAPTER));
|
||||
ioc->alloc_total = sizeof(MPT_ADAPTER);
|
||||
ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
|
||||
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->diagPending = 0;
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Initialize the fc rport list head.
|
||||
*/
|
||||
INIT_LIST_HEAD(&ioc->fc_rports);
|
||||
|
||||
/* Find lookup slot. */
|
||||
INIT_LIST_HEAD(&ioc->list);
|
||||
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->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) {
|
||||
ioc->prod_name = "LSI53C1030";
|
||||
ioc->bus_type = SPI;
|
||||
@ -1622,7 +1630,7 @@ mpt_resume(struct pci_dev *pdev)
|
||||
pci_enable_device(pdev);
|
||||
|
||||
/* enable interrupts */
|
||||
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
|
||||
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
|
||||
ioc->active = 1;
|
||||
|
||||
/* 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) */
|
||||
dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1831,7 +1839,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
|
||||
if (ret == 0) {
|
||||
/* Enable! (reply interrupt) */
|
||||
CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
|
||||
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
|
||||
ioc->active = 1;
|
||||
}
|
||||
|
||||
@ -1839,7 +1847,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
/* (re)Enable alt-IOC! (reply interrupt) */
|
||||
dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1880,7 +1888,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
* (FCPortPage0_t stuff)
|
||||
*/
|
||||
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) &&
|
||||
@ -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
|
||||
* @portnum: IOC Port number
|
||||
*
|
||||
@ -4209,8 +4217,8 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
|
||||
* -EAGAIN if no msg frames currently available
|
||||
* -EFAULT for non-successful reply or no reply (timeout)
|
||||
*/
|
||||
static int
|
||||
GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
int
|
||||
mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
@ -4220,6 +4228,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
int data_sz;
|
||||
int copy_sz;
|
||||
int rc;
|
||||
int count = 400;
|
||||
|
||||
|
||||
/* Get FCPort Page 0 header */
|
||||
hdr.PageVersion = 0;
|
||||
@ -4243,6 +4253,8 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
rc = -ENOMEM;
|
||||
ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
|
||||
if (ppage0_alloc) {
|
||||
|
||||
try_again:
|
||||
memset((u8 *)ppage0_alloc, 0, data_sz);
|
||||
cfg.physAddr = page0_dma;
|
||||
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->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);
|
||||
@ -6358,6 +6383,7 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
||||
EXPORT_SYMBOL(mpt_free_fw_memory);
|
||||
EXPORT_SYMBOL(mptbase_sas_persist_operation);
|
||||
EXPORT_SYMBOL(mpt_alt_ioc_wait);
|
||||
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
|
||||
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
@ -76,8 +76,8 @@
|
||||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||
#endif
|
||||
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.05"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.05"
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.06"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06"
|
||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||
|
||||
#define show_mptmod_ver(s,ver) \
|
||||
@ -413,7 +413,7 @@ typedef struct _MPT_IOCTL {
|
||||
u8 status; /* current command status */
|
||||
u8 reset; /* 1 if bus reset allowed */
|
||||
u8 target; /* target for reset */
|
||||
struct semaphore sem_ioc;
|
||||
struct mutex ioctl_mutex;
|
||||
} MPT_IOCTL;
|
||||
|
||||
#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 */
|
||||
|
||||
typedef struct _MPT_SAS_MGMT {
|
||||
struct semaphore mutex;
|
||||
struct mutex mutex;
|
||||
struct completion done;
|
||||
u8 reply[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
|
||||
u8 status; /* current command status */
|
||||
@ -499,6 +499,22 @@ typedef struct _RaidCfgData {
|
||||
int isRaid; /* bit field, 1 if RAID */
|
||||
}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
|
||||
*/
|
||||
@ -612,7 +628,16 @@ typedef struct _MPT_ADAPTER
|
||||
struct list_head list;
|
||||
struct net_device *netdev;
|
||||
struct list_head sas_topology;
|
||||
struct mutex sas_topology_mutex;
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -999,6 +1024,7 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
|
||||
extern int mpt_findImVolumes(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_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
|
||||
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));
|
||||
|
||||
if (nonblock) {
|
||||
if (down_trylock(&ioc->ioctl->sem_ioc))
|
||||
if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))
|
||||
rc = -EAGAIN;
|
||||
} else {
|
||||
if (down_interruptible(&ioc->ioctl->sem_ioc))
|
||||
if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))
|
||||
rc = -ERESTARTSYS;
|
||||
}
|
||||
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
|
||||
ret = -EINVAL;
|
||||
|
||||
up(&iocp->ioctl->sem_ioc);
|
||||
mutex_unlock(&iocp->ioctl->ioctl_mutex);
|
||||
|
||||
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);
|
||||
|
||||
up(&iocp->ioctl->sem_ioc);
|
||||
mutex_unlock(&iocp->ioctl->ioctl_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2673,7 +2673,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
|
||||
*/
|
||||
ret = mptctl_do_mpt_command (karg, &uarg->MF);
|
||||
|
||||
up(&iocp->ioctl->sem_ioc);
|
||||
mutex_unlock(&iocp->ioctl->ioctl_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -2743,7 +2743,7 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
memset(mem, 0, sz);
|
||||
ioc->ioctl = (MPT_IOCTL *) mem;
|
||||
ioc->ioctl->ioc = ioc;
|
||||
sema_init(&ioc->ioctl->sem_ioc, 1);
|
||||
mutex_init(&ioc->ioctl->ioctl_mutex);
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
|
@ -55,12 +55,14 @@
|
||||
#include <linux/reboot.h> /* notifier code */
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_tcq.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
|
||||
#include "mptbase.h"
|
||||
#include "mptscsih.h"
|
||||
@ -79,19 +81,34 @@ static int mpt_pq_filter = 0;
|
||||
module_param(mpt_pq_filter, int, 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 mptfcTaskCtx = -1;
|
||||
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 = {
|
||||
.module = THIS_MODULE,
|
||||
.proc_name = "mptfc",
|
||||
.proc_info = mptscsih_proc_info,
|
||||
.name = "MPT FC Host",
|
||||
.info = mptscsih_info,
|
||||
.queuecommand = mptscsih_qcmd,
|
||||
.queuecommand = mptfc_qcmd,
|
||||
.target_alloc = mptscsih_target_alloc,
|
||||
.slave_alloc = mptscsih_slave_alloc,
|
||||
.slave_alloc = mptfc_slave_alloc,
|
||||
.slave_configure = mptscsih_slave_configure,
|
||||
.target_destroy = mptscsih_target_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_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
|
||||
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 */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptfc_probe - Installs scsi devices per bus.
|
||||
* @pdev: Pointer to pci_dev structure
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*
|
||||
static struct scsi_transport_template *mptfc_transport_template = NULL;
|
||||
|
||||
struct fc_function_template mptfc_transport_functions = {
|
||||
.dd_fcrport_size = 8,
|
||||
.show_host_node_name = 1,
|
||||
.show_host_port_name = 1,
|
||||
.show_host_supported_classes = 1,
|
||||
.show_host_port_id = 1,
|
||||
.show_rport_supported_classes = 1,
|
||||
.show_starget_node_name = 1,
|
||||
.show_starget_port_name = 1,
|
||||
.show_starget_port_id = 1,
|
||||
.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
|
||||
.show_rport_dev_loss_tmo = 1,
|
||||
|
||||
};
|
||||
|
||||
/* FIXME! values controlling firmware RESCAN event
|
||||
* need to be set low to allow dev_loss_tmo to
|
||||
* work as expected. Currently, firmware doesn't
|
||||
* notify driver of RESCAN event until some number
|
||||
* of seconds elapse. This value can be set via
|
||||
* lsiutil.
|
||||
*/
|
||||
static void
|
||||
mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
|
||||
{
|
||||
if (timeout > 0)
|
||||
rport->dev_loss_tmo = timeout;
|
||||
else
|
||||
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
|
||||
{
|
||||
FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
|
||||
FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
|
||||
|
||||
if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
|
||||
if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
|
||||
return 0;
|
||||
if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((*aa)->CurrentBus < (*bb)->CurrentBus)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
|
||||
void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
FCDevicePage0_t *ppage0_alloc, *fc;
|
||||
dma_addr_t page0_dma;
|
||||
int data_sz;
|
||||
int ii;
|
||||
|
||||
FCDevicePage0_t *p0_array=NULL, *p_p0;
|
||||
FCDevicePage0_t **pp0_array=NULL, **p_pp0;
|
||||
|
||||
int rc = -ENOMEM;
|
||||
U32 port_id = 0xffffff;
|
||||
int num_targ = 0;
|
||||
int max_bus = ioc->facts.MaxBuses;
|
||||
int max_targ = ioc->facts.MaxDevices;
|
||||
|
||||
if (max_bus == 0 || max_targ == 0)
|
||||
goto out;
|
||||
|
||||
data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
|
||||
p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
|
||||
if (!p0_array)
|
||||
goto out;
|
||||
|
||||
data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
|
||||
p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
|
||||
if (!pp0_array)
|
||||
goto out;
|
||||
|
||||
do {
|
||||
/* Get FC Device Page 0 header */
|
||||
hdr.PageVersion = 0;
|
||||
hdr.PageLength = 0;
|
||||
hdr.PageNumber = 0;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
|
||||
cfg.cfghdr.hdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0;
|
||||
cfg.pageAddr = port_id;
|
||||
cfg.timeout = 0;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) != 0)
|
||||
break;
|
||||
|
||||
if (hdr.PageLength <= 0)
|
||||
break;
|
||||
|
||||
data_sz = hdr.PageLength * 4;
|
||||
ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
|
||||
&page0_dma);
|
||||
rc = -ENOMEM;
|
||||
if (!ppage0_alloc)
|
||||
break;
|
||||
|
||||
cfg.physAddr = page0_dma;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) == 0) {
|
||||
ppage0_alloc->PortIdentifier =
|
||||
le32_to_cpu(ppage0_alloc->PortIdentifier);
|
||||
|
||||
ppage0_alloc->WWNN.Low =
|
||||
le32_to_cpu(ppage0_alloc->WWNN.Low);
|
||||
|
||||
ppage0_alloc->WWNN.High =
|
||||
le32_to_cpu(ppage0_alloc->WWNN.High);
|
||||
|
||||
ppage0_alloc->WWPN.Low =
|
||||
le32_to_cpu(ppage0_alloc->WWPN.Low);
|
||||
|
||||
ppage0_alloc->WWPN.High =
|
||||
le32_to_cpu(ppage0_alloc->WWPN.High);
|
||||
|
||||
ppage0_alloc->BBCredit =
|
||||
le16_to_cpu(ppage0_alloc->BBCredit);
|
||||
|
||||
ppage0_alloc->MaxRxFrameSize =
|
||||
le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
|
||||
|
||||
port_id = ppage0_alloc->PortIdentifier;
|
||||
num_targ++;
|
||||
*p_p0 = *ppage0_alloc; /* save data */
|
||||
*p_pp0++ = p_p0++; /* save addr */
|
||||
}
|
||||
pci_free_consistent(ioc->pcidev, data_sz,
|
||||
(u8 *) ppage0_alloc, page0_dma);
|
||||
if (rc != 0)
|
||||
break;
|
||||
|
||||
} while (port_id <= 0xff0000);
|
||||
|
||||
if (num_targ) {
|
||||
/* sort array */
|
||||
if (num_targ > 1)
|
||||
sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
|
||||
mptfc_FcDevPage0_cmp_func, NULL);
|
||||
/* call caller's func for each targ */
|
||||
for (ii = 0; ii < num_targ; ii++) {
|
||||
fc = *(pp0_array+ii);
|
||||
func(ioc, ioc_port, fc);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (pp0_array)
|
||||
kfree(pp0_array);
|
||||
if (p0_array)
|
||||
kfree(p0_array);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
|
||||
{
|
||||
/* not currently usable */
|
||||
if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
|
||||
MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
|
||||
return -1;
|
||||
|
||||
if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
|
||||
return -1;
|
||||
|
||||
if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* board data structure already normalized to platform endianness
|
||||
* shifted to avoid unaligned access on 64 bit architecture
|
||||
*/
|
||||
rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
|
||||
rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
|
||||
rid->port_id = pg0->PortIdentifier;
|
||||
rid->roles = FC_RPORT_ROLE_UNKNOWN;
|
||||
rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
|
||||
if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
|
||||
rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
|
||||
{
|
||||
struct fc_rport_identifiers rport_ids;
|
||||
struct fc_rport *rport;
|
||||
struct mptfc_rport_info *ri;
|
||||
int match = 0;
|
||||
u64 port_name;
|
||||
unsigned long flags;
|
||||
|
||||
if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
|
||||
return;
|
||||
|
||||
/* scan list looking for a match */
|
||||
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
||||
list_for_each_entry(ri, &ioc->fc_rports, list) {
|
||||
port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
|
||||
if (port_name == rport_ids.port_name) { /* match */
|
||||
list_move_tail(&ri->list, &ioc->fc_rports);
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) { /* allocate one */
|
||||
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
||||
ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
|
||||
if (!ri)
|
||||
return;
|
||||
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
||||
list_add_tail(&ri->list, &ioc->fc_rports);
|
||||
}
|
||||
|
||||
ri->pg0 = *pg0; /* add/update pg0 data */
|
||||
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
|
||||
|
||||
if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
|
||||
ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
|
||||
spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
|
||||
rport = fc_remote_port_add(ioc->sh,channel, &rport_ids);
|
||||
spin_lock_irqsave(&ioc->fc_rport_lock, flags);
|
||||
if (rport) {
|
||||
if (*((struct mptfc_rport_info **)rport->dd_data) != ri) {
|
||||
ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV;
|
||||
ri->vdev = NULL;
|
||||
ri->rport = rport;
|
||||
*((struct mptfc_rport_info **)rport->dd_data) = ri;
|
||||
}
|
||||
rport->dev_loss_tmo = mptfc_dev_loss_tmo;
|
||||
/*
|
||||
* if already mapped, remap here. If not mapped,
|
||||
* slave_alloc will allocate vdev and map
|
||||
*/
|
||||
if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) {
|
||||
ri->vdev->target_id = ri->pg0.CurrentTargetID;
|
||||
ri->vdev->bus_id = ri->pg0.CurrentBus;
|
||||
ri->vdev->vtarget->target_id = ri->vdev->target_id;
|
||||
ri->vdev->vtarget->bus_id = ri->vdev->bus_id;
|
||||
}
|
||||
#ifdef MPT_DEBUG
|
||||
printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
|
||||
"rport tid %d, tmo %d\n",
|
||||
ioc->sh->host_no,
|
||||
pg0->PortIdentifier,
|
||||
pg0->WWNN,
|
||||
pg0->WWPN,
|
||||
pg0->CurrentTargetID,
|
||||
ri->rport->scsi_target_id,
|
||||
ri->rport->dev_loss_tmo);
|
||||
#endif
|
||||
} else {
|
||||
list_del(&ri->list);
|
||||
kfree(ri);
|
||||
ri = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
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_ADAPTER *ioc;
|
||||
unsigned long flags;
|
||||
int sz, ii;
|
||||
int ii;
|
||||
int numSGE = 0;
|
||||
int scale;
|
||||
int ioc_cap;
|
||||
u8 *mem;
|
||||
int error=0;
|
||||
int r;
|
||||
|
||||
|
||||
if ((r = mpt_attach(pdev,id)) != 0)
|
||||
return r;
|
||||
|
||||
|
||||
ioc = pci_get_drvdata(pdev);
|
||||
ioc->DoneCtx = mptfcDoneCtx;
|
||||
ioc->TaskCtx = mptfcTaskCtx;
|
||||
@ -194,7 +669,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
printk(MYIOC_s_WARN_FMT
|
||||
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
|
||||
ioc->name, ioc);
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
|
||||
|
||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||
|
||||
/* 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!
|
||||
* (with size equal to req_depth*PtrSz!)
|
||||
*/
|
||||
sz = ioc->req_depth * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->ScsiLookup) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptfc_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->ScsiLookup = (struct scsi_cmnd **) mem;
|
||||
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
|
||||
ioc->name, hd->ScsiLookup, sz));
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
|
||||
ioc->name, hd->ScsiLookup));
|
||||
|
||||
/* Allocate memory for the device structures.
|
||||
* A non-Null pointer at an offset
|
||||
* indicates a device exists.
|
||||
* max_id = 1 + maximum id (hosts.h)
|
||||
*/
|
||||
sz = sh->max_id * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->Targets) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptfc_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->Targets = (VirtTarget **) mem;
|
||||
|
||||
dprintk((KERN_INFO
|
||||
" vdev @ %p, sz=%d\n", hd->Targets, sz));
|
||||
dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
|
||||
|
||||
/* 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->last_queue_full = 0;
|
||||
|
||||
sh->transportt = mptfc_transport_template;
|
||||
error = scsi_add_host (sh, &ioc->pcidev->dev);
|
||||
if(error) {
|
||||
dprintk((KERN_ERR MYNAM
|
||||
@ -339,7 +808,11 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
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;
|
||||
|
||||
out_mptfc_probe:
|
||||
@ -352,7 +825,7 @@ static struct pci_driver mptfc_driver = {
|
||||
.name = "mptfc",
|
||||
.id_table = mptfc_pci_table,
|
||||
.probe = mptfc_probe,
|
||||
.remove = __devexit_p(mptscsih_remove),
|
||||
.remove = __devexit_p(mptfc_remove),
|
||||
.shutdown = mptscsih_shutdown,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mptscsih_suspend,
|
||||
@ -370,9 +843,20 @@ static struct pci_driver mptfc_driver = {
|
||||
static int __init
|
||||
mptfc_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
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);
|
||||
mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
|
||||
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
|
||||
@ -387,7 +871,33 @@ mptfc_init(void)
|
||||
": 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)
|
||||
{
|
||||
pci_unregister_driver(&mptfc_driver);
|
||||
|
||||
fc_release_transport(mptfc_transport_template);
|
||||
|
||||
mpt_reset_deregister(mptfcDoneCtx);
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Deregistered for IOC reset notifications\n"));
|
||||
|
@ -411,14 +411,12 @@ mpt_lan_open(struct net_device *dev)
|
||||
goto out;
|
||||
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);
|
||||
if (priv->SendCtl == NULL)
|
||||
goto out_mpt_txfidx;
|
||||
for (i = 0; i < priv->tx_max_out; i++) {
|
||||
memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));
|
||||
for (i = 0; i < priv->tx_max_out; i++)
|
||||
priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
|
||||
}
|
||||
|
||||
dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
|
||||
|
||||
@ -428,15 +426,13 @@ mpt_lan_open(struct net_device *dev)
|
||||
goto out_SendCtl;
|
||||
priv->mpt_rxfidx_tail = -1;
|
||||
|
||||
priv->RcvCtl = kmalloc(priv->max_buckets_out *
|
||||
sizeof(struct BufferControl),
|
||||
priv->RcvCtl = kcalloc(priv->max_buckets_out,
|
||||
sizeof(struct BufferControl),
|
||||
GFP_KERNEL);
|
||||
if (priv->RcvCtl == NULL)
|
||||
goto out_mpt_rxfidx;
|
||||
for (i = 0; i < priv->max_buckets_out; i++) {
|
||||
memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));
|
||||
for (i = 0; i < priv->max_buckets_out; i++)
|
||||
priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
|
||||
}
|
||||
|
||||
/**/ dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
|
||||
/**/ for (i = 0; i < priv->tx_max_out; i++)
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 1999-2005 LSI Logic Corporation
|
||||
* (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;
|
||||
|
||||
|
||||
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
|
||||
*
|
||||
@ -99,8 +117,8 @@ struct mptsas_devinfo {
|
||||
u8 phy_id; /* phy number of parent device */
|
||||
u8 port_id; /* sas physical port this device
|
||||
is assoc'd with */
|
||||
u8 target; /* logical target id of this device */
|
||||
u8 bus; /* logical bus number of this device */
|
||||
u8 id; /* logical target id of this device */
|
||||
u8 channel; /* logical bus number of this device */
|
||||
u64 sas_address; /* WWN of this device,
|
||||
SATA is assigned by HBA,expander */
|
||||
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 */
|
||||
struct mptsas_devinfo identify; /* point to phy device info */
|
||||
struct mptsas_devinfo attached; /* point to attached device info */
|
||||
struct sas_phy *phy;
|
||||
struct sas_rphy *rphy;
|
||||
};
|
||||
|
||||
@ -239,13 +258,12 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
||||
struct scsi_target *starget;
|
||||
int i;
|
||||
|
||||
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
|
||||
vdev = kzalloc(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));
|
||||
vdev->ioc_id = hd->ioc->id;
|
||||
sdev->hostdata = vdev;
|
||||
starget = scsi_target(sdev);
|
||||
@ -256,19 +274,32 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
||||
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);
|
||||
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) {
|
||||
vdev->target_id =
|
||||
p->phy_info[i].attached.target;
|
||||
vdev->bus_id = p->phy_info[i].attached.bus;
|
||||
p->phy_info[i].attached.id;
|
||||
vdev->bus_id = p->phy_info[i].attached.channel;
|
||||
vdev->lun = sdev->lun;
|
||||
mutex_unlock(&hd->ioc->sas_topology_mutex);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&hd->ioc->sas_topology_mutex);
|
||||
|
||||
printk("No matching SAS device found!!\n");
|
||||
kfree(vdev);
|
||||
@ -282,6 +313,42 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
||||
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 = {
|
||||
.module = THIS_MODULE,
|
||||
.proc_name = "mptsas",
|
||||
@ -293,7 +360,7 @@ static struct scsi_host_template mptsas_driver_template = {
|
||||
.slave_alloc = mptsas_slave_alloc,
|
||||
.slave_configure = mptscsih_slave_configure,
|
||||
.target_destroy = mptscsih_target_destroy,
|
||||
.slave_destroy = mptscsih_slave_destroy,
|
||||
.slave_destroy = mptsas_slave_destroy,
|
||||
.change_queue_depth = mptscsih_change_queue_depth,
|
||||
.eh_abort_handler = mptscsih_abort,
|
||||
.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)
|
||||
return -ENXIO;
|
||||
|
||||
if (down_interruptible(&ioc->sas_mgmt.mutex))
|
||||
if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
|
||||
goto out;
|
||||
|
||||
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;
|
||||
|
||||
out_unlock:
|
||||
up(&ioc->sas_mgmt.mutex);
|
||||
mutex_unlock(&ioc->sas_mgmt.mutex);
|
||||
out:
|
||||
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->phy_id = buffer->PhyNum;
|
||||
device_info->port_id = buffer->PhysicalPort;
|
||||
device_info->target = buffer->TargetID;
|
||||
device_info->bus = buffer->Bus;
|
||||
device_info->id = buffer->TargetID;
|
||||
device_info->channel = buffer->Bus;
|
||||
memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
|
||||
device_info->sas_address = le64_to_cpu(sas_address);
|
||||
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,
|
||||
struct mptsas_phyinfo *phy_info, int index, int local)
|
||||
{
|
||||
struct sas_phy *port;
|
||||
struct sas_phy *phy;
|
||||
int error;
|
||||
|
||||
port = sas_phy_alloc(dev, index);
|
||||
if (!port)
|
||||
phy = sas_phy_alloc(dev, index);
|
||||
if (!phy)
|
||||
return -ENOMEM;
|
||||
|
||||
port->port_identifier = phy_info->port_id;
|
||||
mptsas_parse_device_info(&port->identify, &phy_info->identify);
|
||||
phy->port_identifier = phy_info->port_id;
|
||||
mptsas_parse_device_info(&phy->identify, &phy_info->identify);
|
||||
|
||||
/*
|
||||
* Set Negotiated link rate.
|
||||
*/
|
||||
switch (phy_info->negotiated_link_rate) {
|
||||
case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
|
||||
port->negotiated_linkrate = SAS_PHY_DISABLED;
|
||||
phy->negotiated_linkrate = SAS_PHY_DISABLED;
|
||||
break;
|
||||
case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
|
||||
port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
|
||||
phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
|
||||
case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
|
||||
default:
|
||||
port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
|
||||
phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
@ -911,10 +978,10 @@ static int mptsas_probe_one_phy(struct device *dev,
|
||||
switch (phy_info->programmed_link_rate &
|
||||
MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
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) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
@ -940,28 +1007,29 @@ static int mptsas_probe_one_phy(struct device *dev,
|
||||
switch (phy_info->programmed_link_rate &
|
||||
MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (local)
|
||||
port->local_attached = 1;
|
||||
phy->local_attached = 1;
|
||||
|
||||
error = sas_phy_add(port);
|
||||
error = sas_phy_add(phy);
|
||||
if (error) {
|
||||
sas_phy_free(port);
|
||||
sas_phy_free(phy);
|
||||
return error;
|
||||
}
|
||||
phy_info->phy = phy;
|
||||
|
||||
if (phy_info->attached.handle) {
|
||||
struct sas_rphy *rphy;
|
||||
|
||||
rphy = sas_rphy_alloc(port);
|
||||
rphy = sas_rphy_alloc(phy);
|
||||
if (!rphy)
|
||||
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;
|
||||
int error = -ENOMEM, i;
|
||||
|
||||
port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
|
||||
port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
|
||||
if (!port_info)
|
||||
goto out;
|
||||
memset(port_info, 0, sizeof(*port_info));
|
||||
|
||||
error = mptsas_sas_io_unit_pg0(ioc, port_info);
|
||||
if (error)
|
||||
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);
|
||||
mutex_unlock(&ioc->sas_topology_mutex);
|
||||
|
||||
for (i = 0; i < port_info->num_phys; i++) {
|
||||
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
|
||||
(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;
|
||||
int error = -ENOMEM, i, j;
|
||||
|
||||
port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
|
||||
port_info = kzalloc(sizeof(*port_info), GFP_KERNEL);
|
||||
if (!port_info)
|
||||
goto out;
|
||||
memset(port_info, 0, sizeof(*port_info));
|
||||
|
||||
error = mptsas_sas_expander_pg0(ioc, port_info,
|
||||
(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;
|
||||
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
list_add_tail(&port_info->list, &ioc->sas_topology);
|
||||
mutex_unlock(&ioc->sas_topology_mutex);
|
||||
|
||||
for (i = 0; i < port_info->num_phys; i++) {
|
||||
struct device *parent;
|
||||
|
||||
@ -1079,6 +1152,7 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
|
||||
* HBA phys.
|
||||
*/
|
||||
parent = &ioc->sh->shost_gendev;
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
list_for_each_entry(p, &ioc->sas_topology, list) {
|
||||
for (j = 0; j < p->num_phys; j++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ioc->sas_topology_mutex);
|
||||
|
||||
mptsas_probe_one_phy(parent, &port_info->phy_info[i],
|
||||
*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
|
||||
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_ADAPTER *ioc;
|
||||
unsigned long flags;
|
||||
int sz, ii;
|
||||
int ii;
|
||||
int numSGE = 0;
|
||||
int scale;
|
||||
int ioc_cap;
|
||||
u8 *mem;
|
||||
int error=0;
|
||||
int r;
|
||||
|
||||
@ -1203,7 +1482,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
sh->unique_id = ioc->id;
|
||||
|
||||
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);
|
||||
|
||||
/* 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!
|
||||
* (with size equal to req_depth*PtrSz!)
|
||||
*/
|
||||
sz = ioc->req_depth * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->ScsiLookup) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptsas_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->ScsiLookup = (struct scsi_cmnd **) mem;
|
||||
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
|
||||
ioc->name, hd->ScsiLookup, sz));
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
|
||||
ioc->name, hd->ScsiLookup));
|
||||
|
||||
/* Allocate memory for the device structures.
|
||||
* A non-Null pointer at an offset
|
||||
* indicates a device exists.
|
||||
* max_id = 1 + maximum id (hosts.h)
|
||||
*/
|
||||
sz = sh->max_id * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->Targets) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptsas_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->Targets = (VirtTarget **) mem;
|
||||
|
||||
dprintk((KERN_INFO
|
||||
" vtarget @ %p, sz=%d\n", hd->Targets, sz));
|
||||
dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
|
||||
|
||||
/* 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);
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
out_mptsas_probe:
|
||||
@ -1339,10 +1625,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
|
||||
|
||||
sas_remove_host(ioc->sh);
|
||||
|
||||
mutex_lock(&ioc->sas_topology_mutex);
|
||||
list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
|
||||
list_del(&p->list);
|
||||
kfree(p);
|
||||
}
|
||||
mutex_unlock(&ioc->sas_topology_mutex);
|
||||
|
||||
mptscsih_remove(pdev);
|
||||
}
|
||||
@ -1393,7 +1681,7 @@ mptsas_init(void)
|
||||
mpt_register(mptscsih_scandv_complete, 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
|
||||
": 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.
|
||||
* Do NOT access the referenced scsi_cmnd structure or
|
||||
* 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
|
||||
* @vdevice: per device private data
|
||||
*
|
||||
@ -2162,10 +2163,9 @@ mptscsih_target_alloc(struct scsi_target *starget)
|
||||
{
|
||||
VirtTarget *vtarget;
|
||||
|
||||
vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
|
||||
vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
|
||||
if (!vtarget)
|
||||
return -ENOMEM;
|
||||
memset(vtarget, 0, sizeof(VirtTarget));
|
||||
starget->hostdata = vtarget;
|
||||
return 0;
|
||||
}
|
||||
@ -2185,14 +2185,13 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
|
||||
VirtDevice *vdev;
|
||||
struct scsi_target *starget;
|
||||
|
||||
vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
|
||||
vdev = kzalloc(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));
|
||||
vdev->ioc_id = hd->ioc->id;
|
||||
vdev->target_id = sdev->id;
|
||||
vdev->bus_id = sdev->channel;
|
||||
@ -2559,13 +2558,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
|
||||
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) {
|
||||
ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
|
||||
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));
|
||||
|
||||
}
|
||||
@ -2589,6 +2600,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||
{
|
||||
MPT_SCSI_HOST *hd;
|
||||
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",
|
||||
ioc->name, event));
|
||||
@ -2610,11 +2623,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||
/* FIXME! */
|
||||
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
|
||||
* anything for these, but...
|
||||
*/
|
||||
case MPI_EVENT_RESCAN: /* 06 */
|
||||
case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -158,11 +158,10 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
MPT_SCSI_HOST *hd;
|
||||
MPT_ADAPTER *ioc;
|
||||
unsigned long flags;
|
||||
int sz, ii;
|
||||
int ii;
|
||||
int numSGE = 0;
|
||||
int scale;
|
||||
int ioc_cap;
|
||||
u8 *mem;
|
||||
int error=0;
|
||||
int r;
|
||||
|
||||
@ -288,36 +287,27 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* SCSI needs scsi_cmnd lookup table!
|
||||
* (with size equal to req_depth*PtrSz!)
|
||||
*/
|
||||
sz = ioc->req_depth * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->ScsiLookup) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptspi_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->ScsiLookup = (struct scsi_cmnd **) mem;
|
||||
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
|
||||
ioc->name, hd->ScsiLookup, sz));
|
||||
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
|
||||
ioc->name, hd->ScsiLookup));
|
||||
|
||||
/* Allocate memory for the device structures.
|
||||
* A non-Null pointer at an offset
|
||||
* indicates a device exists.
|
||||
* max_id = 1 + maximum id (hosts.h)
|
||||
*/
|
||||
sz = sh->max_id * sizeof(void *);
|
||||
mem = kmalloc(sz, GFP_ATOMIC);
|
||||
if (mem == NULL) {
|
||||
hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
|
||||
if (!hd->Targets) {
|
||||
error = -ENOMEM;
|
||||
goto out_mptspi_probe;
|
||||
}
|
||||
|
||||
memset(mem, 0, sz);
|
||||
hd->Targets = (VirtTarget **) mem;
|
||||
|
||||
dprintk((KERN_INFO
|
||||
" vdev @ %p, sz=%d\n", hd->Targets, sz));
|
||||
dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
|
||||
|
||||
/* Clear the TM flags
|
||||
*/
|
||||
|
@ -88,11 +88,6 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
|
||||
struct device *dev = &pdev->dev;
|
||||
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++) {
|
||||
/* Skip I/O spaces */
|
||||
if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
|
||||
@ -319,6 +314,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
|
||||
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)) {
|
||||
printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
|
||||
pci_name(pdev));
|
||||
|
@ -1125,6 +1125,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
|
||||
zfcp_free_low_mem_buffers(adapter);
|
||||
/* free memory of adapter data structure and queues */
|
||||
zfcp_qdio_free_queues(adapter);
|
||||
kfree(adapter->fc_stats);
|
||||
kfree(adapter->stats_reset_data);
|
||||
ZFCP_LOG_TRACE("freeing adapter structure\n");
|
||||
kfree(adapter);
|
||||
out:
|
||||
|
@ -921,7 +921,6 @@ struct zfcp_adapter {
|
||||
u32 physical_s_id; /* local FC port ID */
|
||||
struct ccw_device *ccw_device; /* S/390 ccw device */
|
||||
u8 fc_service_class;
|
||||
u32 fc_topology; /* FC topology */
|
||||
u32 hydra_version; /* Hydra version */
|
||||
u32 fsf_lic_version;
|
||||
u32 adapter_features; /* FCP channel features */
|
||||
@ -978,6 +977,9 @@ struct zfcp_adapter {
|
||||
struct zfcp_adapter_mempool pool; /* Adapter memory pools */
|
||||
struct qdio_initialize qdio_init_data; /* for qdio_establish */
|
||||
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_PHYS_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) {
|
||||
ZFCP_LOG_NORMAL("Failed to open port 0x%016Lx "
|
||||
"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);
|
||||
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:
|
||||
ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
|
||||
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 =
|
||||
FSF_FEATURE_CFDC |
|
||||
FSF_FEATURE_LUN_SHARING |
|
||||
FSF_FEATURE_NOTIFICATION_LOST |
|
||||
FSF_FEATURE_UPDATE_ALERT;
|
||||
|
||||
/* 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_speed(shost) = bottom->fc_link_speed;
|
||||
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
|
||||
adapter->fc_topology = bottom->fc_topology;
|
||||
adapter->hydra_version = bottom->adapter_type;
|
||||
if (adapter->physical_wwpn == 0)
|
||||
adapter->physical_wwpn = fc_host_port_name(shost);
|
||||
if (adapter->physical_s_id == 0)
|
||||
adapter->physical_s_id = fc_host_port_id(shost);
|
||||
if (fc_host_permanent_port_name(shost) == -1)
|
||||
fc_host_permanent_port_name(shost) =
|
||||
fc_host_port_name(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 {
|
||||
fc_host_node_name(shost) = 0;
|
||||
fc_host_port_name(shost) = 0;
|
||||
fc_host_port_id(shost) = 0;
|
||||
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
|
||||
adapter->fc_topology = 0;
|
||||
fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
|
||||
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) {
|
||||
adapter->hardware_version = bottom->hardware_version;
|
||||
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))
|
||||
return -EIO;
|
||||
|
||||
switch (adapter->fc_topology) {
|
||||
case FSF_TOPO_P2P:
|
||||
switch (fc_host_port_type(adapter->scsi_host)) {
|
||||
case FC_PORTTYPE_PTP:
|
||||
ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
|
||||
"configuration detected at adapter %s\n"
|
||||
"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,
|
||||
"top-p-to-p");
|
||||
break;
|
||||
case FSF_TOPO_AL:
|
||||
case FC_PORTTYPE_NLPORT:
|
||||
ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
|
||||
"topology detected at adapter %s "
|
||||
"unsupported, shutting down adapter\n",
|
||||
@ -2120,7 +2158,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
|
||||
"top-al");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
return -EIO;
|
||||
case FSF_TOPO_FABRIC:
|
||||
case FC_PORTTYPE_NPORT:
|
||||
ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
|
||||
"network detected at adapter %s.\n",
|
||||
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 "
|
||||
"driver, shutting down adapter\n",
|
||||
zfcp_get_busid_by_adapter(adapter));
|
||||
adapter->fc_topology = FSF_TOPO_ERROR;
|
||||
debug_text_exception(fsf_req->adapter->erp_dbf, 0,
|
||||
"unknown-topo");
|
||||
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;
|
||||
if (data)
|
||||
memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
|
||||
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
|
||||
adapter->physical_wwpn = bottom->wwpn;
|
||||
adapter->physical_s_id = bottom->fc_port_id;
|
||||
} else {
|
||||
adapter->physical_wwpn = fc_host_port_name(shost);
|
||||
adapter->physical_s_id = fc_host_port_id(shost);
|
||||
}
|
||||
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
|
||||
fc_host_permanent_port_name(shost) = bottom->wwpn;
|
||||
else
|
||||
fc_host_permanent_port_name(shost) =
|
||||
fc_host_port_name(shost);
|
||||
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
|
||||
fc_host_supported_speeds(shost) = bottom->supported_speed;
|
||||
break;
|
||||
|
||||
case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
|
||||
|
@ -166,6 +166,7 @@
|
||||
#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004
|
||||
#define FSF_STATUS_READ_LINK_DOWN 0x00000005
|
||||
#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_HARDENED 0x0000000B
|
||||
#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_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 */
|
||||
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
|
||||
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
|
||||
@ -188,7 +199,6 @@
|
||||
#define FSF_TOPO_P2P 0x00000001
|
||||
#define FSF_TOPO_FABRIC 0x00000002
|
||||
#define FSF_TOPO_AL 0x00000003
|
||||
#define FSF_TOPO_FABRIC_VIRT 0x00000004
|
||||
|
||||
/* data direction for FCP commands */
|
||||
#define FSF_DATADIR_WRITE 0x00000001
|
||||
@ -211,6 +221,7 @@
|
||||
/* channel features */
|
||||
#define FSF_FEATURE_CFDC 0x00000002
|
||||
#define FSF_FEATURE_LUN_SHARING 0x00000004
|
||||
#define FSF_FEATURE_NOTIFICATION_LOST 0x00000008
|
||||
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
|
||||
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
|
||||
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
|
||||
|
@ -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,
|
||||
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[];
|
||||
|
||||
@ -406,18 +404,6 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
static void
|
||||
zfcp_get_port_id(struct scsi_target *starget)
|
||||
static struct fc_host_statistics*
|
||||
zfcp_init_fc_host_stats(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
|
||||
struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
|
||||
struct zfcp_port *port;
|
||||
unsigned long flags;
|
||||
struct fc_host_statistics *fc_stats;
|
||||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
port = zfcp_port_lookup(adapter, starget->channel, starget->id);
|
||||
if (port)
|
||||
fc_starget_port_id(starget) = port->d_id;
|
||||
else
|
||||
fc_starget_port_id(starget) = -1;
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
if (!adapter->fc_stats) {
|
||||
fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL);
|
||||
if (!fc_stats)
|
||||
return NULL;
|
||||
adapter->fc_stats = fc_stats; /* freed in adater_dequeue */
|
||||
}
|
||||
memset(adapter->fc_stats, 0, sizeof(*adapter->fc_stats));
|
||||
return adapter->fc_stats;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
port = zfcp_port_lookup(adapter, starget->channel, starget->id);
|
||||
if (port)
|
||||
fc_starget_port_name(starget) = port->wwpn;
|
||||
else
|
||||
fc_starget_port_name(starget) = -1;
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
fc_stats->seconds_since_last_reset = data->seconds_since_last_reset -
|
||||
old->seconds_since_last_reset;
|
||||
fc_stats->tx_frames = data->tx_frames - old->tx_frames;
|
||||
fc_stats->tx_words = data->tx_words - old->tx_words;
|
||||
fc_stats->rx_frames = data->rx_frames - old->rx_frames;
|
||||
fc_stats->rx_words = data->rx_words - old->rx_words;
|
||||
fc_stats->lip_count = data->lip - old->lip;
|
||||
fc_stats->nos_count = data->nos - old->nos;
|
||||
fc_stats->error_frames = data->error_frames - old->error_frames;
|
||||
fc_stats->dumped_frames = data->dumped_frames - old->dumped_frames;
|
||||
fc_stats->link_failure_count = data->link_failure - old->link_failure;
|
||||
fc_stats->loss_of_sync_count = data->loss_of_sync - old->loss_of_sync;
|
||||
fc_stats->loss_of_signal_count = data->loss_of_signal -
|
||||
old->loss_of_signal;
|
||||
fc_stats->prim_seq_protocol_err_count = data->psp_error_counts -
|
||||
old->psp_error_counts;
|
||||
fc_stats->invalid_tx_word_count = data->invalid_tx_words -
|
||||
old->invalid_tx_words;
|
||||
fc_stats->invalid_crc_count = data->invalid_crcs - old->invalid_crcs;
|
||||
fc_stats->fcp_input_requests = data->input_requests -
|
||||
old->input_requests;
|
||||
fc_stats->fcp_output_requests = data->output_requests -
|
||||
old->output_requests;
|
||||
fc_stats->fcp_control_requests = data->control_requests -
|
||||
old->control_requests;
|
||||
fc_stats->fcp_input_megabytes = data->input_mb - old->input_mb;
|
||||
fc_stats->fcp_output_megabytes = data->output_mb - old->output_mb;
|
||||
}
|
||||
|
||||
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);
|
||||
struct zfcp_adapter *adapter = (struct zfcp_adapter *)shost->hostdata[0];
|
||||
struct zfcp_port *port;
|
||||
unsigned long flags;
|
||||
fc_stats->seconds_since_last_reset = data->seconds_since_last_reset;
|
||||
fc_stats->tx_frames = data->tx_frames;
|
||||
fc_stats->tx_words = data->tx_words;
|
||||
fc_stats->rx_frames = data->rx_frames;
|
||||
fc_stats->rx_words = data->rx_words;
|
||||
fc_stats->lip_count = data->lip;
|
||||
fc_stats->nos_count = data->nos;
|
||||
fc_stats->error_frames = data->error_frames;
|
||||
fc_stats->dumped_frames = data->dumped_frames;
|
||||
fc_stats->link_failure_count = data->link_failure;
|
||||
fc_stats->loss_of_sync_count = data->loss_of_sync;
|
||||
fc_stats->loss_of_signal_count = data->loss_of_signal;
|
||||
fc_stats->prim_seq_protocol_err_count = data->psp_error_counts;
|
||||
fc_stats->invalid_tx_word_count = data->invalid_tx_words;
|
||||
fc_stats->invalid_crc_count = data->invalid_crcs;
|
||||
fc_stats->fcp_input_requests = data->input_requests;
|
||||
fc_stats->fcp_output_requests = data->output_requests;
|
||||
fc_stats->fcp_control_requests = data->control_requests;
|
||||
fc_stats->fcp_input_megabytes = data->input_mb;
|
||||
fc_stats->fcp_output_megabytes = data->output_mb;
|
||||
}
|
||||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
port = zfcp_port_lookup(adapter, starget->channel, starget->id);
|
||||
if (port)
|
||||
fc_starget_node_name(starget) = port->wwnn;
|
||||
else
|
||||
fc_starget_node_name(starget) = -1;
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
/**
|
||||
* zfcp_get_fc_host_stats - provide fc_host_statistics for scsi_transport_fc
|
||||
*
|
||||
* assumption: scsi_transport_fc synchronizes calls of
|
||||
* get_fc_host_stats and reset_fc_host_stats
|
||||
* (XXX to be checked otherwise introduce locking)
|
||||
*/
|
||||
static struct fc_host_statistics *
|
||||
zfcp_get_fc_host_stats(struct Scsi_Host *shost)
|
||||
{
|
||||
struct zfcp_adapter *adapter;
|
||||
struct fc_host_statistics *fc_stats;
|
||||
struct fsf_qtcb_bottom_port *data;
|
||||
int ret;
|
||||
|
||||
adapter = (struct zfcp_adapter *)shost->hostdata[0];
|
||||
fc_stats = zfcp_init_fc_host_stats(adapter);
|
||||
if (!fc_stats)
|
||||
return NULL;
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data);
|
||||
if (ret) {
|
||||
kfree(data);
|
||||
return NULL; /* XXX return zeroed fc_stats? */
|
||||
}
|
||||
|
||||
if (adapter->stats_reset &&
|
||||
((jiffies/HZ - adapter->stats_reset) <
|
||||
data->seconds_since_last_reset)) {
|
||||
zfcp_adjust_fc_host_stats(fc_stats, data,
|
||||
adapter->stats_reset_data);
|
||||
} else
|
||||
zfcp_set_fc_host_stats(fc_stats, data);
|
||||
|
||||
kfree(data);
|
||||
return fc_stats;
|
||||
}
|
||||
|
||||
static void
|
||||
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 = {
|
||||
.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_name = 1,
|
||||
.show_starget_node_name = 1,
|
||||
.show_rport_supported_classes = 1,
|
||||
.show_host_node_name = 1,
|
||||
.show_host_port_name = 1,
|
||||
.show_host_permanent_port_name = 1,
|
||||
.show_host_supported_classes = 1,
|
||||
.show_host_supported_speeds = 1,
|
||||
.show_host_maxframe_size = 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_port_id = 1,
|
||||
};
|
||||
|
@ -33,14 +33,6 @@
|
||||
|
||||
#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
|
||||
* @_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(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(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",
|
||||
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_STATUS_COMMON_ERP_INUSE, &adapter->status));
|
||||
|
||||
@ -259,9 +247,6 @@ static struct attribute *zfcp_adapter_attrs[] = {
|
||||
&dev_attr_physical_s_id.attr,
|
||||
&dev_attr_card_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_hardware_version.attr,
|
||||
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);
|
||||
|
||||
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_STATUS_COMMON_ERP_INUSE, &port->status));
|
||||
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_in_recovery.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_wwnn.attr,
|
||||
&dev_attr_d_id.attr,
|
||||
&dev_attr_access_denied.attr,
|
||||
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);
|
||||
|
||||
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_STATUS_COMMON_ERP_INUSE, &unit->status));
|
||||
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);
|
||||
|
||||
static struct attribute *zfcp_unit_attrs[] = {
|
||||
&dev_attr_scsi_lun.attr,
|
||||
&dev_attr_failed.attr,
|
||||
&dev_attr_in_recovery.attr,
|
||||
&dev_attr_status.attr,
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.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;
|
||||
|
||||
/* 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;
|
||||
goto out;
|
||||
}
|
||||
@ -852,7 +853,7 @@ out3:
|
||||
/* 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);
|
||||
out2:
|
||||
up(&tw_dev->ioctl_sem);
|
||||
mutex_unlock(&tw_dev->ioctl_lock);
|
||||
out:
|
||||
return retval;
|
||||
} /* 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->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);
|
||||
|
||||
retval = 0;
|
||||
|
@ -672,7 +672,7 @@ typedef struct TAG_TW_Device_Extension {
|
||||
u32 ioctl_msec;
|
||||
int chrdev_request_id;
|
||||
wait_queue_head_t ioctl_wqueue;
|
||||
struct semaphore ioctl_sem;
|
||||
struct mutex ioctl_lock;
|
||||
char aen_clobber;
|
||||
unsigned short working_srl;
|
||||
unsigned short working_branch;
|
||||
|
@ -203,6 +203,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.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");
|
||||
|
||||
/* 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;
|
||||
|
||||
/* First copy down the buffer length */
|
||||
@ -1029,7 +1030,7 @@ out2:
|
||||
/* 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);
|
||||
out:
|
||||
up(&tw_dev->ioctl_sem);
|
||||
mutex_unlock(&tw_dev->ioctl_lock);
|
||||
return retval;
|
||||
} /* 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->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);
|
||||
|
||||
return 0;
|
||||
|
@ -420,7 +420,7 @@ typedef struct TAG_TW_Device_Extension {
|
||||
u32 max_sector_count;
|
||||
u32 aen_count;
|
||||
struct Scsi_Host *host;
|
||||
struct semaphore ioctl_sem;
|
||||
struct mutex ioctl_lock;
|
||||
unsigned short aen_queue[TW_Q_LENGTH];
|
||||
unsigned char aen_head;
|
||||
unsigned char aen_tail;
|
||||
|
@ -2216,6 +2216,7 @@ static int __init BusLogic_init(void)
|
||||
HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
|
||||
HostAdapter->Bus = ProbeInfo->Bus;
|
||||
HostAdapter->Device = ProbeInfo->Device;
|
||||
HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
|
||||
HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
|
||||
HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
|
||||
/*
|
||||
@ -2296,7 +2297,7 @@ static int __init BusLogic_init(void)
|
||||
scsi_host_put(Host);
|
||||
} else {
|
||||
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);
|
||||
BusLogicHostAdapterCount++;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o
|
||||
obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o
|
||||
obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.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_PAS16) += pas16.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
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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))
|
||||
size = le16_to_cpu(kfib->header.SenderSize);
|
||||
if (size > dev->max_fib_size) {
|
||||
if (size > 2048) {
|
||||
retval = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Highjack the hw_fib */
|
||||
hw_fib = fibptr->hw_fib;
|
||||
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_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 ", "AAR-2410SA SATA ", 1 }, /* 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", "ADAPTEC ", "AAR-2810SA SATA ", 1 }, /* 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-2410SA SATA ", 1, AAC_QUIRK_17SG }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
|
||||
{ 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, AAC_QUIRK_17SG }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
|
||||
{ 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 ", "AAR-2610SA ", 1 }, /* SATA 6Ch (Bearcat) */
|
||||
{ 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;
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
return len;
|
||||
}
|
||||
@ -837,6 +853,13 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
|
||||
= (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.
|
||||
*/
|
||||
|
@ -42,13 +42,13 @@ config AIC7XXX_CMDS_PER_DEVICE
|
||||
config AIC7XXX_RESET_DELAY_MS
|
||||
int "Initial bus reset delay in milli-seconds"
|
||||
depends on SCSI_AIC7XXX
|
||||
default "15000"
|
||||
default "5000"
|
||||
---help---
|
||||
The number of milliseconds to delay after an initial bus reset.
|
||||
The bus settle delay following all error recovery actions is
|
||||
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
|
||||
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
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -75,8 +75,7 @@ struct scb_platform_data;
|
||||
#define INITIATOR_WILDCARD (~0)
|
||||
#define SCB_LIST_NULL 0xFF00
|
||||
#define SCB_LIST_NULL_LE (ahd_htole16(SCB_LIST_NULL))
|
||||
#define QOUTFIFO_ENTRY_VALID 0x8000
|
||||
#define QOUTFIFO_ENTRY_VALID_LE (ahd_htole16(0x8000))
|
||||
#define QOUTFIFO_ENTRY_VALID 0x80
|
||||
#define SCBID_IS_NULL(scbid) (((scbid) & 0xFF00 ) == SCB_LIST_NULL)
|
||||
|
||||
#define SCSIID_TARGET(ahd, scsiid) \
|
||||
@ -1053,6 +1052,13 @@ typedef uint8_t ahd_mode_state;
|
||||
|
||||
typedef void ahd_callback_t (void *);
|
||||
|
||||
struct ahd_completion
|
||||
{
|
||||
uint16_t tag;
|
||||
uint8_t sg_status;
|
||||
uint8_t valid_tag;
|
||||
};
|
||||
|
||||
struct ahd_softc {
|
||||
bus_space_tag_t tags[2];
|
||||
bus_space_handle_t bshs[2];
|
||||
@ -1062,6 +1068,7 @@ struct ahd_softc {
|
||||
struct scb_data scb_data;
|
||||
|
||||
struct hardware_scb *next_queued_hscb;
|
||||
struct map_node *next_queued_hscb_map;
|
||||
|
||||
/*
|
||||
* SCBs that have been sent to the controller
|
||||
@ -1140,16 +1147,23 @@ struct ahd_softc {
|
||||
ahd_flag flags;
|
||||
struct seeprom_config *seep_config;
|
||||
|
||||
/* Values to store in the SEQCTL register for pause and unpause */
|
||||
uint8_t unpause;
|
||||
uint8_t pause;
|
||||
|
||||
/* Command Queues */
|
||||
struct ahd_completion *qoutfifo;
|
||||
uint16_t qoutfifonext;
|
||||
uint16_t qoutfifonext_valid_tag;
|
||||
uint16_t qinfifonext;
|
||||
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 */
|
||||
struct cs *critical_sections;
|
||||
@ -1197,8 +1211,7 @@ struct ahd_softc {
|
||||
*/
|
||||
bus_dma_tag_t parent_dmat;
|
||||
bus_dma_tag_t shared_data_dmat;
|
||||
bus_dmamap_t shared_data_dmamap;
|
||||
dma_addr_t shared_data_busaddr;
|
||||
struct map_node shared_data_map;
|
||||
|
||||
/* Information saved through suspend/resume cycles */
|
||||
struct ahd_suspend_state suspend_state;
|
||||
@ -1296,9 +1309,9 @@ struct ahd_devinfo {
|
||||
};
|
||||
|
||||
/****************************** PCI Structures ********************************/
|
||||
#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/
|
||||
#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */
|
||||
#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */
|
||||
#define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/
|
||||
#define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */
|
||||
#define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */
|
||||
|
||||
typedef int (ahd_device_setup_t)(struct ahd_softc *);
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
*
|
||||
* $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
|
||||
@ -65,13 +65,6 @@ VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $"
|
||||
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) \
|
||||
if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) { \
|
||||
mov mode call set_mode_work_around; \
|
||||
@ -1199,7 +1192,7 @@ register TARGPCISTAT {
|
||||
|
||||
/*
|
||||
* LQ Packet In
|
||||
* The last LQ Packet received
|
||||
* The last LQ Packet recieved
|
||||
*/
|
||||
register LQIN {
|
||||
address 0x020
|
||||
@ -3542,10 +3535,34 @@ scratch_ram {
|
||||
COMPLETE_DMA_SCB_HEAD {
|
||||
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 {
|
||||
size 2
|
||||
}
|
||||
KERNEL_QFREEZE_COUNT {
|
||||
size 2
|
||||
}
|
||||
/*
|
||||
* Mode to restore on legacy idle loop exit.
|
||||
*/
|
||||
@ -3624,6 +3641,17 @@ scratch_ram {
|
||||
QOUTFIFO_ENTRY_VALID_TAG {
|
||||
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
|
||||
* memory. This includes the qoutfifo and target mode
|
||||
@ -3639,17 +3667,6 @@ scratch_ram {
|
||||
QOUTFIFO_NEXT_ADDR {
|
||||
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 {
|
||||
size 1
|
||||
mask SEND_MSG 0x80
|
||||
@ -3951,6 +3968,7 @@ const SG_PREFETCH_ADDR_MASK download
|
||||
const SG_SIZEOF download
|
||||
const PKT_OVERRUN_BUFOFFSET download
|
||||
const SCB_TRANSFER_SIZE download
|
||||
const CACHELINE_MASK download
|
||||
|
||||
/*
|
||||
* BIOS SCB offsets
|
||||
|
@ -40,7 +40,7 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#99 $"
|
||||
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#119 $"
|
||||
PATCH_ARG_LIST = "struct ahd_softc *ahd"
|
||||
PREFIX = "ahd_"
|
||||
|
||||
@ -68,13 +68,47 @@ no_error_set:
|
||||
}
|
||||
SET_MODE(M_SCSI, M_SCSI)
|
||||
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;
|
||||
/*
|
||||
* ENSELO is cleared by a SELDO, so we must test for SELDO
|
||||
* one last time.
|
||||
*/
|
||||
BEGIN_CRITICAL;
|
||||
test SSTAT0, SELDO jnz select_out;
|
||||
END_CRITICAL;
|
||||
call start_selection;
|
||||
@ -90,6 +124,13 @@ idle_loop_check_nonpackreq:
|
||||
test SSTAT2, NONPACKREQ jz . + 2;
|
||||
call unexpected_nonpkt_phase_find_ctxt;
|
||||
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;
|
||||
cmp A, FIFO0FREE|FIFO1FREE jne . + 3;
|
||||
and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
|
||||
@ -101,9 +142,9 @@ idle_loop_check_nonpackreq:
|
||||
call idle_loop_cchan;
|
||||
jmp idle_loop;
|
||||
|
||||
BEGIN_CRITICAL;
|
||||
idle_loop_gsfifo:
|
||||
SET_MODE(M_SCSI, M_SCSI)
|
||||
BEGIN_CRITICAL;
|
||||
idle_loop_gsfifo_in_scsi_mode:
|
||||
test LQISTAT2, LQIGSAVAIL jz return;
|
||||
/*
|
||||
@ -152,11 +193,15 @@ END_CRITICAL;
|
||||
|
||||
idle_loop_service_fifos:
|
||||
SET_MODE(M_DFF0, M_DFF0)
|
||||
BEGIN_CRITICAL;
|
||||
test LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;
|
||||
call longjmp;
|
||||
END_CRITICAL;
|
||||
idle_loop_next_fifo:
|
||||
SET_MODE(M_DFF1, M_DFF1)
|
||||
BEGIN_CRITICAL;
|
||||
test LONGJMP_ADDR[1], INVALID_ADDR jz longjmp;
|
||||
END_CRITICAL;
|
||||
return:
|
||||
ret;
|
||||
|
||||
@ -170,7 +215,6 @@ BEGIN_CRITICAL;
|
||||
test CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;
|
||||
test CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;
|
||||
test CCSCBCTL, CCSCBDONE jz return;
|
||||
END_CRITICAL;
|
||||
/* FALLTHROUGH */
|
||||
scbdma_tohost_done:
|
||||
test CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;
|
||||
@ -180,26 +224,18 @@ scbdma_tohost_done:
|
||||
* bad SCSI status (currently only for underruns), we
|
||||
* queue the SCB for normal completion. Otherwise, we
|
||||
* wait until any select-out activity has halted, and
|
||||
* then notify the host so that the transaction can be
|
||||
* dealt with.
|
||||
* then queue the completion.
|
||||
*/
|
||||
test SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;
|
||||
and CCSCBCTL, ~(CCARREN|CCSCBEN);
|
||||
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 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:
|
||||
and CCSCBCTL, ~(CCARREN|CCSCBEN);
|
||||
call qoutfifo_updated;
|
||||
@ -208,6 +244,7 @@ fill_qoutfifo_dmadone:
|
||||
test QOFF_CTLSTA, SDSCB_ROLLOVR jz return;
|
||||
bmov QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4;
|
||||
xor QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;
|
||||
END_CRITICAL;
|
||||
|
||||
qoutfifo_updated:
|
||||
/*
|
||||
@ -324,14 +361,15 @@ fill_qoutfifo:
|
||||
* Keep track of the SCBs we are dmaing just
|
||||
* in case the DMA fails or is aborted.
|
||||
*/
|
||||
mov A, QOUTFIFO_ENTRY_VALID_TAG;
|
||||
bmov COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;
|
||||
mvi CCSCBCTL, CCSCBRESET;
|
||||
bmov SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;
|
||||
mov A, QOUTFIFO_NEXT_ADDR;
|
||||
bmov SCBPTR, COMPLETE_SCB_HEAD, 2;
|
||||
fill_qoutfifo_loop:
|
||||
mov CCSCBRAM, SCBPTR;
|
||||
or CCSCBRAM, A, SCBPTR[1];
|
||||
bmov CCSCBRAM, SCBPTR, 2;
|
||||
mov CCSCBRAM, SCB_SGPTR[0];
|
||||
mov CCSCBRAM, QOUTFIFO_ENTRY_VALID_TAG;
|
||||
mov NONE, SDSCB_QOFF;
|
||||
inc INT_COALESCING_CMDCOUNT;
|
||||
add CMDS_PENDING, -1;
|
||||
@ -339,6 +377,18 @@ fill_qoutfifo_loop:
|
||||
cmp SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;
|
||||
cmp CCSCBADDR, CCSCBADDR_MAX je 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;
|
||||
jmp fill_qoutfifo_loop;
|
||||
fill_qoutfifo_done:
|
||||
@ -354,7 +404,6 @@ dma_complete_scb:
|
||||
bmov SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;
|
||||
bmov SCBHADDR, SCB_BUSADDR, 4;
|
||||
mvi CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb;
|
||||
END_CRITICAL;
|
||||
|
||||
/*
|
||||
* Either post or fetch an SCB from host memory. The caller
|
||||
@ -371,9 +420,19 @@ dma_scb:
|
||||
mvi SCBHCNT, SCB_TRANSFER_SIZE;
|
||||
mov CCSCBCTL, SINDEX ret;
|
||||
|
||||
BEGIN_CRITICAL;
|
||||
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:
|
||||
bmov LONGJMP_ADDR, STACK, 2;
|
||||
longjmp:
|
||||
@ -392,11 +451,6 @@ set_mode_work_around:
|
||||
mvi SEQINTCTL, INTVEC1DSL;
|
||||
mov MODE_PTR, SINDEX;
|
||||
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_DST_MODE M_SCSI;
|
||||
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) {
|
||||
/*
|
||||
* Test to ensure that the bus has not
|
||||
@ -528,6 +597,21 @@ SET_SRC_MODE M_SCSI;
|
||||
SET_DST_MODE M_SCSI;
|
||||
select_out:
|
||||
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. */
|
||||
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
|
||||
* queue and trigger a completion interrupt via the idle loop. Before doing
|
||||
* so, check to see if there
|
||||
* is a residual or the status byte is something other than STATUS_GOOD (0).
|
||||
* In either of these conditions, we upload the SCB back to the host so it can
|
||||
* 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.
|
||||
* so, check to see if there is a residual or the status byte is something
|
||||
* other than STATUS_GOOD (0). In either of these conditions, we upload the
|
||||
* SCB back to the host so it can process this information.
|
||||
*/
|
||||
mesgin_complete:
|
||||
|
||||
@ -1053,6 +1131,7 @@ complete_nomsg:
|
||||
call queue_scb_completion;
|
||||
jmp await_busfree;
|
||||
|
||||
BEGIN_CRITICAL;
|
||||
freeze_queue:
|
||||
/* Cancel any pending select-out. */
|
||||
test SSTAT0, SELDO|SELINGO jnz . + 2;
|
||||
@ -1063,6 +1142,7 @@ freeze_queue:
|
||||
adc QFREEZE_COUNT[1], A;
|
||||
or SEQ_FLAGS2, SELECTOUT_QFROZEN;
|
||||
mov A, ACCUM_SAVE ret;
|
||||
END_CRITICAL;
|
||||
|
||||
/*
|
||||
* 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_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;
|
||||
complete:
|
||||
BEGIN_CRITICAL;
|
||||
bmov SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;
|
||||
bmov COMPLETE_SCB_HEAD, SCBPTR, 2 ret;
|
||||
END_CRITICAL;
|
||||
bad_status:
|
||||
cmp SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;
|
||||
call freeze_queue;
|
||||
@ -1097,9 +1179,18 @@ upload_scb:
|
||||
* it on the host.
|
||||
*/
|
||||
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;
|
||||
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
|
||||
@ -1146,8 +1237,18 @@ SET_DST_MODE M_DFF1;
|
||||
await_busfree_clrchn:
|
||||
mvi DFFSXFRCTL, CLRCHN;
|
||||
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 .;
|
||||
/*
|
||||
* 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;
|
||||
SET_SEQINTCODE(MISSED_BUSFREE)
|
||||
|
||||
@ -1202,11 +1303,6 @@ msgin_rdptrs_get_fifo:
|
||||
call allocate_fifo;
|
||||
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:
|
||||
if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {
|
||||
/*
|
||||
@ -1297,6 +1393,47 @@ service_fifo:
|
||||
/* Are we actively fetching segments? */
|
||||
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
|
||||
* so we don't end up referencing a non-existant page.
|
||||
@ -1308,7 +1445,7 @@ service_fifo:
|
||||
mvi SGHCNT, SG_PREFETCH_CNT;
|
||||
if ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0) {
|
||||
/*
|
||||
* Need two instruction between "touches" of SGHADDR.
|
||||
* Need two instructions between "touches" of SGHADDR.
|
||||
*/
|
||||
nop;
|
||||
}
|
||||
@ -1658,7 +1795,7 @@ export seq_isr:
|
||||
* savepointer in the current FIFO. We do this so that
|
||||
* a pending CTXTDONE or SAVEPTR is visible in the active
|
||||
* 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
|
||||
* already seen and acked (REQINIT never comes true).
|
||||
*/
|
||||
@ -1667,7 +1804,7 @@ export seq_isr:
|
||||
test DFCNTRL, DIRECTION jz interrupt_return;
|
||||
and DFCNTRL, ~SCSIEN;
|
||||
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;
|
||||
snapshot_data_valid:
|
||||
or DFCNTRL, SCSIEN;
|
||||
@ -1834,7 +1971,6 @@ pkt_saveptrs_check_status:
|
||||
dec SCB_FIFO_USE_COUNT;
|
||||
test SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;
|
||||
mvi DFFSXFRCTL, CLRCHN ret;
|
||||
END_CRITICAL;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
pkt_last_seg_done:
|
||||
BEGIN_CRITICAL;
|
||||
/*
|
||||
* Mark transfer as completed.
|
||||
*/
|
||||
|
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
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -522,12 +522,21 @@ do { \
|
||||
static __inline uint16_t
|
||||
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));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
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+1, (value >> 8) & 0xFF);
|
||||
}
|
||||
@ -684,7 +693,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset)
|
||||
* Razor #528
|
||||
*/
|
||||
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);
|
||||
return (value);
|
||||
}
|
||||
@ -727,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_int tag)
|
||||
static __inline void
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -743,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb)
|
||||
* locate the correct SCB by SCB_TAG.
|
||||
*/
|
||||
q_hscb = ahd->next_queued_hscb;
|
||||
q_hscb_map = ahd->next_queued_hscb_map;
|
||||
saved_hscb_busaddr = q_hscb->hscb_busaddr;
|
||||
memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
|
||||
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. */
|
||||
ahd->next_queued_hscb = scb->hscb;
|
||||
ahd->next_queued_hscb_map = scb->hscb_map;
|
||||
scb->hscb = q_hscb;
|
||||
scb->hscb_map = q_hscb_map;
|
||||
|
||||
/* Now define the mapping from tag to SCB in the scbindex */
|
||||
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
|
||||
ahd_sync_qoutfifo(struct ahd_softc *ahd, int op)
|
||||
{
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
|
||||
/*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op);
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
|
||||
/*offset*/0,
|
||||
/*len*/AHD_SCB_MAX * sizeof(struct ahd_completion), op);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
@ -834,7 +848,7 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd, int op)
|
||||
#ifdef AHD_TARGET_MODE
|
||||
if ((ahd->flags & AHD_TARGETROLE) != 0) {
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
|
||||
ahd->shared_data_dmamap,
|
||||
ahd->shared_data_map.dmamap,
|
||||
ahd_targetcmd_offset(ahd, 0),
|
||||
sizeof(struct target_cmd) * AHD_TMODE_CMDS,
|
||||
op);
|
||||
@ -854,17 +868,17 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd)
|
||||
u_int retval;
|
||||
|
||||
retval = 0;
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap,
|
||||
/*offset*/ahd->qoutfifonext, /*len*/2,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
if ((ahd->qoutfifo[ahd->qoutfifonext]
|
||||
& QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag)
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap,
|
||||
/*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo),
|
||||
/*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD);
|
||||
if (ahd->qoutfifo[ahd->qoutfifonext].valid_tag
|
||||
== ahd->qoutfifonext_valid_tag)
|
||||
retval |= AHD_RUN_QOUTFIFO;
|
||||
#ifdef AHD_TARGET_MODE
|
||||
if ((ahd->flags & AHD_TARGETROLE) != 0
|
||||
&& (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) {
|
||||
ahd_dmamap_sync(ahd, ahd->shared_data_dmat,
|
||||
ahd->shared_data_dmamap,
|
||||
ahd->shared_data_map.dmamap,
|
||||
ahd_targetcmd_offset(ahd, ahd->tqinfifofnext),
|
||||
/*len*/sizeof(struct target_cmd),
|
||||
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) {
|
||||
scb->flags |= SCB_AUTO_NEGOTIATE;
|
||||
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) {
|
||||
@ -2058,6 +2082,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
|
||||
int paused;
|
||||
int wait;
|
||||
int disconnected;
|
||||
int found;
|
||||
ahd_mode_state saved_modes;
|
||||
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);
|
||||
saved_scbptr = ahd_get_scbptr(ahd);
|
||||
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;
|
||||
|
||||
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.
|
||||
*/
|
||||
saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
|
||||
if (last_phase != P_BUSFREE
|
||||
&& (SCB_GET_TAG(pending_scb) == active_scbptr
|
||||
if (SCB_GET_TAG(pending_scb) == active_scbptr
|
||||
|| (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
|
||||
* and hope that the target responds.
|
||||
*/
|
||||
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, 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;
|
||||
} 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) {
|
||||
|
||||
/*
|
||||
* Actually re-queue this SCB in an attempt
|
||||
* 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));
|
||||
pending_scb->hscb->cdb_len = 0;
|
||||
pending_scb->hscb->task_attribute = 0;
|
||||
@ -2296,16 +2335,17 @@ done:
|
||||
timer.expires = jiffies + (5 * HZ);
|
||||
timer.function = ahd_linux_sem_timeout;
|
||||
add_timer(&timer);
|
||||
printf("Recovery code sleeping\n");
|
||||
printf("%s: Recovery code sleeping\n", ahd_name(ahd));
|
||||
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);
|
||||
if (ret == 0) {
|
||||
printf("Timer Expired\n");
|
||||
printf("%s: Timer Expired (active %d)\n",
|
||||
ahd_name(ahd), dev->active);
|
||||
retval = FAILED;
|
||||
}
|
||||
}
|
||||
ahd_unlock(ahd, &flags);
|
||||
ahd_unlock(ahd, &flags);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
|
||||
/***************************** SMP support ************************************/
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define AIC79XX_DRIVER_VERSION "1.3.11"
|
||||
#define AIC79XX_DRIVER_VERSION "3.0"
|
||||
|
||||
/*************************** Device Data Structures ***************************/
|
||||
/*
|
||||
|
@ -38,9 +38,7 @@
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#77 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#89 $
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
@ -114,6 +112,13 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
|
||||
"Adaptec 29320ALP Ultra320 SCSI adapter",
|
||||
ahd_aic7901_setup
|
||||
},
|
||||
/* aic7901A based controllers */
|
||||
{
|
||||
ID_AHA_29320LP,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 29320LP Ultra320 SCSI adapter",
|
||||
ahd_aic7901A_setup
|
||||
},
|
||||
/* aic7902 based controllers */
|
||||
{
|
||||
ID_AHA_29320,
|
||||
@ -127,12 +132,6 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
|
||||
"Adaptec 29320B Ultra320 SCSI adapter",
|
||||
ahd_aic7902_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_29320LP,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 29320LP Ultra320 SCSI adapter",
|
||||
ahd_aic7901A_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_39320,
|
||||
ID_ALL_MASK,
|
||||
@ -145,6 +144,12 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
|
||||
"Adaptec 39320 Ultra320 SCSI adapter",
|
||||
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_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.
|
||||
*/
|
||||
sxfrctl1 = ahd_inb(ahd, SXFRCTL1) & ~STPWEN;
|
||||
ahd->flags &= ~AHD_TERM_ENB_A;
|
||||
if ((termctl & FLX_TERMCTL_ENPRILOW) != 0) {
|
||||
ahd->flags |= AHD_TERM_ENB_A;
|
||||
sxfrctl1 |= STPWEN;
|
||||
|
@ -53,14 +53,15 @@
|
||||
#define ID_AHA_29320ALP 0x8017900500449005ull
|
||||
|
||||
#define ID_AIC7901A 0x801E9005FFFF9005ull
|
||||
#define ID_AHA_29320 0x8012900500429005ull
|
||||
#define ID_AHA_29320B 0x8013900500439005ull
|
||||
#define ID_AHA_29320LP 0x8014900500449005ull
|
||||
|
||||
#define ID_AIC7902 0x801F9005FFFF9005ull
|
||||
#define ID_AIC7902_B 0x801D9005FFFF9005ull
|
||||
#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_DELL 0x8015900501681028ull
|
||||
#define ID_AHA_39320A 0x8016900500409005ull
|
||||
#define ID_AHA_39320D 0x8011900500419005ull
|
||||
#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
|
||||
* from the following source files:
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#94 $
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#70 $
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#118 $
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#75 $
|
||||
*/
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "SEQ_SPLTINT", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -859,21 +859,6 @@ ahd_selid_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
|
||||
{ "AUTO_MSGOUT_DE", 0x02, 0x02 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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 }
|
||||
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_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",
|
||||
0x4b, regvalue, cur_col, wrap));
|
||||
return (ahd_print_register(SBLKCTL_parse_table, 5, "SBLKCTL",
|
||||
0x4a, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "ENARBDO", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "CLRDMADONE", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "DTERR", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "LQOTCRC", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "LQOPHACHGINPKT", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "LQOSTOP0", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "LSTSGCLRDIS", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -1787,13 +1787,6 @@ ahd_hodmaen_print(u_int regvalue, u_int *cur_col, u_int 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
|
||||
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
|
||||
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",
|
||||
0x84, regvalue, cur_col, wrap));
|
||||
return (ahd_print_register(NULL, 0, "SGHADDR",
|
||||
0x7c, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
@ -1815,6 +1808,13 @@ ahd_scbhcnt_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
|
||||
{ "WR_DFTHRSH_MIN", 0x00, 0x70 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -2101,24 +2101,6 @@ ahd_cmcspltstat0_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
|
||||
{ "RXSPLTRSP", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
static ahd_reg_parse_entry_t DCHSPLTSTAT1_parse_table[] = {
|
||||
{ "RXDATABUCKET", 0x01, 0x01 }
|
||||
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_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",
|
||||
0x97, regvalue, cur_col, wrap));
|
||||
return (ahd_print_register(OVLYSPLTSTAT0_parse_table, 8, "OVLYSPLTSTAT0",
|
||||
0x96, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "CFNUM", 0x07, 0x07 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "TEST_NUM", 0x0f, 0x0f },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "DPR", 0x01, 0x01 },
|
||||
{ "TWATERR", 0x02, 0x02 },
|
||||
@ -2537,16 +2537,16 @@ ahd_ccsgaddr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -2566,22 +2566,6 @@ ahd_cmc_rambist_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
|
||||
{ "CCSCBRESET", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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",
|
||||
0xc9, regvalue, cur_col, wrap));
|
||||
return (ahd_print_register(NULL, 0, "DFPTRS",
|
||||
0xc8, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
@ -2868,6 +2861,13 @@ ahd_skewcalc_print(u_int regvalue, u_int *cur_col, u_int 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[] = {
|
||||
{ "DFF_RAMBIST_EN", 0x01, 0x01 },
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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[] = {
|
||||
{ "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));
|
||||
}
|
||||
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
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",
|
||||
0xf6, regvalue, cur_col, wrap));
|
||||
return (ahd_print_register(NULL, 0, "CURADDR",
|
||||
0xf4, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
@ -3096,6 +3089,13 @@ ahd_lastaddr_print(u_int regvalue, u_int *cur_col, u_int 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
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
ahd_qfreeze_count_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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
|
||||
ahd_saved_mode_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "SAVED_MODE",
|
||||
0x130, regvalue, cur_col, wrap));
|
||||
0x136, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_msg_out_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3211,7 +3232,7 @@ int
|
||||
ahd_dmaparams_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3230,21 +3251,21 @@ int
|
||||
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",
|
||||
0x133, regvalue, cur_col, wrap));
|
||||
0x139, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_saved_scsiid_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "SAVED_SCSIID",
|
||||
0x134, regvalue, cur_col, wrap));
|
||||
0x13a, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_saved_lun_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3267,42 +3288,42 @@ int
|
||||
ahd_lastphase_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(LASTPHASE_parse_table, 13, "LASTPHASE",
|
||||
0x136, regvalue, cur_col, wrap));
|
||||
0x13c, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
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",
|
||||
0x137, 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));
|
||||
0x13d, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_kernel_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "KERNEL_TQINPOS",
|
||||
0x140, regvalue, cur_col, wrap));
|
||||
0x13e, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_tqinpos_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3320,21 +3341,21 @@ int
|
||||
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",
|
||||
0x142, regvalue, cur_col, wrap));
|
||||
0x148, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_arg_2_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "ARG_2",
|
||||
0x143, regvalue, cur_col, wrap));
|
||||
0x149, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_last_msg_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3350,14 +3371,14 @@ int
|
||||
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",
|
||||
0x145, regvalue, cur_col, wrap));
|
||||
0x14b, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_initiator_tag_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
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[] = {
|
||||
@ -3369,63 +3390,63 @@ int
|
||||
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",
|
||||
0x147, regvalue, cur_col, wrap));
|
||||
0x14d, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_allocfifo_scbptr_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "ALLOCFIFO_SCBPTR",
|
||||
0x148, regvalue, cur_col, wrap));
|
||||
0x14e, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_int_coalescing_timer_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_TIMER",
|
||||
0x14a, regvalue, cur_col, wrap));
|
||||
0x150, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_int_coalescing_maxcmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_MAXCMDS",
|
||||
0x14c, regvalue, cur_col, wrap));
|
||||
0x152, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_int_coalescing_mincmds_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_MINCMDS",
|
||||
0x14d, regvalue, cur_col, wrap));
|
||||
0x153, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_cmds_pending_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "CMDS_PENDING",
|
||||
0x14e, regvalue, cur_col, wrap));
|
||||
0x154, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_int_coalescing_cmdcount_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "INT_COALESCING_CMDCOUNT",
|
||||
0x150, regvalue, cur_col, wrap));
|
||||
0x156, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_local_hs_mailbox_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "LOCAL_HS_MAILBOX",
|
||||
0x151, regvalue, cur_col, wrap));
|
||||
0x157, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
int
|
||||
ahd_cmdsize_table_print(u_int regvalue, u_int *cur_col, u_int wrap)
|
||||
{
|
||||
return (ahd_print_register(NULL, 0, "CMDSIZE_TABLE",
|
||||
0x152, regvalue, cur_col, wrap));
|
||||
0x158, regvalue, cur_col, wrap));
|
||||
}
|
||||
|
||||
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);
|
||||
static void ahc_linux_sem_timeout(u_long arg);
|
||||
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 void ahc_linux_initialize_scsi_bus(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);
|
||||
|
||||
*((struct ahc_softc **)host->hostdata) = ahc;
|
||||
ahc_lock(ahc, &s);
|
||||
ahc->platform_data->host = host;
|
||||
host->can_queue = AHC_MAX_QUEUE;
|
||||
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_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
|
||||
host->sg_tablesize = AHC_NSEG;
|
||||
ahc_lock(ahc, &s);
|
||||
ahc_set_unit(ahc, ahc_linux_unit++);
|
||||
ahc_unlock(ahc, &s);
|
||||
sprintf(buf, "scsi%d", host->host_no);
|
||||
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
|
||||
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;
|
||||
ahc_linux_initialize_scsi_bus(ahc);
|
||||
ahc_intr_enable(ahc, TRUE);
|
||||
ahc_unlock(ahc, &s);
|
||||
|
||||
host->transportt = ahc_linux_transport_template;
|
||||
|
||||
@ -1120,10 +1120,13 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
|
||||
{
|
||||
int i;
|
||||
int numtarg;
|
||||
unsigned long s;
|
||||
|
||||
i = 0;
|
||||
numtarg = 0;
|
||||
|
||||
ahc_lock(ahc, &s);
|
||||
|
||||
if (aic7xxx_no_reset != 0)
|
||||
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,
|
||||
tinfo, AHC_NEG_ALWAYS);
|
||||
}
|
||||
ahc_unlock(ahc, &s);
|
||||
/* Give the bus some time to recover */
|
||||
if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
|
||||
ahc_linux_freeze_simq(ahc);
|
||||
init_timer(&ahc->platform_data->reset_timer);
|
||||
ahc->platform_data->reset_timer.data = (u_long)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);
|
||||
msleep(AIC7XXX_RESET_DELAY);
|
||||
ahc_linux_release_simq(ahc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2059,6 +2058,9 @@ ahc_linux_sem_timeout(u_long arg)
|
||||
static void
|
||||
ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
||||
{
|
||||
unsigned long s;
|
||||
|
||||
ahc_lock(ahc, &s);
|
||||
ahc->platform_data->qfrozen++;
|
||||
if (ahc->platform_data->qfrozen == 1) {
|
||||
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,
|
||||
ROLE_INITIATOR, CAM_REQUEUE_REQ);
|
||||
}
|
||||
ahc_unlock(ahc, &s);
|
||||
}
|
||||
|
||||
static void
|
||||
ahc_linux_release_simq(u_long arg)
|
||||
ahc_linux_release_simq(struct ahc_softc *ahc)
|
||||
{
|
||||
struct ahc_softc *ahc;
|
||||
u_long s;
|
||||
int unblock_reqs;
|
||||
|
||||
ahc = (struct ahc_softc *)arg;
|
||||
|
||||
unblock_reqs = 0;
|
||||
ahc_lock(ahc, &s);
|
||||
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)
|
||||
|
||||
/************************** Timer DataStructures ******************************/
|
||||
typedef struct timer_list ahc_timer_t;
|
||||
|
||||
/********************************** Includes **********************************/
|
||||
#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
|
||||
#define AIC_DEBUG_REGISTERS 1
|
||||
@ -235,30 +232,9 @@ typedef struct timer_list ahc_timer_t;
|
||||
#include "aic7xxx.h"
|
||||
|
||||
/***************************** 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
|
||||
ahc_scb_timer_reset(struct scb *scb, u_int usec)
|
||||
{
|
||||
mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
|
||||
}
|
||||
|
||||
/***************************** SMP support ************************************/
|
||||
@ -393,7 +369,6 @@ struct ahc_platform_data {
|
||||
|
||||
spinlock_t spin_lock;
|
||||
u_int qfrozen;
|
||||
struct timer_list reset_timer;
|
||||
struct semaphore eh_sem;
|
||||
struct Scsi_Host *host; /* pointer to scsi host */
|
||||
#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
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#69 $
|
||||
*
|
||||
* $FreeBSD$
|
||||
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#79 $
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
@ -393,6 +391,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
||||
"Adaptec aic7892 Ultra160 SCSI adapter (ARO)",
|
||||
ahc_aic7892_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_2915_30LP,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 2915/30LP Ultra160 SCSI adapter",
|
||||
ahc_aic7892_setup
|
||||
},
|
||||
/* aic7895 based controllers */
|
||||
{
|
||||
ID_AHA_2940U_DUAL,
|
||||
@ -1193,9 +1197,19 @@ ahc_pci_test_register_access(struct ahc_softc *ahc)
|
||||
* use for this test.
|
||||
*/
|
||||
hcntrl = ahc_inb(ahc, HCNTRL);
|
||||
|
||||
if (hcntrl == 0xFF)
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
ahc_release_seeprom(&sd);
|
||||
|
||||
/* Remember the SEEPROM type for later */
|
||||
if (sd.sd_chip == C56_66)
|
||||
ahc->flags |= AHC_LARGE_SEEPROM;
|
||||
}
|
||||
|
||||
if (!have_seeprom) {
|
||||
|
@ -105,6 +105,7 @@
|
||||
#define ID_AHA_29160C 0x0080900562209005ull
|
||||
#define ID_AHA_29160B 0x00809005E2209005ull
|
||||
#define ID_AHA_19160B 0x0081900562A19005ull
|
||||
#define ID_AHA_2915_30LP 0x0082900502109005ull
|
||||
|
||||
#define ID_AIC7896 0x005F9005FFFF9005ull
|
||||
#define ID_AIC7896_ARO 0x00539005FFFF9005ull
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/chio.h> /* here are all the ioctls */
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@ -111,7 +112,7 @@ typedef struct {
|
||||
u_int counts[CH_TYPES];
|
||||
u_int unit_attention;
|
||||
u_int voltags;
|
||||
struct semaphore lock;
|
||||
struct mutex lock;
|
||||
} scsi_changer;
|
||||
|
||||
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];
|
||||
unsigned int i;
|
||||
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
for (i = 0; i < ch->counts[type]; i++) {
|
||||
if (0 != ch_read_element_status
|
||||
(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)
|
||||
break;
|
||||
}
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -687,11 +688,11 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
dprintk("CHIOPOSITION: invalid parameter\n");
|
||||
return -EBADSLT;
|
||||
}
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
retval = ch_position(ch,0,
|
||||
ch->firsts[pos.cp_type] + pos.cp_unit,
|
||||
pos.cp_flags & CP_INVERT);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -708,12 +709,12 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
return -EBADSLT;
|
||||
}
|
||||
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
retval = ch_move(ch,0,
|
||||
ch->firsts[mv.cm_fromtype] + mv.cm_fromunit,
|
||||
ch->firsts[mv.cm_totype] + mv.cm_tounit,
|
||||
mv.cm_flags & CM_INVERT);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -731,14 +732,14 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
return -EBADSLT;
|
||||
}
|
||||
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
retval = ch_exchange
|
||||
(ch,0,
|
||||
ch->firsts[mv.ce_srctype] + mv.ce_srcunit,
|
||||
ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit,
|
||||
ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit,
|
||||
mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -772,7 +773,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
|
||||
voltag_retry:
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
@ -823,7 +824,7 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
goto voltag_retry;
|
||||
}
|
||||
kfree(buffer);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
|
||||
if (copy_to_user(argp, &cge, sizeof (cge)))
|
||||
return -EFAULT;
|
||||
@ -832,9 +833,9 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
|
||||
case CHIOINITELEM:
|
||||
{
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
retval = ch_init_elem(ch);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -851,12 +852,12 @@ static int ch_ioctl(struct inode * inode, struct file * file,
|
||||
return -EBADSLT;
|
||||
}
|
||||
elem = ch->firsts[csv.csv_type] + csv.csv_unit;
|
||||
down(&ch->lock);
|
||||
mutex_lock(&ch->lock);
|
||||
retval = ch_set_voltag(ch, elem,
|
||||
csv.csv_flags & CSV_AVOLTAG,
|
||||
csv.csv_flags & CSV_CLEARTAG,
|
||||
csv.csv_voltag);
|
||||
up(&ch->lock);
|
||||
mutex_unlock(&ch->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -929,7 +930,7 @@ static int ch_probe(struct device *dev)
|
||||
memset(ch,0,sizeof(*ch));
|
||||
ch->minor = ch_devcount;
|
||||
sprintf(ch->name,"ch%d",ch->minor);
|
||||
init_MUTEX(&ch->lock);
|
||||
mutex_init(&ch->lock);
|
||||
ch->device = sd;
|
||||
ch_readconfig(ch);
|
||||
if (init)
|
||||
|
@ -61,6 +61,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
|
||||
#include <linux/timer.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <asm/processor.h> /* for boot_cpu_data */
|
||||
#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 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
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||
if (pHba->host == host) {
|
||||
break; /* found adapter */
|
||||
}
|
||||
}
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
if (pHba == NULL) {
|
||||
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)) {
|
||||
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);
|
||||
if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if (!base_addr_virt) {
|
||||
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));
|
||||
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
|
||||
if(hba_chain != NULL){
|
||||
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);
|
||||
hba_count++;
|
||||
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
|
||||
pHba->pDev = pDev;
|
||||
pHba->base_addr_phys = base_addr0_phys;
|
||||
@ -1027,7 +1030,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
||||
struct adpt_device* pNext;
|
||||
|
||||
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
// scsi_unregister calls our adpt_release which
|
||||
// does a quiese
|
||||
if(pHba->host){
|
||||
@ -1046,7 +1049,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
|
||||
}
|
||||
|
||||
hba_count--;
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
|
||||
iounmap(pHba->base_addr_virt);
|
||||
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)
|
||||
{
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
d->controller=pHba;
|
||||
d->owner=NULL;
|
||||
d->next=pHba->devices;
|
||||
@ -1560,7 +1563,7 @@ static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
|
||||
pHba->devices=d;
|
||||
*d->dev_name = 0;
|
||||
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1575,24 +1578,24 @@ static int adpt_open(struct inode *inode, struct file *file)
|
||||
if (minor >= hba_count) {
|
||||
return -ENXIO;
|
||||
}
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||
if (pHba->unit == minor) {
|
||||
break; /* found adapter */
|
||||
}
|
||||
}
|
||||
if (pHba == NULL) {
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
// if(pHba->in_use){
|
||||
// up(&adpt_configuration_lock);
|
||||
// mutex_unlock(&adpt_configuration_lock);
|
||||
// return -EBUSY;
|
||||
// }
|
||||
|
||||
pHba->in_use = 1;
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1606,13 +1609,13 @@ static int adpt_close(struct inode *inode, struct file *file)
|
||||
if (minor >= hba_count) {
|
||||
return -ENXIO;
|
||||
}
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||
if (pHba->unit == minor) {
|
||||
break; /* found adapter */
|
||||
}
|
||||
}
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
if (pHba == NULL) {
|
||||
return -ENXIO;
|
||||
}
|
||||
@ -1910,13 +1913,13 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
|
||||
if (minor >= DPTI_MAX_HBA){
|
||||
return -ENXIO;
|
||||
}
|
||||
down(&adpt_configuration_lock);
|
||||
mutex_lock(&adpt_configuration_lock);
|
||||
for (pHba = hba_chain; pHba; pHba = pHba->next) {
|
||||
if (pHba->unit == minor) {
|
||||
break; /* found adapter */
|
||||
}
|
||||
}
|
||||
up(&adpt_configuration_lock);
|
||||
mutex_unlock(&adpt_configuration_lock);
|
||||
if(pHba == NULL){
|
||||
return -ENXIO;
|
||||
}
|
||||
|
@ -156,16 +156,16 @@ EXPORT_SYMBOL(scsi_host_set_state);
|
||||
void scsi_remove_host(struct Scsi_Host *shost)
|
||||
{
|
||||
unsigned long flags;
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL))
|
||||
if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
scsi_forget_host(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_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->dma_channel = 0xff;
|
||||
|
@ -1319,6 +1319,9 @@ ips_slave_configure(struct scsi_device * SDptr)
|
||||
min = ha->max_cmds - 1;
|
||||
scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
|
||||
}
|
||||
|
||||
SDptr->skip_ms_page_8 = 1;
|
||||
SDptr->skip_ms_page_3f = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <net/tcp.h>
|
||||
#include <scsi/scsi_cmnd.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);
|
||||
ibuf->sent = 0;
|
||||
ibuf->use_sendmsg = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
|
||||
{
|
||||
ibuf->sg.page = (void*)vbuf;
|
||||
ibuf->sg.offset = (unsigned int)-1;
|
||||
ibuf->sg.page = virt_to_page(vbuf);
|
||||
ibuf->sg.offset = offset_in_page(vbuf);
|
||||
ibuf->sg.length = size;
|
||||
ibuf->sent = 0;
|
||||
}
|
||||
|
||||
static inline void*
|
||||
iscsi_buf_iov_base(struct iscsi_buf *ibuf)
|
||||
{
|
||||
return (char*)ibuf->sg.page + ibuf->sent;
|
||||
ibuf->use_sendmsg = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
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
|
||||
*/
|
||||
if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) {
|
||||
ibuf->sg.page = sg->page;
|
||||
ibuf->sg.offset = sg->offset;
|
||||
ibuf->sg.length = sg->length;
|
||||
} else
|
||||
iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length);
|
||||
if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
|
||||
ibuf->use_sendmsg = 0;
|
||||
else
|
||||
ibuf->use_sendmsg = 1;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (res_count > 0 &&
|
||||
@ -366,9 +364,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||
} else
|
||||
sc->result = (DID_BAD_TARGET << 16) |
|
||||
rhdr->cmd_status;
|
||||
} else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW)
|
||||
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
|
||||
else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
|
||||
} else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) {
|
||||
sc->resid = be32_to_cpu(rhdr->residual_count);
|
||||
sc->result = (DID_OK << 16) | rhdr->cmd_status;
|
||||
} 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(conn->writequeue, (void*)&ctask, sizeof(void*));
|
||||
|
||||
schedule_work(&conn->xmitwork);
|
||||
scsi_queue_work(session->host, &conn->xmitwork);
|
||||
conn->r2t_pdus_cnt++;
|
||||
spin_unlock(&session->lock);
|
||||
|
||||
@ -686,7 +682,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
||||
switch(conn->in.opcode) {
|
||||
case ISCSI_OP_LOGIN_RSP:
|
||||
case ISCSI_OP_TEXT_RSP:
|
||||
case ISCSI_OP_LOGOUT_RSP:
|
||||
case ISCSI_OP_LOGOUT_RSP:
|
||||
rc = iscsi_check_assign_cmdsn(session,
|
||||
(struct iscsi_nopin*)hdr);
|
||||
if (rc)
|
||||
@ -727,12 +723,12 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
||||
}
|
||||
spin_unlock(&session->lock);
|
||||
break;
|
||||
case ISCSI_OP_NOOP_IN:
|
||||
case ISCSI_OP_NOOP_IN:
|
||||
if (hdr->ttt != ISCSI_RESERVED_TAG) {
|
||||
rc = ISCSI_ERR_PROTO;
|
||||
break;
|
||||
}
|
||||
rc = iscsi_check_assign_cmdsn(session,
|
||||
rc = iscsi_check_assign_cmdsn(session,
|
||||
(struct iscsi_nopin*)hdr);
|
||||
if (rc)
|
||||
break;
|
||||
@ -767,7 +763,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn)
|
||||
if (!rc && hdr->ttt != ISCSI_RESERVED_TAG)
|
||||
rc = iscsi_recv_pdu(iscsi_handle(conn),
|
||||
hdr, NULL, 0);
|
||||
} else
|
||||
} else
|
||||
rc = ISCSI_ERR_PROTO;
|
||||
break;
|
||||
case ISCSI_OP_REJECT:
|
||||
@ -929,7 +925,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
|
||||
sc->request_bufflen, ctask->data_offset);
|
||||
if (rc == -EAGAIN)
|
||||
return rc;
|
||||
if (conn->datadgst_en)
|
||||
if (conn->datadgst_en)
|
||||
iscsi_recv_digest_update(conn, sc->request_buffer, i);
|
||||
rc = 0;
|
||||
goto done;
|
||||
@ -1024,7 +1020,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
|
||||
conn->in.hdr = &conn->hdr;
|
||||
conn->senselen = (conn->data[0] << 8) | conn->data[1];
|
||||
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,
|
||||
conn->in.datalen);
|
||||
}
|
||||
@ -1051,7 +1047,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
|
||||
rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
|
||||
conn->data, conn->in.datalen);
|
||||
|
||||
if (!rc && conn->datadgst_en &&
|
||||
if (!rc && conn->datadgst_en &&
|
||||
conn->in.opcode != ISCSI_OP_LOGIN_RSP)
|
||||
iscsi_recv_digest_update(conn, conn->data,
|
||||
conn->in.datalen);
|
||||
@ -1271,7 +1267,7 @@ iscsi_write_space(struct sock *sk)
|
||||
conn->old_write_space(sk);
|
||||
debug_tcp("iscsi_write_space: cid %d\n", conn->id);
|
||||
clear_bit(SUSPEND_BIT, &conn->suspend_tx);
|
||||
schedule_work(&conn->xmitwork);
|
||||
scsi_queue_work(conn->session->host, &conn->xmitwork);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1312,35 +1308,25 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn)
|
||||
* @buf: buffer to write from
|
||||
* @size: actual size to write
|
||||
* @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
|
||||
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;
|
||||
|
||||
/* tcp_sendpage */
|
||||
res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags);
|
||||
} else {
|
||||
struct msghdr msg;
|
||||
|
||||
buf->iov.iov_base = iscsi_buf_iov_base(buf);
|
||||
buf->iov.iov_len = size;
|
||||
|
||||
memset(&msg, 0, sizeof(struct msghdr));
|
||||
|
||||
/* tcp_sendmsg */
|
||||
res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size);
|
||||
}
|
||||
|
||||
return res;
|
||||
/*
|
||||
* if we got use_sg=0 or are sending something we kmallocd
|
||||
* then we did not have to do kmap (kmap returns page_address)
|
||||
*
|
||||
* if we got use_sg > 0, but had to drop down, we do not
|
||||
* set clustering so this should only happen for that
|
||||
* slab case.
|
||||
*/
|
||||
if (buf->use_sendmsg)
|
||||
return sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
|
||||
else
|
||||
return conn->sendpage(sk, buf->sg.page, offset, size, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1355,7 +1341,6 @@ iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags)
|
||||
static inline int
|
||||
iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen)
|
||||
{
|
||||
struct socket *sk = conn->sock;
|
||||
int flags = 0; /* MSG_DONTWAIT; */
|
||||
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)
|
||||
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);
|
||||
if (res >= 0) {
|
||||
conn->txdata_octets += res;
|
||||
@ -1395,7 +1380,6 @@ static inline int
|
||||
iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
|
||||
int *count, int *sent)
|
||||
{
|
||||
struct socket *sk = conn->sock;
|
||||
int flags = 0; /* MSG_DONTWAIT; */
|
||||
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)
|
||||
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",
|
||||
size, buf->sent, *count, *sent, res);
|
||||
if (res >= 0) {
|
||||
@ -1434,19 +1418,6 @@ iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||
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
|
||||
iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
|
||||
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);
|
||||
}
|
||||
|
||||
iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
|
||||
iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr,
|
||||
sizeof(struct iscsi_hdr));
|
||||
conn->scsicmd_pdus_cnt++;
|
||||
}
|
||||
@ -1746,7 +1717,7 @@ static inline int
|
||||
handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||
{
|
||||
ctask->xmstate &= ~XMSTATE_R_HDR;
|
||||
if (conn->hdrdgst_en)
|
||||
if (conn->hdrdgst_en)
|
||||
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
||||
if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) {
|
||||
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)
|
||||
{
|
||||
ctask->xmstate &= ~XMSTATE_W_HDR;
|
||||
if (conn->hdrdgst_en)
|
||||
if (conn->hdrdgst_en)
|
||||
iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext);
|
||||
if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) {
|
||||
ctask->xmstate |= XMSTATE_W_HDR;
|
||||
@ -1809,7 +1780,8 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||
return -EAGAIN;
|
||||
}
|
||||
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)
|
||||
break;
|
||||
@ -1894,7 +1866,8 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
|
||||
* so pass it
|
||||
*/
|
||||
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)
|
||||
break;
|
||||
@ -1972,7 +1945,7 @@ solicit_again:
|
||||
|
||||
BUG_ON(r2t->data_count < 0);
|
||||
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) {
|
||||
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) {
|
||||
iscsi_buf_data_digest_update(conn, &ctask->sendbuf);
|
||||
crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1);
|
||||
/* imm data? */
|
||||
if (!dtask) {
|
||||
if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf,
|
||||
@ -2148,7 +2121,7 @@ unsolicit_head_again:
|
||||
solicit_head_again:
|
||||
r2t = ctask->r2t;
|
||||
if (conn->hdrdgst_en)
|
||||
iscsi_hdr_digest(conn, &r2t->headbuf,
|
||||
iscsi_hdr_digest(conn, &r2t->headbuf,
|
||||
(u8*)r2t->dtask->hdrext);
|
||||
if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) {
|
||||
ctask->xmstate &= ~XMSTATE_SOL_DATA;
|
||||
@ -2300,10 +2273,10 @@ iscsi_xmitworker(void *data)
|
||||
/*
|
||||
* serialize Xmit worker on a per-connection basis.
|
||||
*/
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
if (iscsi_data_xmit(conn))
|
||||
schedule_work(&conn->xmitwork);
|
||||
up(&conn->xmitsema);
|
||||
scsi_queue_work(conn->session->host, &conn->xmitwork);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
}
|
||||
|
||||
#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);
|
||||
spin_unlock(&session->lock);
|
||||
|
||||
if (!in_interrupt() && !down_trylock(&conn->xmitsema)) {
|
||||
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);
|
||||
|
||||
scsi_queue_work(host, &conn->xmitwork);
|
||||
return 0;
|
||||
|
||||
reject:
|
||||
@ -2462,17 +2427,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
|
||||
kfree(items);
|
||||
}
|
||||
|
||||
static iscsi_connh_t
|
||||
iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx)
|
||||
static struct iscsi_cls_conn *
|
||||
iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx)
|
||||
{
|
||||
struct iscsi_session *session = iscsi_ptr(sessionh);
|
||||
struct iscsi_conn *conn = NULL;
|
||||
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||
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));
|
||||
|
||||
conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
|
||||
conn->in_progress = IN_PROGRESS_WAIT_HEADER;
|
||||
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;
|
||||
|
||||
init_timer(&conn->tmabort_timer);
|
||||
init_MUTEX(&conn->xmitsema);
|
||||
mutex_init(&conn->xmitmutex);
|
||||
init_waitqueue_head(&conn->ehwait);
|
||||
|
||||
return iscsi_handle(conn);
|
||||
return cls_conn;
|
||||
|
||||
max_recv_dlenght_alloc_fail:
|
||||
spin_lock_bh(&session->lock);
|
||||
@ -2550,18 +2518,18 @@ immqueue_alloc_fail:
|
||||
writequeue_alloc_fail:
|
||||
kfifo_free(conn->xmitqueue);
|
||||
xmitqueue_alloc_fail:
|
||||
kfree(conn);
|
||||
conn_alloc_fail:
|
||||
return iscsi_handle(NULL);
|
||||
iscsi_destroy_conn(cls_conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned long flags;
|
||||
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
set_bit(SUSPEND_BIT, &conn->suspend_tx);
|
||||
if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) {
|
||||
struct sock *sk = conn->sock->sk;
|
||||
@ -2592,19 +2560,19 @@ iscsi_conn_destroy(iscsi_connh_t connh)
|
||||
}
|
||||
spin_unlock_bh(&session->lock);
|
||||
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
|
||||
/*
|
||||
* Block until all in-progress commands for this connection
|
||||
* time out or fail.
|
||||
*/
|
||||
for (;;) {
|
||||
spin_lock_bh(&conn->lock);
|
||||
spin_lock_irqsave(session->host->host_lock, flags);
|
||||
if (!session->host->host_busy) { /* OK for ERL == 0 */
|
||||
spin_unlock_bh(&conn->lock);
|
||||
spin_unlock_irqrestore(session->host->host_lock, flags);
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&conn->lock);
|
||||
spin_unlock_irqrestore(session->host->host_lock, flags);
|
||||
msleep_interruptible(500);
|
||||
printk("conn_destroy(): host_busy %d host_failed %d\n",
|
||||
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->immqueue);
|
||||
kfifo_free(conn->mgmtqueue);
|
||||
kfree(conn);
|
||||
|
||||
iscsi_destroy_conn(cls_conn);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2713,6 +2682,8 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh,
|
||||
*/
|
||||
iscsi_conn_set_callbacks(conn);
|
||||
|
||||
conn->sendpage = conn->sock->ops->sendpage;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
write_unlock_bh(&sk->sk_callback_lock);
|
||||
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
|
||||
spin_lock_irqsave(session->host->host_lock, flags);
|
||||
spin_lock(&session->lock);
|
||||
@ -2878,7 +2849,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag)
|
||||
conn->datadgst_en = 0;
|
||||
}
|
||||
}
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2963,8 +2934,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
|
||||
else
|
||||
__kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*));
|
||||
|
||||
schedule_work(&conn->xmitwork);
|
||||
|
||||
scsi_queue_work(session->host, &conn->xmitwork);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3029,12 +2999,12 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
||||
* 1) connection-level failure;
|
||||
* 2) recovery due protocol error;
|
||||
*/
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
spin_lock_bh(&session->lock);
|
||||
if (session->state != ISCSI_STATE_LOGGED_IN) {
|
||||
if (session->state == ISCSI_STATE_TERMINATE) {
|
||||
spin_unlock_bh(&session->lock);
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
goto failed;
|
||||
}
|
||||
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.
|
||||
*/
|
||||
spin_unlock_bh(&session->lock);
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
goto success;
|
||||
}
|
||||
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_INITIAL;
|
||||
spin_unlock_bh(&session->lock);
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
goto success;
|
||||
}
|
||||
conn->tmabort_state = TMABORT_INITIAL;
|
||||
@ -3116,7 +3086,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc)
|
||||
spin_unlock_bh(&session->lock);
|
||||
}
|
||||
}
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
|
||||
|
||||
/*
|
||||
@ -3182,7 +3152,7 @@ failed:
|
||||
exit:
|
||||
del_timer_sync(&conn->tmabort_timer);
|
||||
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
if (conn->sock) {
|
||||
struct sock *sk = conn->sock->sk;
|
||||
|
||||
@ -3190,7 +3160,7 @@ exit:
|
||||
iscsi_ctask_cleanup(conn, ctask);
|
||||
write_unlock_bh(&sk->sk_callback_lock);
|
||||
}
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3281,17 +3251,23 @@ static struct scsi_host_template iscsi_sht = {
|
||||
.this_id = -1,
|
||||
};
|
||||
|
||||
static iscsi_sessionh_t
|
||||
iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host)
|
||||
static struct iscsi_transport iscsi_tcp_transport;
|
||||
|
||||
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;
|
||||
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));
|
||||
|
||||
session->host = host;
|
||||
session->id = host->host_no;
|
||||
session->host = shost;
|
||||
session->state = ISCSI_STATE_LOGGED_IN;
|
||||
session->mgmtpool_max = ISCSI_MGMT_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))
|
||||
goto r2tpool_alloc_fail;
|
||||
|
||||
return iscsi_handle(session);
|
||||
return shost;
|
||||
|
||||
r2tpool_alloc_fail:
|
||||
for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++)
|
||||
@ -3345,15 +3321,15 @@ immdata_alloc_fail:
|
||||
mgmtpool_alloc_fail:
|
||||
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
||||
cmdpool_alloc_fail:
|
||||
return iscsi_handle(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
struct iscsi_data_task *dtask, *n;
|
||||
struct iscsi_session *session = iscsi_ptr(sessionh);
|
||||
|
||||
for (cmd_i = 0; cmd_i < session->cmds_max; 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_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds);
|
||||
iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
|
||||
|
||||
iscsi_transport_destroy_session(shost);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3467,6 +3445,8 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
|
||||
if (conn->data_rx_tfm)
|
||||
crypto_free_tfm(conn->data_rx_tfm);
|
||||
}
|
||||
conn->sendpage = conn->datadgst_en ?
|
||||
sock_no_sendpage : conn->sock->ops->sendpage;
|
||||
break;
|
||||
case ISCSI_PARAM_INITIAL_R2T_EN:
|
||||
session->initial_r2t_en = value;
|
||||
@ -3515,25 +3495,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param,
|
||||
}
|
||||
|
||||
static int
|
||||
iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
|
||||
uint32_t *value)
|
||||
iscsi_session_get_param(struct Scsi_Host *shost,
|
||||
enum iscsi_param param, uint32_t *value)
|
||||
{
|
||||
struct iscsi_conn *conn = iscsi_ptr(connh);
|
||||
struct iscsi_session *session = conn->session;
|
||||
struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
|
||||
|
||||
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:
|
||||
*value = session->initial_r2t_en;
|
||||
break;
|
||||
@ -3571,6 +3538,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param,
|
||||
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
|
||||
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);
|
||||
int rc;
|
||||
|
||||
down(&conn->xmitsema);
|
||||
mutex_lock(&conn->xmitmutex);
|
||||
rc = iscsi_conn_send_generic(conn, hdr, data, data_size);
|
||||
up(&conn->xmitsema);
|
||||
mutex_unlock(&conn->xmitmutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -3615,6 +3607,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
||||
| CAP_DATADGST,
|
||||
.host_template = &iscsi_sht,
|
||||
.hostdata_size = sizeof(struct iscsi_session),
|
||||
.conndata_size = sizeof(struct iscsi_conn),
|
||||
.max_conn = 1,
|
||||
.max_cmd_len = ISCSI_TCP_MAX_CMD_LEN,
|
||||
.create_session = iscsi_session_create,
|
||||
@ -3623,7 +3616,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
||||
.bind_conn = iscsi_conn_bind,
|
||||
.destroy_conn = iscsi_conn_destroy,
|
||||
.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,
|
||||
.stop_conn = iscsi_conn_stop,
|
||||
.send_pdu = iscsi_conn_send_pdu,
|
||||
@ -3633,8 +3627,6 @@ static struct iscsi_transport iscsi_tcp_transport = {
|
||||
static int __init
|
||||
iscsi_tcp_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (iscsi_max_lun < 1) {
|
||||
printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);
|
||||
return -EINVAL;
|
||||
@ -3647,11 +3639,10 @@ iscsi_tcp_init(void)
|
||||
if (!taskcache)
|
||||
return -ENOMEM;
|
||||
|
||||
error = iscsi_register_transport(&iscsi_tcp_transport);
|
||||
if (error)
|
||||
if (!iscsi_register_transport(&iscsi_tcp_transport))
|
||||
kmem_cache_destroy(taskcache);
|
||||
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
|
@ -158,7 +158,7 @@ struct iscsi_conn {
|
||||
struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
|
||||
struct kfifo *xmitqueue; /* data-path cmd queue */
|
||||
struct work_struct xmitwork; /* per-conn. xmit workqueue */
|
||||
struct semaphore xmitsema; /* serializes connection xmit,
|
||||
struct mutex xmitmutex; /* serializes connection xmit,
|
||||
* access to kfifos: *
|
||||
* xmitqueue, writequeue, *
|
||||
* immqueue, mgmtqueue */
|
||||
@ -191,6 +191,8 @@ struct iscsi_conn {
|
||||
uint32_t sendpage_failures_cnt;
|
||||
uint32_t discontiguous_hdr_cnt;
|
||||
uint32_t eh_abort_cnt;
|
||||
|
||||
ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
|
||||
};
|
||||
|
||||
struct iscsi_session {
|
||||
@ -240,8 +242,8 @@ struct iscsi_session {
|
||||
|
||||
struct iscsi_buf {
|
||||
struct scatterlist sg;
|
||||
struct kvec iov;
|
||||
unsigned int sent;
|
||||
char use_sendmsg;
|
||||
};
|
||||
|
||||
struct iscsi_data_task {
|
||||
|
@ -150,7 +150,7 @@ lpfc_new_scsi_buf(struct lpfc_hba * phba)
|
||||
return psb;
|
||||
}
|
||||
|
||||
struct lpfc_scsi_buf*
|
||||
static struct lpfc_scsi_buf*
|
||||
lpfc_get_scsi_buf(struct lpfc_hba * phba)
|
||||
{
|
||||
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
|
||||
* available command ids for the I/O commands.
|
||||
*/
|
||||
down(&adapter->int_mtx);
|
||||
mutex_lock(&adapter->int_mtx);
|
||||
|
||||
scb = &adapter->int_scb;
|
||||
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);
|
||||
}
|
||||
|
||||
up(&adapter->int_mtx);
|
||||
mutex_unlock(&adapter->int_mtx);
|
||||
|
||||
return rval;
|
||||
}
|
||||
@ -4866,7 +4866,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
adapter->has_64bit_addr = 0;
|
||||
}
|
||||
|
||||
init_MUTEX(&adapter->int_mtx);
|
||||
mutex_init(&adapter->int_mtx);
|
||||
init_completion(&adapter->int_waitq);
|
||||
|
||||
adapter->this_id = DEFAULT_INITIATOR_ID;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __MEGARAID_H__
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define MEGARAID_VERSION \
|
||||
"v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"
|
||||
@ -889,7 +889,7 @@ typedef struct {
|
||||
|
||||
scb_t int_scb;
|
||||
Scsi_Cmnd int_scmd;
|
||||
struct semaphore int_mtx; /* To synchronize the internal
|
||||
struct mutex int_mtx; /* To synchronize the internal
|
||||
commands */
|
||||
struct completion int_waitq; /* wait queue for internal
|
||||
cmds */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@ -72,7 +73,7 @@ MODULE_DEVICE_TABLE(pci, megasas_pci_table);
|
||||
static int megasas_mgmt_majorno;
|
||||
static struct megasas_mgmt_info megasas_mgmt_info;
|
||||
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
|
||||
@ -2362,11 +2363,11 @@ static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
|
||||
{
|
||||
int rc;
|
||||
|
||||
down(&megasas_async_queue_mutex);
|
||||
mutex_lock(&megasas_async_queue_mutex);
|
||||
|
||||
rc = fasync_helper(fd, filep, mode, &megasas_async_queue);
|
||||
|
||||
up(&megasas_async_queue_mutex);
|
||||
mutex_unlock(&megasas_async_queue_mutex);
|
||||
|
||||
if (rc >= 0) {
|
||||
/* For sanity check when we get ioctl */
|
||||
|
@ -1,4 +1,4 @@
|
||||
config SCSI_QLA2XXX
|
||||
config SCSI_QLA_FC
|
||||
tristate "QLogic QLA2XXX Fibre Channel Support"
|
||||
depends on PCI && SCSI
|
||||
select SCSI_FC_ATTRS
|
||||
@ -22,49 +22,57 @@ config SCSI_QLA2XXX
|
||||
Upon request, the driver caches the firmware image until
|
||||
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
|
||||
modules has been deprecated as the firmware-images will
|
||||
be removed from the kernel sources.
|
||||
|
||||
config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
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
|
||||
tristate " Build QLogic ISP2100 firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 21xx (ISP2100) host adapter family.
|
||||
|
||||
config SCSI_QLA22XX
|
||||
tristate " Build QLogic ISP2200 firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
||||
|
||||
config SCSI_QLA2300
|
||||
tristate " Build QLogic ISP2300 firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
|
||||
adapter family.
|
||||
|
||||
config SCSI_QLA2322
|
||||
tristate " Build QLogic ISP2322 firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 2322 (ISP2322) host adapter family.
|
||||
|
||||
config SCSI_QLA6312
|
||||
tristate " Build QLogic ISP63xx firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
|
||||
adapter family.
|
||||
|
||||
config SCSI_QLA24XX
|
||||
tristate " Build QLogic ISP24xx firmware-module"
|
||||
depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
|
||||
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 \
|
||||
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
|
||||
qla2200-y := ql2200.o ql2200_fw.o
|
||||
|
@ -541,7 +541,7 @@ struct fc_function_template qla2xxx_transport_functions = {
|
||||
void
|
||||
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_port_name(ha->host) = wwn_to_u64(ha->init_cb->port_name);
|
||||
fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
|
||||
fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
|
||||
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;
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
fw->hccr = RD_REG_DWORD(®->hccr);
|
||||
fw->host_status = RD_REG_DWORD(®->host_status);
|
||||
|
||||
/* 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 |
|
||||
HCCRX_CLR_HOST_INT);
|
||||
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) {
|
||||
/* Host interface registers. */
|
||||
dmp_reg = (uint32_t __iomem *)(reg + 0);
|
||||
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
|
||||
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. */
|
||||
mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
|
||||
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++)
|
||||
*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. */
|
||||
iter_reg = fw->lmc_reg;
|
||||
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_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");
|
||||
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, "\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");
|
||||
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) {
|
||||
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, "\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");
|
||||
for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) {
|
||||
if (cnt % 8 == 0)
|
||||
|
@ -227,8 +227,9 @@ struct qla2100_fw_dump {
|
||||
#define FW_DUMP_SIZE_24XX 0x2B0000
|
||||
|
||||
struct qla24xx_fw_dump {
|
||||
uint32_t hccr;
|
||||
uint32_t host_status;
|
||||
uint32_t host_reg[32];
|
||||
uint32_t shadow_reg[7];
|
||||
uint16_t mailbox_reg[32];
|
||||
uint32_t xseq_gp_reg[128];
|
||||
uint32_t xseq_0_reg[16];
|
||||
@ -250,7 +251,6 @@ struct qla24xx_fw_dump {
|
||||
uint32_t rcvt0_data_dma_reg[32];
|
||||
uint32_t rcvt1_data_dma_reg[32];
|
||||
uint32_t risc_gp_reg[128];
|
||||
uint32_t shadow_reg[7];
|
||||
uint32_t lmc_reg[112];
|
||||
uint32_t fpm_hdw_reg[192];
|
||||
uint32_t fb_hdw_reg[176];
|
||||
|
@ -62,6 +62,7 @@ extern int qlport_down_retry;
|
||||
extern int ql2xplogiabsentdevice;
|
||||
extern int ql2xloginretrycount;
|
||||
extern int ql2xfdmienable;
|
||||
extern int ql2xprocessrscn;
|
||||
|
||||
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.
|
||||
*/
|
||||
extern int
|
||||
qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t);
|
||||
|
||||
extern int
|
||||
qla2x00_load_ram_ext(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
|
||||
qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
|
||||
|
||||
extern int
|
||||
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[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 */
|
||||
|
||||
/* 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->len = __constant_cpu_to_be16(4 + 4);
|
||||
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);
|
||||
else if (IS_QLA24XX(ha))
|
||||
eiter->a.sup_speed = __constant_cpu_to_be32(4);
|
||||
else if (IS_QLA23XX(ha))
|
||||
eiter->a.sup_speed = __constant_cpu_to_be32(2);
|
||||
else
|
||||
@ -1553,9 +1554,6 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
|
||||
eiter->a.cur_speed = __constant_cpu_to_be32(2);
|
||||
break;
|
||||
case 3:
|
||||
eiter->a.cur_speed = __constant_cpu_to_be32(8);
|
||||
break;
|
||||
case 4:
|
||||
eiter->a.cur_speed = __constant_cpu_to_be32(4);
|
||||
break;
|
||||
}
|
||||
|
@ -1014,11 +1014,13 @@ qla24xx_update_fw_options(scsi_qla_host_t *ha)
|
||||
int rval;
|
||||
|
||||
/* 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;
|
||||
|
||||
rval = qla2x00_set_serdes_params(ha, ha->fw_seriallink_options24[1],
|
||||
ha->fw_seriallink_options24[2], ha->fw_seriallink_options24[3]);
|
||||
rval = qla2x00_set_serdes_params(ha,
|
||||
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) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"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, "
|
||||
"loop_id=0x%04x\n",
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2648,7 +2653,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
|
||||
|
||||
switch (format) {
|
||||
case 0:
|
||||
if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
||||
if (ql2xprocessrscn &&
|
||||
!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
|
||||
!IS_QLA6312(ha) && !IS_QLA6322(ha) &&
|
||||
!IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
|
||||
ha->flags.init_done) {
|
||||
@ -3402,6 +3408,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
|
||||
ha->node_name = icb->node_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);
|
||||
|
||||
/* 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++)
|
||||
dcode[i] = swab32(dcode[i]);
|
||||
|
||||
rval = qla2x00_load_ram_ext(ha, ha->request_dma,
|
||||
risc_addr, dlen);
|
||||
rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
|
||||
dlen);
|
||||
if (rval) {
|
||||
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
||||
"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++)
|
||||
dcode[i] = swab32(fwcode[i]);
|
||||
|
||||
rval = qla2x00_load_ram_ext(ha, ha->request_dma,
|
||||
risc_addr, dlen);
|
||||
rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
|
||||
dlen);
|
||||
if (rval) {
|
||||
DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
|
||||
"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
|
||||
* 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) &&
|
||||
ha->flags.init_done && mb[1] != 0xffff &&
|
||||
((ha->operating_mode == P2P && mb[1] != 0) ||
|
||||
@ -963,15 +964,16 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
|
||||
break;
|
||||
|
||||
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;
|
||||
if (scsi_status & SS_RESIDUAL_UNDER) {
|
||||
cp->resid = 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. */
|
||||
qla2x00_poll(ha);
|
||||
|
||||
udelay(10); /* v4.27 */
|
||||
if (command != MBC_LOAD_RISC_RAM_EXTENDED &&
|
||||
!ha->flags.mbox_int)
|
||||
msleep(10);
|
||||
} /* while */
|
||||
}
|
||||
|
||||
@ -325,98 +327,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
|
||||
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
|
||||
qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr,
|
||||
uint16_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)
|
||||
qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
|
||||
uint32_t risc_code_size)
|
||||
{
|
||||
int rval;
|
||||
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));
|
||||
|
||||
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[2] = MSW(req_dma);
|
||||
mcp->mb[3] = LSW(req_dma);
|
||||
mcp->mb[6] = MSW(MSD(req_dma));
|
||||
mcp->mb[7] = LSW(MSD(req_dma));
|
||||
mcp->mb[8] = MSW(risc_addr);
|
||||
mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
|
||||
if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
|
||||
mcp->mb[4] = MSW(risc_code_size);
|
||||
mcp->mb[5] = LSW(risc_code_size);
|
||||
|
@ -71,6 +71,12 @@ MODULE_PARM_DESC(ql2xfdmienable,
|
||||
"Enables FDMI registratons "
|
||||
"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
|
||||
*/
|
||||
|
@ -573,6 +573,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
|
||||
}
|
||||
} while (0);
|
||||
|
||||
/* Enable flash write-protection. */
|
||||
qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c);
|
||||
|
||||
/* Disable flash write. */
|
||||
WRT_REG_DWORD(®->ctrl_status,
|
||||
RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE);
|
||||
|
@ -7,9 +7,9 @@
|
||||
/*
|
||||
* 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_MINOR_VER 1
|
||||
#define QLA_DRIVER_PATCH_VER 3
|
||||
#define QLA_DRIVER_PATCH_VER 4
|
||||
#define QLA_DRIVER_BETA_VER 0
|
||||
|
@ -148,9 +148,11 @@ static struct {
|
||||
{ RAID_LEVEL_LINEAR, "linear" },
|
||||
{ RAID_LEVEL_0, "raid0" },
|
||||
{ RAID_LEVEL_1, "raid1" },
|
||||
{ RAID_LEVEL_10, "raid10" },
|
||||
{ RAID_LEVEL_3, "raid3" },
|
||||
{ RAID_LEVEL_4, "raid4" },
|
||||
{ RAID_LEVEL_5, "raid5" },
|
||||
{ RAID_LEVEL_50, "raid50" },
|
||||
{ RAID_LEVEL_6, "raid6" },
|
||||
};
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
@ -209,7 +210,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = {
|
||||
.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,
|
||||
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
|
||||
* 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);
|
||||
if (!pool->users) {
|
||||
pool->slab = kmem_cache_create(pool->name,
|
||||
@ -342,7 +343,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost)
|
||||
|
||||
pool->users++;
|
||||
shost->cmd_pool = pool;
|
||||
up(&host_cmd_pool_mutex);
|
||||
mutex_unlock(&host_cmd_pool_mutex);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
return -ENOMEM;
|
||||
fail:
|
||||
up(&host_cmd_pool_mutex);
|
||||
mutex_unlock(&host_cmd_pool_mutex);
|
||||
return -ENOMEM;
|
||||
|
||||
}
|
||||
@ -381,10 +382,10 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost)
|
||||
kmem_cache_free(shost->cmd_pool->slab, cmd);
|
||||
}
|
||||
|
||||
down(&host_cmd_pool_mutex);
|
||||
mutex_lock(&host_cmd_pool_mutex);
|
||||
if (!--shost->cmd_pool->users)
|
||||
kmem_cache_destroy(shost->cmd_pool->slab);
|
||||
up(&host_cmd_pool_mutex);
|
||||
mutex_unlock(&host_cmd_pool_mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCSI_LOGGING
|
||||
|
@ -1212,7 +1212,7 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
|
||||
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));
|
||||
/*
|
||||
@ -1224,7 +1224,7 @@ static void scsi_generic_done(struct scsi_cmnd *cmd)
|
||||
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;
|
||||
|
||||
@ -1241,8 +1241,8 @@ void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
|
||||
cmd->transfersize = req->data_len;
|
||||
cmd->allowed = req->retries;
|
||||
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)
|
||||
{
|
||||
@ -1339,7 +1339,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
|
||||
* happening now.
|
||||
*/
|
||||
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
|
||||
struct scsi_driver *drv;
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
if (unlikely(!drv->init_command(cmd))) {
|
||||
scsi_release_buffers(cmd);
|
||||
scsi_put_command(cmd);
|
||||
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) \
|
||||
(((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 */
|
||||
extern int scsi_init_hosts(void);
|
||||
extern void scsi_exit_hosts(void);
|
||||
|
@ -25,11 +25,13 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
|
||||
#include "scsi_priv.h"
|
||||
#include "scsi_logging.h"
|
||||
@ -41,7 +43,7 @@
|
||||
static struct proc_dir_entry *proc_scsi;
|
||||
|
||||
/* 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,
|
||||
int length, int *eof, void *data)
|
||||
@ -83,7 +85,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
|
||||
if (!sht->proc_info)
|
||||
return;
|
||||
|
||||
down(&global_host_template_sem);
|
||||
mutex_lock(&global_host_template_mutex);
|
||||
if (!sht->present++) {
|
||||
sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
|
||||
if (!sht->proc_dir)
|
||||
@ -92,7 +94,7 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
|
||||
else
|
||||
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)
|
||||
@ -100,12 +102,12 @@ void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
|
||||
if (!sht->proc_info)
|
||||
return;
|
||||
|
||||
down(&global_host_template_sem);
|
||||
mutex_lock(&global_host_template_mutex);
|
||||
if (!--sht->present && sht->proc_dir) {
|
||||
remove_proc_entry(sht->proc_name, proc_scsi);
|
||||
sht->proc_dir = NULL;
|
||||
}
|
||||
up(&global_host_template_sem);
|
||||
mutex_unlock(&global_host_template_mutex);
|
||||
}
|
||||
|
||||
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))
|
||||
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);
|
||||
return error;
|
||||
}
|
||||
|
@ -334,19 +334,6 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
|
||||
struct scsi_target *starget;
|
||||
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);
|
||||
if (!starget) {
|
||||
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 device *parent = &shost->shost_gendev;
|
||||
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)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
get_device(&starget->dev);
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
if (scsi_host_scan_allowed(shost)) {
|
||||
res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
|
||||
hostdata);
|
||||
if (res != SCSI_SCAN_LUN_PRESENT)
|
||||
sdev = ERR_PTR(-ENODEV);
|
||||
}
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
scsi_target_reap(starget);
|
||||
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);
|
||||
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
if (scsi_host_scan_allowed(shost))
|
||||
__scsi_scan_target(parent, channel, id, lun, rescan);
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
}
|
||||
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)))
|
||||
return -EINVAL;
|
||||
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
if (scsi_host_scan_allowed(shost)) {
|
||||
if (channel == SCAN_WILD_CARD)
|
||||
for (channel = 0; channel <= shost->max_channel;
|
||||
@ -1464,7 +1452,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
||||
else
|
||||
scsi_scan_channel(shost, channel, id, lun, rescan);
|
||||
}
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1522,7 +1510,7 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
|
||||
struct scsi_device *sdev = NULL;
|
||||
struct scsi_target *starget;
|
||||
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
if (!scsi_host_scan_allowed(shost))
|
||||
goto out;
|
||||
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);
|
||||
out:
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
return sdev;
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_get_host_dev);
|
||||
|
@ -106,7 +106,10 @@ static int scsi_scan(struct Scsi_Host *shost, const char *str)
|
||||
return -EINVAL;
|
||||
if (check_set(&lun, s3))
|
||||
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;
|
||||
}
|
||||
|
||||
@ -745,9 +748,9 @@ void scsi_remove_device(struct scsi_device *sdev)
|
||||
{
|
||||
struct Scsi_Host *shost = sdev->host;
|
||||
|
||||
down(&shost->scan_mutex);
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
__scsi_remove_device(sdev);
|
||||
up(&shost->scan_mutex);
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
}
|
||||
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_port_name(shost) = -1;
|
||||
fc_host_permanent_port_name(shost) = -1;
|
||||
fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED;
|
||||
memset(fc_host_supported_fc4s(shost), 0,
|
||||
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(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(maxframe_size, "%u bytes\n", 20);
|
||||
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
|
||||
*/
|
||||
static struct device *fc_target_parent(struct Scsi_Host *shost,
|
||||
int channel, uint id)
|
||||
static int fc_user_scan(struct Scsi_Host *shost, uint channel,
|
||||
uint id, uint lun)
|
||||
{
|
||||
struct fc_rport *rport;
|
||||
|
||||
list_for_each_entry(rport, &fc_host_rports(shost), peers)
|
||||
if ((rport->channel == channel) &&
|
||||
(rport->scsi_target_id == id))
|
||||
return &rport->dev;
|
||||
list_for_each_entry(rport, &fc_host_rports(shost), peers) {
|
||||
if (rport->scsi_target_id == -1)
|
||||
continue;
|
||||
|
||||
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 *
|
||||
@ -1139,7 +1148,7 @@ fc_attach_transport(struct fc_function_template *ft)
|
||||
/* Transport uses the shost workq for scsi scanning */
|
||||
i->t.create_work_queue = 1;
|
||||
|
||||
i->t.target_parent = fc_target_parent;
|
||||
i->t.user_scan = fc_user_scan;
|
||||
|
||||
/*
|
||||
* Setup SCSI Target Attributes.
|
||||
@ -1160,6 +1169,7 @@ fc_attach_transport(struct fc_function_template *ft)
|
||||
count=0;
|
||||
SETUP_HOST_ATTRIBUTE_RD(node_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_fc4s);
|
||||
SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
@ -62,7 +63,7 @@ struct sas_internal {
|
||||
|
||||
struct sas_host_attrs {
|
||||
struct list_head rphy_list;
|
||||
spinlock_t lock;
|
||||
struct mutex lock;
|
||||
u32 next_target_id;
|
||||
};
|
||||
#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);
|
||||
|
||||
INIT_LIST_HEAD(&sas_host->rphy_list);
|
||||
spin_lock_init(&sas_host->lock);
|
||||
mutex_init(&sas_host->lock);
|
||||
sas_host->next_target_id = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -626,7 +627,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
|
||||
transport_add_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);
|
||||
if (identify->device_type == SAS_END_DEVICE &&
|
||||
(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++;
|
||||
else
|
||||
rphy->scsi_target_id = -1;
|
||||
spin_unlock(&sas_host->lock);
|
||||
mutex_unlock(&sas_host->lock);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -661,9 +662,9 @@ void sas_rphy_free(struct sas_rphy *rphy)
|
||||
struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
|
||||
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);
|
||||
spin_unlock(&sas_host->lock);
|
||||
mutex_unlock(&sas_host->lock);
|
||||
|
||||
transport_destroy_device(&rphy->dev);
|
||||
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 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);
|
||||
device_del(dev);
|
||||
transport_destroy_device(dev);
|
||||
|
||||
spin_lock(&sas_host->lock);
|
||||
mutex_lock(&sas_host->lock);
|
||||
list_del(&rphy->list);
|
||||
spin_unlock(&sas_host->lock);
|
||||
mutex_unlock(&sas_host->lock);
|
||||
|
||||
parent->rphy = NULL;
|
||||
|
||||
put_device(&parent->dev);
|
||||
}
|
||||
@ -719,23 +732,28 @@ EXPORT_SYMBOL(scsi_is_sas_rphy);
|
||||
* SCSI scan helper
|
||||
*/
|
||||
|
||||
static struct device *sas_target_parent(struct Scsi_Host *shost,
|
||||
int channel, uint id)
|
||||
static int sas_user_scan(struct Scsi_Host *shost, uint channel,
|
||||
uint id, uint lun)
|
||||
{
|
||||
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
|
||||
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) {
|
||||
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;
|
||||
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.class = &sas_host_class.class;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include "scsi_priv.h"
|
||||
#include <scsi/scsi_device.h>
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
/* 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_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 scsi_transport_template t;
|
||||
@ -242,7 +242,7 @@ static int spi_setup_transport_attrs(struct transport_container *tc,
|
||||
spi_hold_mcs(starget) = 0;
|
||||
spi_dv_pending(starget) = 0;
|
||||
spi_initial_dv(starget) = 0;
|
||||
init_MUTEX(&spi_dv_sem(starget));
|
||||
mutex_init(&spi_dv_mutex(starget));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -915,7 +915,7 @@ spi_dv_device(struct scsi_device *sdev)
|
||||
scsi_target_quiesce(starget);
|
||||
|
||||
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");
|
||||
|
||||
@ -923,7 +923,7 @@ spi_dv_device(struct scsi_device *sdev)
|
||||
|
||||
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;
|
||||
|
||||
scsi_target_resume(starget);
|
||||
@ -1075,7 +1075,7 @@ static const char * const extended_msgs[] = {
|
||||
/* 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) {
|
||||
char buf[20];
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <linux/blkpg.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/uaccess.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
|
||||
* face of object destruction (i.e. we can't allow a get on an
|
||||
* 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 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;
|
||||
|
||||
down(&sd_ref_sem);
|
||||
mutex_lock(&sd_ref_mutex);
|
||||
sdkp = __scsi_disk_get(disk);
|
||||
up(&sd_ref_sem);
|
||||
mutex_unlock(&sd_ref_mutex);
|
||||
return sdkp;
|
||||
}
|
||||
|
||||
@ -203,11 +204,11 @@ static struct scsi_disk *scsi_disk_get_from_dev(struct device *dev)
|
||||
{
|
||||
struct scsi_disk *sdkp;
|
||||
|
||||
down(&sd_ref_sem);
|
||||
mutex_lock(&sd_ref_mutex);
|
||||
sdkp = dev_get_drvdata(dev);
|
||||
if (sdkp)
|
||||
sdkp = __scsi_disk_get(sdkp->disk);
|
||||
up(&sd_ref_sem);
|
||||
mutex_unlock(&sd_ref_mutex);
|
||||
return sdkp;
|
||||
}
|
||||
|
||||
@ -215,10 +216,10 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
|
||||
{
|
||||
struct scsi_device *sdev = sdkp->device;
|
||||
|
||||
down(&sd_ref_sem);
|
||||
mutex_lock(&sd_ref_mutex);
|
||||
kref_put(&sdkp->kref, scsi_disk_release);
|
||||
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)
|
||||
{
|
||||
unsigned int this_count, timeout;
|
||||
struct gendisk *disk;
|
||||
sector_t block;
|
||||
struct scsi_device *sdp = SCpnt->device;
|
||||
struct request *rq = SCpnt->request;
|
||||
|
||||
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;
|
||||
struct gendisk *disk = rq->rq_disk;
|
||||
sector_t block = rq->sector;
|
||||
unsigned int this_count = SCpnt->request_bufflen >> 9;
|
||||
unsigned int timeout = sdp->timeout;
|
||||
|
||||
SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
|
||||
"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->underflow = this_count << 9;
|
||||
SCpnt->allowed = SD_MAX_RETRIES;
|
||||
|
||||
queue:
|
||||
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
|
||||
unnecessary additional work such as memcpy's that could be avoided.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 &&
|
||||
if (driver_byte(result) != 0 &&
|
||||
sense_valid && !sense_deferred) {
|
||||
switch (sshdr.sense_key) {
|
||||
case MEDIUM_ERROR:
|
||||
@ -1635,10 +1604,10 @@ static int sd_remove(struct device *dev)
|
||||
del_gendisk(sdkp->disk);
|
||||
sd_shutdown(dev);
|
||||
|
||||
down(&sd_ref_sem);
|
||||
mutex_lock(&sd_ref_mutex);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
kref_put(&sdkp->kref, scsi_disk_release);
|
||||
up(&sd_ref_sem);
|
||||
mutex_unlock(&sd_ref_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1647,7 +1616,7 @@ static int sd_remove(struct device *dev)
|
||||
* scsi_disk_release - Called to free the scsi_disk structure
|
||||
* @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()
|
||||
* scsi_disk_put() helpers which manipulate the semaphore directly
|
||||
* and never do a direct kref_put().
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/uaccess.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
|
||||
* face of object destruction (i.e. we can't allow a get on an
|
||||
* 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 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;
|
||||
|
||||
down(&sr_ref_sem);
|
||||
mutex_lock(&sr_ref_mutex);
|
||||
if (disk->private_data == NULL)
|
||||
goto out;
|
||||
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);
|
||||
cd = NULL;
|
||||
out:
|
||||
up(&sr_ref_sem);
|
||||
mutex_unlock(&sr_ref_mutex);
|
||||
return cd;
|
||||
}
|
||||
|
||||
@ -154,10 +155,10 @@ static inline void scsi_cd_put(struct scsi_cd *cd)
|
||||
{
|
||||
struct scsi_device *sdev = cd->device;
|
||||
|
||||
down(&sr_ref_sem);
|
||||
mutex_lock(&sr_ref_mutex);
|
||||
kref_put(&cd->kref, sr_kref_release);
|
||||
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:
|
||||
if (!(SCpnt->sense_buffer[0] & 0x90))
|
||||
break;
|
||||
if (!blk_fs_request(SCpnt->request))
|
||||
break;
|
||||
error_sector = (SCpnt->sense_buffer[3] << 24) |
|
||||
(SCpnt->sense_buffer[4] << 16) |
|
||||
(SCpnt->sense_buffer[5] << 8) |
|
||||
@ -316,23 +315,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
||||
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,
|
||||
* see CDROMREADMODE2 ioctl)
|
||||
@ -421,8 +403,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
|
||||
*/
|
||||
SCpnt->transfersize = cd->device->sector_size;
|
||||
SCpnt->underflow = this_count << 9;
|
||||
|
||||
queue:
|
||||
SCpnt->allowed = MAX_RETRIES;
|
||||
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 */
|
||||
cd->cdi.speed = 1;
|
||||
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
||||
CDC_DVD | CDC_DVD_RAM |
|
||||
CDC_SELECT_DISC | CDC_SELECT_SPEED);
|
||||
CDC_DVD | CDC_DVD_RAM |
|
||||
CDC_SELECT_DISC | CDC_SELECT_SPEED |
|
||||
CDC_MRW | CDC_MRW_W | CDC_RAM);
|
||||
kfree(buffer);
|
||||
printk("%s: scsi-1 drive\n", cd->cdi.name);
|
||||
return;
|
||||
@ -845,7 +826,7 @@ static int sr_packet(struct cdrom_device_info *cdi,
|
||||
* sr_kref_release - Called to free the scsi_cd structure
|
||||
* @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()
|
||||
* scsi_cd_put() helpers which manipulate the semaphore directly
|
||||
* and never do a direct kref_put().
|
||||
@ -874,9 +855,9 @@ static int sr_remove(struct device *dev)
|
||||
|
||||
del_gendisk(cd->disk);
|
||||
|
||||
down(&sr_ref_sem);
|
||||
mutex_lock(&sr_ref_mutex);
|
||||
kref_put(&cd->kref, sr_kref_release);
|
||||
up(&sr_ref_sem);
|
||||
mutex_unlock(&sr_ref_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,6 +31,79 @@ static int xa_test = 0;
|
||||
|
||||
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
|
||||
|
||||
@ -45,7 +118,8 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
|
||||
struct packet_command cgc;
|
||||
int ntracks, ret;
|
||||
|
||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr)))
|
||||
ret = sr_read_tochdr(cdi, &tochdr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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_format = CDROM_MSF;
|
||||
|
||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk0_te)))
|
||||
ret = sr_read_tocentry(cdi, &trk0_te);
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk1_te)))
|
||||
ret = sr_read_tocentry(cdi, &trk1_te);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
error code is. Normally the UNIT_ATTENTION code will automatically
|
||||
clear after one error */
|
||||
@ -229,13 +329,14 @@ int sr_disk_status(struct cdrom_device_info *cdi)
|
||||
int i, rc, have_datatracks = 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) {
|
||||
toc_e.cdte_track = i;
|
||||
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;
|
||||
if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) {
|
||||
have_datatracks = 1;
|
||||
@ -262,10 +363,6 @@ int sr_get_last_session(struct cdrom_device_info *cdi,
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
case CDROMREADTOCHDR:
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return sr_read_tochdr(cdi, arg);
|
||||
case CDROMREADTOCENTRY:
|
||||
{
|
||||
struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) 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;
|
||||
}
|
||||
|
||||
return sr_read_tocentry(cdi, arg);
|
||||
case CDROMPLAYTRKIND:
|
||||
return sr_play_trkind(cdi, arg);
|
||||
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;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
|
@ -38,6 +38,7 @@ static const char *verstr = "20050830";
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <asm/uaccess.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_remove(struct device *);
|
||||
static int st_init_command(struct scsi_cmnd *);
|
||||
|
||||
static void do_create_driverfs_files(void);
|
||||
static void do_remove_driverfs_files(void);
|
||||
@ -206,7 +206,6 @@ static struct scsi_driver st_template = {
|
||||
.probe = st_probe,
|
||||
.remove = st_remove,
|
||||
},
|
||||
.init_command = st_init_command,
|
||||
};
|
||||
|
||||
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)
|
||||
|
||||
static DECLARE_MUTEX(st_ref_sem);
|
||||
static DEFINE_MUTEX(st_ref_mutex);
|
||||
|
||||
|
||||
#include "osst_detect.h"
|
||||
@ -237,7 +236,7 @@ static struct scsi_tape *scsi_tape_get(int dev)
|
||||
{
|
||||
struct scsi_tape *STp = NULL;
|
||||
|
||||
down(&st_ref_sem);
|
||||
mutex_lock(&st_ref_mutex);
|
||||
write_lock(&st_dev_arr_lock);
|
||||
|
||||
if (dev < st_dev_max && scsi_tapes != NULL)
|
||||
@ -259,7 +258,7 @@ out_put:
|
||||
STp = NULL;
|
||||
out:
|
||||
write_unlock(&st_dev_arr_lock);
|
||||
up(&st_ref_sem);
|
||||
mutex_unlock(&st_ref_mutex);
|
||||
return STp;
|
||||
}
|
||||
|
||||
@ -267,10 +266,10 @@ static void scsi_tape_put(struct scsi_tape *STp)
|
||||
{
|
||||
struct scsi_device *sdev = STp->device;
|
||||
|
||||
down(&st_ref_sem);
|
||||
mutex_lock(&st_ref_mutex);
|
||||
kref_put(&STp->kref, scsi_tape_release);
|
||||
scsi_device_put(sdev);
|
||||
up(&st_ref_sem);
|
||||
mutex_unlock(&st_ref_mutex);
|
||||
}
|
||||
|
||||
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);
|
||||
up(&st_ref_sem);
|
||||
mutex_unlock(&st_ref_mutex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -4156,7 +4155,7 @@ static int st_remove(struct device *dev)
|
||||
* scsi_tape_release - Called to free the Scsi_Tape structure
|
||||
* @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()
|
||||
* scsi_tape_put() helpers which manipulate the semaphore directly
|
||||
* and never do a direct kref_put().
|
||||
@ -4180,29 +4179,6 @@ static void scsi_tape_release(struct kref *kref)
|
||||
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)
|
||||
{
|
||||
validate_options();
|
||||
|
@ -181,6 +181,7 @@
|
||||
#define PCI_DEVICE_ID_LSI_FC929X 0x0626
|
||||
#define PCI_DEVICE_ID_LSI_FC939X 0x0642
|
||||
#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_NCR_YELLOWFIN 0x0701
|
||||
#define PCI_DEVICE_ID_LSI_61C102 0x0901
|
||||
|
@ -31,9 +31,11 @@ enum raid_level {
|
||||
RAID_LEVEL_LINEAR,
|
||||
RAID_LEVEL_0,
|
||||
RAID_LEVEL_1,
|
||||
RAID_LEVEL_10,
|
||||
RAID_LEVEL_3,
|
||||
RAID_LEVEL_4,
|
||||
RAID_LEVEL_5,
|
||||
RAID_LEVEL_50,
|
||||
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_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))
|
||||
|
||||
/*
|
||||
|
@ -31,6 +31,12 @@ extern const unsigned char scsi_command_size[8];
|
||||
#define MAX_SCSI_DEVICE_CODE 15
|
||||
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
|
||||
*/
|
||||
|
@ -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_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
|
||||
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 */
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct block_device;
|
||||
struct completion;
|
||||
@ -469,7 +470,7 @@ struct Scsi_Host {
|
||||
spinlock_t default_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 task_struct * ehandler; /* Error recovery thread. */
|
||||
|
@ -30,12 +30,9 @@ struct scsi_transport_template {
|
||||
struct transport_container device_attrs;
|
||||
|
||||
/*
|
||||
* If set, call target_parent prior to allocating a scsi_target,
|
||||
* 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.
|
||||
* If set, called from sysfs and legacy procfs rescanning code.
|
||||
*/
|
||||
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
|
||||
* 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
Loading…
Reference in New Issue
Block a user