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:
commit
28e4b22495
158 changed files with 7618 additions and 46283 deletions
|
@ -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)
|
||||
|
92
Documentation/scsi/hptiop.txt
Normal file
92
Documentation/scsi/hptiop.txt
Normal file
|
@ -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...
|
||||
|
|
|
@ -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 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_def.h
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* 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_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)
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_erp.c
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* 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
|
||||
|
@ -231,13 +221,6 @@ zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
int
|
||||
zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask)
|
||||
{
|
||||
|
@ -251,13 +234,6 @@ zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
int
|
||||
zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask)
|
||||
{
|
||||
|
@ -271,13 +247,6 @@ zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
int
|
||||
zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
|
||||
{
|
||||
|
@ -306,20 +275,17 @@ zfcp_erp_adisc(struct zfcp_port *port)
|
|||
int retval = 0;
|
||||
struct timer_list *timer;
|
||||
|
||||
send_els = kmalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC);
|
||||
send_els = kzalloc(sizeof(struct zfcp_send_els), GFP_ATOMIC);
|
||||
if (send_els == NULL)
|
||||
goto nomem;
|
||||
memset(send_els, 0, sizeof(*send_els));
|
||||
|
||||
send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
if (send_els->req == NULL)
|
||||
goto nomem;
|
||||
memset(send_els->req, 0, sizeof(*send_els->req));
|
||||
|
||||
send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
|
||||
if (send_els->resp == NULL)
|
||||
goto nomem;
|
||||
memset(send_els->resp, 0, sizeof(*send_els->resp));
|
||||
|
||||
address = (void *) get_zeroed_page(GFP_ATOMIC);
|
||||
if (address == NULL)
|
||||
|
@ -812,13 +778,6 @@ zfcp_erp_unit_unblock(struct zfcp_unit *unit)
|
|||
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static void
|
||||
zfcp_erp_action_ready(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -1356,13 +1315,6 @@ zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -1538,13 +1490,6 @@ zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_statechange(int action,
|
||||
u32 status,
|
||||
|
@ -1586,13 +1531,6 @@ zfcp_erp_strategy_statechange(int action,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static inline int
|
||||
zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
|
||||
{
|
||||
|
@ -1605,13 +1543,6 @@ zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
|
|||
!(ZFCP_STATUS_ERP_CLOSE_ONLY & erp_status));
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
|
||||
{
|
||||
|
@ -1642,13 +1573,6 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
|
||||
{
|
||||
|
@ -1678,13 +1602,6 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
|
||||
{
|
||||
|
@ -1764,13 +1681,6 @@ zfcp_erp_strategy_followup_actions(int action,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
@ -1809,12 +1719,6 @@ zfcp_erp_wait(struct zfcp_adapter *adapter)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_modify_adapter_status
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
*/
|
||||
void
|
||||
zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,
|
||||
u32 mask, int set_or_clear)
|
||||
|
@ -1919,13 +1823,6 @@ zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns: FIXME
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
|
||||
{
|
||||
|
@ -2370,13 +2267,6 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
|
||||
*erp_action)
|
||||
|
@ -2545,13 +2435,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -2566,15 +2449,6 @@ zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* FIXME(design): currently only prepared for fabric (nameserver!)
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -2690,13 +2564,6 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -2813,13 +2680,6 @@ zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
|
||||
{
|
||||
|
@ -3022,13 +2882,6 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
|
||||
{
|
||||
|
@ -3129,13 +2982,6 @@ zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static inline void
|
||||
zfcp_erp_timeout_init(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -3331,13 +3177,6 @@ zfcp_erp_action_enqueue(int action,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -3402,9 +3241,13 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
|
|||
break;
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT:
|
||||
if (atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
|
||||
&port->status)) {
|
||||
zfcp_port_put(port);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((result == ZFCP_ERP_SUCCEEDED)
|
||||
&& !atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
|
||||
&port->status)
|
||||
&& !port->rport) {
|
||||
struct fc_rport_identifiers ids;
|
||||
ids.node_name = port->wwnn;
|
||||
|
@ -3418,12 +3261,30 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
|
|||
"(adapter %s, wwpn=0x%016Lx)\n",
|
||||
zfcp_get_busid_by_port(port),
|
||||
port->wwpn);
|
||||
else
|
||||
else {
|
||||
scsi_flush_work(adapter->scsi_host);
|
||||
port->rport->maxframe_size = port->maxframe_size;
|
||||
port->rport->supported_classes =
|
||||
port->supported_classes;
|
||||
}
|
||||
}
|
||||
if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) {
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
zfcp_port_put(port);
|
||||
break;
|
||||
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
|
||||
if (result != ZFCP_ERP_SUCCEEDED) {
|
||||
struct zfcp_port *port;
|
||||
list_for_each_entry(port, &adapter->port_list_head, list)
|
||||
if (port->rport &&
|
||||
!atomic_test_mask(ZFCP_STATUS_PORT_WKA,
|
||||
&port->status)) {
|
||||
fc_remote_port_delete(port->rport);
|
||||
port->rport = NULL;
|
||||
}
|
||||
}
|
||||
zfcp_adapter_put(adapter);
|
||||
break;
|
||||
default:
|
||||
|
@ -3432,13 +3293,6 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns: FIXME
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
@ -3455,13 +3309,6 @@ zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns: FIXME
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_action_dismiss_port(struct zfcp_port *port)
|
||||
{
|
||||
|
@ -3480,13 +3327,6 @@ zfcp_erp_action_dismiss_port(struct zfcp_port *port)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns: FIXME
|
||||
*/
|
||||
static int
|
||||
zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
|
||||
{
|
||||
|
@ -3501,13 +3341,6 @@ zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose: moves erp_action to 'erp running list'
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static inline void
|
||||
zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -3518,13 +3351,6 @@ zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
|
|||
list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose: moves erp_action to 'erp ready list'
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
static inline void
|
||||
zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
|
@ -3535,11 +3361,6 @@ zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
|
|||
list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_port_boxed
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_port_boxed(struct zfcp_port *port)
|
||||
{
|
||||
|
@ -3556,11 +3377,6 @@ zfcp_erp_port_boxed(struct zfcp_port *port)
|
|||
zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_unit_boxed
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_unit_boxed(struct zfcp_unit *unit)
|
||||
{
|
||||
|
@ -3574,11 +3390,6 @@ zfcp_erp_unit_boxed(struct zfcp_unit *unit)
|
|||
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_port_access_denied
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_port_access_denied(struct zfcp_port *port)
|
||||
{
|
||||
|
@ -3595,11 +3406,6 @@ zfcp_erp_port_access_denied(struct zfcp_port *port)
|
|||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_unit_access_denied
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
|
||||
{
|
||||
|
@ -3613,11 +3419,6 @@ zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
|
|||
ZFCP_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_adapter_access_changed
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
@ -3628,7 +3429,7 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
|
|||
return;
|
||||
|
||||
debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
|
||||
debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
|
||||
debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8);
|
||||
|
||||
read_lock_irqsave(&zfcp_data.config_lock, flags);
|
||||
if (adapter->nameserver_port)
|
||||
|
@ -3639,11 +3440,6 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
|
|||
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_port_access_changed
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_port_access_changed(struct zfcp_port *port)
|
||||
{
|
||||
|
@ -3672,11 +3468,6 @@ zfcp_erp_port_access_changed(struct zfcp_port *port)
|
|||
zfcp_get_busid_by_adapter(adapter), port->wwpn);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_erp_unit_access_changed
|
||||
*
|
||||
* purpose:
|
||||
*/
|
||||
void
|
||||
zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
|
||||
{
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_ext.h
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* 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_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_port(port),
|
||||
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_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_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_adapter(adapter),
|
||||
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 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
|
|||
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;
|
||||
|
@ -2993,8 +2989,8 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
|
|||
erp_action->fsf_req->qtcb->bottom.support.fcp_lun =
|
||||
erp_action->unit->fcp_lun;
|
||||
if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE))
|
||||
erp_action->fsf_req->qtcb->bottom.support.option =
|
||||
FSF_OPEN_LUN_SUPPRESS_BOXING;
|
||||
erp_action->fsf_req->qtcb->bottom.support.option =
|
||||
FSF_OPEN_LUN_SUPPRESS_BOXING;
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
|
||||
erp_action->fsf_req->data = (unsigned long) erp_action->unit;
|
||||
erp_action->fsf_req->erp_action = erp_action;
|
||||
|
@ -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_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_LOG_INFO("error: adapter %s does not support fc "
|
||||
"class %d.\n",
|
||||
zfcp_get_busid_by_unit(unit),
|
||||
ZFCP_FC_SERVICE_CLASS_DEFAULT);
|
||||
/* stop operation for this adapter */
|
||||
debug_text_exception(fsf_req->adapter->erp_dbf, 0,
|
||||
"fsf_s_class_nsup");
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_fsf.h
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* 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
|
||||
|
@ -33,8 +22,7 @@
|
|||
#ifndef FSF_H
|
||||
#define FSF_H
|
||||
|
||||
#define FSF_QTCB_VERSION1 0x00000001
|
||||
#define FSF_QTCB_CURRENT_VERSION FSF_QTCB_VERSION1
|
||||
#define FSF_QTCB_CURRENT_VERSION 0x00000001
|
||||
|
||||
/* FSF commands */
|
||||
#define FSF_QTCB_FCP_CMND 0x00000001
|
||||
|
@ -64,7 +52,7 @@
|
|||
#define FSF_CFDC_OPTION_FULL_ACCESS 0x00000002
|
||||
#define FSF_CFDC_OPTION_RESTRICTED_ACCESS 0x00000004
|
||||
|
||||
/* FSF protocol stati */
|
||||
/* FSF protocol states */
|
||||
#define FSF_PROT_GOOD 0x00000001
|
||||
#define FSF_PROT_QTCB_VERSION_ERROR 0x00000010
|
||||
#define FSF_PROT_SEQ_NUMB_ERROR 0x00000020
|
||||
|
@ -76,7 +64,7 @@
|
|||
#define FSF_PROT_REEST_QUEUE 0x00000800
|
||||
#define FSF_PROT_ERROR_STATE 0x01000000
|
||||
|
||||
/* FSF stati */
|
||||
/* FSF states */
|
||||
#define FSF_GOOD 0x00000000
|
||||
#define FSF_PORT_ALREADY_OPEN 0x00000001
|
||||
#define FSF_LUN_ALREADY_OPEN 0x00000002
|
||||
|
@ -269,20 +257,6 @@
|
|||
#define FSF_UNIT_ACCESS_EXCLUSIVE 0x02000000
|
||||
#define FSF_UNIT_ACCESS_OUTBOUND_TRANSFER 0x10000000
|
||||
|
||||
struct fsf_queue_designator;
|
||||
struct fsf_status_read_buffer;
|
||||
struct fsf_port_closed_payload;
|
||||
struct fsf_bit_error_payload;
|
||||
union fsf_prot_status_qual;
|
||||
struct fsf_qual_version_error;
|
||||
struct fsf_qual_sequence_error;
|
||||
struct fsf_qtcb_prefix;
|
||||
struct fsf_qtcb_header;
|
||||
struct fsf_qtcb_bottom_config;
|
||||
struct fsf_qtcb_bottom_support;
|
||||
struct fsf_qtcb_bottom_io;
|
||||
union fsf_qtcb_bottom;
|
||||
|
||||
struct fsf_queue_designator {
|
||||
u8 cssid;
|
||||
u8 chpid;
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_qdio.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
|
||||
*
|
||||
* QDIO related routines
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
*
|
||||
* Authors:
|
||||
* Martin Peschke <mpeschke@de.ibm.com>
|
||||
* Raimund Schroeder <raimund.schroeder@de.ibm.com>
|
||||
* Wolfgang Taphorn
|
||||
* 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
|
||||
|
@ -178,7 +168,8 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
|
|||
|
||||
init_data->cdev = adapter->ccw_device;
|
||||
init_data->q_format = QDIO_SCSI_QFMT;
|
||||
memcpy(init_data->adapter_name, &adapter->name, 8);
|
||||
memcpy(init_data->adapter_name, zfcp_get_busid_by_adapter(adapter), 8);
|
||||
ASCEBC(init_data->adapter_name, 8);
|
||||
init_data->qib_param_field_format = 0;
|
||||
init_data->qib_param_field = NULL;
|
||||
init_data->input_slib_elements = NULL;
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/scsi/zfcp_scsi.c
|
||||
*
|
||||
* FCP adapter driver for IBM eServer zSeries
|
||||
*
|
||||
* (C) Copyright IBM Corp. 2002, 2004
|
||||
* This file is part of the zfcp device driver for
|
||||
* FCP adapters for IBM System z9 and zSeries.
|
||||
*
|
||||
* 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
|
||||
|
@ -45,8 +35,8 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
|
|||
static int zfcp_task_management_function(struct zfcp_unit *, u8,
|
||||
struct scsi_cmnd *);
|
||||
|
||||
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
|
||||
scsi_lun_t);
|
||||
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
|
||||
unsigned int, unsigned int);
|
||||
|
||||
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
|
||||
|
||||
|
@ -161,14 +151,6 @@ set_driver_byte(u32 * result, char status)
|
|||
set_byte(result, status, 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_scsi_slave_alloc
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
|
||||
static int
|
||||
zfcp_scsi_slave_alloc(struct scsi_device *sdp)
|
||||
{
|
||||
|
@ -195,14 +177,6 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_scsi_slave_destroy
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
|
||||
static void
|
||||
zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
|
||||
{
|
||||
|
@ -374,18 +348,9 @@ zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
|
|||
return zfcp_scsi_command_async(adapter, unit, scpnt, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_unit_lookup
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
* context:
|
||||
*/
|
||||
static struct zfcp_unit *
|
||||
zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id,
|
||||
scsi_lun_t lun)
|
||||
zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
|
||||
unsigned int lun)
|
||||
{
|
||||
struct zfcp_port *port;
|
||||
struct zfcp_unit *unit, *retval = NULL;
|
||||
|
@ -491,13 +456,6 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function: zfcp_scsi_eh_device_reset_handler
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
int
|
||||
zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
|
||||
{
|
||||
|
@ -625,13 +583,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
int
|
||||
zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
@ -657,10 +608,6 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
|||
adapter->scsi_host->unique_id = unique_id++; /* FIXME */
|
||||
adapter->scsi_host->max_cmd_len = ZFCP_MAX_SCSI_CMND_LENGTH;
|
||||
adapter->scsi_host->transportt = zfcp_transport_template;
|
||||
/*
|
||||
* Reverse mapping of the host number to avoid race condition
|
||||
*/
|
||||
adapter->scsi_host_no = adapter->scsi_host->host_no;
|
||||
|
||||
/*
|
||||
* save a pointer to our own adapter data structure within
|
||||
|
@ -678,13 +625,6 @@ zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* function:
|
||||
*
|
||||
* purpose:
|
||||
*
|
||||
* returns:
|
||||
*/
|
||||
void
|
||||
zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
@ -703,7 +643,6 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
|
|||
scsi_remove_host(shost);
|
||||
scsi_host_put(shost);
|
||||
adapter->scsi_host = NULL;
|
||||
adapter->scsi_host_no = 0;
|
||||
atomic_clear_mask(ZFCP_STATUS_ADAPTER_REGISTERED, &adapter->status);
|
||||
|
||||
return;
|
||||
|
@ -817,10 +756,9 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost)
|
|||
if (!fc_stats)
|
||||
return NULL;
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return NULL;
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data);
|
||||
if (ret) {
|
||||
|
@ -848,10 +786,9 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
|
|||
int ret;
|
||||
|
||||
adapter = (struct zfcp_adapter *)shost->hostdata[0];
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return;
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data);
|
||||
if (ret == 0) {
|
||||
|
@ -863,11 +800,18 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
|
|||
}
|
||||
}
|
||||
|
||||
static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
|
||||
{
|
||||
rport->dev_loss_tmo = timeout;
|
||||
}
|
||||
|
||||
struct fc_function_template zfcp_transport_functions = {
|
||||
.show_starget_port_id = 1,
|
||||
.show_starget_port_name = 1,
|
||||
.show_starget_node_name = 1,
|
||||
.show_rport_supported_classes = 1,
|
||||
.show_rport_maxframe_size = 1,
|
||||
.show_rport_dev_loss_tmo = 1,
|
||||
.show_host_node_name = 1,
|
||||
.show_host_port_name = 1,
|
||||
.show_host_permanent_port_name = 1,
|
||||
|
@ -877,6 +821,7 @@ struct fc_function_template zfcp_transport_functions = {
|
|||
.show_host_serial_number = 1,
|
||||
.get_fc_host_stats = zfcp_get_fc_host_stats,
|
||||
.reset_fc_host_stats = zfcp_reset_fc_host_stats,
|
||||
.set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo,
|
||||
/* no functions registered for following dynamic attributes but
|
||||
directly set by LLDD */
|
||||
.show_host_port_type = 1,
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_sysfs_adapter.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
|
||||
*
|
||||
* sysfs adapter 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,16 +1,8 @@
|
|||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_sysfs_driver.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
|
||||
*
|
||||
* sysfs 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,17 +1,8 @@
|
|||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_sysfs_port.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
|
||||
*
|
||||
* sysfs port 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>
|
||||
* 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
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
/*
|
||||
* linux/drivers/s390/scsi/zfcp_sysfs_unit.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
|
||||
*
|
||||
* sysfs unit 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>
|
||||
* 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
|
||||
|
|
|
@ -1388,7 +1388,7 @@ static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
|
|||
if (cmd->use_sg == 0)
|
||||
goto out;
|
||||
|
||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||
|
||||
if (use_sg == 0) {
|
||||
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
|
||||
|
|
|
@ -405,7 +405,7 @@ static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill
|
|||
/* Attempt to return intelligent sense information */
|
||||
if (fill_sense) {
|
||||
if ((command->status == 0xc7) || (command->status == 0xcb)) {
|
||||
for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
|
||||
if (command->flags == tw_sense_table[i][0]) {
|
||||
|
||||
/* Valid bit and 'current errors' */
|
||||
|
@ -625,7 +625,7 @@ static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
|
|||
if (aen == 0x0ff) {
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
|
||||
} else {
|
||||
table_max = sizeof(tw_aen_string)/sizeof(char *);
|
||||
table_max = ARRAY_SIZE(tw_aen_string);
|
||||
if ((aen & 0x0ff) < table_max) {
|
||||
if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
|
||||
|
@ -786,7 +786,7 @@ static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
|
|||
if (aen == 0x0ff) {
|
||||
printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
|
||||
} else {
|
||||
table_max = sizeof(tw_aen_string)/sizeof(char *);
|
||||
table_max = ARRAY_SIZE(tw_aen_string);
|
||||
if ((aen & 0x0ff) < table_max) {
|
||||
if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
|
||||
printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
|
||||
|
@ -1286,7 +1286,7 @@ static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
|
|||
if (cmd->use_sg == 0)
|
||||
return 0;
|
||||
|
||||
use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||
use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
|
||||
|
||||
if (use_sg == 0) {
|
||||
printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
|
||||
|
|
|
@ -183,6 +183,10 @@ STATIC struct device_attribute *NCR_700_dev_attrs[];
|
|||
|
||||
STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
|
||||
|
||||
struct NCR_700_sense {
|
||||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
||||
};
|
||||
|
||||
static char *NCR_700_phase[] = {
|
||||
"",
|
||||
"after selection",
|
||||
|
@ -316,7 +320,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
|
||||
hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
|
||||
hostdata->dev = dev;
|
||||
|
||||
|
||||
pSlots = pScript + SLOTS_OFFSET;
|
||||
|
||||
/* Fill in the missing routines from the host template */
|
||||
|
@ -332,19 +336,18 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
tpnt->slave_destroy = NCR_700_slave_destroy;
|
||||
tpnt->change_queue_depth = NCR_700_change_queue_depth;
|
||||
tpnt->change_queue_type = NCR_700_change_queue_type;
|
||||
|
||||
|
||||
if(tpnt->name == NULL)
|
||||
tpnt->name = "53c700";
|
||||
if(tpnt->proc_name == NULL)
|
||||
tpnt->proc_name = "53c700";
|
||||
|
||||
|
||||
host = scsi_host_alloc(tpnt, 4);
|
||||
if (!host)
|
||||
return NULL;
|
||||
memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
|
||||
* NCR_700_COMMAND_SLOTS_PER_HOST);
|
||||
for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
|
||||
for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
|
||||
dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0]
|
||||
- (unsigned long)&hostdata->slots[0].SG[0]);
|
||||
hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset));
|
||||
|
@ -355,14 +358,12 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
hostdata->slots[j].state = NCR_700_SLOT_FREE;
|
||||
}
|
||||
|
||||
for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) {
|
||||
for (j = 0; j < ARRAY_SIZE(SCRIPT); j++)
|
||||
script[j] = bS_to_host(SCRIPT[j]);
|
||||
}
|
||||
|
||||
/* adjust all labels to be bus physical */
|
||||
for(j = 0; j < PATCHES; j++) {
|
||||
for (j = 0; j < PATCHES; j++)
|
||||
script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
|
||||
}
|
||||
/* now patch up fixed addresses. */
|
||||
script_patch_32(script, MessageLocation,
|
||||
pScript + MSGOUT_OFFSET);
|
||||
|
@ -376,7 +377,7 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE);
|
||||
hostdata->state = NCR_700_HOST_FREE;
|
||||
hostdata->cmd = NULL;
|
||||
host->max_id = 7;
|
||||
host->max_id = 8;
|
||||
host->max_lun = NCR_700_MAX_LUNS;
|
||||
BUG_ON(NCR_700_transport_template == NULL);
|
||||
host->transportt = NCR_700_transport_template;
|
||||
|
@ -385,17 +386,17 @@ NCR_700_detect(struct scsi_host_template *tpnt,
|
|||
host->hostdata[0] = (unsigned long)hostdata;
|
||||
/* kick the chip */
|
||||
NCR_700_writeb(0xff, host, CTEST9_REG);
|
||||
if(hostdata->chip710)
|
||||
if (hostdata->chip710)
|
||||
hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f;
|
||||
else
|
||||
hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f;
|
||||
hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
|
||||
if(banner == 0) {
|
||||
if (banner == 0) {
|
||||
printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
|
||||
banner = 1;
|
||||
}
|
||||
printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
|
||||
hostdata->chip710 ? "53c710" :
|
||||
hostdata->chip710 ? "53c710" :
|
||||
(hostdata->fast ? "53c700-66" : "53c700"),
|
||||
hostdata->rev, hostdata->differential ?
|
||||
"(Differential)" : "");
|
||||
|
@ -540,6 +541,7 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
|
|||
* finish routine. If we cannot queue the command when it
|
||||
* is properly build, we then change to NCR_700_SLOT_QUEUED */
|
||||
slot->state = NCR_700_SLOT_BUSY;
|
||||
slot->flags = 0;
|
||||
hostdata->command_slot_count++;
|
||||
|
||||
return slot;
|
||||
|
@ -589,7 +591,7 @@ NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
|
|||
if(SCp->sc_data_direction != DMA_NONE &&
|
||||
SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
|
||||
if(SCp->use_sg) {
|
||||
dma_unmap_sg(hostdata->dev, SCp->buffer,
|
||||
dma_unmap_sg(hostdata->dev, SCp->request_buffer,
|
||||
SCp->use_sg, SCp->sc_data_direction);
|
||||
} else {
|
||||
dma_unmap_single(hostdata->dev, slot->dma_handle,
|
||||
|
@ -611,30 +613,23 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
|
|||
(struct NCR_700_command_slot *)SCp->host_scribble;
|
||||
|
||||
NCR_700_unmap(hostdata, SCp, slot);
|
||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
||||
if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
|
||||
if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
||||
struct NCR_700_sense *sense = SCp->device->hostdata;
|
||||
#ifdef NCR_700_DEBUG
|
||||
printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
|
||||
SCp, SCp->cmnd[7], result);
|
||||
scsi_print_sense("53c700", SCp);
|
||||
|
||||
#endif
|
||||
dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
|
||||
/* restore the old result if the request sense was
|
||||
* successful */
|
||||
if(result == 0)
|
||||
result = SCp->cmnd[7];
|
||||
/* now restore the original command */
|
||||
memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd,
|
||||
sizeof(SCp->data_cmnd));
|
||||
SCp->request_buffer = SCp->buffer;
|
||||
SCp->request_bufflen = SCp->bufflen;
|
||||
SCp->use_sg = SCp->old_use_sg;
|
||||
SCp->cmd_len = SCp->old_cmd_len;
|
||||
SCp->sc_data_direction = SCp->sc_old_data_direction;
|
||||
SCp->underflow = SCp->old_underflow;
|
||||
|
||||
}
|
||||
result = sense->cmnd[7];
|
||||
} else
|
||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||
sizeof(SCp->cmnd), DMA_TO_DEVICE);
|
||||
|
||||
free_slot(slot, hostdata);
|
||||
#ifdef NCR_700_DEBUG
|
||||
if(NCR_700_get_depth(SCp->device) == 0 ||
|
||||
|
@ -982,6 +977,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
"broken device is looping in contingent allegiance: ignoring\n");
|
||||
NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
|
||||
} else {
|
||||
struct NCR_700_sense *sense = SCp->device->hostdata;
|
||||
#ifdef NCR_DEBUG
|
||||
scsi_print_command(SCp);
|
||||
printk(" cmd %p has status %d, requesting sense\n",
|
||||
|
@ -995,27 +991,25 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
* data associated with the command
|
||||
* here */
|
||||
NCR_700_unmap(hostdata, SCp, slot);
|
||||
dma_unmap_single(hostdata->dev, slot->pCmd,
|
||||
sizeof(SCp->cmnd),
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
SCp->cmnd[0] = REQUEST_SENSE;
|
||||
SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5;
|
||||
SCp->cmnd[2] = 0;
|
||||
SCp->cmnd[3] = 0;
|
||||
SCp->cmnd[4] = sizeof(SCp->sense_buffer);
|
||||
SCp->cmnd[5] = 0;
|
||||
SCp->cmd_len = 6;
|
||||
sense->cmnd[0] = REQUEST_SENSE;
|
||||
sense->cmnd[1] = (SCp->device->lun & 0x7) << 5;
|
||||
sense->cmnd[2] = 0;
|
||||
sense->cmnd[3] = 0;
|
||||
sense->cmnd[4] = sizeof(SCp->sense_buffer);
|
||||
sense->cmnd[5] = 0;
|
||||
/* Here's a quiet hack: the
|
||||
* REQUEST_SENSE command is six bytes,
|
||||
* so store a flag indicating that
|
||||
* this was an internal sense request
|
||||
* and the original status at the end
|
||||
* of the command */
|
||||
SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
|
||||
SCp->cmnd[7] = hostdata->status[0];
|
||||
SCp->use_sg = 0;
|
||||
SCp->sc_data_direction = DMA_FROM_DEVICE;
|
||||
dma_sync_single_for_device(hostdata->dev, slot->pCmd,
|
||||
SCp->cmd_len, DMA_TO_DEVICE);
|
||||
SCp->request_bufflen = sizeof(SCp->sense_buffer);
|
||||
sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
|
||||
sense->cmnd[7] = hostdata->status[0];
|
||||
slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE);
|
||||
slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
|
||||
slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
|
||||
slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
|
||||
|
@ -1027,6 +1021,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
|
||||
/* queue the command for reissue */
|
||||
slot->state = NCR_700_SLOT_QUEUED;
|
||||
slot->flags = NCR_700_FLAG_AUTOSENSE;
|
||||
hostdata->state = NCR_700_HOST_FREE;
|
||||
hostdata->cmd = NULL;
|
||||
}
|
||||
|
@ -1247,7 +1242,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
|
||||
if(SCp->use_sg) {
|
||||
for(i = 0; i < SCp->use_sg + 1; i++) {
|
||||
printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
|
||||
printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1406,12 +1401,14 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
|
|||
/* keep interrupts disabled until we have the command correctly
|
||||
* set up so we cannot take a selection interrupt */
|
||||
|
||||
hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
|
||||
hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE &&
|
||||
slot->flags != NCR_700_FLAG_AUTOSENSE),
|
||||
SCp->device->lun);
|
||||
/* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
|
||||
* if the negotiated transfer parameters still hold, so
|
||||
* always renegotiate them */
|
||||
if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) {
|
||||
if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE ||
|
||||
slot->flags == NCR_700_FLAG_AUTOSENSE) {
|
||||
NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
|
||||
}
|
||||
|
||||
|
@ -1420,7 +1417,8 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
|
|||
* will refuse all tags, so send the request sense as untagged
|
||||
* */
|
||||
if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
|
||||
&& (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
|
||||
&& (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE &&
|
||||
slot->flags != NCR_700_FLAG_AUTOSENSE)) {
|
||||
count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
|
||||
}
|
||||
|
||||
|
@ -1866,8 +1864,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
|||
__u32 count = 0;
|
||||
|
||||
if(SCp->use_sg) {
|
||||
sg_count = dma_map_sg(hostdata->dev, SCp->buffer,
|
||||
SCp->use_sg, direction);
|
||||
sg_count = dma_map_sg(hostdata->dev,
|
||||
SCp->request_buffer, SCp->use_sg,
|
||||
direction);
|
||||
} else {
|
||||
vPtr = dma_map_single(hostdata->dev,
|
||||
SCp->request_buffer,
|
||||
|
@ -1882,7 +1881,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
|
|||
for(i = 0; i < sg_count; i++) {
|
||||
|
||||
if(SCp->use_sg) {
|
||||
struct scatterlist *sg = SCp->buffer;
|
||||
struct scatterlist *sg = SCp->request_buffer;
|
||||
|
||||
vPtr = sg_dma_address(&sg[i]);
|
||||
count = sg_dma_len(&sg[i]);
|
||||
|
@ -2045,6 +2044,11 @@ NCR_700_slave_configure(struct scsi_device *SDp)
|
|||
struct NCR_700_Host_Parameters *hostdata =
|
||||
(struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
|
||||
|
||||
SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense));
|
||||
|
||||
if (!SDp->hostdata)
|
||||
return -ENOMEM;
|
||||
|
||||
/* to do here: allocate memory; build a queue_full list */
|
||||
if(SDp->tagged_supported) {
|
||||
scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
|
||||
|
@ -2068,7 +2072,8 @@ NCR_700_slave_configure(struct scsi_device *SDp)
|
|||
STATIC void
|
||||
NCR_700_slave_destroy(struct scsi_device *SDp)
|
||||
{
|
||||
/* to do here: deallocate memory */
|
||||
kfree(SDp->hostdata);
|
||||
SDp->hostdata = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -163,6 +163,8 @@ struct NCR_700_command_slot {
|
|||
#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC) /* slot has command active on HA */
|
||||
#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC) /* slot has command to be made active on HA */
|
||||
__u8 state;
|
||||
#define NCR_700_FLAG_AUTOSENSE 0x01
|
||||
__u8 flags;
|
||||
int tag;
|
||||
__u32 resume_offset;
|
||||
struct scsi_cmnd *cmnd;
|
||||
|
|
|
@ -361,7 +361,7 @@ int CmdPageStart = (0 - Ent_dsa_zero - sizeof(struct NCR53c7x0_cmd)) & 0xff;
|
|||
static char *setup_strings[] =
|
||||
{"","","","","","","",""};
|
||||
|
||||
#define MAX_SETUP_STRINGS (sizeof(setup_strings) / sizeof(char *))
|
||||
#define MAX_SETUP_STRINGS ARRAY_SIZE(setup_strings)
|
||||
#define SETUP_BUFFER_SIZE 200
|
||||
static char setup_buffer[SETUP_BUFFER_SIZE];
|
||||
static char setup_used[MAX_SETUP_STRINGS];
|
||||
|
@ -709,7 +709,7 @@ request_synchronous (int host, int target) {
|
|||
printk (KERN_ALERT "target %d is host ID\n", target);
|
||||
return -1;
|
||||
}
|
||||
else if (target > h->max_id) {
|
||||
else if (target >= h->max_id) {
|
||||
printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
|
||||
h->max_id);
|
||||
return -1;
|
||||
|
@ -2190,15 +2190,15 @@ static const struct {
|
|||
*/
|
||||
|
||||
|
||||
static void
|
||||
static void
|
||||
synchronous (struct Scsi_Host *host, int target, char *msg) {
|
||||
struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
|
||||
host->hostdata[0];
|
||||
int desire, divisor, i, limit;
|
||||
unsigned char scntl3, sxfer;
|
||||
/* The diagnostic message fits on one line, even with max. width integers */
|
||||
char buf[80];
|
||||
|
||||
char buf[80];
|
||||
|
||||
/* Desired transfer clock in Hz */
|
||||
desire = 1000000000L / (msg[3] * 4);
|
||||
/* Scale the available SCSI clock by 10 so we get tenths */
|
||||
|
@ -2209,14 +2209,14 @@ synchronous (struct Scsi_Host *host, int target, char *msg) {
|
|||
msg[4] = 8;
|
||||
|
||||
if (hostdata->options & OPTION_DEBUG_SDTR)
|
||||
printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
|
||||
printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
|
||||
host->host_no, divisor / 10, divisor % 10);
|
||||
|
||||
limit = (sizeof(syncs) / sizeof(syncs[0]) -1);
|
||||
limit = ARRAY_SIZE(syncs) - 1;
|
||||
for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
|
||||
|
||||
if (hostdata->options & OPTION_DEBUG_SDTR)
|
||||
printk("scsi%d : selected synchronous divisor of %d.%01d\n",
|
||||
printk("scsi%d : selected synchronous divisor of %d.%01d\n",
|
||||
host->host_no, syncs[i].div / 10, syncs[i].div % 10);
|
||||
|
||||
msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
|
||||
|
@ -3622,7 +3622,7 @@ NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
|
|||
#ifdef LINUX_1_2
|
||||
|| cmd->device->id > 7
|
||||
#else
|
||||
|| cmd->device->id > host->max_id
|
||||
|| cmd->device->id >= host->max_id
|
||||
#endif
|
||||
|| cmd->device->id == host->this_id
|
||||
|| hostdata->state == STATE_DISABLED) {
|
||||
|
|
|
@ -532,6 +532,16 @@ config SCSI_PDC_ADMA
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config SCSI_HPTIOP
|
||||
tristate "HighPoint RocketRAID 3xxx Controller support"
|
||||
depends on SCSI && PCI
|
||||
help
|
||||
This option enables support for HighPoint RocketRAID 3xxx
|
||||
controllers.
|
||||
|
||||
To compile this driver as a module, choose M here; the module
|
||||
will be called hptiop. If unsure, say N.
|
||||
|
||||
config SCSI_SATA_QSTOR
|
||||
tristate "Pacific Digital SATA QStor support"
|
||||
depends on SCSI_SATA && PCI
|
||||
|
|
|
@ -33,7 +33,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
|
|||
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
|
||||
obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
|
||||
|
||||
obj-$(CONFIG_ISCSI_TCP) += iscsi_tcp.o
|
||||
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o
|
||||
obj-$(CONFIG_SCSI_AMIGA7XX) += amiga7xx.o 53c7xx.o
|
||||
obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
|
||||
obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
|
||||
|
@ -136,6 +136,7 @@ obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o
|
|||
obj-$(CONFIG_SCSI_SATA_ULI) += libata.o sata_uli.o
|
||||
obj-$(CONFIG_SCSI_SATA_MV) += libata.o sata_mv.o
|
||||
obj-$(CONFIG_SCSI_PDC_ADMA) += libata.o pdc_adma.o
|
||||
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
|
||||
|
||||
obj-$(CONFIG_ARM) += arm/
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
|
|||
*/
|
||||
|
||||
if (cmd->use_sg) {
|
||||
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
|
||||
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
|
||||
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
||||
cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
|
||||
cmd->SCp.buffer->offset;
|
||||
|
|
|
@ -213,16 +213,16 @@ static void *addresses[] = {
|
|||
(void *) 0xd8000,
|
||||
(void *) 0xc8000
|
||||
};
|
||||
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
|
||||
#define ADDRESS_COUNT ARRAY_SIZE(addresses)
|
||||
#endif /* USE_BIOS */
|
||||
|
||||
/* possible i/o port addresses */
|
||||
static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 };
|
||||
#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
|
||||
#define PORT_COUNT ARRAY_SIZE(ports)
|
||||
|
||||
/* possible interrupt channels */
|
||||
static unsigned short intrs[] = { 10, 11, 12, 15 };
|
||||
#define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short ))
|
||||
#define INTR_COUNT ARRAY_SIZE(intrs)
|
||||
|
||||
/* signatures for NCR 53c406a based controllers */
|
||||
#if USE_BIOS
|
||||
|
@ -236,7 +236,7 @@ struct signature {
|
|||
{
|
||||
"Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82},};
|
||||
|
||||
#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
|
||||
#define SIGNATURE_COUNT ARRAY_SIZE(signatures)
|
||||
#endif /* USE_BIOS */
|
||||
|
||||
/* ============================================================ */
|
||||
|
|
|
@ -148,6 +148,8 @@ static int nondasd = -1;
|
|||
static int dacmode = -1;
|
||||
|
||||
static int commit = -1;
|
||||
int startup_timeout = 180;
|
||||
int aif_timeout = 120;
|
||||
|
||||
module_param(nondasd, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
|
||||
|
@ -155,6 +157,10 @@ module_param(dacmode, int, S_IRUGO|S_IWUSR);
|
|||
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
|
||||
module_param(commit, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
|
||||
module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
|
||||
module_param(aif_timeout, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for applications to pick up AIFs before\nderegistering them. This is typically adjusted for heavily burdened systems.");
|
||||
|
||||
int numacb = -1;
|
||||
module_param(numacb, int, S_IRUGO|S_IWUSR);
|
||||
|
@ -635,13 +641,13 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
|
|||
cp[sizeof(str->pid)] = c;
|
||||
} else {
|
||||
struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
|
||||
|
||||
inqstrcpy (mp->vname, str->vid);
|
||||
|
||||
inqstrcpy (mp->vname, str->vid);
|
||||
/* last six chars reserved for vol type */
|
||||
inqstrcpy (mp->model, str->pid);
|
||||
}
|
||||
|
||||
if (tindex < (sizeof(container_types)/sizeof(char *))){
|
||||
if (tindex < ARRAY_SIZE(container_types)){
|
||||
char *findit = str->pid;
|
||||
|
||||
for ( ; *findit != ' '; findit++); /* walk till we find a space */
|
||||
|
@ -955,7 +961,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
|||
|
||||
if(scsicmd->use_sg)
|
||||
pci_unmap_sg(dev->pdev,
|
||||
(struct scatterlist *)scsicmd->buffer,
|
||||
(struct scatterlist *)scsicmd->request_buffer,
|
||||
scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
else if(scsicmd->request_bufflen)
|
||||
|
@ -1570,7 +1576,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||
* see: <vendor>.c i.e. aac.c
|
||||
*/
|
||||
if (scmd_id(scsicmd) == host->this_id) {
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
|
||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
|
@ -1913,7 +1919,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
|||
|
||||
if(scsicmd->use_sg)
|
||||
pci_unmap_sg(dev->pdev,
|
||||
(struct scatterlist *)scsicmd->buffer,
|
||||
(struct scatterlist *)scsicmd->request_buffer,
|
||||
scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
else if(scsicmd->request_bufflen)
|
||||
|
@ -2218,15 +2224,15 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
|
|||
}
|
||||
}
|
||||
else if(scsicmd->request_bufflen) {
|
||||
dma_addr_t addr;
|
||||
addr = pci_map_single(dev->pdev,
|
||||
u32 addr;
|
||||
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
|
||||
scsicmd->request_buffer,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
addr = scsicmd->SCp.dma_handle;
|
||||
psg->count = cpu_to_le32(1);
|
||||
psg->sg[0].addr = cpu_to_le32(addr);
|
||||
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
|
||||
scsicmd->SCp.dma_handle = addr;
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
return byte_count;
|
||||
|
@ -2375,7 +2381,7 @@ static struct aac_srb_status_info srb_status_info[] = {
|
|||
{ SRB_STATUS_SUCCESS, "Success"},
|
||||
{ SRB_STATUS_ABORTED, "Aborted Command"},
|
||||
{ SRB_STATUS_ABORT_FAILED, "Abort Failed"},
|
||||
{ SRB_STATUS_ERROR, "Error Event"},
|
||||
{ SRB_STATUS_ERROR, "Error Event"},
|
||||
{ SRB_STATUS_BUSY, "Device Busy"},
|
||||
{ SRB_STATUS_INVALID_REQUEST, "Invalid Request"},
|
||||
{ SRB_STATUS_INVALID_PATH_ID, "Invalid Path ID"},
|
||||
|
@ -2394,7 +2400,7 @@ static struct aac_srb_status_info srb_status_info[] = {
|
|||
{ SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},
|
||||
{ SRB_STATUS_REQUEST_FLUSHED, "Request Flushed"},
|
||||
{ SRB_STATUS_DELAYED_RETRY, "Delayed Retry"},
|
||||
{ SRB_STATUS_INVALID_LUN, "Invalid LUN"},
|
||||
{ SRB_STATUS_INVALID_LUN, "Invalid LUN"},
|
||||
{ SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"},
|
||||
{ SRB_STATUS_BAD_FUNCTION, "Bad Function"},
|
||||
{ SRB_STATUS_ERROR_RECOVERY, "Error Recovery"},
|
||||
|
@ -2409,11 +2415,9 @@ char *aac_get_status_string(u32 status)
|
|||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < (sizeof(srb_status_info)/sizeof(struct aac_srb_status_info)); i++ ){
|
||||
if(srb_status_info[i].status == status){
|
||||
for (i = 0; i < ARRAY_SIZE(srb_status_info); i++)
|
||||
if (srb_status_info[i].status == status)
|
||||
return srb_status_info[i].str;
|
||||
}
|
||||
}
|
||||
|
||||
return "Bad Status Code";
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 2409
|
||||
# define AAC_DRIVER_BRANCH "-mh1"
|
||||
# define AAC_DRIVER_BRANCH "-mh2"
|
||||
#endif
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
|
||||
|
@ -563,7 +563,6 @@ struct aac_queue {
|
|||
spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */
|
||||
struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */
|
||||
/* only valid for command queues which receive entries from the adapter. */
|
||||
struct list_head pendingq; /* A queue of outstanding fib's to the adapter. */
|
||||
u32 numpending; /* Number of entries on outstanding queue. */
|
||||
struct aac_dev * dev; /* Back pointer to adapter structure */
|
||||
};
|
||||
|
@ -822,11 +821,6 @@ struct fib {
|
|||
fib_callback callback;
|
||||
void *callback_data;
|
||||
u32 flags; // u32 dmb was ulong
|
||||
/*
|
||||
* The following is used to put this fib context onto the
|
||||
* Outstanding I/O queue.
|
||||
*/
|
||||
struct list_head queue;
|
||||
/*
|
||||
* And for the internal issue/reply queues (we may be able
|
||||
* to merge these two)
|
||||
|
@ -1815,3 +1809,5 @@ int aac_probe_container(struct aac_dev *dev, int cid);
|
|||
extern int numacb;
|
||||
extern int acbsize;
|
||||
extern char aac_driver_version[];
|
||||
extern int startup_timeout;
|
||||
extern int aif_timeout;
|
||||
|
|
|
@ -535,7 +535,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
|
|||
default:
|
||||
data_dir = DMA_NONE;
|
||||
}
|
||||
if (user_srbcmd->sg.count > (sizeof(sg_list)/sizeof(sg_list[0]))) {
|
||||
if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) {
|
||||
dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n",
|
||||
le32_to_cpu(srbcmd->sg.count)));
|
||||
rcode = -EINVAL;
|
||||
|
|
|
@ -103,7 +103,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
|
|||
* This assumes the memory is mapped zero->n, which isnt
|
||||
* always true on real computers. It also has some slight problems
|
||||
* with the GART on x86-64. I've btw never tried DMA from PCI space
|
||||
* on this platform but don't be suprised if its problematic.
|
||||
* on this platform but don't be surprised if its problematic.
|
||||
*/
|
||||
#ifndef CONFIG_GART_IOMMU
|
||||
if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
|
||||
|
@ -159,7 +159,6 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
|
|||
{
|
||||
q->numpending = 0;
|
||||
q->dev = dev;
|
||||
INIT_LIST_HEAD(&q->pendingq);
|
||||
init_waitqueue_head(&q->cmdready);
|
||||
INIT_LIST_HEAD(&q->cmdq);
|
||||
init_waitqueue_head(&q->qfull);
|
||||
|
|
|
@ -472,7 +472,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
|||
spin_lock_irqsave(q->lock, qflags);
|
||||
if (dev->new_comm_interface) {
|
||||
unsigned long count = 10000000L; /* 50 seconds */
|
||||
list_add_tail(&fibptr->queue, &q->pendingq);
|
||||
q->numpending++;
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
while (aac_adapter_send(fibptr) != 0) {
|
||||
|
@ -481,7 +480,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
|||
spin_unlock_irqrestore(&fibptr->event_lock, flags);
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
q->numpending--;
|
||||
list_del(&fibptr->queue);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -492,7 +490,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
|||
unsigned long nointr = 0;
|
||||
aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
|
||||
|
||||
list_add_tail(&fibptr->queue, &q->pendingq);
|
||||
q->numpending++;
|
||||
*(q->headers.producer) = cpu_to_le32(index + 1);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
|
@ -520,7 +517,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
|||
if (--count == 0) {
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
q->numpending--;
|
||||
list_del(&fibptr->queue);
|
||||
spin_unlock_irqrestore(q->lock, qflags);
|
||||
if (wait == -1) {
|
||||
printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
|
||||
|
@ -1214,7 +1210,7 @@ int aac_command_thread(void *data)
|
|||
* since the last read off
|
||||
* the queue?
|
||||
*/
|
||||
if ((time_now - time_last) > 120) {
|
||||
if ((time_now - time_last) > aif_timeout) {
|
||||
entry = entry->next;
|
||||
aac_close_fib_context(dev, fibctx);
|
||||
continue;
|
||||
|
|
|
@ -85,10 +85,9 @@ unsigned int aac_response_normal(struct aac_queue * q)
|
|||
* continue. The caller has already been notified that
|
||||
* the fib timed out.
|
||||
*/
|
||||
if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
|
||||
list_del(&fib->queue);
|
||||
if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
|
||||
dev->queues->queue[AdapNormCmdQueue].numpending--;
|
||||
} else {
|
||||
else {
|
||||
printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags);
|
||||
printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib);
|
||||
continue;
|
||||
|
@ -284,7 +283,6 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
list_del(&fib->queue);
|
||||
dev->queues->queue[AdapNormCmdQueue].numpending--;
|
||||
|
||||
if (fast) {
|
||||
|
|
|
@ -119,7 +119,7 @@ static struct pci_device_id aac_pci_tbl[] = {
|
|||
{ 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
|
||||
|
@ -143,7 +143,7 @@ static struct pci_device_id aac_pci_tbl[] = {
|
|||
{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
|
||||
{ 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */
|
||||
{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800SAS (Hurricane44) */
|
||||
|
||||
{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
|
||||
{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
|
||||
|
@ -195,7 +195,7 @@ static struct aac_driver_ident aac_drivers[] = {
|
|||
{ aac_rkt_init, "aacraid", "ICP ", "ICP9014R0 ", 1 }, /* ICP9014R0 (Lancer) */
|
||||
{ aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */
|
||||
{ aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */
|
||||
{ aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */
|
||||
{ aac_rkt_init, "aacraid", "ICP ", "ICP5445AU ", 1 }, /* ICP5445AU (Hurricane44) */
|
||||
{ aac_rx_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */
|
||||
{ aac_rx_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */
|
||||
{ aac_rkt_init, "aacraid", "ICP ", "ICP9067MA ", 1 }, /* ICP9067MA (Intruder-6) */
|
||||
|
@ -217,7 +217,7 @@ static struct aac_driver_ident aac_drivers[] = {
|
|||
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
|
||||
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */
|
||||
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */
|
||||
{ aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */
|
||||
{ aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-3800SAS ", 1 }, /* ASR-3800SAS (Hurricane44) */
|
||||
|
||||
{ aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
|
||||
{ aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
|
||||
|
@ -453,15 +453,10 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
|||
|
||||
printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
|
||||
AAC_DRIVERNAME);
|
||||
|
||||
|
||||
spin_lock_irq(host->host_lock);
|
||||
|
||||
aac = (struct aac_dev *)host->hostdata;
|
||||
if (aac_adapter_check_health(aac)) {
|
||||
printk(KERN_ERR "%s: Host adapter appears dead\n",
|
||||
AAC_DRIVERNAME);
|
||||
spin_unlock_irq(host->host_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
/*
|
||||
|
@ -487,13 +482,10 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
|||
/*
|
||||
* We can exit If all the commands are complete
|
||||
*/
|
||||
spin_unlock_irq(host->host_lock);
|
||||
if (active == 0)
|
||||
return SUCCESS;
|
||||
ssleep(1);
|
||||
spin_lock_irq(host->host_lock);
|
||||
}
|
||||
spin_unlock_irq(host->host_lock);
|
||||
printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -572,7 +564,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
|
|||
|
||||
f = compat_alloc_user_space(sizeof(*f));
|
||||
ret = 0;
|
||||
if (clear_user(f, sizeof(*f)) != sizeof(*f))
|
||||
if (clear_user(f, sizeof(*f)))
|
||||
ret = -EFAULT;
|
||||
if (copy_in_user(f, (void __user *)arg, sizeof(struct fib_ioctl) - sizeof(u32)))
|
||||
ret = -EFAULT;
|
||||
|
|
|
@ -444,14 +444,14 @@ int aac_rkt_init(struct aac_dev *dev)
|
|||
*/
|
||||
while (!(rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))
|
||||
{
|
||||
if(time_after(jiffies, start+180*HZ))
|
||||
if(time_after(jiffies, start+startup_timeout*HZ))
|
||||
{
|
||||
status = rkt_readl(dev, MUnit.OMRx[0]);
|
||||
printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
|
||||
dev->name, instance, status);
|
||||
goto error_iounmap;
|
||||
}
|
||||
schedule_timeout_uninterruptible(1);
|
||||
msleep(1);
|
||||
}
|
||||
if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
|
||||
{
|
||||
|
|
|
@ -444,14 +444,14 @@ int aac_rx_init(struct aac_dev *dev)
|
|||
while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
|
||||
|| (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING)))
|
||||
{
|
||||
if(time_after(jiffies, start+180*HZ))
|
||||
if(time_after(jiffies, start+startup_timeout*HZ))
|
||||
{
|
||||
status = rx_readl(dev, IndexRegs.Mailbox[7]);
|
||||
printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
|
||||
dev->name, instance, status);
|
||||
goto error_iounmap;
|
||||
}
|
||||
schedule_timeout_uninterruptible(1);
|
||||
msleep(1);
|
||||
}
|
||||
if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
|
||||
{
|
||||
|
|
|
@ -66,11 +66,11 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
|
|||
sa_writew(dev, DoorbellClrReg_p, PrintfReady); /* clear PrintfReady */
|
||||
sa_writew(dev, DoorbellReg_s, PrintfDone);
|
||||
} else if (intstat & DOORBELL_1) { // dev -> Host Normal Command Ready
|
||||
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
|
||||
sa_writew(dev, DoorbellClrReg_p, DOORBELL_1);
|
||||
aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
|
||||
} else if (intstat & DOORBELL_2) { // dev -> Host Normal Response Ready
|
||||
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
|
||||
sa_writew(dev, DoorbellClrReg_p, DOORBELL_2);
|
||||
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
|
||||
} else if (intstat & DOORBELL_3) { // dev -> Host Normal Command Not Full
|
||||
sa_writew(dev, DoorbellClrReg_p, DOORBELL_3);
|
||||
} else if (intstat & DOORBELL_4) { // dev -> Host Normal Response Not Full
|
||||
|
@ -318,13 +318,13 @@ int aac_sa_init(struct aac_dev *dev)
|
|||
* Wait for the adapter to be up and running. Wait up to 3 minutes.
|
||||
*/
|
||||
while (!(sa_readl(dev, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
|
||||
if (time_after(jiffies, start+180*HZ)) {
|
||||
if (time_after(jiffies, start+startup_timeout*HZ)) {
|
||||
status = sa_readl(dev, Mailbox7);
|
||||
printk(KERN_WARNING "%s%d: adapter kernel failed to start, init status = %lx.\n",
|
||||
name, instance, status);
|
||||
goto error_iounmap;
|
||||
}
|
||||
schedule_timeout_uninterruptible(1);
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
|
||||
|
|
|
@ -1011,7 +1011,7 @@ static int __init do_setup(char *str)
|
|||
|
||||
int count=setup_idx;
|
||||
|
||||
get_options(str, sizeof(ints)/sizeof(int), ints);
|
||||
get_options(str, ARRAY_SIZE(ints), ints);
|
||||
aha1542_setup(str,ints);
|
||||
|
||||
return count<setup_idx;
|
||||
|
@ -1072,8 +1072,7 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
|
|||
int slot = 0;
|
||||
int pos = 0;
|
||||
|
||||
for (indx = 0; (slot != MCA_NOTFOUND) &&
|
||||
(indx < sizeof(bases)/sizeof(bases[0])); indx++) {
|
||||
for (indx = 0; (slot != MCA_NOTFOUND) && (indx < ARRAY_SIZE(bases)); indx++) {
|
||||
|
||||
if (bases[indx])
|
||||
continue;
|
||||
|
@ -1083,10 +1082,9 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
|
|||
if (slot == MCA_NOTFOUND)
|
||||
break;
|
||||
|
||||
|
||||
/* Found one */
|
||||
pos = mca_read_stored_pos(slot, 3);
|
||||
|
||||
|
||||
/* Decode address */
|
||||
if (pos & 0x80) {
|
||||
if (pos & 0x02) {
|
||||
|
@ -1118,23 +1116,22 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
|
|||
mca_set_adapter_name(slot, "Adapter AHA-1640");
|
||||
mca_set_adapter_procfn(slot, NULL, NULL);
|
||||
mca_mark_as_used(slot);
|
||||
|
||||
|
||||
/* Go on */
|
||||
slot++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hunt for ISA Plug'n'Pray Adaptecs (AHA1535)
|
||||
*/
|
||||
|
||||
|
||||
if(isapnp)
|
||||
{
|
||||
struct pnp_dev *pdev = NULL;
|
||||
for(indx = 0; indx <sizeof(bases)/sizeof(bases[0]);indx++)
|
||||
{
|
||||
for(indx = 0; indx < ARRAY_SIZE(bases); indx++) {
|
||||
if(bases[indx])
|
||||
continue;
|
||||
pdev = pnp_find_dev(NULL, ISAPNP_VENDOR('A', 'D', 'P'),
|
||||
|
@ -1144,29 +1141,29 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
|
|||
/*
|
||||
* Activate the PnP card
|
||||
*/
|
||||
|
||||
|
||||
if(pnp_device_attach(pdev)<0)
|
||||
continue;
|
||||
|
||||
|
||||
if(pnp_activate_dev(pdev)<0) {
|
||||
pnp_device_detach(pdev);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(!pnp_port_valid(pdev, 0)) {
|
||||
pnp_device_detach(pdev);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bases[indx] = pnp_port_start(pdev, 0);
|
||||
|
||||
|
||||
/* The card can be queried for its DMA, we have
|
||||
the DMA set up that is enough */
|
||||
|
||||
|
||||
printk(KERN_INFO "ISAPnP found an AHA1535 at I/O 0x%03X\n", bases[indx]);
|
||||
}
|
||||
}
|
||||
for (indx = 0; indx < sizeof(bases) / sizeof(bases[0]); indx++)
|
||||
for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
|
||||
if (bases[indx] != 0 && request_region(bases[indx], 4, "aha1542")) {
|
||||
shpnt = scsi_register(tpnt,
|
||||
sizeof(struct aha1542_hostdata));
|
||||
|
|
|
@ -107,7 +107,7 @@ struct aic7770_identity aic7770_ident_table[] =
|
|||
ahc_aic7770_EISA_setup
|
||||
}
|
||||
};
|
||||
const int ahc_num_aic7770_devs = NUM_ELEMENTS(aic7770_ident_table);
|
||||
const int ahc_num_aic7770_devs = ARRAY_SIZE(aic7770_ident_table);
|
||||
|
||||
struct aic7770_identity *
|
||||
aic7770_find_device(uint32_t id)
|
||||
|
|
|
@ -68,8 +68,6 @@ struct scb_platform_data;
|
|||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
#define ALL_CHANNELS '\0'
|
||||
#define ALL_TARGETS_MASK 0xFFFF
|
||||
#define INITIATOR_WILDCARD (~0)
|
||||
|
|
|
@ -59,7 +59,7 @@ char *ahd_chip_names[] =
|
|||
"aic7902",
|
||||
"aic7901A"
|
||||
};
|
||||
static const u_int num_chip_names = NUM_ELEMENTS(ahd_chip_names);
|
||||
static const u_int num_chip_names = ARRAY_SIZE(ahd_chip_names);
|
||||
|
||||
/*
|
||||
* Hardware error codes.
|
||||
|
@ -77,7 +77,7 @@ static struct ahd_hard_error_entry ahd_hard_errors[] = {
|
|||
{ MPARERR, "Scratch or SCB Memory Parity Error" },
|
||||
{ CIOPARERR, "CIOBUS Parity Error" },
|
||||
};
|
||||
static const u_int num_errors = NUM_ELEMENTS(ahd_hard_errors);
|
||||
static const u_int num_errors = ARRAY_SIZE(ahd_hard_errors);
|
||||
|
||||
static struct ahd_phase_table_entry ahd_phase_table[] =
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ static struct ahd_phase_table_entry ahd_phase_table[] =
|
|||
* In most cases we only wish to itterate over real phases, so
|
||||
* exclude the last element from the count.
|
||||
*/
|
||||
static const u_int num_phases = NUM_ELEMENTS(ahd_phase_table) - 1;
|
||||
static const u_int num_phases = ARRAY_SIZE(ahd_phase_table) - 1;
|
||||
|
||||
/* Our Sequencer Program */
|
||||
#include "aic79xx_seq.h"
|
||||
|
@ -7259,7 +7259,7 @@ ahd_qinfifo_count(struct ahd_softc *ahd)
|
|||
return (wrap_qinfifonext - wrap_qinpos);
|
||||
else
|
||||
return (wrap_qinfifonext
|
||||
+ NUM_ELEMENTS(ahd->qinfifo) - wrap_qinpos);
|
||||
+ ARRAY_SIZE(ahd->qinfifo) - wrap_qinpos);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8619,7 +8619,7 @@ ahd_check_patch(struct ahd_softc *ahd, struct patch **start_patch,
|
|||
struct patch *last_patch;
|
||||
u_int num_patches;
|
||||
|
||||
num_patches = sizeof(patches)/sizeof(struct patch);
|
||||
num_patches = ARRAY_SIZE(patches);
|
||||
last_patch = &patches[num_patches];
|
||||
cur_patch = *start_patch;
|
||||
|
||||
|
@ -9396,8 +9396,8 @@ ahd_find_tmode_devs(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb,
|
|||
} else {
|
||||
u_int max_id;
|
||||
|
||||
max_id = (ahd->features & AHD_WIDE) ? 15 : 7;
|
||||
if (ccb->ccb_h.target_id > max_id)
|
||||
max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
|
||||
if (ccb->ccb_h.target_id >= max_id)
|
||||
return (CAM_TID_INVALID);
|
||||
|
||||
if (ccb->ccb_h.target_lun >= AHD_NUM_LUNS)
|
||||
|
|
|
@ -916,7 +916,7 @@ ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
|
|||
{
|
||||
|
||||
if ((instance >= 0)
|
||||
&& (instance < NUM_ELEMENTS(aic79xx_iocell_info))) {
|
||||
&& (instance < ARRAY_SIZE(aic79xx_iocell_info))) {
|
||||
uint8_t *iocell_info;
|
||||
|
||||
iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
|
||||
|
@ -934,7 +934,7 @@ ahd_linux_setup_tag_info_global(char *p)
|
|||
tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
|
||||
printf("Setting Global Tags= %d\n", tags);
|
||||
|
||||
for (i = 0; i < NUM_ELEMENTS(aic79xx_tag_info); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
|
||||
for (j = 0; j < AHD_NUM_TARGETS; j++) {
|
||||
aic79xx_tag_info[i].tag_commands[j] = tags;
|
||||
}
|
||||
|
@ -946,7 +946,7 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
|
|||
{
|
||||
|
||||
if ((instance >= 0) && (targ >= 0)
|
||||
&& (instance < NUM_ELEMENTS(aic79xx_tag_info))
|
||||
&& (instance < ARRAY_SIZE(aic79xx_tag_info))
|
||||
&& (targ < AHD_NUM_TARGETS)) {
|
||||
aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
|
||||
if (bootverbose)
|
||||
|
@ -1072,21 +1072,21 @@ aic79xx_setup(char *s)
|
|||
end = strchr(s, '\0');
|
||||
|
||||
/*
|
||||
* XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS
|
||||
* XXX ia64 gcc isn't smart enough to know that ARRAY_SIZE
|
||||
* will never be 0 in this case.
|
||||
*/
|
||||
n = 0;
|
||||
*/
|
||||
n = 0;
|
||||
|
||||
while ((p = strsep(&s, ",.")) != NULL) {
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
for (i = 0; i < NUM_ELEMENTS(options); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(options); i++) {
|
||||
|
||||
n = strlen(options[i].name);
|
||||
if (strncmp(options[i].name, p, n) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == NUM_ELEMENTS(options))
|
||||
if (i == ARRAY_SIZE(options))
|
||||
continue;
|
||||
|
||||
if (strncmp(p, "global_tag_depth", n) == 0) {
|
||||
|
@ -1294,7 +1294,7 @@ ahd_platform_init(struct ahd_softc *ahd)
|
|||
/*
|
||||
* Lookup and commit any modified IO Cell options.
|
||||
*/
|
||||
if (ahd->unit < NUM_ELEMENTS(aic79xx_iocell_info)) {
|
||||
if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
|
||||
struct ahd_linux_iocell_opts *iocell_opts;
|
||||
|
||||
iocell_opts = &aic79xx_iocell_info[ahd->unit];
|
||||
|
@ -1426,7 +1426,7 @@ ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
|
|||
|
||||
tags = 0;
|
||||
if ((ahd->user_discenable & devinfo->target_mask) != 0) {
|
||||
if (ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) {
|
||||
if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
|
||||
|
||||
if (warned_user == 0) {
|
||||
printf(KERN_WARNING
|
||||
|
|
|
@ -201,7 +201,7 @@ struct ahd_pci_identity ahd_pci_ident_table [] =
|
|||
}
|
||||
};
|
||||
|
||||
const u_int ahd_num_pci_devs = NUM_ELEMENTS(ahd_pci_ident_table);
|
||||
const u_int ahd_num_pci_devs = ARRAY_SIZE(ahd_pci_ident_table);
|
||||
|
||||
#define DEVCONFIG 0x40
|
||||
#define PCIXINITPAT 0x0000E000ul
|
||||
|
|
|
@ -76,11 +76,9 @@ static u_int
|
|||
ahd_calc_syncsrate(u_int period_factor)
|
||||
{
|
||||
int i;
|
||||
int num_syncrates;
|
||||
|
||||
num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
|
||||
/* See if the period is in the "exception" table */
|
||||
for (i = 0; i < num_syncrates; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(scsi_syncrates); i++) {
|
||||
|
||||
if (period_factor == scsi_syncrates[i].period_factor) {
|
||||
/* Period in kHz */
|
||||
|
|
|
@ -69,8 +69,6 @@ struct seeprom_descriptor;
|
|||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
#define ALL_CHANNELS '\0'
|
||||
#define ALL_TARGETS_MASK 0xFFFF
|
||||
#define INITIATOR_WILDCARD (~0)
|
||||
|
@ -233,6 +231,7 @@ typedef enum {
|
|||
AHC_TARGETMODE = 0x20000, /* Has tested target mode support */
|
||||
AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */
|
||||
AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */
|
||||
AHC_HVD = 0x100000, /* HVD rather than SE */
|
||||
AHC_AIC7770_FE = AHC_FENONE,
|
||||
/*
|
||||
* The real 7850 does not support Ultra modes, but there are
|
||||
|
|
|
@ -68,7 +68,7 @@ char *ahc_chip_names[] =
|
|||
"aic7892",
|
||||
"aic7899"
|
||||
};
|
||||
static const u_int num_chip_names = NUM_ELEMENTS(ahc_chip_names);
|
||||
static const u_int num_chip_names = ARRAY_SIZE(ahc_chip_names);
|
||||
|
||||
/*
|
||||
* Hardware error codes.
|
||||
|
@ -88,7 +88,7 @@ static struct ahc_hard_error_entry ahc_hard_errors[] = {
|
|||
{ PCIERRSTAT, "PCI Error detected" },
|
||||
{ CIOPARERR, "CIOBUS Parity Error" },
|
||||
};
|
||||
static const u_int num_errors = NUM_ELEMENTS(ahc_hard_errors);
|
||||
static const u_int num_errors = ARRAY_SIZE(ahc_hard_errors);
|
||||
|
||||
static struct ahc_phase_table_entry ahc_phase_table[] =
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ static struct ahc_phase_table_entry ahc_phase_table[] =
|
|||
* In most cases we only wish to itterate over real phases, so
|
||||
* exclude the last element from the count.
|
||||
*/
|
||||
static const u_int num_phases = NUM_ELEMENTS(ahc_phase_table) - 1;
|
||||
static const u_int num_phases = ARRAY_SIZE(ahc_phase_table) - 1;
|
||||
|
||||
/*
|
||||
* Valid SCSIRATE values. (p. 3-17)
|
||||
|
@ -6367,7 +6367,7 @@ ahc_check_patch(struct ahc_softc *ahc, struct patch **start_patch,
|
|||
struct patch *last_patch;
|
||||
u_int num_patches;
|
||||
|
||||
num_patches = sizeof(patches)/sizeof(struct patch);
|
||||
num_patches = ARRAY_SIZE(patches);
|
||||
last_patch = &patches[num_patches];
|
||||
cur_patch = *start_patch;
|
||||
|
||||
|
@ -6774,8 +6774,8 @@ ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb,
|
|||
} else {
|
||||
u_int max_id;
|
||||
|
||||
max_id = (ahc->features & AHC_WIDE) ? 15 : 7;
|
||||
if (ccb->ccb_h.target_id > max_id)
|
||||
max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
|
||||
if (ccb->ccb_h.target_id >= max_id)
|
||||
return (CAM_TID_INVALID);
|
||||
|
||||
if (ccb->ccb_h.target_lun >= AHC_NUM_LUNS)
|
||||
|
|
|
@ -886,7 +886,7 @@ ahc_linux_setup_tag_info_global(char *p)
|
|||
tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
|
||||
printf("Setting Global Tags= %d\n", tags);
|
||||
|
||||
for (i = 0; i < NUM_ELEMENTS(aic7xxx_tag_info); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) {
|
||||
for (j = 0; j < AHC_NUM_TARGETS; j++) {
|
||||
aic7xxx_tag_info[i].tag_commands[j] = tags;
|
||||
}
|
||||
|
@ -898,7 +898,7 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
|
|||
{
|
||||
|
||||
if ((instance >= 0) && (targ >= 0)
|
||||
&& (instance < NUM_ELEMENTS(aic7xxx_tag_info))
|
||||
&& (instance < ARRAY_SIZE(aic7xxx_tag_info))
|
||||
&& (targ < AHC_NUM_TARGETS)) {
|
||||
aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
|
||||
if (bootverbose)
|
||||
|
@ -1020,7 +1020,7 @@ aic7xxx_setup(char *s)
|
|||
end = strchr(s, '\0');
|
||||
|
||||
/*
|
||||
* XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS
|
||||
* XXX ia64 gcc isn't smart enough to know that ARRAY_SIZE
|
||||
* will never be 0 in this case.
|
||||
*/
|
||||
n = 0;
|
||||
|
@ -1028,13 +1028,13 @@ aic7xxx_setup(char *s)
|
|||
while ((p = strsep(&s, ",.")) != NULL) {
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
for (i = 0; i < NUM_ELEMENTS(options); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(options); i++) {
|
||||
|
||||
n = strlen(options[i].name);
|
||||
if (strncmp(options[i].name, p, n) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == NUM_ELEMENTS(options))
|
||||
if (i == ARRAY_SIZE(options))
|
||||
continue;
|
||||
|
||||
if (strncmp(p, "global_tag_depth", n) == 0) {
|
||||
|
@ -1360,7 +1360,7 @@ ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||
|
||||
tags = 0;
|
||||
if ((ahc->user_discenable & devinfo->target_mask) != 0) {
|
||||
if (ahc->unit >= NUM_ELEMENTS(aic7xxx_tag_info)) {
|
||||
if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) {
|
||||
if (warned_user == 0) {
|
||||
|
||||
printf(KERN_WARNING
|
||||
|
@ -2537,6 +2537,22 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void ahc_linux_get_signalling(struct Scsi_Host *shost)
|
||||
{
|
||||
struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
|
||||
u8 mode = ahc_inb(ahc, SBLKCTL);
|
||||
|
||||
if (mode & ENAB40)
|
||||
spi_signalling(shost) = SPI_SIGNAL_LVD;
|
||||
else if (mode & ENAB20)
|
||||
spi_signalling(shost) =
|
||||
ahc->features & AHC_HVD ?
|
||||
SPI_SIGNAL_HVD :
|
||||
SPI_SIGNAL_SE;
|
||||
else
|
||||
spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
|
||||
}
|
||||
|
||||
static struct spi_function_template ahc_linux_transport_functions = {
|
||||
.set_offset = ahc_linux_set_offset,
|
||||
.show_offset = 1,
|
||||
|
@ -2552,6 +2568,7 @@ static struct spi_function_template ahc_linux_transport_functions = {
|
|||
.set_qas = ahc_linux_set_qas,
|
||||
.show_qas = 1,
|
||||
#endif
|
||||
.get_signalling = ahc_linux_get_signalling,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -144,16 +144,22 @@ static ahc_device_setup_t ahc_aic785X_setup;
|
|||
static ahc_device_setup_t ahc_aic7860_setup;
|
||||
static ahc_device_setup_t ahc_apa1480_setup;
|
||||
static ahc_device_setup_t ahc_aic7870_setup;
|
||||
static ahc_device_setup_t ahc_aic7870h_setup;
|
||||
static ahc_device_setup_t ahc_aha394X_setup;
|
||||
static ahc_device_setup_t ahc_aha394Xh_setup;
|
||||
static ahc_device_setup_t ahc_aha494X_setup;
|
||||
static ahc_device_setup_t ahc_aha494Xh_setup;
|
||||
static ahc_device_setup_t ahc_aha398X_setup;
|
||||
static ahc_device_setup_t ahc_aic7880_setup;
|
||||
static ahc_device_setup_t ahc_aic7880h_setup;
|
||||
static ahc_device_setup_t ahc_aha2940Pro_setup;
|
||||
static ahc_device_setup_t ahc_aha394XU_setup;
|
||||
static ahc_device_setup_t ahc_aha394XUh_setup;
|
||||
static ahc_device_setup_t ahc_aha398XU_setup;
|
||||
static ahc_device_setup_t ahc_aic7890_setup;
|
||||
static ahc_device_setup_t ahc_aic7892_setup;
|
||||
static ahc_device_setup_t ahc_aic7895_setup;
|
||||
static ahc_device_setup_t ahc_aic7895h_setup;
|
||||
static ahc_device_setup_t ahc_aic7896_setup;
|
||||
static ahc_device_setup_t ahc_aic7899_setup;
|
||||
static ahc_device_setup_t ahc_aha29160C_setup;
|
||||
|
@ -225,19 +231,19 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
|||
ID_AHA_2944,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 2944 SCSI adapter",
|
||||
ahc_aic7870_setup
|
||||
ahc_aic7870h_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_3944,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 3944 SCSI adapter",
|
||||
ahc_aha394X_setup
|
||||
ahc_aha394Xh_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_4944,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 4944 SCSI adapter",
|
||||
ahc_aha494X_setup
|
||||
ahc_aha494Xh_setup
|
||||
},
|
||||
/* aic7880 based controllers */
|
||||
{
|
||||
|
@ -256,13 +262,13 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
|||
ID_AHA_2944U & ID_DEV_VENDOR_MASK,
|
||||
ID_DEV_VENDOR_MASK,
|
||||
"Adaptec 2944 Ultra SCSI adapter",
|
||||
ahc_aic7880_setup
|
||||
ahc_aic7880h_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_3944U & ID_DEV_VENDOR_MASK,
|
||||
ID_DEV_VENDOR_MASK,
|
||||
"Adaptec 3944 Ultra SCSI adapter",
|
||||
ahc_aha394XU_setup
|
||||
ahc_aha394XUh_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_398XU & ID_DEV_VENDOR_MASK,
|
||||
|
@ -278,7 +284,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
|||
ID_AHA_4944U & ID_DEV_VENDOR_MASK,
|
||||
ID_DEV_VENDOR_MASK,
|
||||
"Adaptec 4944 Ultra SCSI adapter",
|
||||
ahc_aic7880_setup
|
||||
ahc_aic7880h_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_2930U & ID_DEV_VENDOR_MASK,
|
||||
|
@ -414,7 +420,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
|||
ID_AHA_3944AU,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 3944A Ultra SCSI adapter",
|
||||
ahc_aic7895_setup
|
||||
ahc_aic7895h_setup
|
||||
},
|
||||
{
|
||||
ID_AIC7895_ARO,
|
||||
|
@ -553,7 +559,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] =
|
|||
}
|
||||
};
|
||||
|
||||
const u_int ahc_num_pci_devs = NUM_ELEMENTS(ahc_pci_ident_table);
|
||||
const u_int ahc_num_pci_devs = ARRAY_SIZE(ahc_pci_ident_table);
|
||||
|
||||
#define AHC_394X_SLOT_CHANNEL_A 4
|
||||
#define AHC_394X_SLOT_CHANNEL_B 5
|
||||
|
@ -2120,6 +2126,16 @@ ahc_aic7870_setup(struct ahc_softc *ahc)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aic7870h_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aic7870_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha394X_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
@ -2131,6 +2147,16 @@ ahc_aha394X_setup(struct ahc_softc *ahc)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha394Xh_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aha394X_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha398X_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
@ -2153,6 +2179,16 @@ ahc_aha494X_setup(struct ahc_softc *ahc)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha494Xh_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aha494X_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aic7880_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
@ -2174,6 +2210,17 @@ ahc_aic7880_setup(struct ahc_softc *ahc)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aic7880h_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aic7880_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ahc_aha2940Pro_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
@ -2193,6 +2240,16 @@ ahc_aha394XU_setup(struct ahc_softc *ahc)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha394XUh_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aha394XU_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aha398XU_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
@ -2291,6 +2348,16 @@ ahc_aic7895_setup(struct ahc_softc *ahc)
|
|||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aic7895h_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
int error = ahc_aic7895_setup(ahc);
|
||||
|
||||
ahc->features |= AHC_HVD;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ahc_aic7896_setup(struct ahc_softc *ahc)
|
||||
{
|
||||
|
|
|
@ -77,11 +77,9 @@ static u_int
|
|||
ahc_calc_syncsrate(u_int period_factor)
|
||||
{
|
||||
int i;
|
||||
int num_syncrates;
|
||||
|
||||
num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
|
||||
/* See if the period is in the "exception" table */
|
||||
for (i = 0; i < num_syncrates; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(scsi_syncrates); i++) {
|
||||
|
||||
if (period_factor == scsi_syncrates[i].period_factor) {
|
||||
/* Period in kHz */
|
||||
|
|
|
@ -1565,7 +1565,7 @@ aic7xxx_check_patch(struct aic7xxx_host *p,
|
|||
struct sequencer_patch *last_patch;
|
||||
int num_patches;
|
||||
|
||||
num_patches = sizeof(sequencer_patches)/sizeof(struct sequencer_patch);
|
||||
num_patches = ARRAY_SIZE(sequencer_patches);
|
||||
last_patch = &sequencer_patches[num_patches];
|
||||
cur_patch = *start_patch;
|
||||
|
||||
|
|
|
@ -473,7 +473,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *re
|
|||
*/
|
||||
if (workreq->use_sg) {
|
||||
pci_unmap_sg(dev->pdev,
|
||||
(struct scatterlist *)workreq->buffer,
|
||||
(struct scatterlist *)workreq->request_buffer,
|
||||
workreq->use_sg,
|
||||
workreq->sc_data_direction);
|
||||
} else if (workreq->request_bufflen &&
|
||||
|
@ -3047,7 +3047,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (atp_dev.chip_ver == 4)
|
||||
shpnt->max_id = 16;
|
||||
else
|
||||
shpnt->max_id = 7;
|
||||
shpnt->max_id = 8;
|
||||
shpnt->this_id = host_id;
|
||||
shpnt->unique_id = base_io;
|
||||
shpnt->io_port = base_io;
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#include <linux/kernel.h>
|
||||
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include <scsi/scsi_dbg.h>
|
||||
|
||||
|
@ -114,8 +114,7 @@ static const struct value_name_pair maint_in_arr[] = {
|
|||
{0xd, "Report supported task management functions"},
|
||||
{0xe, "Report priority"},
|
||||
};
|
||||
#define MAINT_IN_SZ \
|
||||
(int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0]))
|
||||
#define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr)
|
||||
|
||||
static const struct value_name_pair maint_out_arr[] = {
|
||||
{0x6, "Set device identifier"},
|
||||
|
@ -123,34 +122,29 @@ static const struct value_name_pair maint_out_arr[] = {
|
|||
{0xb, "Change aliases"},
|
||||
{0xe, "Set priority"},
|
||||
};
|
||||
#define MAINT_OUT_SZ \
|
||||
(int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0]))
|
||||
#define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr)
|
||||
|
||||
static const struct value_name_pair serv_in12_arr[] = {
|
||||
{0x1, "Read media serial number"},
|
||||
};
|
||||
#define SERV_IN12_SZ \
|
||||
(int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0]))
|
||||
#define SERV_IN12_SZ ARRAY_SIZE(serv_in12_arr)
|
||||
|
||||
static const struct value_name_pair serv_out12_arr[] = {
|
||||
{-1, "dummy entry"},
|
||||
};
|
||||
#define SERV_OUT12_SZ \
|
||||
(int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0]))
|
||||
#define SERV_OUT12_SZ ARRAY_SIZE(serv_out12_arr)
|
||||
|
||||
static const struct value_name_pair serv_in16_arr[] = {
|
||||
{0x10, "Read capacity(16)"},
|
||||
{0x11, "Read long(16)"},
|
||||
};
|
||||
#define SERV_IN16_SZ \
|
||||
(int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0]))
|
||||
#define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr)
|
||||
|
||||
static const struct value_name_pair serv_out16_arr[] = {
|
||||
{0x11, "Write long(16)"},
|
||||
{0x1f, "Notify data transfer device(16)"},
|
||||
};
|
||||
#define SERV_OUT16_SZ \
|
||||
(int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0]))
|
||||
#define SERV_OUT16_SZ ARRAY_SIZE(serv_out16_arr)
|
||||
|
||||
static const struct value_name_pair variable_length_arr[] = {
|
||||
{0x1, "Rebuild(32)"},
|
||||
|
@ -190,8 +184,7 @@ static const struct value_name_pair variable_length_arr[] = {
|
|||
{0x8f7e, "Perform SCSI command (osd)"},
|
||||
{0x8f7f, "Perform task management function (osd)"},
|
||||
};
|
||||
#define VARIABLE_LENGTH_SZ \
|
||||
(int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0]))
|
||||
#define VARIABLE_LENGTH_SZ ARRAY_SIZE(variable_length_arr)
|
||||
|
||||
static const char * get_sa_name(const struct value_name_pair * arr,
|
||||
int arr_sz, int service_action)
|
||||
|
@ -1268,16 +1261,6 @@ void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
|
|||
}
|
||||
EXPORT_SYMBOL(scsi_print_sense);
|
||||
|
||||
void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
|
||||
{
|
||||
const char *name = devclass;
|
||||
|
||||
if (sreq->sr_request->rq_disk)
|
||||
name = sreq->sr_request->rq_disk->disk_name;
|
||||
__scsi_print_sense(name, sreq->sr_sense_buffer, SCSI_SENSE_BUFFERSIZE);
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_print_req_sense);
|
||||
|
||||
void scsi_print_command(struct scsi_cmnd *cmd)
|
||||
{
|
||||
/* Assume appended output (i.e. not at start of line) */
|
||||
|
@ -1290,10 +1273,10 @@ EXPORT_SYMBOL(scsi_print_command);
|
|||
#ifdef CONFIG_SCSI_CONSTANTS
|
||||
|
||||
static const char * const hostbyte_table[]={
|
||||
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
|
||||
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
|
||||
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
|
||||
"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
|
||||
#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *))
|
||||
#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
|
||||
|
||||
void scsi_print_hostbyte(int scsiresult)
|
||||
{
|
||||
|
@ -1303,7 +1286,7 @@ void scsi_print_hostbyte(int scsiresult)
|
|||
if (hb < NUM_HOSTBYTE_STRS)
|
||||
printk("(%s) ", hostbyte_table[hb]);
|
||||
else
|
||||
printk("is invalid ");
|
||||
printk("is invalid ");
|
||||
}
|
||||
#else
|
||||
void scsi_print_hostbyte(int scsiresult)
|
||||
|
@ -1315,14 +1298,14 @@ void scsi_print_hostbyte(int scsiresult)
|
|||
#ifdef CONFIG_SCSI_CONSTANTS
|
||||
|
||||
static const char * const driverbyte_table[]={
|
||||
"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
|
||||
"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
|
||||
"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
|
||||
#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
|
||||
#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
|
||||
|
||||
static const char * const driversuggest_table[]={"SUGGEST_OK",
|
||||
"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
|
||||
"SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
|
||||
#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
|
||||
#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table)
|
||||
|
||||
void scsi_print_driverbyte(int scsiresult)
|
||||
{
|
||||
|
|
|
@ -230,13 +230,12 @@ struct ScsiReqBlk {
|
|||
struct scsi_cmnd *cmd;
|
||||
|
||||
struct SGentry *segment_x; /* Linear array of hw sg entries (up to 64 entries) */
|
||||
u32 sg_bus_addr; /* Bus address of sg list (ie, of segment_x) */
|
||||
dma_addr_t sg_bus_addr; /* Bus address of sg list (ie, of segment_x) */
|
||||
|
||||
u8 sg_count; /* No of HW sg entries for this request */
|
||||
u8 sg_index; /* Index of HW sg entry for this request */
|
||||
u32 total_xfer_length; /* Total number of bytes remaining to be transfered */
|
||||
unsigned char *virt_addr; /* Virtual address of current transfer position */
|
||||
|
||||
size_t total_xfer_length; /* Total number of bytes remaining to be transfered */
|
||||
size_t request_length; /* Total number of bytes in this request */
|
||||
/*
|
||||
* The sense buffer handling function, request_sense, uses
|
||||
* the first hw sg entry (segment_x[0]) and the transfer
|
||||
|
@ -246,8 +245,7 @@ struct ScsiReqBlk {
|
|||
* total_xfer_length in xferred. These values are restored in
|
||||
* pci_unmap_srb_sense. This is the only place xferred is used.
|
||||
*/
|
||||
unsigned char *virt_addr_req; /* Saved virtual address of the request buffer */
|
||||
u32 xferred; /* Saved copy of total_xfer_length */
|
||||
size_t xferred; /* Saved copy of total_xfer_length */
|
||||
|
||||
u16 state;
|
||||
|
||||
|
@ -977,17 +975,6 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void pio_trigger(void)
|
||||
{
|
||||
static int feedback_requested;
|
||||
|
||||
if (!feedback_requested) {
|
||||
feedback_requested = 1;
|
||||
printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
|
||||
"to help improve support for your system.\n", __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare SRB for being sent to Device DCB w/ command *cmd */
|
||||
static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
|
||||
struct ScsiReqBlk *srb)
|
||||
|
@ -1001,7 +988,6 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
|
|||
srb->sg_count = 0;
|
||||
srb->total_xfer_length = 0;
|
||||
srb->sg_bus_addr = 0;
|
||||
srb->virt_addr = NULL;
|
||||
srb->sg_index = 0;
|
||||
srb->adapter_status = 0;
|
||||
srb->target_status = 0;
|
||||
|
@ -1032,7 +1018,6 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
|
|||
reqlen, cmd->request_buffer, cmd->use_sg,
|
||||
srb->sg_count);
|
||||
|
||||
srb->virt_addr = page_address(sl->page);
|
||||
for (i = 0; i < srb->sg_count; i++) {
|
||||
u32 busaddr = (u32)sg_dma_address(&sl[i]);
|
||||
u32 seglen = (u32)sl[i].length;
|
||||
|
@ -1077,12 +1062,14 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
|
|||
srb->total_xfer_length++;
|
||||
|
||||
srb->segment_x[0].length = srb->total_xfer_length;
|
||||
srb->virt_addr = cmd->request_buffer;
|
||||
|
||||
dprintkdbg(DBG_0,
|
||||
"build_srb: [1] len=%d buf=%p use_sg=%d map=%08x\n",
|
||||
srb->total_xfer_length, cmd->request_buffer,
|
||||
cmd->use_sg, srb->segment_x[0].address);
|
||||
}
|
||||
|
||||
srb->request_length = srb->total_xfer_length;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1414,10 +1401,10 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd)
|
|||
}
|
||||
srb = find_cmd(cmd, &dcb->srb_going_list);
|
||||
if (srb) {
|
||||
dprintkl(KERN_DEBUG, "eh_abort: Command in progress");
|
||||
dprintkl(KERN_DEBUG, "eh_abort: Command in progress\n");
|
||||
/* XXX: Should abort the command here */
|
||||
} else {
|
||||
dprintkl(KERN_DEBUG, "eh_abort: Command not found");
|
||||
dprintkl(KERN_DEBUG, "eh_abort: Command not found\n");
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
@ -1976,14 +1963,11 @@ static void sg_verify_length(struct ScsiReqBlk *srb)
|
|||
|
||||
/*
|
||||
* Compute the next Scatter Gather list index and adjust its length
|
||||
* and address if necessary; also compute virt_addr
|
||||
* and address if necessary
|
||||
*/
|
||||
static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
|
||||
{
|
||||
u8 idx;
|
||||
struct scatterlist *sg;
|
||||
struct scsi_cmnd *cmd = srb->cmd;
|
||||
int segment = cmd->use_sg;
|
||||
u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
|
||||
struct SGentry *psge = srb->segment_x + srb->sg_index;
|
||||
|
||||
|
@ -2016,29 +2000,6 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
|
|||
psge++;
|
||||
}
|
||||
sg_verify_length(srb);
|
||||
|
||||
/* we need the corresponding virtual address */
|
||||
if (!segment || (srb->flag & AUTO_REQSENSE)) {
|
||||
srb->virt_addr += xferred;
|
||||
return;
|
||||
}
|
||||
|
||||
/* We have to walk the scatterlist to find it */
|
||||
sg = (struct scatterlist *)cmd->request_buffer;
|
||||
while (segment--) {
|
||||
unsigned long mask =
|
||||
~((unsigned long)sg->length - 1) & PAGE_MASK;
|
||||
if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
|
||||
srb->virt_addr = (page_address(sg->page)
|
||||
+ psge->address -
|
||||
(psge->address & PAGE_MASK));
|
||||
return;
|
||||
}
|
||||
++sg;
|
||||
}
|
||||
|
||||
dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
|
||||
srb->virt_addr = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2050,15 +2011,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
|
|||
*/
|
||||
static void sg_subtract_one(struct ScsiReqBlk *srb)
|
||||
{
|
||||
srb->total_xfer_length--;
|
||||
srb->segment_x[srb->sg_index].length--;
|
||||
if (srb->total_xfer_length &&
|
||||
!srb->segment_x[srb->sg_index].length) {
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" (next segment)");
|
||||
srb->sg_index++;
|
||||
sg_update_list(srb, srb->total_xfer_length);
|
||||
}
|
||||
sg_update_list(srb, srb->total_xfer_length - 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2118,7 +2071,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||
* If we need more data, the DMA SG list will be freshly set up, anyway
|
||||
*/
|
||||
dprintkdbg(DBG_PIO, "data_out_phase0: "
|
||||
"DMA{fifcnt=0x%02x fifostat=0x%02x} "
|
||||
"DMA{fifocnt=0x%02x fifostat=0x%02x} "
|
||||
"SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n",
|
||||
DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
|
||||
DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
|
||||
|
@ -2239,12 +2192,11 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||
data_io_transfer(acb, srb, XFERDATAOUT);
|
||||
}
|
||||
|
||||
|
||||
static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
||||
u16 *pscsi_status)
|
||||
{
|
||||
u16 scsi_status = *pscsi_status;
|
||||
u32 d_left_counter = 0;
|
||||
|
||||
dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n",
|
||||
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun);
|
||||
|
||||
|
@ -2262,6 +2214,9 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||
* seem to be a bad idea, actually.
|
||||
*/
|
||||
if (!(srb->state & SRB_XFERPAD)) {
|
||||
u32 d_left_counter;
|
||||
unsigned int sc, fc;
|
||||
|
||||
if (scsi_status & PARITYERROR) {
|
||||
dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) "
|
||||
"Parity Error\n", srb->cmd->pid);
|
||||
|
@ -2298,18 +2253,19 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||
DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT));
|
||||
}
|
||||
/* Now: Check remainig data: The SCSI counters should tell us ... */
|
||||
d_left_counter = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER)
|
||||
+ ((DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f)
|
||||
sc = DC395x_read32(acb, TRM_S1040_SCSI_COUNTER);
|
||||
fc = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT);
|
||||
d_left_counter = sc + ((fc & 0x1f)
|
||||
<< ((srb->dcb->sync_period & WIDE_SYNC) ? 1 :
|
||||
0));
|
||||
dprintkdbg(DBG_KG, "data_in_phase0: "
|
||||
"SCSI{fifocnt=0x%02x%s ctr=0x%08x} "
|
||||
"DMA{fifocnt=0x%02x fifostat=0x%02x ctr=0x%08x} "
|
||||
"Remain{totxfer=%i scsi_fifo+ctr=%i}\n",
|
||||
DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT),
|
||||
fc,
|
||||
(srb->dcb->sync_period & WIDE_SYNC) ? "words" : "bytes",
|
||||
DC395x_read32(acb, TRM_S1040_SCSI_COUNTER),
|
||||
DC395x_read8(acb, TRM_S1040_DMA_FIFOCNT),
|
||||
sc,
|
||||
fc,
|
||||
DC395x_read8(acb, TRM_S1040_DMA_FIFOSTAT),
|
||||
DC395x_read32(acb, TRM_S1040_DMA_CXCNT),
|
||||
srb->total_xfer_length, d_left_counter);
|
||||
|
@ -2317,40 +2273,79 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
|
|||
/* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */
|
||||
if (d_left_counter
|
||||
&& srb->total_xfer_length <= DC395x_LASTPIO) {
|
||||
size_t left_io = srb->total_xfer_length;
|
||||
|
||||
/*u32 addr = (srb->segment_x[srb->sg_index].address); */
|
||||
/*sg_update_list (srb, d_left_counter); */
|
||||
dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) to "
|
||||
"%p for remaining %i bytes:",
|
||||
DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) & 0x1f,
|
||||
dprintkdbg(DBG_PIO, "data_in_phase0: PIO (%i %s) "
|
||||
"for remaining %i bytes:",
|
||||
fc & 0x1f,
|
||||
(srb->dcb->sync_period & WIDE_SYNC) ?
|
||||
"words" : "bytes",
|
||||
srb->virt_addr,
|
||||
srb->total_xfer_length);
|
||||
if (srb->dcb->sync_period & WIDE_SYNC)
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
|
||||
CFG2_WIDEFIFO);
|
||||
while (DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT) != 0x40) {
|
||||
u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
|
||||
pio_trigger();
|
||||
*(srb->virt_addr)++ = byte;
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" %02x", byte);
|
||||
d_left_counter--;
|
||||
sg_subtract_one(srb);
|
||||
}
|
||||
if (srb->dcb->sync_period & WIDE_SYNC) {
|
||||
#if 1
|
||||
/* Read the last byte ... */
|
||||
if (srb->total_xfer_length > 0) {
|
||||
u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
|
||||
pio_trigger();
|
||||
*(srb->virt_addr)++ = byte;
|
||||
srb->total_xfer_length--;
|
||||
while (left_io) {
|
||||
unsigned char *virt, *base = NULL;
|
||||
unsigned long flags = 0;
|
||||
size_t len = left_io;
|
||||
|
||||
if (srb->cmd->use_sg) {
|
||||
size_t offset = srb->request_length - left_io;
|
||||
local_irq_save(flags);
|
||||
/* Assumption: it's inside one page as it's at most 4 bytes and
|
||||
I just assume it's on a 4-byte boundary */
|
||||
base = scsi_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer,
|
||||
srb->sg_count, &offset, &len);
|
||||
virt = base + offset;
|
||||
} else {
|
||||
virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io;
|
||||
len = left_io;
|
||||
}
|
||||
left_io -= len;
|
||||
|
||||
while (len) {
|
||||
u8 byte;
|
||||
byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
|
||||
*virt++ = byte;
|
||||
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" %02x", byte);
|
||||
|
||||
d_left_counter--;
|
||||
sg_subtract_one(srb);
|
||||
|
||||
len--;
|
||||
|
||||
fc = DC395x_read8(acb, TRM_S1040_SCSI_FIFOCNT);
|
||||
|
||||
if (fc == 0x40) {
|
||||
left_io = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WARN_ON((fc != 0x40) == !d_left_counter);
|
||||
|
||||
if (fc == 0x40 && (srb->dcb->sync_period & WIDE_SYNC)) {
|
||||
/* Read the last byte ... */
|
||||
if (srb->total_xfer_length > 0) {
|
||||
u8 byte = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
|
||||
|
||||
*virt++ = byte;
|
||||
srb->total_xfer_length--;
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" %02x", byte);
|
||||
}
|
||||
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0);
|
||||
}
|
||||
|
||||
if (srb->cmd->use_sg) {
|
||||
scsi_kunmap_atomic_sg(base);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#endif
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2, 0);
|
||||
}
|
||||
/*printk(" %08x", *(u32*)(bus_to_virt (addr))); */
|
||||
/*srb->total_xfer_length = 0; */
|
||||
|
@ -2509,22 +2504,43 @@ static void data_io_transfer(struct AdapterCtlBlk *acb,
|
|||
SCMD_FIFO_IN);
|
||||
} else { /* write */
|
||||
int ln = srb->total_xfer_length;
|
||||
size_t left_io = srb->total_xfer_length;
|
||||
|
||||
if (srb->dcb->sync_period & WIDE_SYNC)
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_CONFIG2,
|
||||
CFG2_WIDEFIFO);
|
||||
dprintkdbg(DBG_PIO,
|
||||
"data_io_transfer: PIO %i bytes from %p:",
|
||||
srb->total_xfer_length, srb->virt_addr);
|
||||
|
||||
while (srb->total_xfer_length) {
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" %02x", (unsigned char) *(srb->virt_addr));
|
||||
while (left_io) {
|
||||
unsigned char *virt, *base = NULL;
|
||||
unsigned long flags = 0;
|
||||
size_t len = left_io;
|
||||
|
||||
pio_trigger();
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO,
|
||||
*(srb->virt_addr)++);
|
||||
if (srb->cmd->use_sg) {
|
||||
size_t offset = srb->request_length - left_io;
|
||||
local_irq_save(flags);
|
||||
/* Again, max 4 bytes */
|
||||
base = scsi_kmap_atomic_sg((struct scatterlist *)srb->cmd->request_buffer,
|
||||
srb->sg_count, &offset, &len);
|
||||
virt = base + offset;
|
||||
} else {
|
||||
virt = srb->cmd->request_buffer + srb->cmd->request_bufflen - left_io;
|
||||
len = left_io;
|
||||
}
|
||||
left_io -= len;
|
||||
|
||||
sg_subtract_one(srb);
|
||||
while (len--) {
|
||||
if (debug_enabled(DBG_PIO))
|
||||
printk(" %02x", *virt);
|
||||
|
||||
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, *virt++);
|
||||
|
||||
sg_subtract_one(srb);
|
||||
}
|
||||
|
||||
if (srb->cmd->use_sg) {
|
||||
scsi_kunmap_atomic_sg(base);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
if (srb->dcb->sync_period & WIDE_SYNC) {
|
||||
if (ln % 2) {
|
||||
|
@ -3319,7 +3335,6 @@ static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
|
|||
srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].address;
|
||||
srb->segment_x[0].length =
|
||||
srb->segment_x[DC395x_MAX_SG_LISTENTRY - 1].length;
|
||||
srb->virt_addr = srb->virt_addr_req;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3332,21 +3347,14 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
|||
{
|
||||
u8 tempcnt, status;
|
||||
struct scsi_cmnd *cmd = srb->cmd;
|
||||
struct ScsiInqData *ptr;
|
||||
enum dma_data_direction dir = cmd->sc_data_direction;
|
||||
|
||||
if (cmd->use_sg) {
|
||||
struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
|
||||
ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
|
||||
} else {
|
||||
ptr = (struct ScsiInqData *)(cmd->request_buffer);
|
||||
}
|
||||
int ckc_only = 1;
|
||||
|
||||
dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid,
|
||||
srb->cmd->device->id, srb->cmd->device->lun);
|
||||
dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n",
|
||||
dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n",
|
||||
srb, cmd->use_sg, srb->sg_index, srb->sg_count,
|
||||
cmd->request_buffer, ptr);
|
||||
cmd->request_buffer);
|
||||
status = srb->target_status;
|
||||
if (srb->flag & AUTO_REQSENSE) {
|
||||
dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n");
|
||||
|
@ -3485,29 +3493,47 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
|||
srb->segment_x[0].address,
|
||||
cmd->request_bufflen, dir);
|
||||
}
|
||||
|
||||
if ((cmd->result & RES_DID) == 0 && cmd->cmnd[0] == INQUIRY
|
||||
&& cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8
|
||||
&& dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2)
|
||||
dcb->inquiry7 = ptr->Flags;
|
||||
ckc_only = 0;
|
||||
/* Check Error Conditions */
|
||||
ckc_e:
|
||||
|
||||
if (cmd->cmnd[0] == INQUIRY) {
|
||||
unsigned char *base = NULL;
|
||||
struct ScsiInqData *ptr;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (cmd->use_sg) {
|
||||
struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
|
||||
size_t offset = 0, len = sizeof(struct ScsiInqData);
|
||||
|
||||
local_irq_save(flags);
|
||||
base = scsi_kmap_atomic_sg(sg, cmd->use_sg, &offset, &len);
|
||||
ptr = (struct ScsiInqData *)(base + offset);
|
||||
} else
|
||||
ptr = (struct ScsiInqData *)(cmd->request_buffer);
|
||||
|
||||
if (!ckc_only && (cmd->result & RES_DID) == 0
|
||||
&& cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8
|
||||
&& dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2)
|
||||
dcb->inquiry7 = ptr->Flags;
|
||||
|
||||
/*if( srb->cmd->cmnd[0] == INQUIRY && */
|
||||
/* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */
|
||||
if (cmd->cmnd[0] == INQUIRY && (cmd->result == (DID_OK << 16)
|
||||
|| status_byte(cmd->
|
||||
result) &
|
||||
CHECK_CONDITION)) {
|
||||
|
||||
if (!dcb->init_tcq_flag) {
|
||||
add_dev(acb, dcb, ptr);
|
||||
dcb->init_tcq_flag = 1;
|
||||
if ((cmd->result == (DID_OK << 16)
|
||||
|| status_byte(cmd->result) &
|
||||
CHECK_CONDITION)) {
|
||||
if (!dcb->init_tcq_flag) {
|
||||
add_dev(acb, dcb, ptr);
|
||||
dcb->init_tcq_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->use_sg) {
|
||||
scsi_kunmap_atomic_sg(base);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Here is the info for Doug Gilbert's sg3 ... */
|
||||
cmd->resid = srb->total_xfer_length;
|
||||
/* This may be interpreted by sb. or not ... */
|
||||
|
@ -3713,8 +3739,6 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
|
|||
srb->xferred = srb->total_xfer_length;
|
||||
/* srb->segment_x : a one entry of S/G list table */
|
||||
srb->total_xfer_length = sizeof(cmd->sense_buffer);
|
||||
srb->virt_addr_req = srb->virt_addr;
|
||||
srb->virt_addr = cmd->sense_buffer;
|
||||
srb->segment_x[0].length = sizeof(cmd->sense_buffer);
|
||||
/* Map sense buffer */
|
||||
srb->segment_x[0].address =
|
||||
|
|
|
@ -145,35 +145,35 @@ static struct override {
|
|||
0, IRQ_AUTO}};
|
||||
#endif
|
||||
|
||||
#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
|
||||
#define NO_OVERRIDES ARRAY_SIZE(overrides)
|
||||
|
||||
static struct base {
|
||||
unsigned long address;
|
||||
int noauto;
|
||||
} bases[] __initdata = {
|
||||
{ 0xcc000, 0 },
|
||||
{ 0xc8000, 0 },
|
||||
{ 0xdc000, 0 },
|
||||
} bases[] __initdata = {
|
||||
{ 0xcc000, 0 },
|
||||
{ 0xc8000, 0 },
|
||||
{ 0xdc000, 0 },
|
||||
{ 0xd8000, 0 }
|
||||
};
|
||||
|
||||
#define NO_BASES (sizeof (bases) / sizeof (struct base))
|
||||
#define NO_BASES ARRAY_SIZE(bases)
|
||||
|
||||
static const struct signature {
|
||||
const char *string;
|
||||
int offset;
|
||||
} signatures[] = {
|
||||
} signatures[] = {
|
||||
{"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
|
||||
};
|
||||
|
||||
#define NO_SIGNATURES (sizeof (signatures) / sizeof (struct signature))
|
||||
#define NO_SIGNATURES ARRAY_SIZE(signatures)
|
||||
|
||||
#ifndef MODULE
|
||||
/*
|
||||
* Function : dtc_setup(char *str, int *ints)
|
||||
*
|
||||
* Purpose : LILO command line initialization of the overrides array,
|
||||
*
|
||||
*
|
||||
* Inputs : str - unused, ints - array of integer parameters with ints[0]
|
||||
* equal to the number of ints.
|
||||
*
|
||||
|
|
|
@ -279,7 +279,7 @@ static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
|
|||
2},
|
||||
};
|
||||
|
||||
#define FD_BRDS sizeof(fd_mcs_adapters)/sizeof(struct fd_mcs_adapters_struct)
|
||||
#define FD_BRDS ARRAY_SIZE(fd_mcs_adapters)
|
||||
|
||||
static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs);
|
||||
|
||||
|
|
|
@ -420,10 +420,10 @@ static unsigned long addresses[] = {
|
|||
0xd0000,
|
||||
0xe0000,
|
||||
};
|
||||
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
|
||||
|
||||
#define ADDRESS_COUNT ARRAY_SIZE(addresses)
|
||||
|
||||
static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
|
||||
#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
|
||||
#define PORT_COUNT ARRAY_SIZE(ports)
|
||||
|
||||
static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
|
||||
|
||||
|
@ -502,7 +502,7 @@ static struct signature {
|
|||
geometry location are verified). */
|
||||
};
|
||||
|
||||
#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
|
||||
#define SIGNATURE_COUNT ARRAY_SIZE(signatures)
|
||||
|
||||
static void print_banner( struct Scsi_Host *shpnt )
|
||||
{
|
||||
|
@ -519,7 +519,7 @@ static void print_banner( struct Scsi_Host *shpnt )
|
|||
|
||||
if (bios_minor >= 0) printk("%d", bios_minor);
|
||||
else printk("?.");
|
||||
|
||||
|
||||
printk( " at 0x%lx using scsi id %d\n",
|
||||
bios_base, shpnt->this_id );
|
||||
}
|
||||
|
|
|
@ -138,10 +138,9 @@ static struct override {
|
|||
[1] __initdata = { { 0,},};
|
||||
#endif
|
||||
|
||||
#define NO_OVERRIDES ARRAY_SIZE(overrides)
|
||||
|
||||
#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
|
||||
|
||||
#ifndef MODULE
|
||||
#ifndef MODULE
|
||||
|
||||
/**
|
||||
* internal_setup - handle lilo command string override
|
||||
|
@ -210,7 +209,7 @@ static int __init do_NCR5380_setup(char *str)
|
|||
{
|
||||
int ints[10];
|
||||
|
||||
get_options(str, sizeof(ints) / sizeof(int), ints);
|
||||
get_options(str, ARRAY_SIZE(ints), ints);
|
||||
internal_setup(BOARD_NCR5380, str, ints);
|
||||
return 1;
|
||||
}
|
||||
|
@ -218,7 +217,7 @@ static int __init do_NCR5380_setup(char *str)
|
|||
/**
|
||||
* do_NCR53C400_setup - set up entry point
|
||||
* @str: unused
|
||||
* @ints: integer parameters from kernel setup code
|
||||
* @ints: integer parameters from kernel setup code
|
||||
*
|
||||
* Setup function invoked at boot to parse the ncr53c400= command
|
||||
* line.
|
||||
|
@ -228,7 +227,7 @@ static int __init do_NCR53C400_setup(char *str)
|
|||
{
|
||||
int ints[10];
|
||||
|
||||
get_options(str, sizeof(ints) / sizeof(int), ints);
|
||||
get_options(str, ARRAY_SIZE(ints), ints);
|
||||
internal_setup(BOARD_NCR53C400, str, ints);
|
||||
return 1;
|
||||
}
|
||||
|
@ -236,7 +235,7 @@ static int __init do_NCR53C400_setup(char *str)
|
|||
/**
|
||||
* do_NCR53C400A_setup - set up entry point
|
||||
* @str: unused
|
||||
* @ints: integer parameters from kernel setup code
|
||||
* @ints: integer parameters from kernel setup code
|
||||
*
|
||||
* Setup function invoked at boot to parse the ncr53c400a= command
|
||||
* line.
|
||||
|
@ -246,7 +245,7 @@ static int __init do_NCR53C400A_setup(char *str)
|
|||
{
|
||||
int ints[10];
|
||||
|
||||
get_options(str, sizeof(ints) / sizeof(int), ints);
|
||||
get_options(str, ARRAY_SIZE(ints), ints);
|
||||
internal_setup(BOARD_NCR53C400A, str, ints);
|
||||
return 1;
|
||||
}
|
||||
|
@ -254,7 +253,7 @@ static int __init do_NCR53C400A_setup(char *str)
|
|||
/**
|
||||
* do_DTC3181E_setup - set up entry point
|
||||
* @str: unused
|
||||
* @ints: integer parameters from kernel setup code
|
||||
* @ints: integer parameters from kernel setup code
|
||||
*
|
||||
* Setup function invoked at boot to parse the dtc3181e= command
|
||||
* line.
|
||||
|
@ -264,7 +263,7 @@ static int __init do_DTC3181E_setup(char *str)
|
|||
{
|
||||
int ints[10];
|
||||
|
||||
get_options(str, sizeof(ints) / sizeof(int), ints);
|
||||
get_options(str, ARRAY_SIZE(ints), ints);
|
||||
internal_setup(BOARD_DTC3181E, str, ints);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Intel Corporation: Storage RAID Controllers *
|
||||
* *
|
||||
* gdth.c *
|
||||
* Copyright (C) 1995-04 ICP vortex GmbH, Achim Leubner *
|
||||
* Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner *
|
||||
* Copyright (C) 2002-04 Intel Corporation *
|
||||
* Copyright (C) 2003-04 Adaptec Inc. *
|
||||
* Copyright (C) 2003-06 Adaptec Inc. *
|
||||
* <achim_leubner@adaptec.com> *
|
||||
* *
|
||||
* Additions/Fixes: *
|
||||
|
@ -27,9 +27,14 @@
|
|||
* along with this kernel; if not, write to the Free Software *
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
* *
|
||||
* Linux kernel 2.2.x, 2.4.x, 2.6.x supported *
|
||||
* Linux kernel 2.4.x, 2.6.x supported *
|
||||
* *
|
||||
* $Log: gdth.c,v $
|
||||
* Revision 1.74 2006/04/10 13:44:47 achim
|
||||
* Community changes for 2.6.x
|
||||
* Kernel 2.2.x no longer supported
|
||||
* scsi_request interface removed, thanks to Christoph Hellwig
|
||||
*
|
||||
* Revision 1.73 2004/03/31 13:33:03 achim
|
||||
* Special command 0xfd implemented to detect 64-bit DMA support
|
||||
*
|
||||
|
@ -94,7 +99,7 @@
|
|||
* Bugfix free_irq()
|
||||
*
|
||||
* Revision 1.56 2001/08/09 11:19:39 achim
|
||||
* struct scsi_host_template changes
|
||||
* Scsi_Host_Template changes
|
||||
*
|
||||
* Revision 1.55 2001/08/09 10:11:28 achim
|
||||
* Command HOST_UNFREEZE_IO before cache service init.
|
||||
|
@ -388,7 +393,13 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timer.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6)
|
||||
#include <linux/dma-mapping.h>
|
||||
#else
|
||||
#define DMA_32BIT_MASK 0x00000000ffffffffULL
|
||||
#define DMA_64BIT_MASK 0xffffffffffffffffULL
|
||||
#endif
|
||||
|
||||
#ifdef GDTH_RTC
|
||||
#include <linux/mc146818rtc.h>
|
||||
#endif
|
||||
|
@ -408,8 +419,8 @@
|
|||
|
||||
#include "scsi.h"
|
||||
#include <scsi/scsi_host.h>
|
||||
#include "gdth.h"
|
||||
#include "gdth_kcompat.h"
|
||||
#include "gdth.h"
|
||||
|
||||
static void gdth_delay(int milliseconds);
|
||||
static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
|
||||
|
@ -464,6 +475,8 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
|
|||
|
||||
static void gdth_flush(int hanum);
|
||||
static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);
|
||||
static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
|
||||
static void gdth_scsi_done(struct scsi_cmnd *scp);
|
||||
|
||||
#ifdef DEBUG_GDTH
|
||||
static unchar DebugState = DEBUG_GDTH;
|
||||
|
@ -556,8 +569,8 @@ static struct timer_list gdth_timer;
|
|||
#endif
|
||||
|
||||
#define PTR2USHORT(a) (ushort)(ulong)(a)
|
||||
#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b)
|
||||
#define INDEX_OK(i,t) ((i)<sizeof(t)/sizeof((t)[0]))
|
||||
#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b)
|
||||
#define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t))
|
||||
|
||||
#define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata))
|
||||
#define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext)
|
||||
|
@ -643,6 +656,7 @@ static int probe_eisa_isa = 0;
|
|||
static int force_dma32 = 0;
|
||||
|
||||
/* parameters for modprobe/insmod */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
|
||||
module_param_array(irq, int, NULL, 0);
|
||||
module_param(disable, int, 0);
|
||||
module_param(reserve_mode, int, 0);
|
||||
|
@ -655,6 +669,20 @@ module_param(virt_ctr, int, 0);
|
|||
module_param(shared_access, int, 0);
|
||||
module_param(probe_eisa_isa, int, 0);
|
||||
module_param(force_dma32, int, 0);
|
||||
#else
|
||||
MODULE_PARM(irq, "i");
|
||||
MODULE_PARM(disable, "i");
|
||||
MODULE_PARM(reserve_mode, "i");
|
||||
MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i");
|
||||
MODULE_PARM(reverse_scan, "i");
|
||||
MODULE_PARM(hdr_channel, "i");
|
||||
MODULE_PARM(max_ids, "i");
|
||||
MODULE_PARM(rescan, "i");
|
||||
MODULE_PARM(virt_ctr, "i");
|
||||
MODULE_PARM(shared_access, "i");
|
||||
MODULE_PARM(probe_eisa_isa, "i");
|
||||
MODULE_PARM(force_dma32, "i");
|
||||
#endif
|
||||
MODULE_AUTHOR("Achim Leubner");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -683,6 +711,91 @@ static void gdth_delay(int milliseconds)
|
|||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static void gdth_scsi_done(struct scsi_cmnd *scp)
|
||||
{
|
||||
TRACE2(("gdth_scsi_done()\n"));
|
||||
|
||||
if (scp->request)
|
||||
complete((struct completion *)scp->request);
|
||||
}
|
||||
|
||||
int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||
int timeout, u32 *info)
|
||||
{
|
||||
Scsi_Cmnd *scp;
|
||||
DECLARE_COMPLETION(wait);
|
||||
int rval;
|
||||
|
||||
scp = kmalloc(sizeof(*scp), GFP_KERNEL);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
memset(scp, 0, sizeof(*scp));
|
||||
scp->device = sdev;
|
||||
/* use request field to save the ptr. to completion struct. */
|
||||
scp->request = (struct request *)&wait;
|
||||
scp->timeout_per_command = timeout*HZ;
|
||||
scp->request_buffer = gdtcmd;
|
||||
scp->cmd_len = 12;
|
||||
memcpy(scp->cmnd, cmnd, 12);
|
||||
scp->SCp.this_residual = IOCTL_PRI; /* priority */
|
||||
scp->done = gdth_scsi_done; /* some fn. test this */
|
||||
gdth_queuecommand(scp, gdth_scsi_done);
|
||||
wait_for_completion(&wait);
|
||||
|
||||
rval = scp->SCp.Status;
|
||||
if (info)
|
||||
*info = scp->SCp.Message;
|
||||
kfree(scp);
|
||||
return rval;
|
||||
}
|
||||
#else
|
||||
static void gdth_scsi_done(Scsi_Cmnd *scp)
|
||||
{
|
||||
TRACE2(("gdth_scsi_done()\n"));
|
||||
|
||||
scp->request.rq_status = RQ_SCSI_DONE;
|
||||
if (scp->request.waiting)
|
||||
complete(scp->request.waiting);
|
||||
}
|
||||
|
||||
int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||
int timeout, u32 *info)
|
||||
{
|
||||
Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE);
|
||||
unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0;
|
||||
DECLARE_COMPLETION(wait);
|
||||
int rval;
|
||||
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
scp->SCp.this_residual = IOCTL_PRI; /* priority */
|
||||
scp->request.rq_status = RQ_SCSI_BUSY;
|
||||
scp->request.waiting = &wait;
|
||||
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
|
||||
wait_for_completion(&wait);
|
||||
|
||||
rval = scp->SCp.Status;
|
||||
if (info)
|
||||
*info = scp->SCp.Message;
|
||||
|
||||
scsi_release_command(scp);
|
||||
return rval;
|
||||
}
|
||||
#endif
|
||||
|
||||
int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||
int timeout, u32 *info)
|
||||
{
|
||||
struct scsi_device *sdev = scsi_get_host_dev(shost);
|
||||
int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info);
|
||||
|
||||
scsi_free_host_dev(sdev);
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs)
|
||||
{
|
||||
*cyls = size /HEADS/SECS;
|
||||
|
@ -773,7 +886,7 @@ static struct pci_device_id gdthtable[] __attribute_used__ = {
|
|||
MODULE_DEVICE_TABLE(pci,gdthtable);
|
||||
|
||||
static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
|
||||
ushort vendor, ushort device)
|
||||
ushort vendor, ushort device)
|
||||
{
|
||||
ulong base0, base1, base2;
|
||||
struct pci_dev *pdev;
|
||||
|
@ -2248,14 +2361,16 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority)
|
|||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
|
||||
scp->SCp.this_residual = (int)priority;
|
||||
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (priority >= DEFAULT_PRI) {
|
||||
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
|
||||
(b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
|
||||
TRACE2(("gdth_putq(): locked IO -> update_timeout()\n"));
|
||||
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
|
||||
if (scp->done != gdth_scsi_done) {
|
||||
scp->SCp.this_residual = (int)priority;
|
||||
b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (priority >= DEFAULT_PRI) {
|
||||
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
|
||||
(b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) {
|
||||
TRACE2(("gdth_putq(): locked IO ->update_timeout()\n"));
|
||||
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2309,14 +2424,18 @@ static void gdth_next(int hanum)
|
|||
for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
|
||||
if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
|
||||
pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
|
||||
b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
|
||||
t = nscp->device->id;
|
||||
l = nscp->device->lun;
|
||||
if (nscp->SCp.this_residual >= DEFAULT_PRI) {
|
||||
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
|
||||
(b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock))
|
||||
continue;
|
||||
}
|
||||
if (nscp->done != gdth_scsi_done) {
|
||||
b = virt_ctr ?
|
||||
NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
|
||||
t = nscp->device->id;
|
||||
l = nscp->device->lun;
|
||||
if (nscp->SCp.this_residual >= DEFAULT_PRI) {
|
||||
if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
|
||||
(b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock))
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
b = t = l = 0;
|
||||
|
||||
if (firsttime) {
|
||||
if (gdth_test_busy(hanum)) { /* controller busy ? */
|
||||
|
@ -2331,7 +2450,7 @@ static void gdth_next(int hanum)
|
|||
firsttime = FALSE;
|
||||
}
|
||||
|
||||
if (nscp->done != gdth_scsi_done || nscp->cmnd[0] != 0xff) {
|
||||
if (nscp->done != gdth_scsi_done) {
|
||||
if (nscp->SCp.phase == -1) {
|
||||
nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */
|
||||
if (nscp->cmnd[0] == TEST_UNIT_READY) {
|
||||
|
@ -2394,7 +2513,7 @@ static void gdth_next(int hanum)
|
|||
else
|
||||
nscp->scsi_done(nscp);
|
||||
}
|
||||
} else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) {
|
||||
} else if (nscp->done == gdth_scsi_done) {
|
||||
if (!(cmd_index=gdth_special_cmd(hanum,nscp)))
|
||||
this_cmd = FALSE;
|
||||
next_cmd = FALSE;
|
||||
|
@ -2542,13 +2661,13 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
|
|||
gdth_ha_str *ha;
|
||||
char *address;
|
||||
|
||||
cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
|
||||
cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen;
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
|
||||
if (scp->use_sg) {
|
||||
sl = (struct scatterlist *)scp->request_buffer;
|
||||
for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {
|
||||
unsigned long flags;
|
||||
unsigned long flags;
|
||||
cpnow = (ushort)sl->length;
|
||||
TRACE(("copy_internal() now %d sum %d count %d %d\n",
|
||||
cpnow,cpsum,cpcount,(ushort)scp->bufflen));
|
||||
|
@ -2560,12 +2679,19 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp,
|
|||
hanum);
|
||||
return;
|
||||
}
|
||||
local_irq_save(flags);
|
||||
address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
|
||||
local_irq_save(flags);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
|
||||
memcpy(address,buffer,cpnow);
|
||||
flush_dcache_page(sl->page);
|
||||
kunmap_atomic(address, KM_BIO_SRC_IRQ);
|
||||
local_irq_restore(flags);
|
||||
flush_dcache_page(sl->page);
|
||||
kunmap_atomic(address, KM_BIO_SRC_IRQ);
|
||||
#else
|
||||
address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset;
|
||||
memcpy(address,buffer,cpnow);
|
||||
flush_dcache_page(sl->page);
|
||||
kunmap_atomic(address, KM_BH_IRQ);
|
||||
#endif
|
||||
local_irq_restore(flags);
|
||||
if (cpsum == cpcount)
|
||||
break;
|
||||
buffer += cpnow;
|
||||
|
@ -2946,9 +3072,9 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
|
|||
offset = (ulong)scp->sense_buffer & ~PAGE_MASK;
|
||||
sense_paddr = pci_map_page(ha->pdev,page,offset,
|
||||
16,PCI_DMA_FROMDEVICE);
|
||||
scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr);
|
||||
*(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr;
|
||||
/* high part, if 64bit */
|
||||
scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32);
|
||||
*(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32);
|
||||
cmdp->OpCode = GDT_WRITE; /* always */
|
||||
cmdp->BoardNode = LOCALBOARD;
|
||||
if (mode64) {
|
||||
|
@ -3022,7 +3148,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
|
|||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
} else if (scp->request_bufflen) {
|
||||
scp->SCp.Status = GDTH_MAP_SINGLE;
|
||||
scp->SCp.Message = PCI_DMA_BIDIRECTIONAL;
|
||||
page = virt_to_page(scp->request_buffer);
|
||||
|
@ -3309,7 +3435,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
|
|||
}
|
||||
|
||||
if (!gdth_polling)
|
||||
spin_lock_irqsave(&ha2->smp_lock, flags);
|
||||
spin_lock_irqsave(&ha2->smp_lock, flags);
|
||||
wait_index = 0;
|
||||
|
||||
/* search controller */
|
||||
|
@ -3642,9 +3768,10 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
|
|||
scp->request_bufflen,scp->SCp.Message);
|
||||
if (scp->SCp.buffer) {
|
||||
dma_addr_t addr;
|
||||
addr = (dma_addr_t)(ulong32)scp->SCp.buffer;
|
||||
addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer;
|
||||
if (scp->host_scribble)
|
||||
addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32);
|
||||
addr += (dma_addr_t)
|
||||
((ulong64)(*(ulong32 *)&scp->host_scribble) << 32);
|
||||
pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE);
|
||||
}
|
||||
|
||||
|
@ -4154,7 +4281,11 @@ int __init option_setup(char *str)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static int __init gdth_detect(struct scsi_host_template *shtp)
|
||||
#else
|
||||
static int __init gdth_detect(Scsi_Host_Template *shtp)
|
||||
#endif
|
||||
{
|
||||
struct Scsi_Host *shp;
|
||||
gdth_pci_str pcistr[MAXHA];
|
||||
|
@ -4188,7 +4319,7 @@ static int __init gdth_detect(struct scsi_host_template *shtp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
printk("GDT-HA: Storage RAID Controller Driver. Version: %s \n",GDTH_VERSION_STR);
|
||||
printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR);
|
||||
/* initializations */
|
||||
gdth_polling = TRUE; b = 0;
|
||||
gdth_clear_events();
|
||||
|
@ -4751,7 +4882,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
|
|||
gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS,
|
||||
BUS_L2P(ha,b), 0, 0);
|
||||
gdth_polling = FALSE;
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -4819,7 +4950,9 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
|
|||
priority = DEFAULT_PRI;
|
||||
if (scp->done == gdth_scsi_done)
|
||||
priority = scp->SCp.this_residual;
|
||||
gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6);
|
||||
else
|
||||
gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6);
|
||||
|
||||
gdth_putq( hanum, scp, priority );
|
||||
gdth_next( hanum );
|
||||
return 0;
|
||||
|
@ -4922,11 +5055,7 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
|
|||
gdth_cmd_str cmd;
|
||||
int hanum;
|
||||
gdth_ha_str *ha;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
#endif
|
||||
int rval;
|
||||
|
||||
if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
|
||||
res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES)
|
||||
|
@ -4943,25 +5072,11 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
|
|||
cmd.u.cache64.DeviceNo = res.number;
|
||||
else
|
||||
cmd.u.cache.DeviceNo = res.number;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
srp = scsi_allocate_request(ha->sdev, GFP_KERNEL);
|
||||
if (!srp)
|
||||
return -ENOMEM;
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
gdth_do_req(srp, &cmd, cmnd, 30);
|
||||
res.status = (ushort)srp->sr_command->SCp.Status;
|
||||
scsi_release_request(srp);
|
||||
#else
|
||||
scp = scsi_allocate_device(ha->sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
gdth_do_cmd(scp, &cmd, cmnd, 30);
|
||||
res.status = (ushort)scp->SCp.Status;
|
||||
scsi_release_command(scp);
|
||||
#endif
|
||||
|
||||
rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
res.status = rval;
|
||||
|
||||
if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset)))
|
||||
return -EFAULT;
|
||||
|
@ -4974,12 +5089,8 @@ static int ioc_general(void __user *arg, char *cmnd)
|
|||
char *buf = NULL;
|
||||
ulong64 paddr;
|
||||
int hanum;
|
||||
gdth_ha_str *ha;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
#endif
|
||||
gdth_ha_str *ha;
|
||||
int rval;
|
||||
|
||||
if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) ||
|
||||
gen.ionode >= gdth_ctr_count)
|
||||
|
@ -5071,27 +5182,10 @@ static int ioc_general(void __user *arg, char *cmnd)
|
|||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
srp = scsi_allocate_request(ha->sdev, GFP_KERNEL);
|
||||
if (!srp)
|
||||
return -ENOMEM;
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
gdth_do_req(srp, &gen.command, cmnd, gen.timeout);
|
||||
gen.status = srp->sr_command->SCp.Status;
|
||||
gen.info = srp->sr_command->SCp.Message;
|
||||
scsi_release_request(srp);
|
||||
#else
|
||||
scp = scsi_allocate_device(ha->sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
gdth_do_cmd(scp, &gen.command, cmnd, gen.timeout);
|
||||
gen.status = scp->SCp.Status;
|
||||
gen.info = scp->SCp.Message;
|
||||
scsi_release_command(scp);
|
||||
#endif
|
||||
rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
gen.status = rval;
|
||||
|
||||
if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
|
||||
gen.data_len + gen.sense_len)) {
|
||||
|
@ -5114,40 +5208,22 @@ static int ioc_hdrlist(void __user *arg, char *cmnd)
|
|||
gdth_ha_str *ha;
|
||||
unchar i;
|
||||
int hanum, rc = -ENOMEM;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
#endif
|
||||
|
||||
u32 cluster_type = 0;
|
||||
|
||||
rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
|
||||
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
|
||||
if (!rsc || !cmd)
|
||||
goto free_fail;
|
||||
goto free_fail;
|
||||
|
||||
if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
|
||||
rsc->ionode >= gdth_ctr_count) {
|
||||
rc = -EFAULT;
|
||||
goto free_fail;
|
||||
goto free_fail;
|
||||
}
|
||||
hanum = rsc->ionode;
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
memset(cmd, 0, sizeof(gdth_cmd_str));
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
srp = scsi_allocate_request(ha->sdev, GFP_KERNEL);
|
||||
if (!srp)
|
||||
goto free_fail;
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
#else
|
||||
scp = scsi_allocate_device(ha->sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
goto free_fail;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_HDRIVES; ++i) {
|
||||
if (!ha->hdr[i].present) {
|
||||
rsc->hdr_list[i].bus = 0xff;
|
||||
|
@ -5164,27 +5240,15 @@ static int ioc_hdrlist(void __user *arg, char *cmnd)
|
|||
cmd->u.cache64.DeviceNo = i;
|
||||
else
|
||||
cmd->u.cache.DeviceNo = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
if (srp->sr_command->SCp.Status == S_OK)
|
||||
rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
if (scp->SCp.Status == S_OK)
|
||||
rsc->hdr_list[i].cluster_type = scp->SCp.Message;
|
||||
#endif
|
||||
if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK)
|
||||
rsc->hdr_list[i].cluster_type = cluster_type;
|
||||
}
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scsi_release_request(srp);
|
||||
#else
|
||||
scsi_release_command(scp);
|
||||
#endif
|
||||
|
||||
|
||||
if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
rc = 0;
|
||||
|
||||
free_fail:
|
||||
kfree(rsc);
|
||||
|
@ -5202,40 +5266,21 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
int rc = -ENOMEM;
|
||||
ulong flags;
|
||||
gdth_ha_str *ha;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
#endif
|
||||
|
||||
rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
|
||||
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
|
||||
if (!cmd || !rsc)
|
||||
goto free_fail;
|
||||
goto free_fail;
|
||||
|
||||
if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
|
||||
rsc->ionode >= gdth_ctr_count) {
|
||||
rc = -EFAULT;
|
||||
goto free_fail;
|
||||
rc = -EFAULT;
|
||||
goto free_fail;
|
||||
}
|
||||
hanum = rsc->ionode;
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
memset(cmd, 0, sizeof(gdth_cmd_str));
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
srp = scsi_allocate_request(ha->sdev, GFP_KERNEL);
|
||||
if (!srp)
|
||||
goto free_fail;
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
#else
|
||||
scp = scsi_allocate_device(ha->sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
goto free_fail;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
#endif
|
||||
|
||||
if (rsc->flag == 0) {
|
||||
/* old method: re-init. cache service */
|
||||
cmd->Service = CACHESERVICE;
|
||||
|
@ -5246,19 +5291,8 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
cmd->OpCode = GDT_INIT;
|
||||
cmd->u.cache.DeviceNo = LINUX_OS;
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
status = (ushort)srp->sr_command->SCp.Status;
|
||||
info = (ulong32)srp->sr_command->SCp.Message;
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp->SCp.Status;
|
||||
info = (ulong32)scp->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(&scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp.SCp.Status;
|
||||
info = (ulong32)scp.SCp.Message;
|
||||
#endif
|
||||
|
||||
status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
|
||||
i = 0;
|
||||
hdr_cnt = (status == S_OK ? (ushort)info : 0);
|
||||
} else {
|
||||
|
@ -5273,15 +5307,9 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
cmd->u.cache64.DeviceNo = i;
|
||||
else
|
||||
cmd->u.cache.DeviceNo = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
status = (ushort)srp->sr_command->SCp.Status;
|
||||
info = (ulong32)srp->sr_command->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp->SCp.Status;
|
||||
info = (ulong32)scp->SCp.Message;
|
||||
#endif
|
||||
|
||||
status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
rsc->hdr_list[i].bus = ha->virt_bus;
|
||||
rsc->hdr_list[i].target = i;
|
||||
|
@ -5313,15 +5341,9 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
cmd->u.cache64.DeviceNo = i;
|
||||
else
|
||||
cmd->u.cache.DeviceNo = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
status = (ushort)srp->sr_command->SCp.Status;
|
||||
info = (ulong32)srp->sr_command->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp->SCp.Status;
|
||||
info = (ulong32)scp->SCp.Message;
|
||||
#endif
|
||||
|
||||
status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
|
@ -5332,15 +5354,9 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
cmd->u.cache64.DeviceNo = i;
|
||||
else
|
||||
cmd->u.cache.DeviceNo = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
status = (ushort)srp->sr_command->SCp.Status;
|
||||
info = (ulong32)srp->sr_command->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp->SCp.Status;
|
||||
info = (ulong32)scp->SCp.Message;
|
||||
#endif
|
||||
|
||||
status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
ha->hdr[i].cluster_type =
|
||||
((status == S_OK && !shared_access) ? (ushort)info : 0);
|
||||
|
@ -5353,29 +5369,18 @@ static int ioc_rescan(void __user *arg, char *cmnd)
|
|||
cmd->u.cache64.DeviceNo = i;
|
||||
else
|
||||
cmd->u.cache.DeviceNo = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, cmd, cmnd, 30);
|
||||
status = (ushort)srp->sr_command->SCp.Status;
|
||||
info = (ulong32)srp->sr_command->SCp.Message;
|
||||
#else
|
||||
gdth_do_cmd(scp, cmd, cmnd, 30);
|
||||
status = (ushort)scp->SCp.Status;
|
||||
info = (ulong32)scp->SCp.Message;
|
||||
#endif
|
||||
|
||||
status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info);
|
||||
|
||||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scsi_release_request(srp);
|
||||
#else
|
||||
scsi_release_command(scp);
|
||||
#endif
|
||||
|
||||
if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
|
||||
rc = -EFAULT;
|
||||
else
|
||||
rc = 0;
|
||||
rc = 0;
|
||||
|
||||
free_fail:
|
||||
kfree(rsc);
|
||||
|
@ -5515,17 +5520,18 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
|
|||
hanum = res.ionode;
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
|
||||
/* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.6.x */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scp = scsi_get_command(ha->sdev, GFP_KERNEL);
|
||||
scp = kmalloc(sizeof(*scp), GFP_KERNEL);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
memset(scp, 0, sizeof(*scp));
|
||||
scp->device = ha->sdev;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
scp->device->channel = virt_ctr ? 0 : res.number;
|
||||
rval = gdth_eh_bus_reset(scp);
|
||||
res.status = (rval == SUCCESS ? S_OK : S_GENERR);
|
||||
scsi_put_command(scp);
|
||||
kfree(scp);
|
||||
#else
|
||||
scp = scsi_allocate_device(ha->sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
|
@ -5558,34 +5564,12 @@ static void gdth_flush(int hanum)
|
|||
int i;
|
||||
gdth_ha_str *ha;
|
||||
gdth_cmd_str gdtcmd;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
#endif
|
||||
struct scsi_device *sdev;
|
||||
char cmnd[MAX_COMMAND_SIZE];
|
||||
memset(cmnd, 0xff, MAX_COMMAND_SIZE);
|
||||
|
||||
TRACE2(("gdth_flush() hanum %d\n",hanum));
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
|
||||
srp = scsi_allocate_request(sdev, GFP_KERNEL);
|
||||
if (!srp)
|
||||
return;
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
#else
|
||||
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
|
||||
scp = scsi_allocate_device(sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
return;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_HDRIVES; ++i) {
|
||||
if (ha->hdr[i].present) {
|
||||
gdtcmd.BoardNode = LOCALBOARD;
|
||||
|
@ -5601,20 +5585,10 @@ static void gdth_flush(int hanum)
|
|||
gdtcmd.u.cache.sg_canz = 0;
|
||||
}
|
||||
TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(srp, &gdtcmd, cmnd, 30);
|
||||
#else
|
||||
gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
|
||||
#endif
|
||||
|
||||
gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL);
|
||||
}
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scsi_release_request(srp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#else
|
||||
scsi_release_command(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* shutdown routine */
|
||||
|
@ -5623,18 +5597,11 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
|
|||
int hanum;
|
||||
#ifndef __alpha__
|
||||
gdth_cmd_str gdtcmd;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *srp;
|
||||
struct scsi_device *sdev;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
struct scsi_device *sdev;
|
||||
#endif
|
||||
char cmnd[MAX_COMMAND_SIZE];
|
||||
#endif
|
||||
|
||||
if (notifier_disabled)
|
||||
return NOTIFY_OK;
|
||||
return NOTIFY_OK;
|
||||
|
||||
TRACE2(("gdth_halt() event %d\n",(int)event));
|
||||
if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF)
|
||||
|
@ -5652,31 +5619,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
|
|||
gdtcmd.Service = CACHESERVICE;
|
||||
gdtcmd.OpCode = GDT_RESET;
|
||||
TRACE2(("gdth_halt(): reset controller %d\n", hanum));
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
|
||||
srp = scsi_allocate_request(sdev, GFP_KERNEL);
|
||||
if (!srp) {
|
||||
unregister_reboot_notifier(&gdth_notifier);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
srp->sr_cmd_len = 12;
|
||||
srp->sr_use_sg = 0;
|
||||
gdth_do_req(srp, &gdtcmd, cmnd, 10);
|
||||
scsi_release_request(srp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#else
|
||||
sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
|
||||
scp = scsi_allocate_device(sdev, 1, FALSE);
|
||||
if (!scp) {
|
||||
unregister_reboot_notifier(&gdth_notifier);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
|
||||
scsi_release_command(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#endif
|
||||
gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL);
|
||||
#endif
|
||||
}
|
||||
printk("Done.\n");
|
||||
|
@ -5687,7 +5630,22 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf)
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
/* configure lun */
|
||||
static int gdth_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
|
||||
sdev->skip_ms_page_3f = 1;
|
||||
sdev->skip_ms_page_8 = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static struct scsi_host_template driver_template = {
|
||||
#else
|
||||
static Scsi_Host_Template driver_template = {
|
||||
#endif
|
||||
.proc_name = "gdth",
|
||||
.proc_info = gdth_proc_info,
|
||||
.name = "GDT SCSI Disk Array Controller",
|
||||
|
@ -5698,6 +5656,9 @@ static struct scsi_host_template driver_template = {
|
|||
.eh_bus_reset_handler = gdth_eh_bus_reset,
|
||||
.bios_param = gdth_bios_param,
|
||||
.can_queue = GDTH_MAXCMDS,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
.slave_configure = gdth_slave_configure,
|
||||
#endif
|
||||
.this_id = -1,
|
||||
.sg_tablesize = GDTH_MAXSG,
|
||||
.cmd_per_lun = GDTH_MAXC_P_L,
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
/*
|
||||
* Header file for the GDT Disk Array/Storage RAID controllers driver for Linux
|
||||
*
|
||||
* gdth.h Copyright (C) 1995-03 ICP vortex, Achim Leubner
|
||||
* gdth.h Copyright (C) 1995-06 ICP vortex, Achim Leubner
|
||||
* See gdth.c for further informations and
|
||||
* below for supported controller types
|
||||
*
|
||||
* <achim_leubner@adaptec.com>
|
||||
*
|
||||
* $Id: gdth.h,v 1.57 2004/03/31 11:52:09 achim Exp $
|
||||
* $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
|
@ -26,9 +26,9 @@
|
|||
/* defines, macros */
|
||||
|
||||
/* driver version */
|
||||
#define GDTH_VERSION_STR "3.04"
|
||||
#define GDTH_VERSION_STR "3.05"
|
||||
#define GDTH_VERSION 3
|
||||
#define GDTH_SUBVERSION 4
|
||||
#define GDTH_SUBVERSION 5
|
||||
|
||||
/* protocol version */
|
||||
#define PROTOCOL_VERSION 1
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
#ifndef IRQ_HANDLED
|
||||
typedef void irqreturn_t;
|
||||
#define IRQ_NONE
|
||||
|
@ -10,6 +8,18 @@ typedef void irqreturn_t;
|
|||
#define MODULE_LICENSE(x)
|
||||
#endif
|
||||
|
||||
#ifndef __iomem
|
||||
#define __iomem
|
||||
#endif
|
||||
|
||||
#ifndef __attribute_used__
|
||||
#define __attribute_used__ __devinitdata
|
||||
#endif
|
||||
|
||||
#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
|
||||
#ifndef SERVICE_ACTION_IN
|
||||
#define SERVICE_ACTION_IN 0x9e
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* gdth_proc.c
|
||||
* $Id: gdth_proc.c,v 1.42 2004/03/05 15:50:20 achim Exp $
|
||||
* $Id: gdth_proc.c,v 1.43 2006/01/11 16:15:00 achim Exp $
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
|
@ -51,57 +51,26 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length,int hostno,
|
|||
static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
|
||||
int hanum,int busnum)
|
||||
{
|
||||
int ret_val = -EINVAL;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *scp;
|
||||
struct scsi_device *sdev;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
struct scsi_device *sdev;
|
||||
#endif
|
||||
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
|
||||
int ret_val = -EINVAL;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
sdev = scsi_get_host_dev(host);
|
||||
scp = scsi_allocate_request(sdev, GFP_KERNEL);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
scp->sr_cmd_len = 12;
|
||||
scp->sr_use_sg = 0;
|
||||
#else
|
||||
sdev = scsi_get_host_dev(host);
|
||||
scp = scsi_allocate_device(sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
return -ENOMEM;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
#endif
|
||||
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
|
||||
|
||||
if (length >= 4) {
|
||||
if (strncmp(buffer,"gdth",4) == 0) {
|
||||
buffer += 5;
|
||||
length -= 5;
|
||||
ret_val = gdth_set_asc_info( buffer, length, hanum, scp );
|
||||
ret_val = gdth_set_asc_info(host, buffer, length, hanum);
|
||||
}
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scsi_release_request(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#else
|
||||
scsi_release_command(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#endif
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp)
|
||||
#else
|
||||
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
|
||||
#endif
|
||||
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
|
||||
int length,int hanum)
|
||||
{
|
||||
int orig_length, drive, wb_mode;
|
||||
int i, found;
|
||||
int orig_length, drive, wb_mode;
|
||||
int i, found;
|
||||
gdth_ha_str *ha;
|
||||
gdth_cmd_str gdtcmd;
|
||||
gdth_cpar_str *pcpar;
|
||||
|
@ -146,11 +115,8 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
|
|||
gdtcmd.u.cache.DeviceNo = i;
|
||||
gdtcmd.u.cache.BlockNo = 1;
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, &gdtcmd, cmnd, 30);
|
||||
#else
|
||||
gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
|
||||
#endif
|
||||
|
||||
gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
|
@ -202,11 +168,9 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
|
|||
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
|
||||
gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
|
||||
pcpar->write_back = wb_mode==1 ? 0:1;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, &gdtcmd, cmnd, 30);
|
||||
#else
|
||||
gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
|
||||
#endif
|
||||
|
||||
gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
|
||||
|
||||
gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
|
||||
printk("Done.\n");
|
||||
return(orig_length);
|
||||
|
@ -230,13 +194,6 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
|
||||
gdth_cmd_str *gdtcmd;
|
||||
gdth_evt_str *estr;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
Scsi_Request *scp;
|
||||
struct scsi_device *sdev;
|
||||
#else
|
||||
Scsi_Cmnd *scp;
|
||||
struct scsi_device *sdev;
|
||||
#endif
|
||||
char hrec[161];
|
||||
struct timeval tv;
|
||||
|
||||
|
@ -252,7 +209,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
|
||||
estr = kmalloc(sizeof(*estr), GFP_KERNEL);
|
||||
if (!gdtcmd || !estr)
|
||||
goto free_fail;
|
||||
goto free_fail;
|
||||
|
||||
memset(cmnd, 0xff, 12);
|
||||
memset(gdtcmd, 0, sizeof(gdth_cmd_str));
|
||||
|
@ -260,28 +217,6 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
|
||||
ha = HADATA(gdth_ctr_tab[hanum]);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
sdev = scsi_get_host_dev(host);
|
||||
scp = scsi_allocate_request(sdev, GFP_KERNEL);
|
||||
if (!scp)
|
||||
goto free_fail;
|
||||
scp->sr_cmd_len = 12;
|
||||
scp->sr_use_sg = 0;
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
|
||||
sdev = scsi_get_host_dev(host);
|
||||
scp = scsi_allocate_device(sdev, 1, FALSE);
|
||||
if (!scp)
|
||||
goto free_fail;
|
||||
scp->cmd_len = 12;
|
||||
scp->use_sg = 0;
|
||||
#else
|
||||
memset(&sdev,0,sizeof(struct scsi_device));
|
||||
memset(&scp, 0,sizeof(Scsi_Cmnd));
|
||||
sdev.host = scp.host = host;
|
||||
sdev.id = scp.target = sdev.host->this_id;
|
||||
scp.device = &sdev;
|
||||
#endif
|
||||
|
||||
|
||||
/* request is i.e. "cat /proc/scsi/gdth/0" */
|
||||
/* format: %-15s\t%-10s\t%-15s\t%s */
|
||||
|
@ -386,16 +321,9 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
sizeof(pds->list[0]);
|
||||
if (pds->entries > cnt)
|
||||
pds->entries = cnt;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status != S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status != S_OK)
|
||||
#endif
|
||||
{
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
|
||||
pds->count = 0;
|
||||
}
|
||||
|
||||
/* other IOCTLs must fit into area GDTH_SCRATCH/4 */
|
||||
for (j = 0; j < ha->raw[i].pdev_cnt; ++j) {
|
||||
|
@ -410,14 +338,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel =
|
||||
ha->raw[i].address | ha->raw[i].id_list[j];
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status == S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status == S_OK)
|
||||
#endif
|
||||
{
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
strncpy(hrec,pdi->vendor,8);
|
||||
strncpy(hrec+8,pdi->product,16);
|
||||
strncpy(hrec+24,pdi->revision,4);
|
||||
|
@ -466,14 +388,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd->u.ioctl.channel =
|
||||
ha->raw[i].address | ha->raw[i].id_list[j];
|
||||
pdef->sddc_type = 0x08;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status == S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status == S_OK)
|
||||
#endif
|
||||
{
|
||||
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
size = sprintf(buffer+len,
|
||||
" Grown Defects:\t%d\n",
|
||||
pdef->sddc_cnt);
|
||||
|
@ -519,16 +435,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
|
||||
gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
|
||||
gdtcmd->u.ioctl.channel = drv_no;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status != S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status != S_OK)
|
||||
#endif
|
||||
{
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) != S_OK)
|
||||
break;
|
||||
}
|
||||
pcdi->ld_dtype >>= 16;
|
||||
j++;
|
||||
if (pcdi->ld_dtype > 2) {
|
||||
|
@ -629,14 +537,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
|
||||
gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
|
||||
gdtcmd->u.ioctl.channel = i;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status == S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status == S_OK)
|
||||
#endif
|
||||
{
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
if (pai->ai_state == 0)
|
||||
strcpy(hrec, "idle");
|
||||
else if (pai->ai_state == 2)
|
||||
|
@ -710,14 +611,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
gdtcmd->u.ioctl.channel = i;
|
||||
phg->entries = MAX_HDRIVES;
|
||||
phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
gdth_do_req(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->sr_command->SCp.Status != S_OK)
|
||||
#else
|
||||
gdth_do_cmd(scp, gdtcmd, cmnd, 30);
|
||||
if (scp->SCp.Status != S_OK)
|
||||
#endif
|
||||
{
|
||||
if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {
|
||||
ha->hdr[i].ldr_no = i;
|
||||
ha->hdr[i].rw_attribs = 0;
|
||||
ha->hdr[i].start_sec = 0;
|
||||
|
@ -791,13 +685,6 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
}
|
||||
|
||||
stop_output:
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scsi_release_request(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#else
|
||||
scsi_release_command(scp);
|
||||
scsi_free_host_dev(sdev);
|
||||
#endif
|
||||
*start = buffer +(offset-begin);
|
||||
len -= (offset-begin);
|
||||
if (len > length)
|
||||
|
@ -812,64 +699,6 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static void gdth_do_req(Scsi_Request *scp, gdth_cmd_str *gdtcmd,
|
||||
char *cmnd, int timeout)
|
||||
{
|
||||
unsigned bufflen;
|
||||
DECLARE_COMPLETION(wait);
|
||||
|
||||
TRACE2(("gdth_do_req()\n"));
|
||||
if (gdtcmd != NULL) {
|
||||
bufflen = sizeof(gdth_cmd_str);
|
||||
} else {
|
||||
bufflen = 0;
|
||||
}
|
||||
scp->sr_request->rq_status = RQ_SCSI_BUSY;
|
||||
scp->sr_request->waiting = &wait;
|
||||
scsi_do_req(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
|
||||
wait_for_completion(&wait);
|
||||
}
|
||||
|
||||
#else
|
||||
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
|
||||
char *cmnd, int timeout)
|
||||
{
|
||||
unsigned bufflen;
|
||||
DECLARE_COMPLETION(wait);
|
||||
|
||||
TRACE2(("gdth_do_cmd()\n"));
|
||||
if (gdtcmd != NULL) {
|
||||
scp->SCp.this_residual = IOCTL_PRI;
|
||||
bufflen = sizeof(gdth_cmd_str);
|
||||
} else {
|
||||
scp->SCp.this_residual = DEFAULT_PRI;
|
||||
bufflen = 0;
|
||||
}
|
||||
|
||||
scp->request.rq_status = RQ_SCSI_BUSY;
|
||||
scp->request.waiting = &wait;
|
||||
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
|
||||
wait_for_completion(&wait);
|
||||
}
|
||||
#endif
|
||||
|
||||
void gdth_scsi_done(Scsi_Cmnd *scp)
|
||||
{
|
||||
TRACE2(("gdth_scsi_done()\n"));
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
scp->request->rq_status = RQ_SCSI_DONE;
|
||||
if (scp->request->waiting != NULL)
|
||||
complete(scp->request->waiting);
|
||||
#else
|
||||
scp->request.rq_status = RQ_SCSI_DONE;
|
||||
if (scp->request.waiting != NULL)
|
||||
complete(scp->request.waiting);
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
|
||||
ulong64 *paddr)
|
||||
{
|
||||
|
@ -976,11 +805,14 @@ static void gdth_stop_timeout(int hanum, int busnum, int id)
|
|||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
|
||||
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
|
||||
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (t == (unchar)id && b == (unchar)busnum) {
|
||||
TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
|
||||
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
|
||||
if (scp->done != gdth_scsi_done) {
|
||||
b = virt_ctr ?
|
||||
NUMDATA(scp->device->host)->busnum : scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (t == (unchar)id && b == (unchar)busnum) {
|
||||
TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
|
||||
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
|
@ -997,11 +829,14 @@ static void gdth_start_timeout(int hanum, int busnum, int id)
|
|||
spin_lock_irqsave(&ha->smp_lock, flags);
|
||||
|
||||
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
|
||||
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (t == (unchar)id && b == (unchar)busnum) {
|
||||
TRACE2(("gdth_start_timeout(): update_timeout()\n"));
|
||||
gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
|
||||
if (scp->done != gdth_scsi_done) {
|
||||
b = virt_ctr ?
|
||||
NUMDATA(scp->device->host)->busnum : scp->device->channel;
|
||||
t = scp->device->id;
|
||||
if (t == (unchar)id && b == (unchar)busnum) {
|
||||
TRACE2(("gdth_start_timeout(): update_timeout()\n"));
|
||||
gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
||||
|
|
|
@ -5,20 +5,16 @@
|
|||
* $Id: gdth_proc.h,v 1.16 2004/01/14 13:09:01 achim Exp $
|
||||
*/
|
||||
|
||||
int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
|
||||
int timeout, u32 *info);
|
||||
|
||||
static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
|
||||
int hanum,int busnum);
|
||||
static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
|
||||
struct Scsi_Host *host,int hanum,int busnum);
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd,
|
||||
char *cmnd, int timeout);
|
||||
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp);
|
||||
#else
|
||||
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd,
|
||||
char *cmnd, int timeout);
|
||||
static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
|
||||
#endif
|
||||
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
|
||||
int length, int hanum);
|
||||
|
||||
static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
|
||||
ulong64 *paddr);
|
||||
|
@ -28,7 +24,5 @@ static void gdth_stop_timeout(int hanum, int busnum, int id);
|
|||
static void gdth_start_timeout(int hanum, int busnum, int id);
|
||||
static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout);
|
||||
|
||||
void gdth_scsi_done(Scsi_Cmnd *scp);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
1493
drivers/scsi/hptiop.c
Normal file
1493
drivers/scsi/hptiop.c
Normal file
File diff suppressed because it is too large
Load diff
465
drivers/scsi/hptiop.h
Normal file
465
drivers/scsi/hptiop.h
Normal file
|
@ -0,0 +1,465 @@
|
|||
/*
|
||||
* HighPoint RR3xxx controller driver for Linux
|
||||
* Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* Please report bugs/comments/suggestions to linux@highpoint-tech.com
|
||||
*
|
||||
* For more information, visit http://www.highpoint-tech.com
|
||||
*/
|
||||
#ifndef _HPTIOP_H_
|
||||
#define _HPTIOP_H_
|
||||
|
||||
/*
|
||||
* logical device type.
|
||||
* Identify array (logical device) and physical device.
|
||||
*/
|
||||
#define LDT_ARRAY 1
|
||||
#define LDT_DEVICE 2
|
||||
|
||||
/*
|
||||
* Array types
|
||||
*/
|
||||
#define AT_UNKNOWN 0
|
||||
#define AT_RAID0 1
|
||||
#define AT_RAID1 2
|
||||
#define AT_RAID5 3
|
||||
#define AT_RAID6 4
|
||||
#define AT_JBOD 7
|
||||
|
||||
#define MAX_NAME_LENGTH 36
|
||||
#define MAX_ARRAYNAME_LEN 16
|
||||
|
||||
#define MAX_ARRAY_MEMBERS_V1 8
|
||||
#define MAX_ARRAY_MEMBERS_V2 16
|
||||
|
||||
/* keep definition for source code compatiblity */
|
||||
#define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1
|
||||
|
||||
/*
|
||||
* array flags
|
||||
*/
|
||||
#define ARRAY_FLAG_DISABLED 0x00000001 /* The array is disabled */
|
||||
#define ARRAY_FLAG_NEEDBUILDING 0x00000002 /* need to be rebuilt */
|
||||
#define ARRAY_FLAG_REBUILDING 0x00000004 /* in rebuilding process */
|
||||
#define ARRAY_FLAG_BROKEN 0x00000008 /* broken but still working */
|
||||
#define ARRAY_FLAG_BOOTDISK 0x00000010 /* has a active partition */
|
||||
#define ARRAY_FLAG_BOOTMARK 0x00000040 /* array has boot mark set */
|
||||
#define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */
|
||||
#define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */
|
||||
#define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */
|
||||
#define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */
|
||||
#define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */
|
||||
#define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */
|
||||
#define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */
|
||||
|
||||
/*
|
||||
* device flags
|
||||
*/
|
||||
#define DEVICE_FLAG_DISABLED 0x00000001 /* device is disabled */
|
||||
#define DEVICE_FLAG_UNINITIALIZED 0x00010000 /* device is not initialized */
|
||||
#define DEVICE_FLAG_LEGACY 0x00020000 /* lagacy drive */
|
||||
#define DEVICE_FLAG_IS_SPARE 0x80000000 /* is a spare disk */
|
||||
|
||||
/*
|
||||
* ioctl codes
|
||||
*/
|
||||
#define HPT_CTL_CODE(x) (x+0xFF00)
|
||||
#define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00)
|
||||
|
||||
#define HPT_IOCTL_GET_CONTROLLER_INFO HPT_CTL_CODE(2)
|
||||
#define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3)
|
||||
#define HPT_IOCTL_GET_LOGICAL_DEVICES HPT_CTL_CODE(4)
|
||||
#define HPT_IOCTL_GET_DRIVER_CAPABILITIES HPT_CTL_CODE(19)
|
||||
#define HPT_IOCTL_GET_DEVICE_INFO_V3 HPT_CTL_CODE(46)
|
||||
#define HPT_IOCTL_GET_CONTROLLER_INFO_V2 HPT_CTL_CODE(47)
|
||||
|
||||
/*
|
||||
* Controller information.
|
||||
*/
|
||||
struct hpt_controller_info {
|
||||
u8 chip_type; /* chip type */
|
||||
u8 interrupt_level; /* IRQ level */
|
||||
u8 num_buses; /* bus count */
|
||||
u8 chip_flags;
|
||||
|
||||
u8 product_id[MAX_NAME_LENGTH];/* product name */
|
||||
u8 vendor_id[MAX_NAME_LENGTH]; /* vendor name */
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
/*
|
||||
* Channel information.
|
||||
*/
|
||||
struct hpt_channel_info {
|
||||
__le32 io_port; /* IDE Base Port Address */
|
||||
__le32 control_port; /* IDE Control Port Address */
|
||||
__le32 devices[2]; /* device connected to this channel */
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
/*
|
||||
* Array information.
|
||||
*/
|
||||
struct hpt_array_info_v3 {
|
||||
u8 name[MAX_ARRAYNAME_LEN]; /* array name */
|
||||
u8 description[64]; /* array description */
|
||||
u8 create_manager[16]; /* who created it */
|
||||
__le32 create_time; /* when created it */
|
||||
|
||||
u8 array_type; /* array type */
|
||||
u8 block_size_shift; /* stripe size */
|
||||
u8 ndisk; /* Number of ID in Members[] */
|
||||
u8 reserved;
|
||||
|
||||
__le32 flags; /* working flags, see ARRAY_FLAG_XXX */
|
||||
__le32 members[MAX_ARRAY_MEMBERS_V2]; /* member array/disks */
|
||||
|
||||
__le32 rebuilding_progress;
|
||||
__le64 rebuilt_sectors; /* rebuilding point (LBA) for single member */
|
||||
|
||||
__le32 transform_source;
|
||||
__le32 transform_target; /* destination device ID */
|
||||
__le32 transforming_progress;
|
||||
__le32 signature; /* persistent identification*/
|
||||
__le16 critical_members; /* bit mask of critical members */
|
||||
__le16 reserve2;
|
||||
__le32 reserve;
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
/*
|
||||
* physical device information.
|
||||
*/
|
||||
#define MAX_PARENTS_PER_DISK 8
|
||||
|
||||
struct hpt_device_info_v2 {
|
||||
u8 ctlr_id; /* controller id */
|
||||
u8 path_id; /* bus */
|
||||
u8 target_id; /* id */
|
||||
u8 device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */
|
||||
/* 5-7 MW DMA0-2, 8-13 UDMA0-5 */
|
||||
u8 device_type; /* device type */
|
||||
u8 usable_mode; /* highest usable mode */
|
||||
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
u8 NCQ_enabled: 1;
|
||||
u8 NCQ_supported: 1;
|
||||
u8 TCQ_enabled: 1;
|
||||
u8 TCQ_supported: 1;
|
||||
u8 write_cache_enabled: 1;
|
||||
u8 write_cache_supported: 1;
|
||||
u8 read_ahead_enabled: 1;
|
||||
u8 read_ahead_supported: 1;
|
||||
u8 reserved6: 6;
|
||||
u8 spin_up_mode: 2;
|
||||
#else
|
||||
u8 read_ahead_supported: 1;
|
||||
u8 read_ahead_enabled: 1;
|
||||
u8 write_cache_supported: 1;
|
||||
u8 write_cache_enabled: 1;
|
||||
u8 TCQ_supported: 1;
|
||||
u8 TCQ_enabled: 1;
|
||||
u8 NCQ_supported: 1;
|
||||
u8 NCQ_enabled: 1;
|
||||
u8 spin_up_mode: 2;
|
||||
u8 reserved6: 6;
|
||||
#endif
|
||||
|
||||
__le32 flags; /* working flags, see DEVICE_FLAG_XXX */
|
||||
u8 ident[150]; /* (partitial) Identify Data of this device */
|
||||
|
||||
__le64 total_free;
|
||||
__le64 max_free;
|
||||
__le64 bad_sectors;
|
||||
__le32 parent_arrays[MAX_PARENTS_PER_DISK];
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
/*
|
||||
* Logical device information.
|
||||
*/
|
||||
#define INVALID_TARGET_ID 0xFF
|
||||
#define INVALID_BUS_ID 0xFF
|
||||
|
||||
struct hpt_logical_device_info_v3 {
|
||||
u8 type; /* LDT_ARRAY or LDT_DEVICE */
|
||||
u8 cache_policy; /* refer to CACHE_POLICY_xxx */
|
||||
u8 vbus_id; /* vbus sequence in vbus_list */
|
||||
u8 target_id; /* OS target id. 0xFF is invalid */
|
||||
/* OS name: DISK $VBusId_$TargetId */
|
||||
__le64 capacity; /* array capacity */
|
||||
__le32 parent_array; /* don't use this field for physical
|
||||
device. use ParentArrays field in
|
||||
hpt_device_info_v2 */
|
||||
/* reserved statistic fields */
|
||||
__le32 stat1;
|
||||
__le32 stat2;
|
||||
__le32 stat3;
|
||||
__le32 stat4;
|
||||
|
||||
union {
|
||||
struct hpt_array_info_v3 array;
|
||||
struct hpt_device_info_v2 device;
|
||||
} __attribute__((packed)) u;
|
||||
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
/*
|
||||
* ioctl structure
|
||||
*/
|
||||
#define HPT_IOCTL_MAGIC 0xA1B2C3D4
|
||||
|
||||
struct hpt_ioctl_u {
|
||||
u32 magic; /* used to check if it's a valid ioctl packet */
|
||||
u32 ioctl_code; /* operation control code */
|
||||
void __user *inbuf; /* input data buffer */
|
||||
u32 inbuf_size; /* size of input data buffer */
|
||||
void __user *outbuf; /* output data buffer */
|
||||
u32 outbuf_size; /* size of output data buffer */
|
||||
void __user *bytes_returned; /* count of bytes returned */
|
||||
}
|
||||
__attribute__((packed));
|
||||
|
||||
|
||||
struct hpt_iopmu
|
||||
{
|
||||
__le32 resrved0[4];
|
||||
__le32 inbound_msgaddr0;
|
||||
__le32 inbound_msgaddr1;
|
||||
__le32 outbound_msgaddr0;
|
||||
__le32 outbound_msgaddr1;
|
||||
__le32 inbound_doorbell;
|
||||
__le32 inbound_intstatus;
|
||||
__le32 inbound_intmask;
|
||||
__le32 outbound_doorbell;
|
||||
__le32 outbound_intstatus;
|
||||
__le32 outbound_intmask;
|
||||
__le32 reserved1[2];
|
||||
__le32 inbound_queue;
|
||||
__le32 outbound_queue;
|
||||
};
|
||||
|
||||
#define IOPMU_QUEUE_EMPTY 0xffffffff
|
||||
#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000
|
||||
#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000
|
||||
|
||||
#define IOPMU_OUTBOUND_INT_MSG0 1
|
||||
#define IOPMU_OUTBOUND_INT_MSG1 2
|
||||
#define IOPMU_OUTBOUND_INT_DOORBELL 4
|
||||
#define IOPMU_OUTBOUND_INT_POSTQUEUE 8
|
||||
#define IOPMU_OUTBOUND_INT_PCI 0x10
|
||||
|
||||
#define IOPMU_INBOUND_INT_MSG0 1
|
||||
#define IOPMU_INBOUND_INT_MSG1 2
|
||||
#define IOPMU_INBOUND_INT_DOORBELL 4
|
||||
#define IOPMU_INBOUND_INT_ERROR 8
|
||||
#define IOPMU_INBOUND_INT_POSTQUEUE 0x10
|
||||
|
||||
enum hpt_iopmu_message {
|
||||
/* host-to-iop messages */
|
||||
IOPMU_INBOUND_MSG0_NOP = 0,
|
||||
IOPMU_INBOUND_MSG0_RESET,
|
||||
IOPMU_INBOUND_MSG0_FLUSH,
|
||||
IOPMU_INBOUND_MSG0_SHUTDOWN,
|
||||
IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
|
||||
IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
|
||||
IOPMU_INBOUND_MSG0_MAX = 0xff,
|
||||
/* iop-to-host messages */
|
||||
IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
|
||||
IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff,
|
||||
IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200,
|
||||
IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff,
|
||||
IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300,
|
||||
IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff,
|
||||
};
|
||||
|
||||
struct hpt_iop_request_header
|
||||
{
|
||||
__le32 size;
|
||||
__le32 type;
|
||||
__le32 flags;
|
||||
__le32 result;
|
||||
__le32 context; /* host context */
|
||||
__le32 context_hi32;
|
||||
};
|
||||
|
||||
#define IOP_REQUEST_FLAG_SYNC_REQUEST 1
|
||||
#define IOP_REQUEST_FLAG_BIST_REQUEST 2
|
||||
#define IOP_REQUEST_FLAG_REMAPPED 4
|
||||
#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
|
||||
|
||||
enum hpt_iop_request_type {
|
||||
IOP_REQUEST_TYPE_GET_CONFIG = 0,
|
||||
IOP_REQUEST_TYPE_SET_CONFIG,
|
||||
IOP_REQUEST_TYPE_BLOCK_COMMAND,
|
||||
IOP_REQUEST_TYPE_SCSI_COMMAND,
|
||||
IOP_REQUEST_TYPE_IOCTL_COMMAND,
|
||||
IOP_REQUEST_TYPE_MAX
|
||||
};
|
||||
|
||||
enum hpt_iop_result_type {
|
||||
IOP_RESULT_PENDING = 0,
|
||||
IOP_RESULT_SUCCESS,
|
||||
IOP_RESULT_FAIL,
|
||||
IOP_RESULT_BUSY,
|
||||
IOP_RESULT_RESET,
|
||||
IOP_RESULT_INVALID_REQUEST,
|
||||
IOP_RESULT_BAD_TARGET,
|
||||
IOP_RESULT_MODE_SENSE_CHECK_CONDITION,
|
||||
};
|
||||
|
||||
struct hpt_iop_request_get_config
|
||||
{
|
||||
struct hpt_iop_request_header header;
|
||||
__le32 interface_version;
|
||||
__le32 firmware_version;
|
||||
__le32 max_requests;
|
||||
__le32 request_size;
|
||||
__le32 max_sg_count;
|
||||
__le32 data_transfer_length;
|
||||
__le32 alignment_mask;
|
||||
__le32 max_devices;
|
||||
__le32 sdram_size;
|
||||
};
|
||||
|
||||
struct hpt_iop_request_set_config
|
||||
{
|
||||
struct hpt_iop_request_header header;
|
||||
__le32 iop_id;
|
||||
__le32 vbus_id;
|
||||
__le32 reserve[6];
|
||||
};
|
||||
|
||||
struct hpt_iopsg
|
||||
{
|
||||
__le32 size;
|
||||
__le32 eot; /* non-zero: end of table */
|
||||
__le64 pci_address;
|
||||
};
|
||||
|
||||
struct hpt_iop_request_block_command
|
||||
{
|
||||
struct hpt_iop_request_header header;
|
||||
u8 channel;
|
||||
u8 target;
|
||||
u8 lun;
|
||||
u8 pad1;
|
||||
__le16 command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */
|
||||
__le16 sectors;
|
||||
__le64 lba;
|
||||
struct hpt_iopsg sg_list[1];
|
||||
};
|
||||
|
||||
#define IOP_BLOCK_COMMAND_READ 1
|
||||
#define IOP_BLOCK_COMMAND_WRITE 2
|
||||
#define IOP_BLOCK_COMMAND_VERIFY 3
|
||||
#define IOP_BLOCK_COMMAND_FLUSH 4
|
||||
#define IOP_BLOCK_COMMAND_SHUTDOWN 5
|
||||
|
||||
struct hpt_iop_request_scsi_command
|
||||
{
|
||||
struct hpt_iop_request_header header;
|
||||
u8 channel;
|
||||
u8 target;
|
||||
u8 lun;
|
||||
u8 pad1;
|
||||
u8 cdb[16];
|
||||
__le32 dataxfer_length;
|
||||
struct hpt_iopsg sg_list[1];
|
||||
};
|
||||
|
||||
struct hpt_iop_request_ioctl_command
|
||||
{
|
||||
struct hpt_iop_request_header header;
|
||||
__le32 ioctl_code;
|
||||
__le32 inbuf_size;
|
||||
__le32 outbuf_size;
|
||||
__le32 bytes_returned;
|
||||
u8 buf[1];
|
||||
/* out data should be put at buf[(inbuf_size+3)&~3] */
|
||||
};
|
||||
|
||||
#define HPTIOP_MAX_REQUESTS 256u
|
||||
|
||||
struct hptiop_request {
|
||||
struct hptiop_request * next;
|
||||
void * req_virt;
|
||||
u32 req_shifted_phy;
|
||||
struct scsi_cmnd * scp;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct hpt_scsi_pointer {
|
||||
int mapped;
|
||||
int sgcnt;
|
||||
dma_addr_t dma_handle;
|
||||
};
|
||||
|
||||
#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp)
|
||||
|
||||
struct hptiop_hba {
|
||||
struct hpt_iopmu __iomem * iop;
|
||||
struct Scsi_Host * host;
|
||||
struct pci_dev * pcidev;
|
||||
|
||||
struct list_head link;
|
||||
|
||||
/* IOP config info */
|
||||
u32 firmware_version;
|
||||
u32 sdram_size;
|
||||
u32 max_devices;
|
||||
u32 max_requests;
|
||||
u32 max_request_size;
|
||||
u32 max_sg_descriptors;
|
||||
|
||||
u32 req_size; /* host-allocated request buffer size */
|
||||
int initialized;
|
||||
int msg_done;
|
||||
|
||||
struct hptiop_request * req_list;
|
||||
struct hptiop_request reqs[HPTIOP_MAX_REQUESTS];
|
||||
|
||||
/* used to free allocated dma area */
|
||||
void * dma_coherent;
|
||||
dma_addr_t dma_coherent_handle;
|
||||
|
||||
atomic_t reset_count;
|
||||
atomic_t resetting;
|
||||
|
||||
wait_queue_head_t reset_wq;
|
||||
wait_queue_head_t ioctl_wq;
|
||||
};
|
||||
|
||||
struct hpt_ioctl_k
|
||||
{
|
||||
struct hptiop_hba * hba;
|
||||
u32 ioctl_code;
|
||||
u32 inbuf_size;
|
||||
u32 outbuf_size;
|
||||
void * inbuf;
|
||||
void * outbuf;
|
||||
u32 * bytes_returned;
|
||||
void (*done)(struct hpt_ioctl_k *);
|
||||
int result; /* HPT_IOCTL_RESULT_ */
|
||||
};
|
||||
|
||||
#define HPT_IOCTL_RESULT_OK 0
|
||||
#define HPT_IOCTL_RESULT_FAILED (-1)
|
||||
|
||||
#if 0
|
||||
#define dprintk(fmt, args...) do { printk(fmt, ##args); } while(0)
|
||||
#else
|
||||
#define dprintk(fmt, args...)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1441,7 +1441,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
|
|||
struct Scsi_Host *dev = dev_id;
|
||||
|
||||
spin_lock_irqsave(dev->host_lock, flags);
|
||||
|
||||
|
||||
shpnt = dev; /* assign host-structure to local pointer */
|
||||
len = 0; /* set filled text-buffer index to 0 */
|
||||
/* get the _special contents of the hostdata structure */
|
||||
|
@ -1456,7 +1456,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
|
|||
/* if the integrated subsystem has been found automatically: */
|
||||
len += sprintf(buf + len,
|
||||
"Adapter category: integrated\n" "Chip revision level: %d\n" "Chip status: %s\n" "8 kByte NVRAM status: %s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 1) ? "enabled" : "disabled", (pos[2] & 2) ? "locked" : "accessible");
|
||||
} else if ((speciale >= 0) && (speciale < (sizeof(subsys_list) / sizeof(struct subsys_list_struct)))) {
|
||||
} else if ((speciale >= 0) && (speciale < ARRAY_SIZE(subsys_list))) {
|
||||
/* if the subsystem is a slot adapter */
|
||||
len += sprintf(buf + len, "Adapter category: slot-card\n" "ROM Segment Address: ");
|
||||
if ((pos[2] & 0xf0) == 0xf0)
|
||||
|
@ -1477,16 +1477,16 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
|
|||
while (len % sizeof(int) != (sizeof(int) - 1))
|
||||
len += sprintf(buf + len, " ");
|
||||
len += sprintf(buf + len, "\n");
|
||||
|
||||
|
||||
spin_unlock_irqrestore(shpnt->host_lock, flags);
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int ibmmca_detect(struct scsi_host_template * scsi_template)
|
||||
{
|
||||
struct Scsi_Host *shpnt;
|
||||
int port, id, i, j, k, list_size, slot;
|
||||
int port, id, i, j, k, slot;
|
||||
int devices_on_irq_11 = 0;
|
||||
int devices_on_irq_14 = 0;
|
||||
int IRQ14_registered = 0;
|
||||
|
@ -1603,8 +1603,7 @@ int ibmmca_detect(struct scsi_host_template * scsi_template)
|
|||
/* now look for other adapters in MCA slots, */
|
||||
/* determine the number of known IBM-SCSI-subsystem types */
|
||||
/* see the pos[2] dependence to get the adapter port-offset. */
|
||||
list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
|
||||
for (i = 0; i < list_size; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
|
||||
/* scan each slot for a fitting adapter id */
|
||||
slot = 0; /* start at slot 0 */
|
||||
while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
|
||||
|
@ -1669,8 +1668,7 @@ int ibmmca_detect(struct scsi_host_template * scsi_template)
|
|||
/* now check for SCSI-adapters, mapped to the integrated SCSI
|
||||
* area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here,
|
||||
* as this is a known effect on some models 95xx. */
|
||||
list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
|
||||
for (i = 0; i < list_size; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(subsys_list); i++) {
|
||||
/* scan each slot for a fitting adapter id */
|
||||
slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
|
||||
if (slot != MCA_NOTFOUND) { /* scan through all slots */
|
||||
|
|
|
@ -121,10 +121,9 @@ static int initialize_event_pool(struct event_pool *pool,
|
|||
|
||||
pool->size = size;
|
||||
pool->next = 0;
|
||||
pool->events = kmalloc(pool->size * sizeof(*pool->events), GFP_KERNEL);
|
||||
pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL);
|
||||
if (!pool->events)
|
||||
return -ENOMEM;
|
||||
memset(pool->events, 0x00, pool->size * sizeof(*pool->events));
|
||||
|
||||
pool->iu_storage =
|
||||
dma_alloc_coherent(hostdata->dev,
|
||||
|
|
|
@ -1119,6 +1119,10 @@ static int device_check(imm_struct *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* imm cannot deal with highmem, so this causes all IO pages for this host
|
||||
* to reside in low memory (hence mapped)
|
||||
*/
|
||||
static int imm_adjust_queue(struct scsi_device *device)
|
||||
{
|
||||
blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
|
||||
|
@ -1141,10 +1145,6 @@ static struct scsi_host_template imm_template = {
|
|||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.can_queue = 1,
|
||||
.slave_alloc = imm_adjust_queue,
|
||||
.unchecked_isa_dma = 1, /* imm cannot deal with highmem, so
|
||||
* this is an easy trick to ensure
|
||||
* all io pages for this host reside
|
||||
* in low memory */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
|
|
|
@ -370,7 +370,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
|
|||
*/
|
||||
|
||||
if (cmd->use_sg) {
|
||||
cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
|
||||
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
|
||||
cmd->SCp.buffers_residual = cmd->use_sg - 1;
|
||||
cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
|
||||
cmd->SCp.this_residual = cmd->SCp.buffer->length;
|
||||
|
@ -1809,7 +1809,7 @@ static int in2000_abort(Scsi_Cmnd * cmd)
|
|||
|
||||
|
||||
#define MAX_IN2000_HOSTS 3
|
||||
#define MAX_SETUP_ARGS (sizeof(setup_args) / sizeof(char *))
|
||||
#define MAX_SETUP_ARGS ARRAY_SIZE(setup_args)
|
||||
#define SETUP_BUFFER_SIZE 200
|
||||
static char setup_buffer[SETUP_BUFFER_SIZE];
|
||||
static char setup_used[MAX_SETUP_ARGS];
|
||||
|
|
|
@ -154,7 +154,6 @@
|
|||
static unsigned int i91u_debug = DEBUG_DEFAULT;
|
||||
#endif
|
||||
|
||||
#define TULSZ(sz) (sizeof(sz) / sizeof(sz[0]))
|
||||
#define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
|
||||
|
||||
typedef struct PCI_ID_Struc {
|
||||
|
@ -2771,7 +2770,7 @@ static int tul_NewReturnNumberOfAdapters(void)
|
|||
|
||||
init_i91uAdapter_table();
|
||||
|
||||
for (i = 0; i < TULSZ(i91u_pci_devices); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++)
|
||||
{
|
||||
while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) {
|
||||
if (pci_enable_device(pDev))
|
||||
|
|
|
@ -79,7 +79,6 @@
|
|||
#include <scsi/scsi_tcq.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include "ipr.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -556,7 +556,7 @@ ips_setup(char *ips_str)
|
|||
* We now have key/value pairs.
|
||||
* Update the variables
|
||||
*/
|
||||
for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(options); i++) {
|
||||
if (strnicmp
|
||||
(key, options[i].option_name,
|
||||
strlen(options[i].option_name)) == 0) {
|
||||
|
@ -4364,7 +4364,7 @@ ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
|
|||
|
||||
METHOD_TRACE("ips_rdcap", 1);
|
||||
|
||||
if (scb->scsi_cmd->bufflen < 8)
|
||||
if (scb->scsi_cmd->request_bufflen < 8)
|
||||
return (0);
|
||||
|
||||
cap.lba =
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,8 @@
|
|||
* iSCSI Initiator TCP Transport
|
||||
* Copyright (C) 2004 Dmitry Yusupov
|
||||
* Copyright (C) 2004 Alex Aizman
|
||||
* Copyright (C) 2005 Mike Christie
|
||||
* Copyright (C) 2005 - 2006 Mike Christie
|
||||
* Copyright (C) 2006 Red Hat, Inc. All rights reserved.
|
||||
* maintained by open-iscsi@googlegroups.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -21,20 +22,7 @@
|
|||
#ifndef ISCSI_TCP_H
|
||||
#define ISCSI_TCP_H
|
||||
|
||||
/* Session's states */
|
||||
#define ISCSI_STATE_FREE 1
|
||||
#define ISCSI_STATE_LOGGED_IN 2
|
||||
#define ISCSI_STATE_FAILED 3
|
||||
#define ISCSI_STATE_TERMINATE 4
|
||||
|
||||
/* Connection's states */
|
||||
#define ISCSI_CONN_INITIAL_STAGE 0
|
||||
#define ISCSI_CONN_STARTED 1
|
||||
#define ISCSI_CONN_STOPPED 2
|
||||
#define ISCSI_CONN_CLEANUP_WAIT 3
|
||||
|
||||
/* Connection suspend "bit" */
|
||||
#define SUSPEND_BIT 1
|
||||
#include <scsi/libiscsi.h>
|
||||
|
||||
/* Socket's Receive state machine */
|
||||
#define IN_PROGRESS_WAIT_HEADER 0x0
|
||||
|
@ -42,12 +30,6 @@
|
|||
#define IN_PROGRESS_DATA_RECV 0x2
|
||||
#define IN_PROGRESS_DDIGEST_RECV 0x3
|
||||
|
||||
/* Task Mgmt states */
|
||||
#define TMABORT_INITIAL 0x0
|
||||
#define TMABORT_SUCCESS 0x1
|
||||
#define TMABORT_FAILED 0x2
|
||||
#define TMABORT_TIMEDOUT 0x3
|
||||
|
||||
/* xmit state machine */
|
||||
#define XMSTATE_IDLE 0x0
|
||||
#define XMSTATE_R_HDR 0x1
|
||||
|
@ -62,34 +44,14 @@
|
|||
#define XMSTATE_W_PAD 0x200
|
||||
#define XMSTATE_DATA_DIGEST 0x400
|
||||
|
||||
#define ISCSI_CONN_MAX 1
|
||||
#define ISCSI_CONN_RCVBUF_MIN 262144
|
||||
#define ISCSI_CONN_SNDBUF_MIN 262144
|
||||
#define ISCSI_PAD_LEN 4
|
||||
#define ISCSI_R2T_MAX 16
|
||||
#define ISCSI_XMIT_CMDS_MAX 128 /* must be power of 2 */
|
||||
#define ISCSI_MGMT_CMDS_MAX 32 /* must be power of 2 */
|
||||
#define ISCSI_MGMT_ITT_OFFSET 0xa00
|
||||
#define ISCSI_SG_TABLESIZE SG_ALL
|
||||
#define ISCSI_DEF_CMD_PER_LUN 32
|
||||
#define ISCSI_MAX_CMD_PER_LUN 128
|
||||
#define ISCSI_TCP_MAX_CMD_LEN 16
|
||||
|
||||
#define ITT_MASK (0xfff)
|
||||
#define CID_SHIFT 12
|
||||
#define CID_MASK (0xffff<<CID_SHIFT)
|
||||
#define AGE_SHIFT 28
|
||||
#define AGE_MASK (0xf<<AGE_SHIFT)
|
||||
|
||||
struct iscsi_queue {
|
||||
struct kfifo *queue; /* FIFO Queue */
|
||||
void **pool; /* Pool of elements */
|
||||
int max; /* Max number of elements */
|
||||
};
|
||||
|
||||
struct iscsi_session;
|
||||
struct iscsi_cmd_task;
|
||||
struct iscsi_mgmt_task;
|
||||
struct socket;
|
||||
|
||||
/* Socket connection recieve helper */
|
||||
struct iscsi_tcp_recv {
|
||||
|
@ -104,48 +66,32 @@ struct iscsi_tcp_recv {
|
|||
struct iscsi_cmd_task *ctask; /* current cmd in progress */
|
||||
|
||||
/* copied and flipped values */
|
||||
int opcode;
|
||||
int flags;
|
||||
int cmd_status;
|
||||
int ahslen;
|
||||
int datalen;
|
||||
uint32_t itt;
|
||||
int datadgst;
|
||||
char zero_copy_hdr;
|
||||
};
|
||||
|
||||
struct iscsi_cls_conn;
|
||||
|
||||
struct iscsi_conn {
|
||||
struct iscsi_cls_conn *cls_conn; /* ptr to class connection */
|
||||
struct iscsi_tcp_conn {
|
||||
struct iscsi_conn *iscsi_conn;
|
||||
struct socket *sock;
|
||||
struct iscsi_hdr hdr; /* header placeholder */
|
||||
char hdrext[4*sizeof(__u16) +
|
||||
sizeof(__u32)];
|
||||
int data_copied;
|
||||
char *data; /* data placeholder */
|
||||
struct socket *sock; /* TCP socket */
|
||||
int data_size; /* actual recv_dlength */
|
||||
int stop_stage; /* conn_stop() flag: *
|
||||
* stop to recover, *
|
||||
* stop to terminate */
|
||||
/* iSCSI connection-wide sequencing */
|
||||
uint32_t exp_statsn;
|
||||
int hdr_size; /* PDU header size */
|
||||
unsigned long suspend_rx; /* suspend Rx */
|
||||
|
||||
struct crypto_tfm *rx_tfm; /* CRC32C (Rx) */
|
||||
struct crypto_tfm *data_rx_tfm; /* CRC32C (Rx) for data */
|
||||
|
||||
/* control data */
|
||||
int senselen; /* scsi sense length */
|
||||
int id; /* CID */
|
||||
struct iscsi_tcp_recv in; /* TCP receive context */
|
||||
struct iscsi_session *session; /* parent session */
|
||||
struct list_head item; /* maintains list of conns */
|
||||
int in_progress; /* connection state machine */
|
||||
int c_stage; /* connection state */
|
||||
struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */
|
||||
struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */
|
||||
struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
|
||||
|
||||
/* old values for socket callbacks */
|
||||
void (*old_data_ready)(struct sock *, int);
|
||||
|
@ -155,93 +101,14 @@ struct iscsi_conn {
|
|||
/* xmit */
|
||||
struct crypto_tfm *tx_tfm; /* CRC32C (Tx) */
|
||||
struct crypto_tfm *data_tx_tfm; /* CRC32C (Tx) for data */
|
||||
struct kfifo *writequeue; /* write cmds for Data-Outs */
|
||||
struct kfifo *immqueue; /* immediate xmit queue */
|
||||
struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
|
||||
struct kfifo *xmitqueue; /* data-path cmd queue */
|
||||
struct work_struct xmitwork; /* per-conn. xmit workqueue */
|
||||
struct mutex xmitmutex; /* serializes connection xmit,
|
||||
* access to kfifos: *
|
||||
* xmitqueue, writequeue, *
|
||||
* immqueue, mgmtqueue */
|
||||
unsigned long suspend_tx; /* suspend Tx */
|
||||
|
||||
/* abort */
|
||||
wait_queue_head_t ehwait; /* used in eh_abort() */
|
||||
struct iscsi_tm tmhdr;
|
||||
struct timer_list tmabort_timer; /* abort timer */
|
||||
int tmabort_state; /* see TMABORT_INITIAL, etc.*/
|
||||
|
||||
/* negotiated params */
|
||||
int max_recv_dlength;
|
||||
int max_xmit_dlength;
|
||||
int hdrdgst_en;
|
||||
int datadgst_en;
|
||||
|
||||
/* MIB-statistics */
|
||||
uint64_t txdata_octets;
|
||||
uint64_t rxdata_octets;
|
||||
uint32_t scsicmd_pdus_cnt;
|
||||
uint32_t dataout_pdus_cnt;
|
||||
uint32_t scsirsp_pdus_cnt;
|
||||
uint32_t datain_pdus_cnt;
|
||||
uint32_t r2t_pdus_cnt;
|
||||
uint32_t tmfcmd_pdus_cnt;
|
||||
int32_t tmfrsp_pdus_cnt;
|
||||
|
||||
/* custom statistics */
|
||||
/* MIB custom statistics */
|
||||
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 {
|
||||
/* iSCSI session-wide sequencing */
|
||||
uint32_t cmdsn;
|
||||
uint32_t exp_cmdsn;
|
||||
uint32_t max_cmdsn;
|
||||
|
||||
/* configuration */
|
||||
int initial_r2t_en;
|
||||
int max_r2t;
|
||||
int imm_data_en;
|
||||
int first_burst;
|
||||
int max_burst;
|
||||
int time2wait;
|
||||
int time2retain;
|
||||
int pdu_inorder_en;
|
||||
int dataseq_inorder_en;
|
||||
int erl;
|
||||
int ifmarker_en;
|
||||
int ofmarker_en;
|
||||
|
||||
/* control data */
|
||||
struct Scsi_Host *host;
|
||||
int id;
|
||||
struct iscsi_conn *leadconn; /* leading connection */
|
||||
spinlock_t lock; /* protects session state, *
|
||||
* sequence numbers, *
|
||||
* session resources: *
|
||||
* - cmdpool, *
|
||||
* - mgmtpool, *
|
||||
* - r2tpool */
|
||||
int state; /* session state */
|
||||
struct list_head item;
|
||||
void *auth_client;
|
||||
int conn_cnt;
|
||||
int age; /* counts session re-opens */
|
||||
|
||||
struct list_head connections; /* list of connections */
|
||||
int cmds_max; /* size of cmds array */
|
||||
struct iscsi_cmd_task **cmds; /* Original Cmds arr */
|
||||
struct iscsi_queue cmdpool; /* PDU's pool */
|
||||
int mgmtpool_max; /* size of mgmt array */
|
||||
struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */
|
||||
struct iscsi_queue mgmtpool; /* Mgmt PDU's pool */
|
||||
};
|
||||
|
||||
struct iscsi_buf {
|
||||
struct scatterlist sg;
|
||||
unsigned int sent;
|
||||
|
@ -251,22 +118,17 @@ struct iscsi_buf {
|
|||
struct iscsi_data_task {
|
||||
struct iscsi_data hdr; /* PDU */
|
||||
char hdrext[sizeof(__u32)]; /* Header-Digest */
|
||||
struct list_head item; /* data queue item */
|
||||
struct iscsi_buf digestbuf; /* digest buffer */
|
||||
uint32_t digest; /* data digest */
|
||||
};
|
||||
#define ISCSI_DTASK_DEFAULT_MAX ISCSI_SG_TABLESIZE * PAGE_SIZE / 512
|
||||
|
||||
struct iscsi_mgmt_task {
|
||||
struct iscsi_hdr hdr; /* mgmt. PDU */
|
||||
char hdrext[sizeof(__u32)]; /* Header-Digest */
|
||||
char *data; /* mgmt payload */
|
||||
struct iscsi_tcp_mgmt_task {
|
||||
struct iscsi_hdr hdr;
|
||||
char hdrext[sizeof(__u32)]; /* Header-Digest */
|
||||
int xmstate; /* mgmt xmit progress */
|
||||
int data_count; /* counts data to be sent */
|
||||
struct iscsi_buf headbuf; /* header buffer */
|
||||
struct iscsi_buf sendbuf; /* in progress buffer */
|
||||
int sent;
|
||||
uint32_t itt; /* this ITT */
|
||||
};
|
||||
|
||||
struct iscsi_r2t_info {
|
||||
|
@ -280,48 +142,36 @@ struct iscsi_r2t_info {
|
|||
int data_count; /* DATA-Out payload progress */
|
||||
struct scatterlist *sg; /* per-R2T SG list */
|
||||
int solicit_datasn;
|
||||
struct iscsi_data_task *dtask; /* which data task */
|
||||
struct iscsi_data_task dtask; /* which data task */
|
||||
};
|
||||
|
||||
struct iscsi_cmd_task {
|
||||
struct iscsi_cmd hdr; /* iSCSI PDU header */
|
||||
struct iscsi_tcp_cmd_task {
|
||||
struct iscsi_cmd hdr;
|
||||
char hdrext[4*sizeof(__u16)+ /* AHS */
|
||||
sizeof(__u32)]; /* HeaderDigest */
|
||||
char pad[ISCSI_PAD_LEN];
|
||||
int itt; /* this ITT */
|
||||
int datasn; /* DataSN */
|
||||
int pad_count; /* padded bytes */
|
||||
struct iscsi_buf headbuf; /* header buf (xmit) */
|
||||
struct iscsi_buf sendbuf; /* in progress buffer*/
|
||||
int xmstate; /* xmit xtate machine */
|
||||
int sent;
|
||||
struct scatterlist *sg; /* per-cmd SG list */
|
||||
struct scatterlist *bad_sg; /* assert statement */
|
||||
int sg_count; /* SG's to process */
|
||||
uint32_t unsol_datasn;
|
||||
uint32_t exp_r2tsn;
|
||||
int xmstate; /* xmit xtate machine */
|
||||
int imm_count; /* imm-data (bytes) */
|
||||
int unsol_count; /* unsolicited (bytes)*/
|
||||
int r2t_data_count; /* R2T Data-Out bytes */
|
||||
int data_count; /* remaining Data-Out */
|
||||
int pad_count; /* padded bytes */
|
||||
struct scsi_cmnd *sc; /* associated SCSI cmd*/
|
||||
int total_length;
|
||||
int data_offset;
|
||||
struct iscsi_conn *conn; /* used connection */
|
||||
struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */
|
||||
|
||||
struct iscsi_r2t_info *r2t; /* in progress R2T */
|
||||
struct iscsi_queue r2tpool;
|
||||
struct kfifo *r2tqueue;
|
||||
struct iscsi_r2t_info **r2ts;
|
||||
struct list_head dataqueue; /* Data-Out dataqueue */
|
||||
mempool_t *datapool;
|
||||
uint32_t datadigest; /* for recover digest */
|
||||
int digest_count;
|
||||
uint32_t immdigest; /* for imm data */
|
||||
struct iscsi_buf immbuf; /* for imm data digest */
|
||||
struct iscsi_data_task *dtask; /* data task in progress*/
|
||||
int digest_offset; /* for partial buff digest */
|
||||
struct iscsi_data_task *dtask; /* data task in progress*/
|
||||
struct iscsi_data_task unsol_dtask; /* unsol data task */
|
||||
int digest_offset; /* for partial buff digest */
|
||||
};
|
||||
|
||||
#endif /* ISCSI_H */
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_eh.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_request.h>
|
||||
#include <scsi/scsi_transport.h>
|
||||
#include <linux/libata.h>
|
||||
#include <linux/hdreg.h>
|
||||
|
@ -2310,7 +2310,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
|
|||
#endif
|
||||
}
|
||||
|
||||
qc->nbytes = cmd->bufflen;
|
||||
qc->nbytes = cmd->request_bufflen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2500,7 +2500,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
|
|||
* TODO: find out if we need to do more here to
|
||||
* cover scatter/gather case.
|
||||
*/
|
||||
qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
|
||||
qc->nsect = cmd->request_bufflen / ATA_SECT_SIZE;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
1702
drivers/scsi/libiscsi.c
Normal file
1702
drivers/scsi/libiscsi.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -524,7 +524,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
|
|||
* filter the internal and ioctl commands
|
||||
*/
|
||||
if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) {
|
||||
return cmd->buffer;
|
||||
return cmd->request_buffer;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4492,7 +4492,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
|
|||
scmd->device = sdev;
|
||||
|
||||
scmd->device->host = adapter->host;
|
||||
scmd->buffer = (void *)scb;
|
||||
scmd->request_buffer = (void *)scb;
|
||||
scmd->cmnd[0] = MEGA_INTERNAL_CMD;
|
||||
|
||||
scb->state |= SCB_ACTIVE;
|
||||
|
|
|
@ -741,7 +741,6 @@ static int
|
|||
megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
|
||||
{
|
||||
u32 frame_count;
|
||||
unsigned long flags;
|
||||
struct megasas_cmd *cmd;
|
||||
struct megasas_instance *instance;
|
||||
|
||||
|
@ -776,9 +775,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
|
|||
/*
|
||||
* Issue the command to the FW
|
||||
*/
|
||||
spin_lock_irqsave(&instance->instance_lock, flags);
|
||||
instance->fw_outstanding++;
|
||||
spin_unlock_irqrestore(&instance->instance_lock, flags);
|
||||
atomic_inc(&instance->fw_outstanding);
|
||||
|
||||
instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
|
||||
|
||||
|
@ -826,19 +823,20 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
|
|||
|
||||
for (i = 0; i < wait_time; i++) {
|
||||
|
||||
if (!instance->fw_outstanding)
|
||||
int outstanding = atomic_read(&instance->fw_outstanding);
|
||||
|
||||
if (!outstanding)
|
||||
break;
|
||||
|
||||
if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
|
||||
printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
|
||||
"commands to complete\n", i,
|
||||
instance->fw_outstanding);
|
||||
"commands to complete\n",i,outstanding);
|
||||
}
|
||||
|
||||
msleep(1000);
|
||||
}
|
||||
|
||||
if (instance->fw_outstanding) {
|
||||
if (atomic_read(&instance->fw_outstanding)) {
|
||||
instance->hw_crit_error = 1;
|
||||
return FAILED;
|
||||
}
|
||||
|
@ -1050,7 +1048,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
{
|
||||
int exception = 0;
|
||||
struct megasas_header *hdr = &cmd->frame->hdr;
|
||||
unsigned long flags;
|
||||
|
||||
if (cmd->scmd) {
|
||||
cmd->scmd->SCp.ptr = (char *)0;
|
||||
|
@ -1082,9 +1079,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
|
||||
if (exception) {
|
||||
|
||||
spin_lock_irqsave(&instance->instance_lock, flags);
|
||||
instance->fw_outstanding--;
|
||||
spin_unlock_irqrestore(&instance->instance_lock, flags);
|
||||
atomic_dec(&instance->fw_outstanding);
|
||||
|
||||
megasas_unmap_sgbuf(instance, cmd);
|
||||
cmd->scmd->scsi_done(cmd->scmd);
|
||||
|
@ -1132,9 +1127,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
|
|||
break;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&instance->instance_lock, flags);
|
||||
instance->fw_outstanding--;
|
||||
spin_unlock_irqrestore(&instance->instance_lock, flags);
|
||||
atomic_dec(&instance->fw_outstanding);
|
||||
|
||||
megasas_unmap_sgbuf(instance, cmd);
|
||||
cmd->scmd->scsi_done(cmd->scmd);
|
||||
|
@ -2171,11 +2164,12 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
*/
|
||||
INIT_LIST_HEAD(&instance->cmd_pool);
|
||||
|
||||
atomic_set(&instance->fw_outstanding,0);
|
||||
|
||||
init_waitqueue_head(&instance->int_cmd_wait_q);
|
||||
init_waitqueue_head(&instance->abort_cmd_wait_q);
|
||||
|
||||
spin_lock_init(&instance->cmd_pool_lock);
|
||||
spin_lock_init(&instance->instance_lock);
|
||||
|
||||
sema_init(&instance->aen_mutex, 1);
|
||||
sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
|
||||
|
|
|
@ -1077,9 +1077,8 @@ struct megasas_instance {
|
|||
struct pci_dev *pdev;
|
||||
u32 unique_id;
|
||||
|
||||
u32 fw_outstanding;
|
||||
atomic_t fw_outstanding;
|
||||
u32 hw_crit_error;
|
||||
spinlock_t instance_lock;
|
||||
|
||||
struct megasas_instance_template *instancet;
|
||||
};
|
||||
|
|
|
@ -529,7 +529,7 @@ static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
|
|||
{
|
||||
switch(cmd->__data_mapped) {
|
||||
case 2:
|
||||
dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
|
||||
dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
|
||||
cmd->sc_data_direction);
|
||||
break;
|
||||
case 1:
|
||||
|
@ -564,7 +564,7 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
|
|||
if (cmd->use_sg == 0)
|
||||
return 0;
|
||||
|
||||
use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
|
||||
use_sg = dma_map_sg(dev, cmd->request_buffer, cmd->use_sg,
|
||||
cmd->sc_data_direction);
|
||||
cmd->__data_mapped = 2;
|
||||
cmd->__data_mapping = use_sg;
|
||||
|
@ -7697,7 +7697,7 @@ static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd)
|
|||
if (!use_sg)
|
||||
segment = ncr_scatter_no_sglist(np, cp, cmd);
|
||||
else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
|
||||
struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
|
||||
struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
|
||||
struct scr_tblmove *data;
|
||||
|
||||
if (use_sg > MAX_SCATTER) {
|
||||
|
|
|
@ -1636,7 +1636,7 @@ static void nsp32_scsi_done(struct scsi_cmnd *SCpnt)
|
|||
|
||||
if (SCpnt->use_sg) {
|
||||
pci_unmap_sg(data->Pci,
|
||||
(struct scatterlist *)SCpnt->buffer,
|
||||
(struct scatterlist *)SCpnt->request_buffer,
|
||||
SCpnt->use_sg, SCpnt->sc_data_direction);
|
||||
} else {
|
||||
pci_unmap_single(data->Pci,
|
||||
|
|
|
@ -5492,7 +5492,7 @@ static int __init osst_setup (char *str)
|
|||
char *stp;
|
||||
|
||||
stp = get_options(str, ARRAY_SIZE(ints), ints);
|
||||
|
||||
|
||||
if (ints[0] > 0) {
|
||||
for (i = 0; i < ints[0] && i < ARRAY_SIZE(parms); i++)
|
||||
*parms[i].val = ints[i + 1];
|
||||
|
@ -5507,7 +5507,7 @@ static int __init osst_setup (char *str)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i >= sizeof(parms) / sizeof(struct osst_dev_parm))
|
||||
if (i >= ARRAY_SIZE(parms))
|
||||
printk(KERN_INFO "osst :I: Illegal parameter in '%s'\n",
|
||||
stp);
|
||||
stp = strchr(stp, ',');
|
||||
|
|
|
@ -156,7 +156,7 @@ static int default_irqs[] __initdata =
|
|||
static struct override {
|
||||
unsigned short io_port;
|
||||
int irq;
|
||||
} overrides
|
||||
} overrides
|
||||
#ifdef PAS16_OVERRIDE
|
||||
[] __initdata = PAS16_OVERRIDE;
|
||||
#else
|
||||
|
@ -164,19 +164,19 @@ static struct override {
|
|||
{0,IRQ_AUTO}};
|
||||
#endif
|
||||
|
||||
#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
|
||||
#define NO_OVERRIDES ARRAY_SIZE(overrides)
|
||||
|
||||
static struct base {
|
||||
unsigned short io_port;
|
||||
int noauto;
|
||||
} bases[] __initdata =
|
||||
} bases[] __initdata =
|
||||
{ {PAS16_DEFAULT_BASE_1, 0},
|
||||
{PAS16_DEFAULT_BASE_2, 0},
|
||||
{PAS16_DEFAULT_BASE_3, 0},
|
||||
{PAS16_DEFAULT_BASE_4, 0}
|
||||
};
|
||||
|
||||
#define NO_BASES (sizeof (bases) / sizeof (struct base))
|
||||
#define NO_BASES ARRAY_SIZE(bases)
|
||||
|
||||
static const unsigned short pas16_offset[ 8 ] =
|
||||
{
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
|
||||
#define RQ_SCSI_BUSY 0xffff
|
||||
#define RQ_SCSI_DONE 0xfffe
|
||||
|
||||
/* #define PLUTO_DEBUG */
|
||||
|
||||
#define pluto_printk printk ("PLUTO %s: ", fc->name); printk
|
||||
|
|
|
@ -4239,15 +4239,12 @@ qla1280_get_token(char *str)
|
|||
{
|
||||
char *sep;
|
||||
long ret = -1;
|
||||
int i, len;
|
||||
|
||||
len = sizeof(setup_token)/sizeof(struct setup_tokens);
|
||||
int i;
|
||||
|
||||
sep = strchr(str, ':');
|
||||
|
||||
if (sep) {
|
||||
for (i = 0; i < len; i++){
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(setup_token); i++) {
|
||||
if (!strncmp(setup_token[i].token, str, (sep - str))) {
|
||||
ret = setup_token[i].val;
|
||||
break;
|
||||
|
|
|
@ -24,48 +24,3 @@ config SCSI_QLA_FC
|
|||
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_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_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_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 22xx (ISP2200) host adapter family.
|
||||
|
||||
config SCSI_QLA2300
|
||||
tristate " Build QLogic ISP2300/ISP6312 firmware-module"
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 2300 (ISP2300, ISP2312 and
|
||||
ISP6312) host adapter family.
|
||||
|
||||
config SCSI_QLA2322
|
||||
tristate " Build QLogic ISP2322/ISP6322 firmware-module"
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 2322 (ISP2322 and ISP6322) host
|
||||
adapter family.
|
||||
|
||||
config SCSI_QLA24XX
|
||||
tristate " Build QLogic ISP24xx firmware-module"
|
||||
depends on SCSI_QLA_FC && SCSI_QLA2XXX_EMBEDDED_FIRMWARE
|
||||
---help---
|
||||
This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
|
||||
adapter family.
|
||||
|
|
|
@ -1,18 +1,4 @@
|
|||
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
|
||||
qla_dbg.o qla_sup.o qla_attr.o
|
||||
|
||||
obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
|
||||
|
||||
qla2100-y := ql2100.o ql2100_fw.o
|
||||
qla2200-y := ql2200.o ql2200_fw.o
|
||||
qla2300-y := ql2300.o ql2300_fw.o
|
||||
qla2322-y := ql2322.o ql2322_fw.o
|
||||
qla2400-y := ql2400.o ql2400_fw.o
|
||||
|
||||
obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
|
||||
obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
|
||||
obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
|
||||
obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
|
||||
obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (C) 2003 Christoph Hellwig.
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "qla_def.h"
|
||||
|
||||
static char qla_driver_name[] = "qla2100";
|
||||
|
||||
extern unsigned char fw2100tp_version[];
|
||||
extern unsigned char fw2100tp_version_str[];
|
||||
extern unsigned short fw2100tp_addr01;
|
||||
extern unsigned short fw2100tp_code01[];
|
||||
extern unsigned short fw2100tp_length01;
|
||||
|
||||
static struct qla_fw_info qla_fw_tbl[] = {
|
||||
{
|
||||
.addressing = FW_INFO_ADDR_NORMAL,
|
||||
.fwcode = &fw2100tp_code01[0],
|
||||
.fwlen = &fw2100tp_length01,
|
||||
.fwstart = &fw2100tp_addr01,
|
||||
},
|
||||
|
||||
{ FW_INFO_ADDR_NOMORE, },
|
||||
};
|
||||
|
||||
static struct qla_board_info qla_board_tbl = {
|
||||
.drv_name = qla_driver_name,
|
||||
|
||||
.isp_name = "ISP2100",
|
||||
.fw_info = qla_fw_tbl,
|
||||
};
|
||||
|
||||
static struct pci_device_id qla2100_pci_tbl[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||
.device = PCI_DEVICE_ID_QLOGIC_ISP2100,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.driver_data = (unsigned long)&qla_board_tbl,
|
||||
},
|
||||
|
||||
{0, 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, qla2100_pci_tbl);
|
||||
|
||||
static int __devinit
|
||||
qla2100_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
return qla2x00_probe_one(pdev,
|
||||
(struct qla_board_info *)id->driver_data);
|
||||
}
|
||||
|
||||
static void __devexit
|
||||
qla2100_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
qla2x00_remove_one(pdev);
|
||||
}
|
||||
|
||||
static struct pci_driver qla2100_pci_driver = {
|
||||
.name = "qla2100",
|
||||
.id_table = qla2100_pci_tbl,
|
||||
.probe = qla2100_probe_one,
|
||||
.remove = __devexit_p(qla2100_remove_one),
|
||||
};
|
||||
|
||||
static int __init
|
||||
qla2100_init(void)
|
||||
{
|
||||
return pci_module_init(&qla2100_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
qla2100_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&qla2100_pci_driver);
|
||||
}
|
||||
|
||||
module_init(qla2100_init);
|
||||
module_exit(qla2100_exit);
|
||||
|
||||
MODULE_AUTHOR("QLogic Corporation");
|
||||
MODULE_DESCRIPTION("QLogic ISP21xx FC-SCSI Host Bus Adapter driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(QLA2XXX_VERSION);
|
File diff suppressed because it is too large
Load diff
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (C) 2003 Christoph Hellwig.
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "qla_def.h"
|
||||
|
||||
static char qla_driver_name[] = "qla2200";
|
||||
|
||||
extern unsigned char fw2200tp_version[];
|
||||
extern unsigned char fw2200tp_version_str[];
|
||||
extern unsigned short fw2200tp_addr01;
|
||||
extern unsigned short fw2200tp_code01[];
|
||||
extern unsigned short fw2200tp_length01;
|
||||
|
||||
static struct qla_fw_info qla_fw_tbl[] = {
|
||||
{
|
||||
.addressing = FW_INFO_ADDR_NORMAL,
|
||||
.fwcode = &fw2200tp_code01[0],
|
||||
.fwlen = &fw2200tp_length01,
|
||||
.fwstart = &fw2200tp_addr01,
|
||||
},
|
||||
|
||||
{ FW_INFO_ADDR_NOMORE, },
|
||||
};
|
||||
|
||||
static struct qla_board_info qla_board_tbl = {
|
||||
.drv_name = qla_driver_name,
|
||||
|
||||
.isp_name = "ISP2200",
|
||||
.fw_info = qla_fw_tbl,
|
||||
};
|
||||
|
||||
static struct pci_device_id qla2200_pci_tbl[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||
.device = PCI_DEVICE_ID_QLOGIC_ISP2200,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.driver_data = (unsigned long)&qla_board_tbl,
|
||||
},
|
||||
|
||||
{0, 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, qla2200_pci_tbl);
|
||||
|
||||
static int __devinit
|
||||
qla2200_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
return qla2x00_probe_one(pdev,
|
||||
(struct qla_board_info *)id->driver_data);
|
||||
}
|
||||
|
||||
static void __devexit
|
||||
qla2200_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
qla2x00_remove_one(pdev);
|
||||
}
|
||||
|
||||
static struct pci_driver qla2200_pci_driver = {
|
||||
.name = "qla2200",
|
||||
.id_table = qla2200_pci_tbl,
|
||||
.probe = qla2200_probe_one,
|
||||
.remove = __devexit_p(qla2200_remove_one),
|
||||
};
|
||||
|
||||
static int __init
|
||||
qla2200_init(void)
|
||||
{
|
||||
return pci_module_init(&qla2200_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
qla2200_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&qla2200_pci_driver);
|
||||
}
|
||||
|
||||
module_init(qla2200_init);
|
||||
module_exit(qla2200_exit);
|
||||
|
||||
MODULE_AUTHOR("QLogic Corporation");
|
||||
MODULE_DESCRIPTION("QLogic ISP22xx FC-SCSI Host Bus Adapter driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(QLA2XXX_VERSION);
|
File diff suppressed because it is too large
Load diff
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* QLogic Fibre Channel HBA Driver
|
||||
* Copyright (C) 2003 Christoph Hellwig.
|
||||
* Copyright (c) 2003-2005 QLogic Corporation
|
||||
*
|
||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "qla_def.h"
|
||||
|
||||
static char qla_driver_name[] = "qla2300";
|
||||
|
||||
extern unsigned char fw2300ipx_version[];
|
||||
extern unsigned char fw2300ipx_version_str[];
|
||||
extern unsigned short fw2300ipx_addr01;
|
||||
extern unsigned short fw2300ipx_code01[];
|
||||
extern unsigned short fw2300ipx_length01;
|
||||
|
||||
static struct qla_fw_info qla_fw_tbl[] = {
|
||||
{
|
||||
.addressing = FW_INFO_ADDR_NORMAL,
|
||||
.fwcode = &fw2300ipx_code01[0],
|
||||
.fwlen = &fw2300ipx_length01,
|
||||
.fwstart = &fw2300ipx_addr01,
|
||||
},
|
||||
{ FW_INFO_ADDR_NOMORE, },
|
||||
};
|
||||
|
||||
static struct qla_board_info qla_board_tbl[] = {
|
||||
{
|
||||
.drv_name = qla_driver_name,
|
||||
.isp_name = "ISP2300",
|
||||
.fw_info = qla_fw_tbl,
|
||||
},
|
||||
{
|
||||
.drv_name = qla_driver_name,
|
||||
.isp_name = "ISP2312",
|
||||
.fw_info = qla_fw_tbl,
|
||||
},
|
||||
{
|
||||
.drv_name = qla_driver_name,
|
||||
.isp_name = "ISP6312",
|
||||
.fw_info = qla_fw_tbl,
|
||||
},
|
||||
};
|
||||
|
||||
static struct pci_device_id qla2300_pci_tbl[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||
.device = PCI_DEVICE_ID_QLOGIC_ISP2300,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.driver_data = (unsigned long)&qla_board_tbl[0],
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||
.device = PCI_DEVICE_ID_QLOGIC_ISP2312,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.driver_data = (unsigned long)&qla_board_tbl[1],
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_QLOGIC,
|
||||
.device = PCI_DEVICE_ID_QLOGIC_ISP6312,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.driver_data = (unsigned long)&qla_board_tbl[2],
|
||||
},
|
||||
{0, 0},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, qla2300_pci_tbl);
|
||||
|
||||
static int __devinit
|
||||
qla2300_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
return qla2x00_probe_one(pdev,
|
||||
(struct qla_board_info *)id->driver_data);
|
||||
}
|
||||
|
||||
static void __devexit
|
||||
qla2300_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
qla2x00_remove_one(pdev);
|
||||
}
|
||||
|
||||
static struct pci_driver qla2300_pci_driver = {
|
||||
.name = "qla2300",
|
||||
.id_table = qla2300_pci_tbl,
|
||||
.probe = qla2300_probe_one,
|
||||
.remove = __devexit_p(qla2300_remove_one),
|
||||
};
|
||||
|
||||
static int __init
|
||||
qla2300_init(void)
|
||||
{
|
||||
return pci_module_init(&qla2300_pci_driver);
|
||||
}
|
||||
|
||||
static void __exit
|
||||
qla2300_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&qla2300_pci_driver);
|
||||
}
|
||||
|
||||
module_init(qla2300_init);
|
||||
module_exit(qla2300_exit);
|
||||
|
||||
MODULE_AUTHOR("QLogic Corporation");
|
||||
MODULE_DESCRIPTION("QLogic ISP23xx FC-SCSI Host Bus Adapter driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(QLA2XXX_VERSION);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue