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:
Linus Torvalds 2006-06-21 11:18:25 -07:00
commit 28e4b22495
158 changed files with 7618 additions and 46283 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View 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

View file

@ -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

View file

@ -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;
}

View file

@ -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++) {

View file

@ -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);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

View file

@ -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...

View file

@ -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);
}

View file

@ -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;
/*

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)
{

View file

@ -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;

View file

@ -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");

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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");

View file

@ -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

View file

@ -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;

View file

@ -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) {

View file

@ -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

View file

@ -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/

View file

@ -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;

View file

@ -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 */
/* ============================================================ */

View file

@ -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";
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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) {

View file

@ -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));

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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)

View file

@ -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,
};

View file

@ -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)
{

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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)
{

View file

@ -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 =

View file

@ -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.
*

View file

@ -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);

View file

@ -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 );
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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

File diff suppressed because it is too large Load diff

465
drivers/scsi/hptiop.h Normal file
View 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

View file

@ -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 */

View file

@ -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,

View file

@ -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 */
};
/***************************************************************************

View file

@ -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];

View file

@ -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))

View file

@ -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"
/*

View file

@ -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

View file

@ -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 */

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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);

View file

@ -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;
};

View file

@ -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) {

View file

@ -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,

View file

@ -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, ',');

View file

@ -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 ] =
{

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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