You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (85 commits) [SCSI] 53c700: remove reliance on deprecated cmnd fields [SCSI] hptiop: don't use cmnd->bufflen [SCSI] hptiop: HighPoint RocketRAID 3xxx controller driver [SCSI] aacraid: small misc. cleanups [SCSI] aacraid: Update supported product information [SCSI] aacraid: Fix return code interpretation [SCSI] scsi_transport_sas: fix panic in sas_free_rphy [SCSI] remove RQ_SCSI_* flags [SCSI] remove scsi_request infrastructure [SCSI] mptfusion: change driver revision to 3.03.10 [SCSI] mptfc: abort of board reset leaves port dead requiring reboot [SCSI] mptfc: fix fibre channel infinite request/response loop [SCSI] mptfc: set fibre channel fw target missing timers to one second [SCSI] mptfusion: move fc event/reset handling to mptfc [SCSI] spi transport: don't allow dt to be set on SE or HVD buses [SCSI] aic7xxx: expose the bus setting to sysfs [SCSI] scsi: remove Documentation/scsi/cpqfc.txt [SCSI] drivers/scsi: Use ARRAY_SIZE macro [SCSI] Remove last page_address from dc395x.c [SCSI] hptiop: HighPoint RocketRAID 3xxx controller driver ... Fixed up conflicts in drivers/message/fusion/mptbase.c manually (due to the sparc interrupt cleanups)
This commit is contained in:
@@ -30,8 +30,6 @@ aic7xxx.txt
|
||||
- info on driver for Adaptec controllers
|
||||
aic7xxx_old.txt
|
||||
- info on driver for Adaptec controllers, old generation
|
||||
cpqfc.txt
|
||||
- info on driver for Compaq Tachyon TS adapters
|
||||
dpti.txt
|
||||
- info on driver for DPT SmartRAID and Adaptec I2O RAID based adapters
|
||||
dtc3x80.txt
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
|
||||
1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
|
||||
2 Current Version : 00.00.02.04
|
||||
3 Older Version : 00.00.02.04
|
||||
|
||||
i. Remove superflous instance_lock
|
||||
|
||||
gets rid of the otherwise superflous instance_lock and avoids an unsave
|
||||
unsynchronized access in the error handler.
|
||||
|
||||
- Christoph Hellwig <hch@lst.de>
|
||||
|
||||
|
||||
1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>
|
||||
2 Current Version : 00.00.02.04
|
||||
3 Older Version : 00.00.02.04
|
||||
|
||||
@@ -24,10 +24,10 @@ Supported Cards/Chipsets
|
||||
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:103c:3227 Adaptec 2610SA (Bearcat HP release)
|
||||
9005:0285:9005:0292 Adaptec 2810SA (Corsair-8)
|
||||
9005:0285:9005:0294 Adaptec Prowler
|
||||
9005:0286:9005:029d Adaptec 2420SA (Intruder)
|
||||
9005:0286:9005:029d Adaptec 2420SA (Intruder HP release)
|
||||
9005:0286:9005:029c Adaptec 2620SA (Intruder)
|
||||
9005:0286:9005:029b Adaptec 2820SA (Intruder)
|
||||
9005:0286:9005:02a7 Adaptec 2830SA (Skyray)
|
||||
@@ -38,7 +38,7 @@ Supported Cards/Chipsets
|
||||
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)
|
||||
9005:0286:9005:02a2 Adaptec 3800SAS (Hurricane44)
|
||||
1011:0046:9005:0364 Adaptec 5400S (Mustang)
|
||||
1011:0046:9005:0365 Adaptec 5400S (Mustang)
|
||||
9005:0283:9005:0283 Adaptec Catapult (3210S with arc firmware)
|
||||
@@ -72,7 +72,7 @@ Supported Cards/Chipsets
|
||||
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:02a3 ICP ICP5445AU (Hurricane44)
|
||||
9005:0286:9005:02a6 ICP ICP9067MA (Intruder-6)
|
||||
9005:0286:9005:02a9 ICP ICP5087AU (Skyray)
|
||||
9005:0286:9005:02aa ICP ICP5047AU (Skyray)
|
||||
|
||||
@@ -1,272 +0,0 @@
|
||||
Notes for CPQFCTS driver for Compaq Tachyon TS
|
||||
Fibre Channel Host Bus Adapter, PCI 64-bit, 66MHz
|
||||
for Linux (RH 6.1, 6.2 kernel 2.2.12-32, 2.2.14-5)
|
||||
SMP tested
|
||||
Tested in single and dual HBA configuration, 32 and 64bit busses,
|
||||
33 and 66MHz. Only supports FC-AL.
|
||||
SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc()
|
||||
max of 128k bytes contiguous.
|
||||
|
||||
Ver 2.5.4 Oct 03, 2002
|
||||
* fixed memcpy of sense buffer in ioctl to copy the smaller defined size
|
||||
Ver 2.5.3 Aug 01, 2002
|
||||
* fix the passthru ioctl to handle the Scsi_Cmnd->request being a pointer
|
||||
Ver 2.5.1 Jul 30, 2002
|
||||
* fix ioctl to pay attention to the specified LUN.
|
||||
Ver 2.5.0 Nov 29, 2001
|
||||
* eliminated io_request_lock. This change makes the driver specific
|
||||
to the 2.5.x kernels.
|
||||
* silenced excessively noisy printks.
|
||||
|
||||
Ver 2.1.2 July 23, 2002
|
||||
* initialize DumCmnd->lun in cpqfcTS_ioctl (used in fcFindLoggedInPorts as LUN index)
|
||||
|
||||
Ver 2.1.1 Oct 18, 2001
|
||||
* reinitialize Cmnd->SCp.sent_command (used to identify commands as
|
||||
passthrus) on calling scsi_done, since the scsi mid layer does not
|
||||
use (or reinitialize) this field to prevent subsequent comands from
|
||||
having it set incorrectly.
|
||||
|
||||
Ver 2.1.0 Aug 27, 2001
|
||||
* Revise driver to use new kernel 2.4.x PCI DMA API, instead of
|
||||
virt_to_bus(). (enables driver to work w/ ia64 systems with >2Gb RAM.)
|
||||
Rework main scatter-gather code to handle cases where SG element
|
||||
lengths are larger than 0x7FFFF bytes and use as many scatter
|
||||
gather pages as necessary. (Steve Cameron)
|
||||
* Makefile changes to bring cpqfc into line w/ rest of SCSI drivers
|
||||
(thanks to Keith Owens)
|
||||
|
||||
Ver 2.0.5 Aug 06, 2001
|
||||
* Reject non-existent luns in the driver rather than letting the
|
||||
hardware do it. (some HW behaves differently than others in this area.)
|
||||
* Changed Makefile to rely on "make dep" instead of explicit dependencies
|
||||
* ifdef'ed out fibre channel analyzer triggering debug code
|
||||
* fixed a jiffies wrapping issue
|
||||
|
||||
Ver 2.0.4 Aug 01, 2001
|
||||
* Incorporated fix for target device reset from Steeleye
|
||||
* Fixed passthrough ioctl so it doesn't hang.
|
||||
* Fixed hang in launch_FCworker_thread() that occurred on some machines.
|
||||
* Avoid problem when number of volumes in a single cabinet > 8
|
||||
|
||||
Ver 2.0.2 July 23, 2001
|
||||
Changed the semiphore changes so the driver would compile in 2.4.7.
|
||||
This version is for 2.4.7 and beyond.
|
||||
|
||||
Ver 2.0.1 May 7, 2001
|
||||
Merged version 1.3.6 fixes into version 2.0.0.
|
||||
|
||||
Ver 2.0.0 May 7, 2001
|
||||
Fixed problem so spinlock is being initialized to UNLOCKED.
|
||||
Fixed updated driver so it compiles in the 2.4 tree.
|
||||
|
||||
Ver 1.3.6 Feb 27, 2001
|
||||
Added Target_Device_Reset function for SCSI error handling
|
||||
Fixed problem with not reseting addressing mode after implicit logout
|
||||
|
||||
|
||||
Ver 1.3.4 Sep 7, 2000
|
||||
Added Modinfo information
|
||||
Fixed problem with statically linking the driver
|
||||
|
||||
Ver 1.3.3, Aug 23, 2000
|
||||
Fixed device/function number in ioctl
|
||||
|
||||
Ver 1.3.2, July 27, 2000
|
||||
Add include for Alpha compile on 2.2.14 kernel (cpq*i2c.c)
|
||||
Change logic for different FCP-RSP sense_buffer location for HSG80 target
|
||||
And search for Agilent Tachyon XL2 HBAs (not finished! - in test)
|
||||
|
||||
Tested with
|
||||
(storage):
|
||||
Compaq RA-4x000, RAID firmware ver 2.40 - 2.54
|
||||
Seagate FC drives model ST39102FC, rev 0006
|
||||
Hitachi DK31CJ-72FC rev J8A8
|
||||
IBM DDYF-T18350R rev F60K
|
||||
Compaq FC-SCSI bridge w/ DLT 35/70 Gb DLT (tape)
|
||||
(servers):
|
||||
Compaq PL-1850R
|
||||
Compaq PL-6500 Xeon (400MHz)
|
||||
Compaq PL-8500 (500MHz, 66MHz, 64bit PCI)
|
||||
Compaq Alpha DS20 (RH 6.1)
|
||||
(hubs):
|
||||
Vixel Rapport 1000 (7-port "dumb")
|
||||
Gadzoox Gibralter (12-port "dumb")
|
||||
Gadzoox Capellix 2000, 3000
|
||||
(switches):
|
||||
Brocade 2010, 2400, 2800, rev 2.0.3a (& later)
|
||||
Gadzoox 3210 (Fabric blade beta)
|
||||
Vixel 7100 (Fabric beta firmare - known hot plug issues)
|
||||
using "qa_test" (esp. io_test script) suite modified from Unix tests.
|
||||
|
||||
Installation:
|
||||
make menuconfig
|
||||
(select SCSI low-level, Compaq FC HBA)
|
||||
make modules
|
||||
make modules_install
|
||||
|
||||
e.g. insmod -f cpqfc
|
||||
|
||||
Due to Fabric/switch delays, driver requires 4 seconds
|
||||
to initialize. If adapters are found, there will be a entries at
|
||||
/proc/scsi/cpqfcTS/*
|
||||
|
||||
sample contents of startup messages
|
||||
|
||||
*************************
|
||||
scsi_register allocating 3596 bytes for CPQFCHBA
|
||||
ioremap'd Membase: c887e600
|
||||
HBA Tachyon RevId 1.2
|
||||
Allocating 119808 for 576 Exchanges @ c0dc0000
|
||||
Allocating 112904 for LinkQ @ c0c20000 (576 elements)
|
||||
Allocating 110600 for TachSEST for 512 Exchanges
|
||||
cpqfcTS: writing IMQ BASE 7C0000h PI 7C4000h
|
||||
cpqfcTS: SEST c0e40000(virt): Wrote base E40000h @ c887e740
|
||||
cpqfcTS: New FC port 0000E8h WWN: 500507650642499D SCSI Chan/Trgt 0/0
|
||||
cpqfcTS: New FC port 0000EFh WWN: 50000E100000D5A6 SCSI Chan/Trgt 0/1
|
||||
cpqfcTS: New FC port 0000E4h WWN: 21000020370097BB SCSI Chan/Trgt 0/2
|
||||
cpqfcTS: New FC port 0000E2h WWN: 2100002037009946 SCSI Chan/Trgt 0/3
|
||||
cpqfcTS: New FC port 0000E1h WWN: 21000020370098FE SCSI Chan/Trgt 0/4
|
||||
cpqfcTS: New FC port 0000E0h WWN: 21000020370097B2 SCSI Chan/Trgt 0/5
|
||||
cpqfcTS: New FC port 0000DCh WWN: 2100002037006CC1 SCSI Chan/Trgt 0/6
|
||||
cpqfcTS: New FC port 0000DAh WWN: 21000020370059F6 SCSI Chan/Trgt 0/7
|
||||
cpqfcTS: New FC port 00000Fh WWN: 500805F1FADB0E20 SCSI Chan/Trgt 0/8
|
||||
cpqfcTS: New FC port 000008h WWN: 500805F1FADB0EBA SCSI Chan/Trgt 0/9
|
||||
cpqfcTS: New FC port 000004h WWN: 500805F1FADB1EB9 SCSI Chan/Trgt 0/10
|
||||
cpqfcTS: New FC port 000002h WWN: 500805F1FADB1ADE SCSI Chan/Trgt 0/11
|
||||
cpqfcTS: New FC port 000001h WWN: 500805F1FADBA2CA SCSI Chan/Trgt 0/12
|
||||
scsi4 : Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2: WWN 500508B200193F50
|
||||
on PCI bus 0 device 0xa0fc irq 5 IObaseL 0x3400, MEMBASE 0xc6ef8600
|
||||
PCI bus width 32 bits, bus speed 33 MHz
|
||||
FCP-SCSI Driver v1.3.0
|
||||
GBIC detected: Short-wave. LPSM 0h Monitor
|
||||
scsi : 5 hosts.
|
||||
Vendor: IBM Model: DDYF-T18350R Rev: F60K
|
||||
Type: Direct-Access ANSI SCSI revision: 03
|
||||
Detected scsi disk sdb at scsi4, channel 0, id 0, lun 0
|
||||
Vendor: HITACHI Model: DK31CJ-72FC Rev: J8A8
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdc at scsi4, channel 0, id 1, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdd at scsi4, channel 0, id 2, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sde at scsi4, channel 0, id 3, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdf at scsi4, channel 0, id 4, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdg at scsi4, channel 0, id 5, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdh at scsi4, channel 0, id 6, lun 0
|
||||
Vendor: SEAGATE Model: ST39102FC Rev: 0006
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdi at scsi4, channel 0, id 7, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdj at scsi4, channel 0, id 8, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdk at scsi4, channel 0, id 8, lun 1
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdl at scsi4, channel 0, id 9, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdm at scsi4, channel 0, id 9, lun 1
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdn at scsi4, channel 0, id 10, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdo at scsi4, channel 0, id 11, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdp at scsi4, channel 0, id 11, lun 1
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdq at scsi4, channel 0, id 12, lun 0
|
||||
Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
|
||||
Type: Direct-Access ANSI SCSI revision: 02
|
||||
Detected scsi disk sdr at scsi4, channel 0, id 12, lun 1
|
||||
resize_dma_pool: unknown device type 12
|
||||
resize_dma_pool: unknown device type 12
|
||||
SCSI device sdb: hdwr sector= 512 bytes. Sectors= 35843670 [17501 MB] [17.5 GB]
|
||||
sdb: sdb1
|
||||
SCSI device sdc: hdwr sector= 512 bytes. Sectors= 144410880 [70513 MB] [70.5 GB]
|
||||
sdc: sdc1
|
||||
SCSI device sdd: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sdd: sdd1
|
||||
SCSI device sde: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sde: sde1
|
||||
SCSI device sdf: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sdf: sdf1
|
||||
SCSI device sdg: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sdg: sdg1
|
||||
SCSI device sdh: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sdh: sdh1
|
||||
SCSI device sdi: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
|
||||
sdi: sdi1
|
||||
SCSI device sdj: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB]
|
||||
sdj: sdj1
|
||||
SCSI device sdk: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB]
|
||||
sdk: sdk1
|
||||
SCSI device sdl: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
|
||||
sdl: sdl1
|
||||
SCSI device sdm: hdwr sector= 512 bytes. Sectors= 8380320 [4091 MB] [4.1 GB]
|
||||
sdm: sdm1
|
||||
SCSI device sdn: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
|
||||
sdn: sdn1
|
||||
SCSI device sdo: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
|
||||
sdo: sdo1
|
||||
SCSI device sdp: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
|
||||
sdp: sdp1
|
||||
SCSI device sdq: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB]
|
||||
sdq: sdq1
|
||||
SCSI device sdr: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB]
|
||||
sdr: sdr1
|
||||
|
||||
*************************
|
||||
|
||||
If a GBIC of type Short-wave, Long-wave, or Copper is detected, it will
|
||||
print out; otherwise, "none" is displayed. If the cabling is correct
|
||||
and a loop circuit is completed, you should see "Monitor"; otherwise,
|
||||
"LoopFail" (on open circuit) or some LPSM number/state with bit 3 set.
|
||||
|
||||
|
||||
ERRATA:
|
||||
1. Normally, Linux Scsi queries FC devices with INQUIRY strings. All LUNs
|
||||
found according to INQUIRY should get READ commands at sector 0 to find
|
||||
partition table, etc. Older kernels only query the first 4 devices. Some
|
||||
Linux kernels only look for one LUN per target (i.e. FC device).
|
||||
|
||||
2. Physically removing a device, or a malfunctioning system which hides a
|
||||
device, leads to a 30-second timeout and subsequent _abort call.
|
||||
In some process contexts, this will hang the kernel (crashing the system).
|
||||
Single bit errors in frames and virtually all hot plugging events are
|
||||
gracefully handled with internal driver timer and Abort processing.
|
||||
|
||||
3. Some SCSI drives with error conditions will not handle the 7 second timeout
|
||||
in this software driver, leading to infinite retries on timed out SCSI commands.
|
||||
The 7 secs balances the need to quickly recover from lost frames (esp. on sequence
|
||||
initiatives) and time needed by older/slower/error-state drives in responding.
|
||||
This can be easily changed in "Exchanges[].timeOut".
|
||||
|
||||
4. Due to the nature of FC soft addressing, there is no assurance that the
|
||||
same LUNs (drives) will have the same path (e.g. /dev/sdb1) from one boot to
|
||||
next. Dynamic soft address changes (i.e. 24-bit FC port_id) are
|
||||
supported during run time (e.g. due to hot plug event) by the use of WWN to
|
||||
SCSI Nexus (channel/target/LUN) mapping.
|
||||
|
||||
5. Compaq RA4x00 firmware version 2.54 and later supports SSP (Selective
|
||||
Storage Presentation), which maps LUNs to a WWN. If RA4x00 firmware prior
|
||||
2.54 (e.g. older controller) is used, or the FC HBA is replaced (another WWN
|
||||
is used), logical volumes on the RA4x00 will no longer be visible.
|
||||
|
||||
|
||||
Send questions/comments to:
|
||||
Amy Vanzant-Hodge (fibrechannel@compaq.com)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
HIGHPOINT ROCKETRAID 3xxx RAID DRIVER (hptiop)
|
||||
|
||||
Controller Register Map
|
||||
-------------------------
|
||||
|
||||
The controller IOP is accessed via PCI BAR0.
|
||||
|
||||
BAR0 offset Register
|
||||
0x10 Inbound Message Register 0
|
||||
0x14 Inbound Message Register 1
|
||||
0x18 Outbound Message Register 0
|
||||
0x1C Outbound Message Register 1
|
||||
0x20 Inbound Doorbell Register
|
||||
0x24 Inbound Interrupt Status Register
|
||||
0x28 Inbound Interrupt Mask Register
|
||||
0x30 Outbound Interrupt Status Register
|
||||
0x34 Outbound Interrupt Mask Register
|
||||
0x40 Inbound Queue Port
|
||||
0x44 Outbound Queue Port
|
||||
|
||||
|
||||
I/O Request Workflow
|
||||
----------------------
|
||||
|
||||
All queued requests are handled via inbound/outbound queue port.
|
||||
A request packet can be allocated in either IOP or host memory.
|
||||
|
||||
To send a request to the controller:
|
||||
|
||||
- Get a free request packet by reading the inbound queue port or
|
||||
allocate a free request in host DMA coherent memory.
|
||||
|
||||
The value returned from the inbound queue port is an offset
|
||||
relative to the IOP BAR0.
|
||||
|
||||
Requests allocated in host memory must be aligned on 32-bytes boundary.
|
||||
|
||||
- Fill the packet.
|
||||
|
||||
- Post the packet to IOP by writing it to inbound queue. For requests
|
||||
allocated in IOP memory, write the offset to inbound queue port. For
|
||||
requests allocated in host memory, write (0x80000000|(bus_addr>>5))
|
||||
to the inbound queue port.
|
||||
|
||||
- The IOP process the request. When the request is completed, it
|
||||
will be put into outbound queue. An outbound interrupt will be
|
||||
generated.
|
||||
|
||||
For requests allocated in IOP memory, the request offset is posted to
|
||||
outbound queue.
|
||||
|
||||
For requests allocated in host memory, (0x80000000|(bus_addr>>5))
|
||||
is posted to the outbound queue. If IOP_REQUEST_FLAG_OUTPUT_CONTEXT
|
||||
flag is set in the request, the low 32-bit context value will be
|
||||
posted instead.
|
||||
|
||||
- The host read the outbound queue and complete the request.
|
||||
|
||||
For requests allocated in IOP memory, the host driver free the request
|
||||
by writing it to the outbound queue.
|
||||
|
||||
Non-queued requests (reset/flush etc) can be sent via inbound message
|
||||
register 0. An outbound message with the same value indicates the completion
|
||||
of an inbound message.
|
||||
|
||||
|
||||
User-level Interface
|
||||
---------------------
|
||||
|
||||
The driver exposes following sysfs attributes:
|
||||
|
||||
NAME R/W Description
|
||||
driver-version R driver version string
|
||||
firmware-version R firmware version string
|
||||
|
||||
The driver registers char device "hptiop" to communicate with HighPoint RAID
|
||||
management software. Its ioctl routine acts as a general binary interface
|
||||
between the IOP firmware and HighPoint RAID management software. New management
|
||||
functions can be implemented in application/firmware without modification
|
||||
in driver code.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
linux@highpoint-tech.com
|
||||
http://www.highpoint-tech.com
|
||||
@@ -1147,6 +1147,12 @@ L: linux-hams@vger.kernel.org
|
||||
W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/
|
||||
S: Maintained
|
||||
|
||||
HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
|
||||
P: HighPoint Linux Team
|
||||
M: linux@highpoint-tech.com
|
||||
W: http://www.highpoint-tech.com
|
||||
S: Supported
|
||||
|
||||
HIPPI
|
||||
P: Jes Sorensen
|
||||
M: jes@trained-monkey.org
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#define DAC960_DriverVersion "2.5.47"
|
||||
#define DAC960_DriverDate "14 November 2002"
|
||||
#define DAC960_DriverVersion "2.5.48"
|
||||
#define DAC960_DriverDate "14 May 2006"
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -4780,15 +4780,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
|
||||
(NewPhysicalDeviceInfo->LogicalUnit !=
|
||||
PhysicalDeviceInfo->LogicalUnit))
|
||||
{
|
||||
PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
|
||||
PhysicalDeviceInfo =
|
||||
kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
|
||||
InquiryUnitSerialNumber =
|
||||
(DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
|
||||
kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
|
||||
GFP_ATOMIC);
|
||||
if (InquiryUnitSerialNumber == NULL &&
|
||||
PhysicalDeviceInfo != NULL)
|
||||
if (InquiryUnitSerialNumber == NULL ||
|
||||
PhysicalDeviceInfo == NULL)
|
||||
{
|
||||
kfree(InquiryUnitSerialNumber);
|
||||
InquiryUnitSerialNumber = NULL;
|
||||
kfree(PhysicalDeviceInfo);
|
||||
PhysicalDeviceInfo = NULL;
|
||||
}
|
||||
|
||||
@@ -578,7 +578,7 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
|
||||
|
||||
if (cmd->use_sg) {
|
||||
pci_unmap_sg(ctlr->pdev,
|
||||
cmd->buffer, cmd->use_sg,
|
||||
cmd->request_buffer, cmd->use_sg,
|
||||
cmd->sc_data_direction);
|
||||
}
|
||||
else if (cmd->request_bufflen) {
|
||||
@@ -1210,7 +1210,7 @@ cciss_scatter_gather(struct pci_dev *pdev,
|
||||
struct scsi_cmnd *cmd)
|
||||
{
|
||||
unsigned int use_sg, nsegs=0, len;
|
||||
struct scatterlist *scatter = (struct scatterlist *) cmd->buffer;
|
||||
struct scatterlist *scatter = (struct scatterlist *) cmd->request_buffer;
|
||||
__u64 addr64;
|
||||
|
||||
/* is it just one virtual address? */
|
||||
@@ -1232,7 +1232,7 @@ cciss_scatter_gather(struct pci_dev *pdev,
|
||||
} /* else, must be a list of virtual addresses.... */
|
||||
else if (cmd->use_sg <= MAXSGENTRIES) { /* not too many addrs? */
|
||||
|
||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg,
|
||||
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg,
|
||||
cmd->sc_data_direction);
|
||||
|
||||
for (nsegs=0; nsegs < use_sg; nsegs++) {
|
||||
|
||||
@@ -1185,7 +1185,6 @@ 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->initializing_hba_lock);
|
||||
|
||||
/* Initialize the event logging.
|
||||
@@ -1383,30 +1382,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* Set lookup ptr. */
|
||||
list_add_tail(&ioc->list, &ioc_list);
|
||||
|
||||
ioc->pci_irq = -1;
|
||||
if (pdev->irq) {
|
||||
if (mpt_msi_enable && !pci_enable_msi(pdev))
|
||||
printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name);
|
||||
|
||||
r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
|
||||
|
||||
if (r < 0) {
|
||||
printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
|
||||
ioc->name, pdev->irq);
|
||||
list_del(&ioc->list);
|
||||
iounmap(mem);
|
||||
kfree(ioc);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ioc->pci_irq = pdev->irq;
|
||||
|
||||
pci_set_master(pdev); /* ?? */
|
||||
pci_set_drvdata(pdev, ioc);
|
||||
|
||||
dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
|
||||
}
|
||||
|
||||
/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
|
||||
*/
|
||||
mpt_detect_bound_ports(ioc, pdev);
|
||||
@@ -1416,11 +1391,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
printk(KERN_WARNING MYNAM
|
||||
": WARNING - %s did not initialize properly! (%d)\n",
|
||||
ioc->name, r);
|
||||
|
||||
list_del(&ioc->list);
|
||||
free_irq(ioc->pci_irq, ioc);
|
||||
if (mpt_msi_enable)
|
||||
pci_disable_msi(pdev);
|
||||
if (ioc->alt_ioc)
|
||||
ioc->alt_ioc->alt_ioc = NULL;
|
||||
iounmap(mem);
|
||||
@@ -1639,6 +1610,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
int handlers;
|
||||
int ret = 0;
|
||||
int reset_alt_ioc_active = 0;
|
||||
int irq_allocated = 0;
|
||||
|
||||
printk(KERN_INFO MYNAM ": Initiating %s %s\n",
|
||||
ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
|
||||
@@ -1722,6 +1694,36 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Device is reset now. It must have de-asserted the interrupt line
|
||||
* (if it was asserted) and it should be safe to register for the
|
||||
* interrupt now.
|
||||
*/
|
||||
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
|
||||
ioc->pci_irq = -1;
|
||||
if (ioc->pcidev->irq) {
|
||||
if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
|
||||
printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
|
||||
ioc->name);
|
||||
rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
|
||||
SA_SHIRQ, ioc->name, ioc);
|
||||
if (rc < 0) {
|
||||
printk(MYIOC_s_ERR_FMT "Unable to allocate "
|
||||
"interrupt %d!\n", ioc->name,
|
||||
ioc->pcidev->irq);
|
||||
if (mpt_msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
return -EBUSY;
|
||||
}
|
||||
irq_allocated = 1;
|
||||
ioc->pci_irq = ioc->pcidev->irq;
|
||||
pci_set_master(ioc->pcidev); /* ?? */
|
||||
pci_set_drvdata(ioc->pcidev, ioc);
|
||||
dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
|
||||
"%d\n", ioc->name, ioc->pcidev->irq));
|
||||
}
|
||||
}
|
||||
|
||||
/* Prime reply & request queues!
|
||||
* (mucho alloc's) Must be done prior to
|
||||
* init as upper addresses are needed for init.
|
||||
@@ -1821,7 +1823,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
ret = mptbase_sas_persist_operation(ioc,
|
||||
MPI_SAS_OP_CLEAR_NOT_PRESENT);
|
||||
if(ret != 0)
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Find IM volumes
|
||||
@@ -1829,14 +1831,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
mpt_findImVolumes(ioc);
|
||||
|
||||
} else if (ioc->bus_type == FC) {
|
||||
/*
|
||||
* Pre-fetch FC port WWN and stuff...
|
||||
* (FCPortPage0_t stuff)
|
||||
*/
|
||||
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
|
||||
(void) mptbase_GetFcPortPage0(ioc, ii);
|
||||
}
|
||||
|
||||
if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
|
||||
(ioc->lan_cnfg_page0.Header.PageLength == 0)) {
|
||||
/*
|
||||
@@ -1902,6 +1896,12 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
|
||||
/* FIXME? Examine results here? */
|
||||
}
|
||||
|
||||
out:
|
||||
if ((ret != 0) && irq_allocated) {
|
||||
free_irq(ioc->pci_irq, ioc);
|
||||
if (mpt_msi_enable)
|
||||
pci_disable_msi(ioc->pcidev);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2276,7 +2276,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
|
||||
}
|
||||
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible(1);
|
||||
msleep(1);
|
||||
} else {
|
||||
mdelay (1); /* 1 msec delay */
|
||||
}
|
||||
@@ -2664,7 +2664,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
|
||||
state = mpt_GetIocState(ioc, 1);
|
||||
while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible(1);
|
||||
msleep(1);
|
||||
} else {
|
||||
mdelay(1);
|
||||
}
|
||||
@@ -2916,7 +2916,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
|
||||
|
||||
/* wait 1 msec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible(1);
|
||||
msleep(1);
|
||||
} else {
|
||||
mdelay (1);
|
||||
}
|
||||
@@ -2933,7 +2933,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
|
||||
}
|
||||
/* wait .1 sec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (100);
|
||||
msleep (100);
|
||||
} else {
|
||||
mdelay (100);
|
||||
}
|
||||
@@ -3023,7 +3023,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
|
||||
|
||||
/* wait 1 msec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (1);
|
||||
msleep (1);
|
||||
} else {
|
||||
mdelay (1);
|
||||
}
|
||||
@@ -3071,7 +3071,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
|
||||
return 0;
|
||||
}
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (10);
|
||||
msleep (10);
|
||||
} else {
|
||||
mdelay (10);
|
||||
}
|
||||
@@ -3122,7 +3122,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
|
||||
SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
|
||||
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (1000);
|
||||
msleep (1000);
|
||||
} else {
|
||||
mdelay (1000);
|
||||
}
|
||||
@@ -3144,7 +3144,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
|
||||
return hard_reset_done;
|
||||
}
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (10);
|
||||
msleep (10);
|
||||
} else {
|
||||
mdelay (10);
|
||||
}
|
||||
@@ -3215,7 +3215,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
||||
|
||||
/* wait 100 msec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (100);
|
||||
msleep (100);
|
||||
} else {
|
||||
mdelay (100);
|
||||
}
|
||||
@@ -3294,7 +3294,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
||||
|
||||
/* wait 1 sec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (1000);
|
||||
msleep (1000);
|
||||
} else {
|
||||
mdelay (1000);
|
||||
}
|
||||
@@ -3322,7 +3322,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
||||
|
||||
/* wait 1 sec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (1000);
|
||||
msleep (1000);
|
||||
} else {
|
||||
mdelay (1000);
|
||||
}
|
||||
@@ -3356,7 +3356,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
||||
|
||||
/* wait 100 msec */
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible (100);
|
||||
msleep (100);
|
||||
} else {
|
||||
mdelay (100);
|
||||
}
|
||||
@@ -3450,7 +3450,7 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
|
||||
}
|
||||
|
||||
if (sleepFlag == CAN_SLEEP) {
|
||||
msleep_interruptible(1);
|
||||
msleep(1);
|
||||
} else {
|
||||
mdelay (1); /* 1 msec delay */
|
||||
}
|
||||
@@ -3890,7 +3890,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
|
||||
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
||||
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
|
||||
break;
|
||||
msleep_interruptible (1);
|
||||
msleep (1);
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
@@ -3939,7 +3939,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
|
||||
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
||||
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
|
||||
break;
|
||||
msleep_interruptible(1);
|
||||
msleep(1);
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
@@ -4160,108 +4160,6 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
|
||||
* @ioc: Pointer to MPT_ADAPTER structure
|
||||
* @portnum: IOC Port number
|
||||
*
|
||||
* Return: 0 for success
|
||||
* -ENOMEM if no memory available
|
||||
* -EPERM if not allowed due to ISR context
|
||||
* -EAGAIN if no msg frames currently available
|
||||
* -EFAULT for non-successful reply or no reply (timeout)
|
||||
*/
|
||||
int
|
||||
mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
FCPortPage0_t *ppage0_alloc;
|
||||
FCPortPage0_t *pp0dest;
|
||||
dma_addr_t page0_dma;
|
||||
int data_sz;
|
||||
int copy_sz;
|
||||
int rc;
|
||||
int count = 400;
|
||||
|
||||
|
||||
/* Get FCPort Page 0 header */
|
||||
hdr.PageVersion = 0;
|
||||
hdr.PageLength = 0;
|
||||
hdr.PageNumber = 0;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
|
||||
cfg.cfghdr.hdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0;
|
||||
cfg.pageAddr = portnum;
|
||||
cfg.timeout = 0;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) != 0)
|
||||
return rc;
|
||||
|
||||
if (hdr.PageLength == 0)
|
||||
return 0;
|
||||
|
||||
data_sz = hdr.PageLength * 4;
|
||||
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;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) == 0) {
|
||||
/* save the data */
|
||||
pp0dest = &ioc->fc_port_page0[portnum];
|
||||
copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
|
||||
memcpy(pp0dest, ppage0_alloc, copy_sz);
|
||||
|
||||
/*
|
||||
* Normalize endianness of structure data,
|
||||
* by byte-swapping all > 1 byte fields!
|
||||
*/
|
||||
pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
|
||||
pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
|
||||
pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
|
||||
pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
|
||||
pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
|
||||
pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
|
||||
pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
|
||||
pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
|
||||
pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
|
||||
pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
|
||||
pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
|
||||
pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
|
||||
pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
|
||||
pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
|
||||
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);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/*
|
||||
* mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
|
||||
@@ -6467,7 +6365,6 @@ EXPORT_SYMBOL(mpt_findImVolumes);
|
||||
EXPORT_SYMBOL(mpt_alloc_fw_memory);
|
||||
EXPORT_SYMBOL(mpt_free_fw_memory);
|
||||
EXPORT_SYMBOL(mptbase_sas_persist_operation);
|
||||
EXPORT_SYMBOL(mptbase_GetFcPortPage0);
|
||||
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
@@ -76,8 +76,8 @@
|
||||
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
|
||||
#endif
|
||||
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.09"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09"
|
||||
#define MPT_LINUX_VERSION_COMMON "3.03.10"
|
||||
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.10"
|
||||
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
|
||||
|
||||
#define show_mptmod_ver(s,ver) \
|
||||
@@ -487,6 +487,15 @@ typedef struct _RaidCfgData {
|
||||
int isRaid; /* bit field, 1 if RAID */
|
||||
}RaidCfgData;
|
||||
|
||||
typedef struct _FcCfgData {
|
||||
/* will ultimately hold fc_port_page0 also */
|
||||
struct {
|
||||
FCPortPage1_t *data;
|
||||
dma_addr_t dma;
|
||||
int pg_sz;
|
||||
} fc_port_page1[2];
|
||||
} FcCfgData;
|
||||
|
||||
#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
|
||||
#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
|
||||
|
||||
@@ -565,6 +574,7 @@ typedef struct _MPT_ADAPTER
|
||||
SpiCfgData spi_data; /* Scsi config. data */
|
||||
RaidCfgData raid_data; /* Raid config. data */
|
||||
SasCfgData sas_data; /* Sas config. data */
|
||||
FcCfgData fc_data; /* Fc config. data */
|
||||
MPT_IOCTL *ioctl; /* ioctl data pointer */
|
||||
struct proc_dir_entry *ioc_dentry;
|
||||
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
|
||||
@@ -625,6 +635,7 @@ typedef struct _MPT_ADAPTER
|
||||
int num_ports;
|
||||
struct work_struct mptscsih_persistTask;
|
||||
|
||||
struct work_struct fc_setup_reset_work;
|
||||
struct list_head fc_rports;
|
||||
spinlock_t fc_rescan_work_lock;
|
||||
int fc_rescan_work_count;
|
||||
@@ -1027,7 +1038,6 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
|
||||
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
|
||||
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
|
||||
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
|
||||
extern int mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
|
||||
|
||||
/*
|
||||
* Public data decl's...
|
||||
|
||||
+380
-14
@@ -169,13 +169,6 @@ static struct fc_function_template mptfc_transport_functions = {
|
||||
|
||||
};
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@@ -587,15 +580,266 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||
#ifdef DMPT_DEBUG_FC
|
||||
if (unlikely(err)) {
|
||||
dfcprintk ((MYIOC_s_INFO_FMT
|
||||
"mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n",
|
||||
"mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero, (%x).\n",
|
||||
((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
|
||||
((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
|
||||
SCpnt->device->id,SCpnt->device->lun));
|
||||
SCpnt->device->id,SCpnt->device->lun,err));
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
|
||||
* @ioc: Pointer to MPT_ADAPTER structure
|
||||
* @portnum: IOC Port number
|
||||
*
|
||||
* Return: 0 for success
|
||||
* -ENOMEM if no memory available
|
||||
* -EPERM if not allowed due to ISR context
|
||||
* -EAGAIN if no msg frames currently available
|
||||
* -EFAULT for non-successful reply or no reply (timeout)
|
||||
* -EINVAL portnum arg out of range (hardwired to two elements)
|
||||
*/
|
||||
static int
|
||||
mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
FCPortPage0_t *ppage0_alloc;
|
||||
FCPortPage0_t *pp0dest;
|
||||
dma_addr_t page0_dma;
|
||||
int data_sz;
|
||||
int copy_sz;
|
||||
int rc;
|
||||
int count = 400;
|
||||
|
||||
if (portnum > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get FCPort Page 0 header */
|
||||
hdr.PageVersion = 0;
|
||||
hdr.PageLength = 0;
|
||||
hdr.PageNumber = 0;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
|
||||
cfg.cfghdr.hdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0;
|
||||
cfg.pageAddr = portnum;
|
||||
cfg.timeout = 0;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) != 0)
|
||||
return rc;
|
||||
|
||||
if (hdr.PageLength == 0)
|
||||
return 0;
|
||||
|
||||
data_sz = hdr.PageLength * 4;
|
||||
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;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) == 0) {
|
||||
/* save the data */
|
||||
pp0dest = &ioc->fc_port_page0[portnum];
|
||||
copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
|
||||
memcpy(pp0dest, ppage0_alloc, copy_sz);
|
||||
|
||||
/*
|
||||
* Normalize endianness of structure data,
|
||||
* by byte-swapping all > 1 byte fields!
|
||||
*/
|
||||
pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
|
||||
pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
|
||||
pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
|
||||
pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
|
||||
pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
|
||||
pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
|
||||
pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
|
||||
pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
|
||||
pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
|
||||
pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
|
||||
pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
|
||||
pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
|
||||
pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
|
||||
pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
|
||||
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(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);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
int rc;
|
||||
|
||||
if (portnum > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(ioc->fc_data.fc_port_page1[portnum].data))
|
||||
return -EINVAL;
|
||||
|
||||
/* get fcport page 1 header */
|
||||
hdr.PageVersion = 0;
|
||||
hdr.PageLength = 0;
|
||||
hdr.PageNumber = 1;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
|
||||
cfg.cfghdr.hdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0;
|
||||
cfg.pageAddr = portnum;
|
||||
cfg.timeout = 0;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) != 0)
|
||||
return rc;
|
||||
|
||||
if (hdr.PageLength == 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
||||
cfg.dir = 1;
|
||||
|
||||
rc = mpt_config(ioc, &cfg);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
|
||||
{
|
||||
ConfigPageHeader_t hdr;
|
||||
CONFIGPARMS cfg;
|
||||
FCPortPage1_t *page1_alloc;
|
||||
dma_addr_t page1_dma;
|
||||
int data_sz;
|
||||
int rc;
|
||||
|
||||
if (portnum > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* get fcport page 1 header */
|
||||
hdr.PageVersion = 0;
|
||||
hdr.PageLength = 0;
|
||||
hdr.PageNumber = 1;
|
||||
hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
|
||||
cfg.cfghdr.hdr = &hdr;
|
||||
cfg.physAddr = -1;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfg.dir = 0;
|
||||
cfg.pageAddr = portnum;
|
||||
cfg.timeout = 0;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) != 0)
|
||||
return rc;
|
||||
|
||||
if (hdr.PageLength == 0)
|
||||
return -ENODEV;
|
||||
|
||||
start_over:
|
||||
|
||||
if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
|
||||
data_sz = hdr.PageLength * 4;
|
||||
if (data_sz < sizeof(FCPortPage1_t))
|
||||
data_sz = sizeof(FCPortPage1_t);
|
||||
|
||||
page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
|
||||
data_sz,
|
||||
&page1_dma);
|
||||
if (!page1_alloc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
else {
|
||||
page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
|
||||
page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
|
||||
data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
|
||||
if (hdr.PageLength * 4 > data_sz) {
|
||||
ioc->fc_data.fc_port_page1[portnum].data = NULL;
|
||||
pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
|
||||
page1_alloc, page1_dma);
|
||||
goto start_over;
|
||||
}
|
||||
}
|
||||
|
||||
memset(page1_alloc,0,data_sz);
|
||||
|
||||
cfg.physAddr = page1_dma;
|
||||
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
|
||||
if ((rc = mpt_config(ioc, &cfg)) == 0) {
|
||||
ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
|
||||
ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
|
||||
ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
|
||||
}
|
||||
else {
|
||||
ioc->fc_data.fc_port_page1[portnum].data = NULL;
|
||||
pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
|
||||
page1_alloc, page1_dma);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
|
||||
{
|
||||
int ii;
|
||||
FCPortPage1_t *pp1;
|
||||
|
||||
#define MPTFC_FW_DEVICE_TIMEOUT (1)
|
||||
#define MPTFC_FW_IO_PEND_TIMEOUT (1)
|
||||
#define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
|
||||
#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
|
||||
|
||||
for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
|
||||
if (mptfc_GetFcPortPage1(ioc, ii) != 0)
|
||||
continue;
|
||||
pp1 = ioc->fc_data.fc_port_page1[ii].data;
|
||||
if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
|
||||
&& (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
|
||||
&& ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
|
||||
&& ((pp1->Flags & OFF_FLAGS) == 0))
|
||||
continue;
|
||||
pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
|
||||
pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
|
||||
pp1->Flags &= ~OFF_FLAGS;
|
||||
pp1->Flags |= ON_FLAGS;
|
||||
mptfc_WriteFcPortPage1(ioc, ii);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
|
||||
{
|
||||
@@ -628,6 +872,31 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
|
||||
fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
|
||||
}
|
||||
|
||||
static void
|
||||
mptfc_setup_reset(void *arg)
|
||||
{
|
||||
MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
|
||||
u64 pn;
|
||||
struct mptfc_rport_info *ri;
|
||||
|
||||
/* reset about to happen, delete (block) all rports */
|
||||
list_for_each_entry(ri, &ioc->fc_rports, list) {
|
||||
if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
|
||||
ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
|
||||
fc_remote_port_delete(ri->rport); /* won't sleep */
|
||||
ri->rport = NULL;
|
||||
|
||||
pn = (u64)ri->pg0.WWPN.High << 32 |
|
||||
(u64)ri->pg0.WWPN.Low;
|
||||
dfcprintk ((MYIOC_s_INFO_FMT
|
||||
"mptfc_setup_reset.%d: %llx deleted\n",
|
||||
ioc->name,
|
||||
ioc->sh->host_no,
|
||||
(unsigned long long)pn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mptfc_rescan_devices(void *arg)
|
||||
{
|
||||
@@ -651,7 +920,7 @@ mptfc_rescan_devices(void *arg)
|
||||
* will reregister existing rports
|
||||
*/
|
||||
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
|
||||
(void) mptbase_GetFcPortPage0(ioc, ii);
|
||||
(void) mptfc_GetFcPortPage0(ioc, ii);
|
||||
mptfc_init_host_attr(ioc,ii); /* refresh */
|
||||
mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
|
||||
}
|
||||
@@ -753,7 +1022,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto out_mptfc_probe;
|
||||
}
|
||||
|
||||
spin_lock_init(&ioc->fc_rescan_work_lock);
|
||||
INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
|
||||
INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc);
|
||||
|
||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||
|
||||
@@ -888,6 +1159,15 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (!ioc->fc_rescan_work_q)
|
||||
goto out_mptfc_probe;
|
||||
|
||||
/*
|
||||
* Pre-fetch FC port WWN and stuff...
|
||||
* (FCPortPage0_t stuff)
|
||||
*/
|
||||
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
|
||||
(void) mptfc_GetFcPortPage0(ioc, ii);
|
||||
}
|
||||
mptfc_SetFcPortPage1_defaults(ioc);
|
||||
|
||||
/*
|
||||
* scan for rports -
|
||||
* by doing it via the workqueue, some locking is eliminated
|
||||
@@ -917,6 +1197,81 @@ static struct pci_driver mptfc_driver = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||
{
|
||||
MPT_SCSI_HOST *hd;
|
||||
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
|
||||
unsigned long flags;
|
||||
int rc=1;
|
||||
|
||||
devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
|
||||
ioc->name, event));
|
||||
|
||||
if (ioc->sh == NULL ||
|
||||
((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
|
||||
return 1;
|
||||
|
||||
switch (event) {
|
||||
case MPI_EVENT_RESCAN:
|
||||
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
|
||||
if (ioc->fc_rescan_work_q) {
|
||||
if (ioc->fc_rescan_work_count++ == 0) {
|
||||
queue_work(ioc->fc_rescan_work_q,
|
||||
&ioc->fc_rescan_work);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
|
||||
break;
|
||||
default:
|
||||
rc = mptscsih_event_process(ioc,pEvReply);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
|
||||
{
|
||||
int rc;
|
||||
unsigned long flags;
|
||||
|
||||
rc = mptscsih_ioc_reset(ioc,reset_phase);
|
||||
if (rc == 0)
|
||||
return rc;
|
||||
|
||||
|
||||
dtmprintk((KERN_WARNING MYNAM
|
||||
": IOC %s_reset routed to FC host driver!\n",
|
||||
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
|
||||
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
|
||||
|
||||
if (reset_phase == MPT_IOC_SETUP_RESET) {
|
||||
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
|
||||
if (ioc->fc_rescan_work_q) {
|
||||
queue_work(ioc->fc_rescan_work_q,
|
||||
&ioc->fc_setup_reset_work);
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
|
||||
}
|
||||
|
||||
else if (reset_phase == MPT_IOC_PRE_RESET) {
|
||||
}
|
||||
|
||||
else { /* MPT_IOC_POST_RESET */
|
||||
mptfc_SetFcPortPage1_defaults(ioc);
|
||||
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
|
||||
if (ioc->fc_rescan_work_q) {
|
||||
if (ioc->fc_rescan_work_count++ == 0) {
|
||||
queue_work(ioc->fc_rescan_work_q,
|
||||
&ioc->fc_rescan_work);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
/**
|
||||
* mptfc_init - Register MPT adapter(s) as SCSI host(s) with
|
||||
@@ -931,8 +1286,8 @@ mptfc_init(void)
|
||||
|
||||
show_mptmod_ver(my_NAME, my_VERSION);
|
||||
|
||||
/* sanity check module parameter */
|
||||
if (mptfc_dev_loss_tmo == 0)
|
||||
/* sanity check module parameters */
|
||||
if (mptfc_dev_loss_tmo <= 0)
|
||||
mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
|
||||
|
||||
mptfc_transport_template =
|
||||
@@ -945,12 +1300,12 @@ mptfc_init(void)
|
||||
mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
|
||||
mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
|
||||
|
||||
if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
|
||||
if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) {
|
||||
devtverboseprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC event notifications\n"));
|
||||
}
|
||||
|
||||
if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
|
||||
if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) {
|
||||
dprintk((KERN_INFO MYNAM
|
||||
": Registered for IOC reset notifications\n"));
|
||||
}
|
||||
@@ -975,6 +1330,7 @@ mptfc_remove(struct pci_dev *pdev)
|
||||
struct mptfc_rport_info *p, *n;
|
||||
struct workqueue_struct *work_q;
|
||||
unsigned long flags;
|
||||
int ii;
|
||||
|
||||
/* destroy workqueue */
|
||||
if ((work_q=ioc->fc_rescan_work_q)) {
|
||||
@@ -991,6 +1347,16 @@ mptfc_remove(struct pci_dev *pdev)
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
|
||||
if (ioc->fc_data.fc_port_page1[ii].data) {
|
||||
pci_free_consistent(ioc->pcidev,
|
||||
ioc->fc_data.fc_port_page1[ii].pg_sz,
|
||||
(u8 *) ioc->fc_data.fc_port_page1[ii].data,
|
||||
ioc->fc_data.fc_port_page1[ii].dma);
|
||||
ioc->fc_data.fc_port_page1[ii].data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mptscsih_remove(pdev);
|
||||
}
|
||||
|
||||
|
||||
@@ -1922,7 +1922,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
|
||||
msleep_interruptible(250);
|
||||
msleep(250);
|
||||
} while (--loop_count);
|
||||
|
||||
return status;
|
||||
@@ -2521,18 +2521,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
|
||||
hd->cmdPtr = NULL;
|
||||
}
|
||||
|
||||
/* 7. FC: Rescan for blocked rports which might have returned.
|
||||
*/
|
||||
if (ioc->bus_type == FC) {
|
||||
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
|
||||
if (ioc->fc_rescan_work_q) {
|
||||
if (ioc->fc_rescan_work_count++ == 0) {
|
||||
queue_work(ioc->fc_rescan_work_q,
|
||||
&ioc->fc_rescan_work);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
|
||||
}
|
||||
dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
|
||||
|
||||
}
|
||||
@@ -2546,7 +2534,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||
{
|
||||
MPT_SCSI_HOST *hd;
|
||||
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
|
||||
unsigned long flags;
|
||||
|
||||
devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
|
||||
ioc->name, event));
|
||||
@@ -2569,14 +2556,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
|
||||
break;
|
||||
|
||||
case MPI_EVENT_RESCAN: /* 06 */
|
||||
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
|
||||
if (ioc->fc_rescan_work_q) {
|
||||
if (ioc->fc_rescan_work_count++ == 0) {
|
||||
queue_work(ioc->fc_rescan_work_q,
|
||||
&ioc->fc_rescan_work);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
||||
@@ -65,9 +65,7 @@
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include <scsi/sg.h>
|
||||
#include <scsi/sg_request.h>
|
||||
|
||||
#define OSM_NAME "scsi-osm"
|
||||
#define OSM_VERSION "1.316"
|
||||
@@ -588,6 +586,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
|
||||
|
||||
mptr = &msg->body[0];
|
||||
|
||||
#if 0 /* this code can't work */
|
||||
#ifdef CONFIG_I2O_EXT_ADAPTEC
|
||||
if (c->adaptec) {
|
||||
u32 adpt_flags = 0;
|
||||
@@ -624,6 +623,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
|
||||
*mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
|
||||
*mptr++ = cpu_to_le32(adpt_flags | tid);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_aux.c
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
*
|
||||
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
|
||||
* Aron Zeh
|
||||
* Wolfgang Taphorn
|
||||
* Stefan Bader <stefan.bader@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Andreas Herrmann <aherrman@de.ibm.com>
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -29,6 +19,20 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver authors:
|
||||
* Martin Peschke (originator of the driver)
|
||||
* Raimund Schroeder
|
||||
* Aron Zeh
|
||||
* Wolfgang Taphorn
|
||||
* Stefan Bader
|
||||
* Heiko Carstens (kernel 2.6 port of the driver)
|
||||
* Andreas Herrmann
|
||||
* Maxim Shchetynin
|
||||
* Volker Sameske
|
||||
* Ralph Wuerthner
|
||||
*/
|
||||
|
||||
#include "zfcp_ext.h"
|
||||
|
||||
/* accumulated log level (module parameter) */
|
||||
@@ -75,15 +79,9 @@ static struct miscdevice zfcp_cfdc_misc = {
|
||||
/* declare driver module init/cleanup functions */
|
||||
module_init(zfcp_module_init);
|
||||
|
||||
MODULE_AUTHOR("Heiko Carstens <heiko.carstens@de.ibm.com>, "
|
||||
"Andreas Herrman <aherrman@de.ibm.com>, "
|
||||
"Martin Peschke <mpeschke@de.ibm.com>, "
|
||||
"Raimund Schroeder <raimund.schroeder@de.ibm.com>, "
|
||||
"Wolfgang Taphorn <taphorn@de.ibm.com>, "
|
||||
"Aron Zeh <arzeh@de.ibm.com>, "
|
||||
"IBM Deutschland Entwicklung GmbH");
|
||||
MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com");
|
||||
MODULE_DESCRIPTION
|
||||
("FCP (SCSI over Fibre Channel) HBA driver for IBM eServer zSeries");
|
||||
("FCP (SCSI over Fibre Channel) HBA driver for IBM System z9 and zSeries");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_param(device, charp, 0400);
|
||||
@@ -291,12 +289,11 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
|
||||
goto out;
|
||||
}
|
||||
|
||||
sg_list = kmalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL);
|
||||
sg_list = kzalloc(sizeof(struct zfcp_sg_list), GFP_KERNEL);
|
||||
if (sg_list == NULL) {
|
||||
retval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memset(sg_list, 0, sizeof(*sg_list));
|
||||
|
||||
if (command != ZFCP_CFDC_IOC) {
|
||||
ZFCP_LOG_INFO("IOC request code 0x%x invalid\n", command);
|
||||
@@ -478,14 +475,13 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
|
||||
sg_list->count = size >> PAGE_SHIFT;
|
||||
if (size & ~PAGE_MASK)
|
||||
sg_list->count++;
|
||||
sg_list->sg = kmalloc(sg_list->count * sizeof(struct scatterlist),
|
||||
sg_list->sg = kcalloc(sg_list->count, sizeof(struct scatterlist),
|
||||
GFP_KERNEL);
|
||||
if (sg_list->sg == NULL) {
|
||||
sg_list->count = 0;
|
||||
retval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
memset(sg_list->sg, 0, sg_list->count * sizeof(struct scatterlist));
|
||||
|
||||
for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
|
||||
sg->length = min(size, PAGE_SIZE);
|
||||
@@ -744,7 +740,7 @@ struct zfcp_unit *
|
||||
zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
||||
{
|
||||
struct zfcp_unit *unit, *tmp_unit;
|
||||
scsi_lun_t scsi_lun;
|
||||
unsigned int scsi_lun;
|
||||
int found;
|
||||
|
||||
/*
|
||||
@@ -758,10 +754,9 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
|
||||
if (unit)
|
||||
return NULL;
|
||||
|
||||
unit = kmalloc(sizeof (struct zfcp_unit), GFP_KERNEL);
|
||||
unit = kzalloc(sizeof (struct zfcp_unit), GFP_KERNEL);
|
||||
if (!unit)
|
||||
return NULL;
|
||||
memset(unit, 0, sizeof (struct zfcp_unit));
|
||||
|
||||
/* initialise reference count stuff */
|
||||
atomic_set(&unit->refcount, 0);
|
||||
@@ -929,13 +924,12 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
||||
*/
|
||||
|
||||
/* try to allocate new adapter data structure (zeroed) */
|
||||
adapter = kmalloc(sizeof (struct zfcp_adapter), GFP_KERNEL);
|
||||
adapter = kzalloc(sizeof (struct zfcp_adapter), GFP_KERNEL);
|
||||
if (!adapter) {
|
||||
ZFCP_LOG_INFO("error: allocation of base adapter "
|
||||
"structure failed\n");
|
||||
goto out;
|
||||
}
|
||||
memset(adapter, 0, sizeof (struct zfcp_adapter));
|
||||
|
||||
ccw_device->handler = NULL;
|
||||
|
||||
@@ -997,12 +991,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
||||
/* intitialise SCSI ER timer */
|
||||
init_timer(&adapter->scsi_er_timer);
|
||||
|
||||
/* set FC service class used per default */
|
||||
adapter->fc_service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
|
||||
|
||||
sprintf(adapter->name, "%s", zfcp_get_busid_by_adapter(adapter));
|
||||
ASCEBC(adapter->name, strlen(adapter->name));
|
||||
|
||||
/* mark adapter unusable as long as sysfs registration is not complete */
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
|
||||
|
||||
@@ -1139,10 +1127,9 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
port = kmalloc(sizeof (struct zfcp_port), GFP_KERNEL);
|
||||
port = kzalloc(sizeof (struct zfcp_port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return NULL;
|
||||
memset(port, 0, sizeof (struct zfcp_port));
|
||||
|
||||
/* initialise reference count stuff */
|
||||
atomic_set(&port->refcount, 0);
|
||||
@@ -1354,18 +1341,19 @@ static void
|
||||
zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
|
||||
struct fsf_status_read_buffer *status_buffer)
|
||||
{
|
||||
logi *els_logi = (logi *) status_buffer->payload;
|
||||
struct fsf_plogi *els_plogi;
|
||||
struct zfcp_port *port;
|
||||
unsigned long flags;
|
||||
|
||||
els_plogi = (struct fsf_plogi *) status_buffer->payload;
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
list_for_each_entry(port, &adapter->port_list_head, list) {
|
||||
if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))
|
||||
if (port->wwpn == (*(wwn_t *) &els_plogi->serv_param.wwpn))
|
||||
break;
|
||||
}
|
||||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
|
||||
if (!port || (port->wwpn != (*(wwn_t *) & els_logi->nport_wwn))) {
|
||||
if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) {
|
||||
ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port "
|
||||
"with d_id 0x%08x on adapter %s\n",
|
||||
status_buffer->d_id,
|
||||
@@ -1760,4 +1748,25 @@ zfcp_handle_els_rjt(u32 sq, struct zfcp_ls_rjt_par *rjt_par)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_plogi_evaluate - evaluate PLOGI playload and copy important fields
|
||||
* into zfcp_port structure
|
||||
* @port: zfcp_port structure
|
||||
* @plogi: plogi payload
|
||||
*/
|
||||
void
|
||||
zfcp_plogi_evaluate(struct zfcp_port *port, struct fsf_plogi *plogi)
|
||||
{
|
||||
port->maxframe_size = plogi->serv_param.common_serv_param[7] |
|
||||
((plogi->serv_param.common_serv_param[6] & 0x0F) << 8);
|
||||
if (plogi->serv_param.class1_serv_param[0] & 0x80)
|
||||
port->supported_classes |= FC_COS_CLASS1;
|
||||
if (plogi->serv_param.class2_serv_param[0] & 0x80)
|
||||
port->supported_classes |= FC_COS_CLASS2;
|
||||
if (plogi->serv_param.class3_serv_param[0] & 0x80)
|
||||
port->supported_classes |= FC_COS_CLASS3;
|
||||
if (plogi->serv_param.class4_serv_param[0] & 0x80)
|
||||
port->supported_classes |= FC_COS_CLASS4;
|
||||
}
|
||||
|
||||
#undef ZFCP_LOG_AREA
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_ccw.c
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* CCW driver related routines
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2003, 2004
|
||||
*
|
||||
* Authors:
|
||||
* Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Andreas Herrmann <aherrman@de.ibm.com>
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_dbf.c
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* Debugging facilities
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2005
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_def.h
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
*
|
||||
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
|
||||
* Aron Zeh
|
||||
* Wolfgang Taphorn
|
||||
* Stefan Bader <stefan.bader@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Andreas Herrmann <aherrman@de.ibm.com>
|
||||
* Volker Sameske <sameske@de.ibm.com>
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -50,7 +39,6 @@
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
#include "../../fc4/fc.h"
|
||||
#include "zfcp_fsf.h"
|
||||
#include <asm/ccwdev.h>
|
||||
#include <asm/qdio.h>
|
||||
@@ -64,7 +52,7 @@
|
||||
/********************* GENERAL DEFINES *********************************/
|
||||
|
||||
/* zfcp version number, it consists of major, minor, and patch-level number */
|
||||
#define ZFCP_VERSION "4.5.0"
|
||||
#define ZFCP_VERSION "4.7.0"
|
||||
|
||||
/**
|
||||
* zfcp_sg_to_address - determine kernel address from struct scatterlist
|
||||
@@ -89,13 +77,9 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
|
||||
list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
#define REQUEST_LIST_SIZE 128
|
||||
|
||||
/********************* SCSI SPECIFIC DEFINES *********************************/
|
||||
|
||||
/* 32 bit for SCSI ID and LUN as long as the SCSI stack uses this type */
|
||||
typedef u32 scsi_id_t;
|
||||
typedef u32 scsi_lun_t;
|
||||
|
||||
#define ZFCP_ERP_SCSI_LOW_MEM_TIMEOUT (100*HZ)
|
||||
#define ZFCP_SCSI_ER_TIMEOUT (100*HZ)
|
||||
|
||||
/********************* CIO/QDIO SPECIFIC DEFINES *****************************/
|
||||
@@ -233,8 +217,9 @@ struct fcp_rsp_iu {
|
||||
#define RSP_CODE_TASKMAN_FAILED 5
|
||||
|
||||
/* see fc-fs */
|
||||
#define LS_FAN 0x60000000
|
||||
#define LS_RSCN 0x61040000
|
||||
#define LS_LOGO 0x05000000
|
||||
#define LS_PLOGI 0x03000000
|
||||
|
||||
struct fcp_rscn_head {
|
||||
u8 command;
|
||||
@@ -263,13 +248,6 @@ struct fcp_rscn_element {
|
||||
#define ZFCP_NO_PORTS_PER_DOMAIN 0x10000
|
||||
#define ZFCP_NO_PORTS_PER_FABRIC 0x1000000
|
||||
|
||||
struct fcp_fan {
|
||||
u32 command;
|
||||
u32 fport_did;
|
||||
wwn_t fport_wwpn;
|
||||
wwn_t fport_wwname;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* see fc-ph */
|
||||
struct fcp_logo {
|
||||
u32 command;
|
||||
@@ -507,9 +485,6 @@ struct zfcp_rc_entry {
|
||||
|
||||
#define ZFCP_NAME "zfcp"
|
||||
|
||||
/* read-only LUN sharing switch initial value */
|
||||
#define ZFCP_RO_LUN_SHARING_DEFAULTS 0
|
||||
|
||||
/* independent log areas */
|
||||
#define ZFCP_LOG_AREA_OTHER 0
|
||||
#define ZFCP_LOG_AREA_SCSI 1
|
||||
@@ -608,7 +583,6 @@ do { \
|
||||
* and unit
|
||||
*/
|
||||
#define ZFCP_COMMON_FLAGS 0xfff00000
|
||||
#define ZFCP_SPECIFIC_FLAGS 0x000fffff
|
||||
|
||||
/* common status bits */
|
||||
#define ZFCP_STATUS_COMMON_REMOVE 0x80000000
|
||||
@@ -633,11 +607,6 @@ do { \
|
||||
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
|
||||
#define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800
|
||||
|
||||
#define ZFCP_STATUS_ADAPTER_SCSI_UP \
|
||||
(ZFCP_STATUS_COMMON_UNBLOCKED | \
|
||||
ZFCP_STATUS_ADAPTER_REGISTERED)
|
||||
|
||||
|
||||
/* FC-PH/FC-GS well-known address identifiers for generic services */
|
||||
#define ZFCP_DID_MANAGEMENT_SERVICE 0xFFFFFA
|
||||
#define ZFCP_DID_TIME_SERVICE 0xFFFFFB
|
||||
@@ -652,7 +621,6 @@ do { \
|
||||
#define ZFCP_STATUS_PORT_NO_WWPN 0x00000008
|
||||
#define ZFCP_STATUS_PORT_NO_SCSI_ID 0x00000010
|
||||
#define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020
|
||||
#define ZFCP_STATUS_PORT_ACCESS_DENIED 0x00000040
|
||||
|
||||
/* for ports with well known addresses */
|
||||
#define ZFCP_STATUS_PORT_WKA \
|
||||
@@ -908,15 +876,12 @@ struct zfcp_adapter {
|
||||
wwn_t peer_wwpn; /* P2P peer WWPN */
|
||||
u32 peer_d_id; /* P2P peer D_ID */
|
||||
struct ccw_device *ccw_device; /* S/390 ccw device */
|
||||
u8 fc_service_class;
|
||||
u32 hydra_version; /* Hydra version */
|
||||
u32 fsf_lic_version;
|
||||
u32 adapter_features; /* FCP channel features */
|
||||
u32 connection_features; /* host connection features */
|
||||
u32 hardware_version; /* of FCP channel */
|
||||
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
|
||||
unsigned short scsi_host_no; /* Assigned host number */
|
||||
unsigned char name[9];
|
||||
struct list_head port_list_head; /* remote port list */
|
||||
struct list_head port_remove_lh; /* head of ports to be
|
||||
removed */
|
||||
@@ -994,6 +959,8 @@ struct zfcp_port {
|
||||
u32 handle; /* handle assigned by FSF */
|
||||
struct zfcp_erp_action erp_action; /* pending error recovery */
|
||||
atomic_t erp_counter;
|
||||
u32 maxframe_size;
|
||||
u32 supported_classes;
|
||||
};
|
||||
|
||||
/* the struct device sysfs_device must be at the beginning of this structure.
|
||||
@@ -1008,7 +975,7 @@ struct zfcp_unit {
|
||||
refcount drop to zero */
|
||||
struct zfcp_port *port; /* remote port of unit */
|
||||
atomic_t status; /* status of this logical unit */
|
||||
scsi_lun_t scsi_lun; /* own SCSI LUN */
|
||||
unsigned int scsi_lun; /* own SCSI LUN */
|
||||
fcp_lun_t fcp_lun; /* own FCP_LUN */
|
||||
u32 handle; /* handle assigned by FSF */
|
||||
struct scsi_device *device; /* scsi device struct pointer */
|
||||
@@ -1052,11 +1019,6 @@ struct zfcp_data {
|
||||
struct list_head adapter_list_head; /* head of adapter list */
|
||||
struct list_head adapter_remove_lh; /* head of adapters to be
|
||||
removed */
|
||||
rwlock_t status_read_lock; /* for status read thread */
|
||||
struct list_head status_read_receive_head;
|
||||
struct list_head status_read_send_head;
|
||||
struct semaphore status_read_sema;
|
||||
wait_queue_head_t status_read_thread_wqh;
|
||||
u32 adapters; /* # of adapters in list */
|
||||
rwlock_t config_lock; /* serialises changes
|
||||
to adapter/port/unit
|
||||
@@ -1095,9 +1057,6 @@ struct zfcp_fsf_req_pool_element {
|
||||
|
||||
/********************** ZFCP SPECIFIC DEFINES ********************************/
|
||||
|
||||
#define ZFCP_FSFREQ_CLEANUP_TIMEOUT HZ/10
|
||||
|
||||
#define ZFCP_KNOWN 0x00000001
|
||||
#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
|
||||
#define ZFCP_WAIT_FOR_SBAL 0x00000004
|
||||
#define ZFCP_REQ_NO_QTCB 0x00000008
|
||||
@@ -1105,9 +1064,6 @@ struct zfcp_fsf_req_pool_element {
|
||||
#define ZFCP_SET 0x00000100
|
||||
#define ZFCP_CLEAR 0x00000200
|
||||
|
||||
#define ZFCP_INTERRUPTIBLE 1
|
||||
#define ZFCP_UNINTERRUPTIBLE 0
|
||||
|
||||
#ifndef atomic_test_mask
|
||||
#define atomic_test_mask(mask, target) \
|
||||
((atomic_read(target) & mask) == mask)
|
||||
|
||||
+32
-241
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,8 @@
|
||||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_ext.h
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
*
|
||||
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
|
||||
* Aron Zeh
|
||||
* Wolfgang Taphorn
|
||||
* Stefan Bader <stefan.bader@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Andreas Herrmann <aherrman@de.ibm.com>
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -125,6 +115,7 @@ extern int zfcp_nameserver_enqueue(struct zfcp_adapter *);
|
||||
extern int zfcp_ns_gid_pn_request(struct zfcp_erp_action *);
|
||||
extern int zfcp_check_ct_response(struct ct_hdr *);
|
||||
extern int zfcp_handle_els_rjt(u32, struct zfcp_ls_rjt_par *);
|
||||
extern void zfcp_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
|
||||
|
||||
/******************************* SCSI ****************************************/
|
||||
extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
|
||||
@@ -141,8 +132,6 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *,
|
||||
struct scsi_cmnd *, struct timer_list *);
|
||||
extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
|
||||
struct timer_list *);
|
||||
extern void zfcp_set_fc_host_attrs(struct zfcp_adapter *);
|
||||
extern void zfcp_set_fc_rport_attrs(struct zfcp_port *);
|
||||
extern struct scsi_transport_template *zfcp_transport_template;
|
||||
extern struct fc_function_template zfcp_transport_functions;
|
||||
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
/*
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_fsf.c
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
*
|
||||
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
|
||||
* Aron Zeh
|
||||
* Wolfgang Taphorn
|
||||
* Stefan Bader <stefan.bader@de.ibm.com>
|
||||
* Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
* Andreas Herrmann <aherrman@de.ibm.com>
|
||||
* Volker Sameske <sameske@de.ibm.com>
|
||||
* (C) Copyright IBM Corp. 2002, 2006
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -877,6 +866,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
|
||||
struct zfcp_adapter *adapter = fsf_req->adapter;
|
||||
struct fsf_status_read_buffer *status_buffer =
|
||||
(struct fsf_status_read_buffer *) fsf_req->data;
|
||||
struct fsf_bit_error_payload *fsf_bit_error;
|
||||
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
|
||||
zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer);
|
||||
@@ -903,10 +893,37 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
|
||||
break;
|
||||
|
||||
case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
|
||||
ZFCP_LOG_NORMAL("Bit error threshold data received:\n");
|
||||
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
|
||||
(char *) status_buffer,
|
||||
sizeof (struct fsf_status_read_buffer));
|
||||
fsf_bit_error = (struct fsf_bit_error_payload *)
|
||||
status_buffer->payload;
|
||||
ZFCP_LOG_NORMAL("Warning: bit error threshold data "
|
||||
"received (adapter %s, "
|
||||
"link failures = %i, loss of sync errors = %i, "
|
||||
"loss of signal errors = %i, "
|
||||
"primitive sequence errors = %i, "
|
||||
"invalid transmission word errors = %i, "
|
||||
"CRC errors = %i)\n",
|
||||
zfcp_get_busid_by_adapter(adapter),
|
||||
fsf_bit_error->link_failure_error_count,
|
||||
fsf_bit_error->loss_of_sync_error_count,
|
||||
fsf_bit_error->loss_of_signal_error_count,
|
||||
fsf_bit_error->primitive_sequence_error_count,
|
||||
fsf_bit_error->invalid_transmission_word_error_count,
|
||||
fsf_bit_error->crc_error_count);
|
||||
ZFCP_LOG_INFO("Additional bit error threshold data "
|
||||
"(adapter %s, "
|
||||
"primitive sequence event time-outs = %i, "
|
||||
"elastic buffer overrun errors = %i, "
|
||||
"advertised receive buffer-to-buffer credit = %i, "
|
||||
"current receice buffer-to-buffer credit = %i, "
|
||||
"advertised transmit buffer-to-buffer credit = %i, "
|
||||
"current transmit buffer-to-buffer credit = %i)\n",
|
||||
zfcp_get_busid_by_adapter(adapter),
|
||||
fsf_bit_error->primitive_sequence_event_timeout_count,
|
||||
fsf_bit_error->elastic_buffer_overrun_error_count,
|
||||
fsf_bit_error->advertised_receive_b2b_credit,
|
||||
fsf_bit_error->current_receive_b2b_credit,
|
||||
fsf_bit_error->advertised_transmit_b2b_credit,
|
||||
fsf_bit_error->current_transmit_b2b_credit);
|
||||
break;
|
||||
|
||||
case FSF_STATUS_READ_LINK_DOWN:
|
||||
@@ -1427,7 +1444,8 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
|
||||
|
||||
/* settings in QTCB */
|
||||
fsf_req->qtcb->header.port_handle = port->handle;
|
||||
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
|
||||
fsf_req->qtcb->bottom.support.service_class =
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT;
|
||||
fsf_req->qtcb->bottom.support.timeout = ct->timeout;
|
||||
fsf_req->data = (unsigned long) ct;
|
||||
|
||||
@@ -1496,18 +1514,10 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
|
||||
break;
|
||||
|
||||
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
|
||||
if (adapter->fc_service_class <= 3) {
|
||||
ZFCP_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_port(port),
|
||||
adapter->fc_service_class);
|
||||
} else {
|
||||
ZFCP_LOG_INFO("bug: The fibre channel class at the "
|
||||
"adapter %s is invalid. "
|
||||
"(debug info %d)\n",
|
||||
zfcp_get_busid_by_port(port),
|
||||
adapter->fc_service_class);
|
||||
}
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT);
|
||||
/* stop operation for this adapter */
|
||||
debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
@@ -1730,7 +1740,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
|
||||
|
||||
/* settings in QTCB */
|
||||
fsf_req->qtcb->bottom.support.d_id = d_id;
|
||||
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
|
||||
fsf_req->qtcb->bottom.support.service_class =
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT;
|
||||
fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT;
|
||||
fsf_req->data = (unsigned long) els;
|
||||
|
||||
@@ -1800,18 +1811,10 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
|
||||
break;
|
||||
|
||||
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
|
||||
if (adapter->fc_service_class <= 3) {
|
||||
ZFCP_LOG_INFO("error: adapter %s does "
|
||||
"not support fibrechannel class %d.\n",
|
||||
ZFCP_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_adapter(adapter),
|
||||
adapter->fc_service_class);
|
||||
} else {
|
||||
ZFCP_LOG_INFO("bug: The fibrechannel class at "
|
||||
"adapter %s is invalid. "
|
||||
"(debug info %d)\n",
|
||||
zfcp_get_busid_by_adapter(adapter),
|
||||
adapter->fc_service_class);
|
||||
}
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT);
|
||||
/* stop operation for this adapter */
|
||||
debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0);
|
||||
@@ -1940,14 +1943,6 @@ skip_fsfstatus:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns: address of initiated FSF request
|
||||
* NULL - request could not be initiated
|
||||
*/
|
||||
int
|
||||
zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
@@ -2565,8 +2560,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
|
||||
if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status))
|
||||
{
|
||||
if (fsf_req->qtcb->bottom.support.els1_length <
|
||||
((((unsigned long) &plogi->serv_param.wwpn) -
|
||||
((unsigned long) plogi)) + sizeof (u64))) {
|
||||
sizeof (struct fsf_plogi)) {
|
||||
ZFCP_LOG_INFO(
|
||||
"warning: insufficient length of "
|
||||
"PLOGI payload (%i)\n",
|
||||
@@ -2585,8 +2579,10 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
|
||||
atomic_clear_mask(
|
||||
ZFCP_STATUS_PORT_DID_DID,
|
||||
&port->status);
|
||||
} else
|
||||
} else {
|
||||
port->wwnn = plogi->serv_param.wwnn;
|
||||
zfcp_plogi_evaluate(port, plogi);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3569,7 +3565,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
|
||||
}
|
||||
|
||||
/* set FC service class in QTCB (3 per default) */
|
||||
fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class;
|
||||
fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
|
||||
|
||||
/* set FCP_LUN in FCP_CMND IU in QTCB */
|
||||
fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
|
||||
@@ -3667,18 +3663,6 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_fsf_send_fcp_command_task_management
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* FIXME(design): should be watched by a timeout!!!
|
||||
* FIXME(design) shouldn't this be modified to return an int
|
||||
* also...don't know how though
|
||||
*
|
||||
*/
|
||||
struct zfcp_fsf_req *
|
||||
zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
|
||||
struct zfcp_unit *unit,
|
||||
@@ -3720,7 +3704,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
|
||||
fsf_req->qtcb->header.lun_handle = unit->handle;
|
||||
fsf_req->qtcb->header.port_handle = unit->port->handle;
|
||||
fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
|
||||
fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class;
|
||||
fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
|
||||
fsf_req->qtcb->bottom.io.fcp_cmnd_length =
|
||||
sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t);
|
||||
|
||||
@@ -3843,18 +3827,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
|
||||
break;
|
||||
|
||||
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
|
||||
if (fsf_req->adapter->fc_service_class <= 3) {
|
||||
ZFCP_LOG_NORMAL("error: The adapter %s does "
|
||||
"not support fibrechannel class %d.\n",
|
||||
ZFCP_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_unit(unit),
|
||||
fsf_req->adapter->fc_service_class);
|
||||
} else {
|
||||
ZFCP_LOG_NORMAL("bug: The fibrechannel class at "
|
||||
"adapter %s is invalid. "
|
||||
"(debug info %d)\n",
|
||||
zfcp_get_busid_by_unit(unit),
|
||||
fsf_req->adapter->fc_service_class);
|
||||
}
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT);
|
||||
/* stop operation for this adapter */
|
||||
debug_text_exception(fsf_req->adapter->erp_dbf, 0,
|
||||
"fsf_s_class_nsup");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user