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: (207 commits)
  [SCSI] gdth: fix CONFIG_ISA build failure
  [SCSI] esp_scsi: remove __dev{init,exit}
  [SCSI] gdth: !use_sg cleanup and use of scsi accessors
  [SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2
  [SCSI] gdth: Setup proper per-command private data
  [SCSI] gdth: Remove gdth_ctr_tab[]
  [SCSI] gdth: switch to modern scsi host registration
  [SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes
  [SCSI] gdth: clean up host private data
  [SCSI] gdth: Remove virt hosts
  [SCSI] gdth: Reorder scsi_host_template intitializers
  [SCSI] gdth: kill gdth_{read,write}[bwl] wrappers
  [SCSI] gdth: Remove 2.4.x support, in-kernel changelog
  [SCSI] gdth: split out pci probing
  [SCSI] gdth: split out eisa probing
  [SCSI] gdth: split out isa probing
  gdth: Make one abuse of scsi_cmnd less obvious
  [SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation
  [SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution
  [SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE
  ...
This commit is contained in:
Linus Torvalds 2007-10-15 08:19:33 -07:00
commit df3d80f5a5
168 changed files with 16306 additions and 20251 deletions

View file

@ -2,14 +2,20 @@
- this file - this file
53c700.txt 53c700.txt
- info on driver for 53c700 based adapters - info on driver for 53c700 based adapters
AM53C974.txt
- info on driver for AM53c974 based adapters
BusLogic.txt BusLogic.txt
- info on driver for adapters with BusLogic chips - info on driver for adapters with BusLogic chips
ChangeLog ChangeLog.1992-1997
- Changes to scsi files, if not listed elsewhere - Changes to scsi files, if not listed elsewhere
ChangeLog.arcmsr
- Changes to driver for ARECA's SATA RAID controller cards
ChangeLog.ips ChangeLog.ips
- IBM ServeRAID driver Changelog - IBM ServeRAID driver Changelog
ChangeLog.lpfc
- Changes to lpfc driver
ChangeLog.megaraid
- Changes to LSI megaraid controller.
ChangeLog.megaraid_sas
- Changes to serial attached scsi version of LSI megaraid controller.
ChangeLog.ncr53c8xx ChangeLog.ncr53c8xx
- Changes to ncr53c8xx driver - Changes to ncr53c8xx driver
ChangeLog.sym53c8xx ChangeLog.sym53c8xx
@ -20,26 +26,44 @@ FlashPoint.txt
- info on driver for BusLogic FlashPoint adapters - info on driver for BusLogic FlashPoint adapters
LICENSE.FlashPoint LICENSE.FlashPoint
- Licence of the Flashpoint driver - Licence of the Flashpoint driver
LICENSE.qla2xxx
- License for QLogic Linux Fibre Channel HBA Driver firmware.
Mylex.txt Mylex.txt
- info on driver for Mylex adapters - info on driver for Mylex adapters
NinjaSCSI.txt NinjaSCSI.txt
- info on WorkBiT NinjaSCSI-32/32Bi driver - info on WorkBiT NinjaSCSI-32/32Bi driver
aacraid.txt
- Driver supporting Adaptec RAID controllers
aha152x.txt aha152x.txt
- info on driver for Adaptec AHA152x based adapters - info on driver for Adaptec AHA152x based adapters
aic79xx.txt
- Adaptec Ultra320 SCSI host adapters
aic7xxx.txt aic7xxx.txt
- info on driver for Adaptec controllers - info on driver for Adaptec controllers
aic7xxx_old.txt aic7xxx_old.txt
- info on driver for Adaptec controllers, old generation - info on driver for Adaptec controllers, old generation
arcmsr_spec.txt
- ARECA FIRMWARE SPEC (for IOP331 adapter)
dc395x.txt
- README file for the dc395x SCSI driver
dpti.txt dpti.txt
- info on driver for DPT SmartRAID and Adaptec I2O RAID based adapters - info on driver for DPT SmartRAID and Adaptec I2O RAID based adapters
dtc3x80.txt dtc3x80.txt
- info on driver for DTC 2x80 based adapters - info on driver for DTC 2x80 based adapters
g_NCR5380.txt g_NCR5380.txt
- info on driver for NCR5380 and NCR53c400 based adapters - info on driver for NCR5380 and NCR53c400 based adapters
hptiop.txt
- HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
ibmmca.txt ibmmca.txt
- info on driver for IBM adapters with MCA bus - info on driver for IBM adapters with MCA bus
in2000.txt in2000.txt
- info on in2000 driver - info on in2000 driver
libsas.txt
- Serial Attached SCSI management layer.
lpfc.txt
- LPFC driver release notes
megaraid.txt
- Common Management Module, shared code handling ioctls for LSI drivers
ncr53c7xx.txt ncr53c7xx.txt
- info on driver for NCR53c7xx based adapters - info on driver for NCR53c7xx based adapters
ncr53c8xx.txt ncr53c8xx.txt
@ -50,6 +74,8 @@ ppa.txt
- info on driver for IOmega zip drive - info on driver for IOmega zip drive
qlogicfas.txt qlogicfas.txt
- info on driver for QLogic FASxxx based adapters - info on driver for QLogic FASxxx based adapters
scsi-changer.txt
- README for the SCSI media changer driver
scsi-generic.txt scsi-generic.txt
- info on the sg driver for generic (non-disk/CD/tape) SCSI devices. - info on the sg driver for generic (non-disk/CD/tape) SCSI devices.
scsi.txt scsi.txt
@ -58,6 +84,8 @@ scsi_mid_low_api.txt
- info on API between SCSI layer and low level drivers - info on API between SCSI layer and low level drivers
scsi_eh.txt scsi_eh.txt
- info on SCSI midlayer error handling infrastructure - info on SCSI midlayer error handling infrastructure
scsi_fc_transport.txt
- SCSI Fiber Channel Tansport
st.txt st.txt
- info on scsi tape driver - info on scsi tape driver
sym53c500_cs.txt sym53c500_cs.txt

View file

@ -53,4 +53,19 @@
** for linux standard list ** for linux standard list
** enable usage of pci message signal interrupt ** enable usage of pci message signal interrupt
** follow Randy.Danlup kindness suggestion cleanup this code ** follow Randy.Danlup kindness suggestion cleanup this code
************************************************************************** ** 1.20.00.14 05/02/2007 Erich Chen & Nick Cheng
** 1.implement PCI-Express error recovery function and AER capability
** 2.implement the selection of ARCMSR_MAX_XFER_SECTORS_B=4096
** if firmware version is newer than 1.42
** 3.modify arcmsr_iop_reset to improve the ability
** 4.modify the ISR, arcmsr_interrupt routine,to prevent the
** inconsistency with sg_mod driver if application directly calls
** the arcmsr driver w/o passing through scsi mid layer
** specially thanks to Yanmin Zhang's openhanded help about AER
** 1.20.00.15 08/30/2007 Erich Chen & Nick Cheng
** 1. support ARC1200/1201/1202 SATA RAID adapter, which is named
** ACB_ADAPTER_TYPE_B
** 2. modify the arcmsr_pci_slot_reset function
** 3. modify the arcmsr_pci_ers_disconnect_forepart function
** 4. modify the arcmsr_pci_ers_need_reset_forepart function
**************************************************************************

View file

@ -38,10 +38,8 @@ Supported Cards/Chipsets
9005:0286:9005:02ac Adaptec 1800 (Typhoon44) 9005:0286:9005:02ac Adaptec 1800 (Typhoon44)
9005:0285:9005:02b5 Adaptec 5445 (Voodoo44) 9005:0285:9005:02b5 Adaptec 5445 (Voodoo44)
9005:0285:15d9:02b5 SMC AOC-USAS-S4i 9005:0285:15d9:02b5 SMC AOC-USAS-S4i
9005:0285:15d9:02c9 SMC AOC-USAS-S4iR
9005:0285:9005:02b6 Adaptec 5805 (Voodoo80) 9005:0285:9005:02b6 Adaptec 5805 (Voodoo80)
9005:0285:15d9:02b6 SMC AOC-USAS-S8i 9005:0285:15d9:02b6 SMC AOC-USAS-S8i
9005:0285:15d9:02ca SMC AOC-USAS-S8iR
9005:0285:9005:02b7 Adaptec 5085 (Voodoo08) 9005:0285:9005:02b7 Adaptec 5085 (Voodoo08)
9005:0285:9005:02bb Adaptec 3405 (Marauder40LP) 9005:0285:9005:02bb Adaptec 3405 (Marauder40LP)
9005:0285:9005:02bc Adaptec 3805 (Marauder80LP) 9005:0285:9005:02bc Adaptec 3805 (Marauder80LP)
@ -50,9 +48,14 @@ Supported Cards/Chipsets
9005:0285:9005:02be Adaptec 31605 (Marauder160) 9005:0285:9005:02be Adaptec 31605 (Marauder160)
9005:0285:9005:02c3 Adaptec 51205 (Voodoo120) 9005:0285:9005:02c3 Adaptec 51205 (Voodoo120)
9005:0285:9005:02c4 Adaptec 51605 (Voodoo160) 9005:0285:9005:02c4 Adaptec 51605 (Voodoo160)
9005:0285:15d9:02c9 SMC AOC-USAS-S4iR
9005:0285:15d9:02ca SMC AOC-USAS-S8iR
9005:0285:9005:02ce Adaptec 51245 (Voodoo124) 9005:0285:9005:02ce Adaptec 51245 (Voodoo124)
9005:0285:9005:02cf Adaptec 51645 (Voodoo164) 9005:0285:9005:02cf Adaptec 51645 (Voodoo164)
9005:0285:9005:02d0 Adaptec 52445 (Voodoo244) 9005:0285:9005:02d0 Adaptec 52445 (Voodoo244)
9005:0285:9005:02d1 Adaptec 5405 (Voodoo40)
9005:0285:15d9:02d2 SMC AOC-USAS-S8i-LP
9005:0285:15d9:02d3 SMC AOC-USAS-S8iR-LP
1011:0046:9005:0364 Adaptec 5400S (Mustang) 1011:0046:9005:0364 Adaptec 5400S (Mustang)
9005:0287:9005:0800 Adaptec Themisto (Jupiter) 9005:0287:9005:0800 Adaptec Themisto (Jupiter)
9005:0200:9005:0200 Adaptec Themisto (Jupiter) 9005:0200:9005:0200 Adaptec Themisto (Jupiter)
@ -103,6 +106,7 @@ Supported Cards/Chipsets
9005:0285:108e:7aac SUN STK RAID REM (Voodoo44 Coyote) 9005:0285:108e:7aac SUN STK RAID REM (Voodoo44 Coyote)
9005:0285:108e:0286 SUN STK RAID INT (Cougar) 9005:0285:108e:0286 SUN STK RAID INT (Cougar)
9005:0285:108e:0287 SUN STK RAID EXT (Prometheus) 9005:0285:108e:0287 SUN STK RAID EXT (Prometheus)
9005:0285:108e:7aae SUN STK RAID EM (Narvi)
People People
------------------------- -------------------------

View file

@ -0,0 +1,243 @@
AdvanSys (Advanced System Products, Inc.) manufactures the following
RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
(8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
transfer) SCSI Host Adapters for the PCI bus.
The CDB counts below indicate the number of SCSI CDB (Command
Descriptor Block) requests that can be stored in the RISC chip
cache and board LRAM. A CDB is a single SCSI command. The driver
detect routine will display the number of CDBs available for each
adapter detected. The number of CDBs used by the driver can be
lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
Laptop Products:
ABP-480 - Bus-Master CardBus (16 CDB)
Connectivity Products:
ABP510/5150 - Bus-Master ISA (240 CDB)
ABP5140 - Bus-Master ISA PnP (16 CDB)
ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
ABP902/3902 - Bus-Master PCI (16 CDB)
ABP3905 - Bus-Master PCI (16 CDB)
ABP915 - Bus-Master PCI (16 CDB)
ABP920 - Bus-Master PCI (16 CDB)
ABP3922 - Bus-Master PCI (16 CDB)
ABP3925 - Bus-Master PCI (16 CDB)
ABP930 - Bus-Master PCI (16 CDB)
ABP930U - Bus-Master PCI Ultra (16 CDB)
ABP930UA - Bus-Master PCI Ultra (16 CDB)
ABP960 - Bus-Master PCI MAC/PC (16 CDB)
ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
Single Channel Products:
ABP542 - Bus-Master ISA with floppy (240 CDB)
ABP742 - Bus-Master EISA (240 CDB)
ABP842 - Bus-Master VL (240 CDB)
ABP940 - Bus-Master PCI (240 CDB)
ABP940U - Bus-Master PCI Ultra (240 CDB)
ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
ABP970 - Bus-Master PCI MAC/PC (240 CDB)
ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
Multi-Channel Products:
ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
Driver Compile Time Options and Debugging
The following constants can be defined in the source file.
1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
Enabling this option adds assertion logic statements to the
driver. If an assertion fails a message will be displayed to
the console, but the system will continue to operate. Any
assertions encountered should be reported to the person
responsible for the driver. Assertion statements may proactively
detect problems with the driver and facilitate fixing these
problems. Enabling assertions will add a small overhead to the
execution of the driver.
2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
Enabling this option adds tracing functions to the driver and the
ability to set a driver tracing level at boot time. This option is
very useful for debugging the driver, but it will add to the size
of the driver execution image and add overhead to the execution of
the driver.
The amount of debugging output can be controlled with the global
variable 'asc_dbglvl'. The higher the number the more output. By
default the debug level is 0.
If the driver is loaded at boot time and the LILO Driver Option
is included in the system, the debug level can be changed by
specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
first three hex digits of the pseudo I/O Port must be set to
'deb' and the fourth hex digit specifies the debug level: 0 - F.
The following command line will look for an adapter at 0x330
and set the debug level to 2.
linux advansys=0x330,0,0,0,0xdeb2
If the driver is built as a loadable module this variable can be
defined when the driver is loaded. The following insmod command
will set the debug level to one.
insmod advansys.o asc_dbglvl=1
Debugging Message Levels:
0: Errors Only
1: High-Level Tracing
2-N: Verbose Tracing
To enable debug output to console, please make sure that:
a. System and kernel logging is enabled (syslogd, klogd running).
b. Kernel messages are routed to console output. Check
/etc/syslog.conf for an entry similar to this:
kern.* /dev/console
c. klogd is started with the appropriate -c parameter
(e.g. klogd -c 8)
This will cause printk() messages to be be displayed on the
current console. Refer to the klogd(8) and syslogd(8) man pages
for details.
Alternatively you can enable printk() to console with this
program. However, this is not the 'official' way to do this.
Debug output is logged in /var/log/messages.
main()
{
syscall(103, 7, 0, 0);
}
Increasing LOG_BUF_LEN in kernel/printk.c to something like
40960 allows more debug messages to be buffered in the kernel
and written to the console or log file.
3. ADVANSYS_STATS - Enable statistics (Def: Enabled)
Enabling this option adds statistics collection and display
through /proc to the driver. The information is useful for
monitoring driver and device performance. It will add to the
size of the driver execution image and add minor overhead to
the execution of the driver.
Statistics are maintained on a per adapter basis. Driver entry
point call counts and transfer size counts are maintained.
Statistics are only available for kernels greater than or equal
to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
AdvanSys SCSI adapter files have the following path name format:
/proc/scsi/advansys/{0,1,2,3,...}
This information can be displayed with cat. For example:
cat /proc/scsi/advansys/0
When ADVANSYS_STATS is not defined the AdvanSys /proc files only
contain adapter and device configuration information.
Driver LILO Option
If init/main.c is modified as described in the 'Directions for Adding
the AdvanSys Driver to Linux' section (B.4.) above, the driver will
recognize the 'advansys' LILO command line and /etc/lilo.conf option.
This option can be used to either disable I/O port scanning or to limit
scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
PCI boards will still be searched for and detected. This option only
affects searching for ISA and VL boards.
Examples:
1. Eliminate I/O port scanning:
boot: linux advansys=
or
boot: linux advansys=0x0
2. Limit I/O port scanning to one I/O port:
boot: linux advansys=0x110
3. Limit I/O port scanning to four I/O ports:
boot: linux advansys=0x110,0x210,0x230,0x330
For a loadable module the same effect can be achieved by setting
the 'asc_iopflag' variable and 'asc_ioport' array when loading
the driver, e.g.
insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
I/O Port may be added to specify the driver debug level. Refer to
the 'Driver Compile Time Options and Debugging' section above for
more information.
Credits (Chronological Order)
Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
and maintained it up to 3.3F. He continues to answer questions
and help maintain the driver.
Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
basis for the Linux v1.3.X changes which were included in the
1.2 release.
Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
in advansys_biosparam() which was fixed in the 1.3 release.
Erik Ratcliffe <erik@caldera.com> has done testing of the
AdvanSys driver in the Caldera releases.
Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
AscWaitTixISRDone() which he found necessary to make the
driver work with a SCSI-1 disk.
Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
support in the 3.1A driver.
Doug Gilbert <dgilbert@interlog.com> has made changes and
suggestions to improve the driver and done a lot of testing.
Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
in 3.2K.
Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
patch and helped with PowerPC wide and narrow board support.
Philip Blundell <philb@gnu.org> provided an
advansys_interrupts_enabled patch.
Dave Jones <dave@denial.force9.co.uk> reported the compiler
warnings generated when CONFIG_PROC_FS was not defined in
the 3.2M driver.
Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
problems) for wide cards.
Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
card error handling.
Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
board support and fixed a bug in AscGetEEPConfig().
Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
save_flags/restore_flags changes.
Andy Kellner <AKellner@connectcom.net> continued the Advansys SCSI
driver development for ConnectCom (Version > 3.3F).
Ken Witherow for extensive testing during the development of version 3.4.

View file

@ -297,6 +297,12 @@ P: Colin Leroy
M: colin@colino.net M: colin@colino.net
S: Maintained S: Maintained
ADVANSYS SCSI DRIVER
P: Matthew Wilcox
M: matthew@wil.cx
L: linux-scsi@vger.kernel.org
S: Maintained
AEDSP16 DRIVER AEDSP16 DRIVER
P: Riccardo Facchetti P: Riccardo Facchetti
M: fizban@tin.it M: fizban@tin.it
@ -1889,6 +1895,11 @@ M: Gadi Oxman <gadio@netvision.net.il>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Maintained S: Maintained
IDE-SCSI DRIVER
L: linux-ide@vger.kernel.org
L: linux-scsi@vger.kernel.org
S: Orphan
IEEE 1394 SUBSYSTEM IEEE 1394 SUBSYSTEM
P: Ben Collins P: Ben Collins
M: ben.collins@ubuntu.com M: ben.collins@ubuntu.com
@ -2404,7 +2415,7 @@ LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
P: Eric Moore P: Eric Moore
M: Eric.Moore@lsi.com M: Eric.Moore@lsi.com
M: support@lsi.com M: support@lsi.com
L: mpt_linux_developer@lsi.com L: DL-MPTFusionLinux@lsi.com
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
W: http://www.lsilogic.com/support W: http://www.lsilogic.com/support
S: Supported S: Supported

View file

@ -372,8 +372,13 @@ simscsi_init(void)
return -ENOMEM; return -ENOMEM;
error = scsi_add_host(host, NULL); error = scsi_add_host(host, NULL);
if (!error) if (error)
scsi_scan_host(host); goto free_host;
scsi_scan_host(host);
return 0;
free_host:
scsi_host_put(host);
return error; return error;
} }

View file

@ -427,15 +427,10 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd
memcpy(SCpnt->sense_buffer, ((char *)(rsp+1)), sense_len); memcpy(SCpnt->sense_buffer, ((char *)(rsp+1)), sense_len);
} }
if (fcmd->data) { if (fcmd->data)
if (SCpnt->use_sg) dma_unmap_sg(fc->dev, scsi_sglist(SCpnt),
dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer, scsi_sg_count(SCpnt),
SCpnt->use_sg, SCpnt->sc_data_direction);
SCpnt->sc_data_direction);
else
dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen,
SCpnt->sc_data_direction);
}
break; break;
default: default:
host_status=DID_ERROR; /* FIXME */ host_status=DID_ERROR; /* FIXME */
@ -793,10 +788,14 @@ static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt,
fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
} else } else
fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED; fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
if (!SCpnt->request_bufflen && !SCpnt->use_sg) {
if (!scsi_bufflen(SCpnt)) {
cmd->fcp_cntl = fcp_cntl; cmd->fcp_cntl = fcp_cntl;
fcmd->data = (dma_addr_t)NULL; fcmd->data = (dma_addr_t)NULL;
} else { } else {
struct scatterlist *sg;
int nents;
switch (SCpnt->cmnd[0]) { switch (SCpnt->cmnd[0]) {
case WRITE_6: case WRITE_6:
case WRITE_10: case WRITE_10:
@ -805,22 +804,12 @@ static int fcp_scsi_queue_it(fc_channel *fc, struct scsi_cmnd *SCpnt,
default: default:
cmd->fcp_cntl = (FCP_CNTL_READ | fcp_cntl); break; cmd->fcp_cntl = (FCP_CNTL_READ | fcp_cntl); break;
} }
if (!SCpnt->use_sg) {
cmd->fcp_data_len = SCpnt->request_bufflen;
fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer,
SCpnt->request_bufflen,
SCpnt->sc_data_direction);
} else {
struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
int nents;
FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) sg = scsi_sglist(SCpnt);
nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg, nents = dma_map_sg(fc->dev, sg, scsi_sg_count(SCpnt),
SCpnt->sc_data_direction); SCpnt->sc_data_direction);
if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yet\n", fc->name, nents, SCpnt->use_sg); fcmd->data = sg_dma_address(sg);
fcmd->data = sg_dma_address(sg); cmd->fcp_data_len = sg_dma_len(sg);
cmd->fcp_data_len = sg_dma_len(sg);
}
} }
memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len); memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len);
memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len); memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len);

View file

@ -1,6 +1,7 @@
config INFINIBAND_SRP config INFINIBAND_SRP
tristate "InfiniBand SCSI RDMA Protocol" tristate "InfiniBand SCSI RDMA Protocol"
depends on SCSI depends on SCSI
select SCSI_SRP_ATTRS
---help--- ---help---
Support for the SCSI RDMA Protocol over InfiniBand. This Support for the SCSI RDMA Protocol over InfiniBand. This
allows you to access storage devices that speak SRP over allows you to access storage devices that speak SRP over

View file

@ -47,6 +47,7 @@
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_dbg.h> #include <scsi/scsi_dbg.h>
#include <scsi/srp.h> #include <scsi/srp.h>
#include <scsi/scsi_transport_srp.h>
#include <rdma/ib_cache.h> #include <rdma/ib_cache.h>
@ -86,6 +87,8 @@ static void srp_remove_one(struct ib_device *device);
static void srp_completion(struct ib_cq *cq, void *target_ptr); static void srp_completion(struct ib_cq *cq, void *target_ptr);
static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
static struct scsi_transport_template *ib_srp_transport_template;
static struct ib_client srp_client = { static struct ib_client srp_client = {
.name = "srp", .name = "srp",
.add = srp_add_one, .add = srp_add_one,
@ -420,6 +423,7 @@ static void srp_remove_work(struct work_struct *work)
list_del(&target->list); list_del(&target->list);
spin_unlock(&target->srp_host->target_lock); spin_unlock(&target->srp_host->target_lock);
srp_remove_host(target->scsi_host);
scsi_remove_host(target->scsi_host); scsi_remove_host(target->scsi_host);
ib_destroy_cm_id(target->cm_id); ib_destroy_cm_id(target->cm_id);
srp_free_target_ib(target); srp_free_target_ib(target);
@ -1544,12 +1548,24 @@ static struct scsi_host_template srp_template = {
static int srp_add_target(struct srp_host *host, struct srp_target_port *target) static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
{ {
struct srp_rport_identifiers ids;
struct srp_rport *rport;
sprintf(target->target_name, "SRP.T10:%016llX", sprintf(target->target_name, "SRP.T10:%016llX",
(unsigned long long) be64_to_cpu(target->id_ext)); (unsigned long long) be64_to_cpu(target->id_ext));
if (scsi_add_host(target->scsi_host, host->dev->dev->dma_device)) if (scsi_add_host(target->scsi_host, host->dev->dev->dma_device))
return -ENODEV; return -ENODEV;
memcpy(ids.port_id, &target->id_ext, 8);
memcpy(ids.port_id + 8, &target->ioc_guid, 8);
ids.roles = SRP_RPORT_ROLE_TARGET;
rport = srp_rport_add(target->scsi_host, &ids);
if (IS_ERR(rport)) {
scsi_remove_host(target->scsi_host);
return PTR_ERR(rport);
}
spin_lock(&host->target_lock); spin_lock(&host->target_lock);
list_add_tail(&target->list, &host->target_list); list_add_tail(&target->list, &host->target_list);
spin_unlock(&host->target_lock); spin_unlock(&host->target_lock);
@ -1775,6 +1791,7 @@ static ssize_t srp_create_target(struct class_device *class_dev,
if (!target_host) if (!target_host)
return -ENOMEM; return -ENOMEM;
target_host->transportt = ib_srp_transport_template;
target_host->max_lun = SRP_MAX_LUN; target_host->max_lun = SRP_MAX_LUN;
target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb; target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
@ -2054,10 +2071,18 @@ static void srp_remove_one(struct ib_device *device)
kfree(srp_dev); kfree(srp_dev);
} }
static struct srp_function_template ib_srp_transport_functions = {
};
static int __init srp_init_module(void) static int __init srp_init_module(void)
{ {
int ret; int ret;
ib_srp_transport_template =
srp_attach_transport(&ib_srp_transport_functions);
if (!ib_srp_transport_template)
return -ENOMEM;
srp_template.sg_tablesize = srp_sg_tablesize; srp_template.sg_tablesize = srp_sg_tablesize;
srp_max_iu_len = (sizeof (struct srp_cmd) + srp_max_iu_len = (sizeof (struct srp_cmd) +
sizeof (struct srp_indirect_buf) + sizeof (struct srp_indirect_buf) +
@ -2066,6 +2091,7 @@ static int __init srp_init_module(void)
ret = class_register(&srp_class); ret = class_register(&srp_class);
if (ret) { if (ret) {
printk(KERN_ERR PFX "couldn't register class infiniband_srp\n"); printk(KERN_ERR PFX "couldn't register class infiniband_srp\n");
srp_release_transport(ib_srp_transport_template);
return ret; return ret;
} }
@ -2074,6 +2100,7 @@ static int __init srp_init_module(void)
ret = ib_register_client(&srp_client); ret = ib_register_client(&srp_client);
if (ret) { if (ret) {
printk(KERN_ERR PFX "couldn't register IB client\n"); printk(KERN_ERR PFX "couldn't register IB client\n");
srp_release_transport(ib_srp_transport_template);
ib_sa_unregister_client(&srp_sa_client); ib_sa_unregister_client(&srp_sa_client);
class_unregister(&srp_class); class_unregister(&srp_class);
return ret; return ret;
@ -2087,6 +2114,7 @@ static void __exit srp_cleanup_module(void)
ib_unregister_client(&srp_client); ib_unregister_client(&srp_client);
ib_sa_unregister_client(&srp_sa_client); ib_sa_unregister_client(&srp_sa_client);
class_unregister(&srp_class); class_unregister(&srp_class);
srp_release_transport(ib_srp_transport_template);
} }
module_init(srp_init_module); module_init(srp_init_module);

View file

@ -1,15 +1,19 @@
menu "Fusion MPT device support" menuconfig FUSION
bool "Fusion MPT device support"
depends on PCI depends on PCI
---help---
Say Y here to get to see options for Fusion Message
Passing Technology (MPT) drivers.
This option alone does not add any kernel code.
config FUSION If you say N, all options in this submenu will be skipped and disabled.
bool
default n if FUSION
config FUSION_SPI config FUSION_SPI
tristate "Fusion MPT ScsiHost drivers for SPI" tristate "Fusion MPT ScsiHost drivers for SPI"
depends on PCI && SCSI depends on PCI && SCSI
select FUSION
select SCSI_SPI_ATTRS select SCSI_SPI_ATTRS
---help--- ---help---
SCSI HOST support for a parallel SCSI host adapters. SCSI HOST support for a parallel SCSI host adapters.
@ -20,11 +24,11 @@ config FUSION_SPI
LSI53C1020A LSI53C1020A
LSI53C1030 LSI53C1030
LSI53C1035 LSI53C1035
ATTO UL4D
config FUSION_FC config FUSION_FC
tristate "Fusion MPT ScsiHost drivers for FC" tristate "Fusion MPT ScsiHost drivers for FC"
depends on PCI && SCSI depends on PCI && SCSI
select FUSION
select SCSI_FC_ATTRS select SCSI_FC_ATTRS
---help--- ---help---
SCSI HOST support for a Fiber Channel host adapters. SCSI HOST support for a Fiber Channel host adapters.
@ -37,12 +41,13 @@ config FUSION_FC
LSIFC929 LSIFC929
LSIFC929X LSIFC929X
LSIFC929XL LSIFC929XL
LSIFC949X
LSIFC949E
Brocade FC 410/420 Brocade FC 410/420
config FUSION_SAS config FUSION_SAS
tristate "Fusion MPT ScsiHost drivers for SAS" tristate "Fusion MPT ScsiHost drivers for SAS"
depends on PCI && SCSI depends on PCI && SCSI
select FUSION
select SCSI_SAS_ATTRS select SCSI_SAS_ATTRS
---help--- ---help---
SCSI HOST support for a SAS host adapters. SCSI HOST support for a SAS host adapters.
@ -53,10 +58,10 @@ config FUSION_SAS
LSISAS1068 LSISAS1068
LSISAS1064E LSISAS1064E
LSISAS1068E LSISAS1068E
LSISAS1078
config FUSION_MAX_SGE config FUSION_MAX_SGE
int "Maximum number of scatter gather entries (16 - 128)" int "Maximum number of scatter gather entries (16 - 128)"
depends on FUSION
default "128" default "128"
range 16 128 range 16 128
help help
@ -104,7 +109,6 @@ config FUSION_LAN
config FUSION_LOGGING config FUSION_LOGGING
bool "Fusion MPT logging facility" bool "Fusion MPT logging facility"
depends on FUSION
---help--- ---help---
This turns on a logging facility that can be used to debug a number This turns on a logging facility that can be used to debug a number
of Fusion MPT related problems. of Fusion MPT related problems.
@ -113,7 +117,7 @@ config FUSION_LOGGING
echo [level] > /sys/class/scsi_host/host#/debug_level echo [level] > /sys/class/scsi_host/host#/debug_level
There are various debug levels that an be found in the source: There are various debug levels that can be found in the source:
file:drivers/message/fusion/mptdebug.h file:drivers/message/fusion/mptdebug.h
endmenu endif # FUSION

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 LSI Logic Corporation. * Copyright (c) 2000-2007 LSI Corporation.
* *
* *
* Name: mpi.h * Name: mpi.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 LSI Logic Corporation. * Copyright (c) 2000-2007 LSI Corporation.
* *
* *
* Name: mpi_cnfg.h * Name: mpi_cnfg.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2004 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Corporation.
* *
* *
* Name: mpi_fc.h * Name: mpi_fc.h

View file

@ -3,7 +3,7 @@
MPI Header File Change History MPI Header File Change History
============================== ==============================
Copyright (c) 2000-2007 LSI Logic Corporation. Copyright (c) 2000-2007 LSI Corporation.
--------------------------------------- ---------------------------------------
Header Set Release Version: 01.05.16 Header Set Release Version: 01.05.16

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 LSI Logic Corporation. * Copyright (c) 2000-2007 LSI Corporation.
* *
* *
* Name: mpi_init.h * Name: mpi_init.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2007 LSI Logic Corporation. * Copyright (c) 2000-2007 LSI Corporation.
* *
* *
* Name: mpi_ioc.h * Name: mpi_ioc.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2004 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Corporation.
* *
* *
* Name: mpi_lan.h * Name: mpi_lan.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2001 LSI Logic Corporation. All rights reserved. * Copyright (c) 2000-2001 LSI Corporation. All rights reserved.
* *
* NAME: fc_log.h * NAME: fc_log.h
* SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips * SUMMARY: MPI IocLogInfo definitions for the SYMFC9xx chips

View file

@ -1,6 +1,6 @@
/*************************************************************************** /***************************************************************************
* * * *
* Copyright 2003 LSI Logic Corporation. All rights reserved. * * Copyright 2003 LSI Corporation. All rights reserved. *
* * * *
* Description * * Description *
* ------------ * * ------------ *

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2007 LSI Logic Corporation. * Copyright (c) 2001-2007 LSI Corporation.
* *
* *
* Name: mpi_raid.h * Name: mpi_raid.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2006 LSI Logic Corporation. * Copyright (c) 2004-2006 LSI Corporation.
* *
* *
* Name: mpi_sas.h * Name: mpi_sas.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2004 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Corporation.
* *
* *
* Name: mpi_targ.h * Name: mpi_targ.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2005 LSI Logic Corporation. * Copyright (c) 2001-2005 LSI Corporation.
* *
* *
* Name: mpi_tool.h * Name: mpi_tool.h

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2004 LSI Logic Corporation. * Copyright (c) 2000-2004 LSI Corporation.
* *
* *
* Name: mpi_type.h * Name: mpi_type.h

File diff suppressed because it is too large Load diff

View file

@ -3,9 +3,9 @@
* High performance SCSI + LAN / Fibre Channel device drivers. * High performance SCSI + LAN / Fibre Channel device drivers.
* For use with PCI chip/adapter(s): * For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel * LSIFC9xx/LSI409xx Fibre Channel
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -68,15 +68,15 @@
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#ifndef MODULEAUTHOR #ifndef MODULEAUTHOR
#define MODULEAUTHOR "LSI Logic Corporation" #define MODULEAUTHOR "LSI Corporation"
#endif #endif
#ifndef COPYRIGHT #ifndef COPYRIGHT
#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.04.05" #define MPT_LINUX_VERSION_COMMON "3.04.06"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.05" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.06"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
@ -186,12 +186,42 @@
* MPT drivers. NOTE: Users of these macro defs must * MPT drivers. NOTE: Users of these macro defs must
* themselves define their own MYNAM. * themselves define their own MYNAM.
*/ */
#define MYIOC_s_FMT MYNAM ": %s: "
#define MYIOC_s_DEBUG_FMT KERN_DEBUG MYNAM ": %s: " #define MYIOC_s_DEBUG_FMT KERN_DEBUG MYNAM ": %s: "
#define MYIOC_s_INFO_FMT KERN_INFO MYNAM ": %s: " #define MYIOC_s_INFO_FMT KERN_INFO MYNAM ": %s: "
#define MYIOC_s_NOTE_FMT KERN_NOTICE MYNAM ": %s: " #define MYIOC_s_NOTE_FMT KERN_NOTICE MYNAM ": %s: "
#define MYIOC_s_WARN_FMT KERN_WARNING MYNAM ": %s: WARNING - " #define MYIOC_s_WARN_FMT KERN_WARNING MYNAM ": %s: WARNING - "
#define MYIOC_s_ERR_FMT KERN_ERR MYNAM ": %s: ERROR - " #define MYIOC_s_ERR_FMT KERN_ERR MYNAM ": %s: ERROR - "
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* ATTO UL4D associated structures and defines
*/
#define ATTOFLAG_DISC 0x0001
#define ATTOFLAG_TAGGED 0x0002
#define ATTOFLAG_WIDE_ENB 0x0008
#define ATTOFLAG_ID_ENB 0x0010
#define ATTOFLAG_LUN_ENB 0x0060
typedef struct _ATTO_DEVICE_INFO
{
u8 Offset; /* 00h */
u8 Period; /* 01h */
u16 ATTOFlags; /* 02h */
} ATTO_DEVICE_INFO, MPI_POINTER PTR_ATTO_DEVICE_INFO,
ATTODeviceInfo_t, MPI_POINTER pATTODeviceInfo_t;
typedef struct _ATTO_CONFIG_PAGE_SCSI_PORT_2
{
CONFIG_PAGE_HEADER Header; /* 00h */
u16 PortFlags; /* 04h */
u16 Unused1; /* 06h */
u32 Unused2; /* 08h */
ATTO_DEVICE_INFO DeviceSettings[16]; /* 0Ch */
} fATTO_CONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_ATTO_CONFIG_PAGE_SCSI_PORT_2,
ATTO_SCSIPortPage2_t, MPI_POINTER pATTO_SCSIPortPage2_t;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* MPT protocol driver defs... * MPT protocol driver defs...
@ -307,7 +337,8 @@ typedef struct _SYSIF_REGS
u32 Reserved2[2]; /* 38-3F reserved for future use */ u32 Reserved2[2]; /* 38-3F reserved for future use */
u32 RequestFifo; /* 40 Request Post/Free FIFO */ u32 RequestFifo; /* 40 Request Post/Free FIFO */
u32 ReplyFifo; /* 44 Reply Post/Free FIFO */ u32 ReplyFifo; /* 44 Reply Post/Free FIFO */
u32 Reserved3[2]; /* 48-4F reserved for future use */ u32 RequestHiPriFifo; /* 48 Hi Priority Request FIFO */
u32 Reserved3; /* 4C-4F reserved for future use */
u32 HostIndex; /* 50 Host Index register */ u32 HostIndex; /* 50 Host Index register */
u32 Reserved4[15]; /* 54-8F */ u32 Reserved4[15]; /* 54-8F */
u32 Fubar; /* 90 For Fubar usage */ u32 Fubar; /* 90 For Fubar usage */
@ -649,9 +680,9 @@ typedef struct _MPT_ADAPTER
u8 reload_fw; /* Force a FW Reload on next reset */ u8 reload_fw; /* Force a FW Reload on next reset */
u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4]; u8 pad1[4];
int DoneCtx; u8 DoneCtx;
int TaskCtx; u8 TaskCtx;
int InternalCtx; u8 InternalCtx;
spinlock_t initializing_hba_lock; spinlock_t initializing_hba_lock;
int initializing_hba_lock_flag; int initializing_hba_lock_flag;
struct list_head list; struct list_head list;
@ -668,10 +699,14 @@ typedef struct _MPT_ADAPTER
struct work_struct fc_setup_reset_work; struct work_struct fc_setup_reset_work;
struct list_head fc_rports; struct list_head fc_rports;
struct work_struct fc_lsc_work;
u8 fc_link_speed[2];
spinlock_t fc_rescan_work_lock; spinlock_t fc_rescan_work_lock;
struct work_struct fc_rescan_work; struct work_struct fc_rescan_work;
char fc_rescan_work_q_name[KOBJ_NAME_LEN]; char fc_rescan_work_q_name[KOBJ_NAME_LEN];
struct workqueue_struct *fc_rescan_work_q; struct workqueue_struct *fc_rescan_work_q;
struct scsi_cmnd **ScsiLookup;
spinlock_t scsi_lookup_lock;
} MPT_ADAPTER; } MPT_ADAPTER;
/* /*
@ -785,7 +820,6 @@ typedef struct _MPT_SCSI_HOST {
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
int port; int port;
u32 pad0; u32 pad0;
struct scsi_cmnd **ScsiLookup;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer; struct timer_list timer;
/* Pool of memory for holding SCpnts before doing /* Pool of memory for holding SCpnts before doing
@ -853,20 +887,21 @@ extern void mpt_detach(struct pci_dev *pdev);
extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state); extern int mpt_suspend(struct pci_dev *pdev, pm_message_t state);
extern int mpt_resume(struct pci_dev *pdev); extern int mpt_resume(struct pci_dev *pdev);
#endif #endif
extern int mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass); extern u8 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
extern void mpt_deregister(int cb_idx); extern void mpt_deregister(u8 cb_idx);
extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc); extern int mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc);
extern void mpt_event_deregister(int cb_idx); extern void mpt_event_deregister(u8 cb_idx);
extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func); extern int mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func);
extern void mpt_reset_deregister(int cb_idx); extern void mpt_reset_deregister(u8 cb_idx);
extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx); extern int mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx);
extern void mpt_device_driver_deregister(int cb_idx); extern void mpt_device_driver_deregister(u8 cb_idx);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc); extern MPT_FRAME_HDR *mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc);
extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf);
extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr);
extern int mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); extern int mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag);
extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
@ -884,9 +919,6 @@ extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhys
extern struct list_head ioc_list; extern struct list_head ioc_list;
extern struct proc_dir_entry *mpt_proc_root_dir; extern struct proc_dir_entry *mpt_proc_root_dir;
extern int mpt_lan_index; /* needed by mptlan.c */
extern int mpt_stm_index; /* needed by mptstm.c */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */ #endif /* } __KERNEL__ */

View file

@ -1,10 +1,10 @@
/* /*
* linux/drivers/message/fusion/mptctl.c * linux/drivers/message/fusion/mptctl.c
* mpt Ioctl driver. * mpt Ioctl driver.
* For use with LSI Logic PCI chip/adapters * For use with LSI PCI chip/adapters
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -66,8 +66,8 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h> #include <scsi/scsi_tcq.h>
#define COPYRIGHT "Copyright (c) 1999-2007 LSI Logic Corporation" #define COPYRIGHT "Copyright (c) 1999-2007 LSI Corporation"
#define MODULEAUTHOR "LSI Logic Corporation" #define MODULEAUTHOR "LSI Corporation"
#include "mptbase.h" #include "mptbase.h"
#include "mptctl.h" #include "mptctl.h"
@ -83,7 +83,7 @@ MODULE_VERSION(my_VERSION);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int mptctl_id = -1; static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait ); static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
@ -181,7 +181,6 @@ static inline int
mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
{ {
int rc = 0; int rc = 0;
// dctlprintk(ioc, printk(KERN_DEBUG MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
if (nonblock) { if (nonblock) {
if (!mutex_trylock(&ioc->ioctl->ioctl_mutex)) if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))
@ -190,7 +189,6 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex)) if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))
rc = -ERESTARTSYS; rc = -ERESTARTSYS;
} }
// dctlprintk(ioc, printk(KERN_DEBUG MYNAM "::mptctl_syscall_down return %d\n", rc));
return rc; return rc;
} }
@ -342,7 +340,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
SCSITaskMgmt_t *pScsiTm; SCSITaskMgmt_t *pScsiTm;
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
int ii; int ii;
int retval; int retval=0;
ioctl->reset &= ~MPTCTL_RESET_OK; ioctl->reset &= ~MPTCTL_RESET_OK;
@ -350,7 +348,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
if (ioctl->ioc->sh == NULL) if (ioctl->ioc->sh == NULL)
return -EPERM; return -EPERM;
hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata; hd = shost_priv(ioctl->ioc->sh);
if (hd == NULL) if (hd == NULL)
return -EPERM; return -EPERM;
@ -395,12 +393,19 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
DBG_DUMP_TM_REQUEST_FRAME(ioctl->ioc, (u32 *)mf); DBG_DUMP_TM_REQUEST_FRAME(ioctl->ioc, (u32 *)mf);
ioctl->wait_done=0; ioctl->wait_done=0;
if ((retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) { if ((ioctl->ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
dfailprintk(ioctl->ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!" (ioctl->ioc->facts.MsgVersion >= MPI_VERSION_01_05))
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, mpt_put_msg_frame_hi_pri(mptctl_id, ioctl->ioc, mf);
hd->ioc, mf)); else {
goto mptctl_bus_reset_done; retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
if (retval != 0) {
dfailprintk(ioctl->ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!"
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
hd->ioc, mf));
goto mptctl_bus_reset_done;
}
} }
/* Now wait for the command to complete */ /* Now wait for the command to complete */
@ -444,7 +449,7 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc)
MPT_SCSI_HOST * hd; MPT_SCSI_HOST * hd;
unsigned long flags; unsigned long flags;
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; hd = shost_priv(ioc->sh);
if (hd == NULL) if (hd == NULL)
return; return;
@ -468,7 +473,7 @@ static int
mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
MPT_IOCTL *ioctl = ioc->ioctl; MPT_IOCTL *ioctl = ioc->ioctl;
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": IOC %s_reset routed to IOCTL driver!\n",ioc->name, dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC %s_reset routed to IOCTL driver!\n", ioc->name,
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
@ -574,7 +579,7 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
MPT_ADAPTER *iocp = NULL; MPT_ADAPTER *iocp = NULL;
if (copy_from_user(&khdr, uhdr, sizeof(khdr))) { if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
printk(KERN_ERR "%s::mptctl_ioctl() @%d - " printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - "
"Unable to copy mpt_ioctl_header data @ %p\n", "Unable to copy mpt_ioctl_header data @ %p\n",
__FILE__, __LINE__, uhdr); __FILE__, __LINE__, uhdr);
return -EFAULT; return -EFAULT;
@ -587,13 +592,13 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
iocnumX = khdr.iocnum & 0xFF; iocnumX = khdr.iocnum & 0xFF;
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (iocp == NULL)) {
printk(KERN_DEBUG "%s::mptctl_ioctl() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnumX); __FILE__, __LINE__, iocnumX);
return -ENODEV; return -ENODEV;
} }
if (!iocp->active) { if (!iocp->active) {
printk(KERN_DEBUG "%s::mptctl_ioctl() @%d - Controller disabled.\n", printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
__FILE__, __LINE__); __FILE__, __LINE__);
return -EFAULT; return -EFAULT;
} }
@ -660,14 +665,14 @@ static int mptctl_do_reset(unsigned long arg)
MPT_ADAPTER *iocp; MPT_ADAPTER *iocp;
if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) { if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
printk(KERN_ERR "%s@%d::mptctl_do_reset - " printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
"Unable to copy mpt_ioctl_diag_reset struct @ %p\n", "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
__FILE__, __LINE__, urinfo); __FILE__, __LINE__, urinfo);
return -EFAULT; return -EFAULT;
} }
if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) { if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
printk(KERN_DEBUG "%s@%d::mptctl_do_reset - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
__FILE__, __LINE__, krinfo.hdr.iocnum); __FILE__, __LINE__, krinfo.hdr.iocnum);
return -ENODEV; /* (-6) No such device or address */ return -ENODEV; /* (-6) No such device or address */
} }
@ -676,8 +681,8 @@ static int mptctl_do_reset(unsigned long arg)
iocp->name)); iocp->name));
if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) { if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n", printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
__FILE__, __LINE__); iocp->name, __FILE__, __LINE__);
return -1; return -1;
} }
@ -708,7 +713,7 @@ mptctl_fw_download(unsigned long arg)
struct mpt_fw_xfer kfwdl; struct mpt_fw_xfer kfwdl;
if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) { if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
printk(KERN_ERR "%s@%d::_ioctl_fwdl - " printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - "
"Unable to copy mpt_fw_xfer struct @ %p\n", "Unable to copy mpt_fw_xfer struct @ %p\n",
__FILE__, __LINE__, ufwdl); __FILE__, __LINE__, ufwdl);
return -EFAULT; return -EFAULT;
@ -756,7 +761,8 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
pFWDownloadReply_t ReplyMsg = NULL; pFWDownloadReply_t ReplyMsg = NULL;
if (mpt_verify_adapter(ioc, &iocp) < 0) { if (mpt_verify_adapter(ioc, &iocp) < 0) {
printk(KERN_DEBUG "ioctl_fwdl - ioc%d not found!\n", ioc); printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
ioc);
return -ENODEV; /* (-6) No such device or address */ return -ENODEV; /* (-6) No such device or address */
} else { } else {
@ -868,9 +874,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address); mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
n++; n++;
if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) { if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
printk(KERN_ERR "%s@%d::_ioctl_fwdl - " printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
"Unable to copy f/w buffer hunk#%d @ %p\n", "Unable to copy f/w buffer hunk#%d @ %p\n",
__FILE__, __LINE__, n, ufwbuf); iocp->name, __FILE__, __LINE__, n, ufwbuf);
goto fwdl_out; goto fwdl_out;
} }
fw_bytes_copied += bl->len; fw_bytes_copied += bl->len;
@ -906,21 +912,22 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
ReplyMsg = (pFWDownloadReply_t)iocp->ioctl->ReplyFrame; ReplyMsg = (pFWDownloadReply_t)iocp->ioctl->ReplyFrame;
iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK; iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
if (iocstat == MPI_IOCSTATUS_SUCCESS) { if (iocstat == MPI_IOCSTATUS_SUCCESS) {
printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name); printk(MYIOC_s_INFO_FMT "F/W update successfull!\n", iocp->name);
return 0; return 0;
} else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) { } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
printk(KERN_WARNING MYNAM ": ?Hmmm... %s says it doesn't support F/W download!?!\n", printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n",
iocp->name); iocp->name);
printk(KERN_WARNING MYNAM ": (time to go bang on somebodies door)\n"); printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
iocp->name);
return -EBADRQC; return -EBADRQC;
} else if (iocstat == MPI_IOCSTATUS_BUSY) { } else if (iocstat == MPI_IOCSTATUS_BUSY) {
printk(KERN_WARNING MYNAM ": Warning! %s says: IOC_BUSY!\n", iocp->name); printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
printk(KERN_WARNING MYNAM ": (try again later?)\n"); printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
return -EBUSY; return -EBUSY;
} else { } else {
printk(KERN_WARNING MYNAM "::ioctl_fwdl() ERROR! %s returned [bad] status = %04xh\n", printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
iocp->name, iocstat); iocp->name, iocstat);
printk(KERN_WARNING MYNAM ": (bad VooDoo)\n"); printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
return -ENOMSG; return -ENOMSG;
} }
return 0; return 0;
@ -970,10 +977,9 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
* structures for the SG elements. * structures for the SG elements.
*/ */
i = MAX_SGL_BYTES / 8; i = MAX_SGL_BYTES / 8;
buflist = kmalloc(i, GFP_USER); buflist = kzalloc(i, GFP_USER);
if (buflist == NULL) if (!buflist)
return NULL; return NULL;
memset(buflist, 0, i);
buflist_ent = 0; buflist_ent = 0;
/* Allocate a single block of memory to store the sg elements and /* Allocate a single block of memory to store the sg elements and
@ -1008,10 +1014,10 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
if (buflist[buflist_ent].kptr == NULL) { if (buflist[buflist_ent].kptr == NULL) {
alloc_sz = alloc_sz / 2; alloc_sz = alloc_sz / 2;
if (alloc_sz == 0) { if (alloc_sz == 0) {
printk(KERN_WARNING MYNAM "-SG: No can do - " printk(MYIOC_s_WARN_FMT "-SG: No can do - "
"not enough memory! :-(\n"); "not enough memory! :-(\n", ioc->name);
printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n", printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
numfrags); ioc->name, numfrags);
goto free_and_fail; goto free_and_fail;
} }
continue; continue;
@ -1034,18 +1040,19 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
/* Need to chain? */ /* Need to chain? */
if (fragcnt == sg_spill) { if (fragcnt == sg_spill) {
printk(KERN_WARNING MYNAM "-SG: No can do - " "Chain required! :-(\n"); printk(MYIOC_s_WARN_FMT
printk(KERN_WARNING MYNAM "(freeing %d frags)\n", numfrags); "-SG: No can do - " "Chain required! :-(\n", ioc->name);
printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
goto free_and_fail; goto free_and_fail;
} }
/* overflow check... */ /* overflow check... */
if (numfrags*8 > MAX_SGL_BYTES){ if (numfrags*8 > MAX_SGL_BYTES){
/* GRRRRR... */ /* GRRRRR... */
printk(KERN_WARNING MYNAM "-SG: No can do - " printk(MYIOC_s_WARN_FMT "-SG: No can do - "
"too many SG frags! :-(\n"); "too many SG frags! :-(\n", ioc->name);
printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n", printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
numfrags); ioc->name, numfrags);
goto free_and_fail; goto free_and_fail;
} }
} }
@ -1066,8 +1073,6 @@ kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
free_and_fail: free_and_fail:
if (sglbuf != NULL) { if (sglbuf != NULL) {
int i;
for (i = 0; i < numfrags; i++) { for (i = 0; i < numfrags; i++) {
dma_addr_t dma_addr; dma_addr_t dma_addr;
u8 *kptr; u8 *kptr;
@ -1170,7 +1175,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
int cim_rev; int cim_rev;
u8 revision; u8 revision;
struct scsi_device *sdev; struct scsi_device *sdev;
VirtDevice *vdev; VirtDevice *vdevice;
/* Add of PCI INFO results in unaligned access for /* Add of PCI INFO results in unaligned access for
* IA64 and Sparc. Reset long to int. Return no PCI * IA64 and Sparc. Reset long to int. Return no PCI
@ -1189,13 +1194,13 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
karg = kmalloc(data_size, GFP_KERNEL); karg = kmalloc(data_size, GFP_KERNEL);
if (karg == NULL) { if (karg == NULL) {
printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n", printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
__FILE__, __LINE__); __FILE__, __LINE__);
return -ENOMEM; return -ENOMEM;
} }
if (copy_from_user(karg, uarg, data_size)) { if (copy_from_user(karg, uarg, data_size)) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
"Unable to read in mpt_ioctl_iocinfo struct @ %p\n", "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
kfree(karg); kfree(karg);
@ -1204,7 +1209,7 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
kfree(karg); kfree(karg);
return -ENODEV; return -ENODEV;
@ -1212,9 +1217,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Verify the data transfer size is correct. */ /* Verify the data transfer size is correct. */
if (karg->hdr.maxDataSize != data_size) { if (karg->hdr.maxDataSize != data_size) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
"Structure size mismatch. Command not completed.\n", "Structure size mismatch. Command not completed.\n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
kfree(karg); kfree(karg);
return -EFAULT; return -EFAULT;
} }
@ -1265,8 +1270,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
karg->numDevices = 0; karg->numDevices = 0;
if (ioc->sh) { if (ioc->sh) {
shost_for_each_device(sdev, ioc->sh) { shost_for_each_device(sdev, ioc->sh) {
vdev = sdev->hostdata; vdevice = sdev->hostdata;
if (vdev->vtarget->tflags & if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT) MPT_TARGET_FLAGS_RAID_COMPONENT)
continue; continue;
karg->numDevices++; karg->numDevices++;
@ -1290,9 +1295,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, karg, data_size)) { if (copy_to_user((char __user *)arg, karg, data_size)) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
"Unable to write out mpt_ioctl_iocinfo struct @ %p\n", "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
kfree(karg); kfree(karg);
return -EFAULT; return -EFAULT;
} }
@ -1317,7 +1322,7 @@ mptctl_gettargetinfo (unsigned long arg)
struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_targetinfo karg; struct mpt_ioctl_targetinfo karg;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
VirtDevice *vdev; VirtDevice *vdevice;
char *pmem; char *pmem;
int *pdata; int *pdata;
int iocnum; int iocnum;
@ -1329,7 +1334,7 @@ mptctl_gettargetinfo (unsigned long arg)
struct scsi_device *sdev; struct scsi_device *sdev;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
"Unable to read in mpt_ioctl_targetinfo struct @ %p\n", "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1337,7 +1342,7 @@ mptctl_gettargetinfo (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1353,8 +1358,8 @@ mptctl_gettargetinfo (unsigned long arg)
port = karg.hdr.port; port = karg.hdr.port;
if (maxWordsLeft <= 0) { if (maxWordsLeft <= 0) {
printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n", printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
return -ENOMEM; return -ENOMEM;
} }
@ -1372,13 +1377,12 @@ mptctl_gettargetinfo (unsigned long arg)
* 15- 8: Bus Number * 15- 8: Bus Number
* 7- 0: Target ID * 7- 0: Target ID
*/ */
pmem = kmalloc(numBytes, GFP_KERNEL); pmem = kzalloc(numBytes, GFP_KERNEL);
if (pmem == NULL) { if (!pmem) {
printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n", printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
return -ENOMEM; return -ENOMEM;
} }
memset(pmem, 0, numBytes);
pdata = (int *) pmem; pdata = (int *) pmem;
/* Get number of devices /* Get number of devices
@ -1387,13 +1391,13 @@ mptctl_gettargetinfo (unsigned long arg)
shost_for_each_device(sdev, ioc->sh) { shost_for_each_device(sdev, ioc->sh) {
if (!maxWordsLeft) if (!maxWordsLeft)
continue; continue;
vdev = sdev->hostdata; vdevice = sdev->hostdata;
if (vdev->vtarget->tflags & if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT) MPT_TARGET_FLAGS_RAID_COMPONENT)
continue; continue;
lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun; lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
*pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) + *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
(vdev->vtarget->id )); (vdevice->vtarget->id ));
pdata++; pdata++;
numDevices++; numDevices++;
--maxWordsLeft; --maxWordsLeft;
@ -1405,9 +1409,9 @@ mptctl_gettargetinfo (unsigned long arg)
*/ */
if (copy_to_user((char __user *)arg, &karg, if (copy_to_user((char __user *)arg, &karg,
sizeof(struct mpt_ioctl_targetinfo))) { sizeof(struct mpt_ioctl_targetinfo))) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n", "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
kfree(pmem); kfree(pmem);
return -EFAULT; return -EFAULT;
} }
@ -1415,9 +1419,9 @@ mptctl_gettargetinfo (unsigned long arg)
/* Copy the remaining data from kernel memory to user memory /* Copy the remaining data from kernel memory to user memory
*/ */
if (copy_to_user(uarg->targetInfo, pmem, numBytes)) { if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n", "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, pdata); ioc->name, __FILE__, __LINE__, pdata);
kfree(pmem); kfree(pmem);
return -EFAULT; return -EFAULT;
} }
@ -1444,7 +1448,7 @@ mptctl_readtest (unsigned long arg)
int iocnum; int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR "%s@%d::mptctl_readtest - " printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
"Unable to read in mpt_ioctl_test struct @ %p\n", "Unable to read in mpt_ioctl_test struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1452,7 +1456,7 @@ mptctl_readtest (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_readtest() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1476,9 +1480,9 @@ mptctl_readtest (unsigned long arg)
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) { if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR "%s@%d::mptctl_readtest - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
"Unable to write out mpt_ioctl_test struct @ %p\n", "Unable to write out mpt_ioctl_test struct @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
} }
@ -1505,7 +1509,7 @@ mptctl_eventquery (unsigned long arg)
int iocnum; int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
printk(KERN_ERR "%s@%d::mptctl_eventquery - " printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
"Unable to read in mpt_ioctl_eventquery struct @ %p\n", "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1513,7 +1517,7 @@ mptctl_eventquery (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_eventquery() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1526,9 +1530,9 @@ mptctl_eventquery (unsigned long arg)
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) { if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
printk(KERN_ERR "%s@%d::mptctl_eventquery - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
"Unable to write out mpt_ioctl_eventquery struct @ %p\n", "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
@ -1544,7 +1548,7 @@ mptctl_eventenable (unsigned long arg)
int iocnum; int iocnum;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
printk(KERN_ERR "%s@%d::mptctl_eventenable - " printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
"Unable to read in mpt_ioctl_eventenable struct @ %p\n", "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1552,7 +1556,7 @@ mptctl_eventenable (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_eventenable() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1563,12 +1567,13 @@ mptctl_eventenable (unsigned long arg)
/* Have not yet allocated memory - do so now. /* Have not yet allocated memory - do so now.
*/ */
int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
ioc->events = kmalloc(sz, GFP_KERNEL); ioc->events = kzalloc(sz, GFP_KERNEL);
if (ioc->events == NULL) { if (!ioc->events) {
printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); printk(MYIOC_s_ERR_FMT
": ERROR - Insufficient memory to add adapter!\n",
ioc->name);
return -ENOMEM; return -ENOMEM;
} }
memset(ioc->events, 0, sz);
ioc->alloc_total += sz; ioc->alloc_total += sz;
ioc->eventContext = 0; ioc->eventContext = 0;
@ -1592,7 +1597,7 @@ mptctl_eventreport (unsigned long arg)
int numBytes, maxEvents, max; int numBytes, maxEvents, max;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
printk(KERN_ERR "%s@%d::mptctl_eventreport - " printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
"Unable to read in mpt_ioctl_eventreport struct @ %p\n", "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1600,7 +1605,7 @@ mptctl_eventreport (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_eventreport() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1626,9 +1631,9 @@ mptctl_eventreport (unsigned long arg)
*/ */
numBytes = max * sizeof(MPT_IOCTL_EVENTS); numBytes = max * sizeof(MPT_IOCTL_EVENTS);
if (copy_to_user(uarg->eventData, ioc->events, numBytes)) { if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
printk(KERN_ERR "%s@%d::mptctl_eventreport - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
"Unable to write out mpt_ioctl_eventreport struct @ %p\n", "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
__FILE__, __LINE__, ioc->events); ioc->name, __FILE__, __LINE__, ioc->events);
return -EFAULT; return -EFAULT;
} }
@ -1646,7 +1651,7 @@ mptctl_replace_fw (unsigned long arg)
int newFwSize; int newFwSize;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
printk(KERN_ERR "%s@%d::mptctl_replace_fw - " printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
"Unable to read in mpt_ioctl_replace_fw struct @ %p\n", "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1654,7 +1659,7 @@ mptctl_replace_fw (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1684,9 +1689,9 @@ mptctl_replace_fw (unsigned long arg)
/* Copy the data from user memory to kernel space /* Copy the data from user memory to kernel space
*/ */
if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) { if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
printk(KERN_ERR "%s@%d::mptctl_replace_fw - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
"Unable to read in mpt_ioctl_replace_fw image " "Unable to read in mpt_ioctl_replace_fw image "
"@ %p\n", __FILE__, __LINE__, uarg); "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
mpt_free_fw_memory(ioc); mpt_free_fw_memory(ioc);
return -EFAULT; return -EFAULT;
} }
@ -1720,7 +1725,7 @@ mptctl_mpt_command (unsigned long arg)
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) { if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
printk(KERN_ERR "%s@%d::mptctl_mpt_command - " printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
"Unable to read in mpt_ioctl_command struct @ %p\n", "Unable to read in mpt_ioctl_command struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -1728,7 +1733,7 @@ mptctl_mpt_command (unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -1769,21 +1774,24 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
ulong timeout; ulong timeout;
struct scsi_device *sdev; struct scsi_device *sdev;
/* bufIn and bufOut are used for user to kernel space transfers
*/
bufIn.kptr = bufOut.kptr = NULL; bufIn.kptr = bufOut.kptr = NULL;
bufIn.len = bufOut.len = 0;
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
if (!ioc->ioctl) { if (!ioc->ioctl) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
"No memory available during driver init.\n", "No memory available during driver init.\n",
__FILE__, __LINE__); __FILE__, __LINE__);
return -ENOMEM; return -ENOMEM;
} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) { } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
"Busy with IOC Reset \n", __FILE__, __LINE__); "Busy with IOC Reset \n", __FILE__, __LINE__);
return -EBUSY; return -EBUSY;
} }
@ -1797,9 +1805,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
sz += sizeof(dma_addr_t) + sizeof(u32); sz += sizeof(dma_addr_t) + sizeof(u32);
if (sz > ioc->req_sz) { if (sz > ioc->req_sz) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Request frame too large (%d) maximum (%d)\n", "Request frame too large (%d) maximum (%d)\n",
__FILE__, __LINE__, sz, ioc->req_sz); ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
return -EFAULT; return -EFAULT;
} }
@ -1817,9 +1825,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
* Request frame in user space * Request frame in user space
*/ */
if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) { if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Unable to read MF from mpt_ioctl_command struct @ %p\n", "Unable to read MF from mpt_ioctl_command struct @ %p\n",
__FILE__, __LINE__, mfPtr); ioc->name, __FILE__, __LINE__, mfPtr);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -1870,17 +1878,17 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
if (pScsiReq->TargetID > id) { if (pScsiReq->TargetID > id) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Target ID out of bounds. \n", "Target ID out of bounds. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -ENODEV; rc = -ENODEV;
goto done_free_mem; goto done_free_mem;
} }
if (pScsiReq->Bus >= ioc->number_of_buses) { if (pScsiReq->Bus >= ioc->number_of_buses) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Target Bus out of bounds. \n", "Target Bus out of bounds. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -ENODEV; rc = -ENODEV;
goto done_free_mem; goto done_free_mem;
} }
@ -1932,9 +1940,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
ioc->ioctl->id = pScsiReq->TargetID; ioc->ioctl->id = pScsiReq->TargetID;
} else { } else {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"SCSI driver is not loaded. \n", "SCSI driver is not loaded. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -1951,9 +1959,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
case MPI_FUNCTION_SATA_PASSTHROUGH: case MPI_FUNCTION_SATA_PASSTHROUGH:
if (!ioc->sh) { if (!ioc->sh) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"SCSI driver is not loaded. \n", "SCSI driver is not loaded. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -2010,9 +2018,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
ioc->ioctl->reset = MPTCTL_RESET_OK; ioc->ioctl->reset = MPTCTL_RESET_OK;
ioc->ioctl->id = pScsiReq->TargetID; ioc->ioctl->id = pScsiReq->TargetID;
} else { } else {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"SCSI driver is not loaded. \n", "SCSI driver is not loaded. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -2021,10 +2029,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
case MPI_FUNCTION_SCSI_TASK_MGMT: case MPI_FUNCTION_SCSI_TASK_MGMT:
{ {
MPT_SCSI_HOST *hd = NULL; MPT_SCSI_HOST *hd = NULL;
if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) { if ((ioc->sh == NULL) || ((hd = shost_priv(ioc->sh)) == NULL)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"SCSI driver not loaded or SCSI host not found. \n", "SCSI driver not loaded or SCSI host not found. \n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} else if (mptctl_set_tm_flags(hd) != 0) { } else if (mptctl_set_tm_flags(hd) != 0) {
@ -2055,9 +2063,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
(pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) || (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
(pInit->HostMfaHighAddr != high_addr) || (pInit->HostMfaHighAddr != high_addr) ||
(pInit->SenseBufferHighAddr != sense_high)) { (pInit->SenseBufferHighAddr != sense_high)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n", "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
__FILE__, __LINE__); ioc->name, __FILE__, __LINE__);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -2088,9 +2096,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
MPI_FUNCTION_LAN_RESET MPI_FUNCTION_LAN_RESET
*/ */
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Illegal request (function 0x%x) \n", "Illegal request (function 0x%x) \n",
__FILE__, __LINE__, hdr->Function); ioc->name, __FILE__, __LINE__, hdr->Function);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -2103,11 +2111,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
psge = (char *) (((int *) mf) + karg.dataSgeOffset); psge = (char *) (((int *) mf) + karg.dataSgeOffset);
flagsLength = 0; flagsLength = 0;
/* bufIn and bufOut are used for user to kernel space transfers
*/
bufIn.kptr = bufOut.kptr = NULL;
bufIn.len = bufOut.len = 0;
if (karg.dataOutSize > 0) if (karg.dataOutSize > 0)
sgSize ++; sgSize ++;
@ -2147,11 +2150,11 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
if (copy_from_user(bufOut.kptr, if (copy_from_user(bufOut.kptr,
karg.dataOutBufPtr, karg.dataOutBufPtr,
bufOut.len)) { bufOut.len)) {
printk(KERN_ERR printk(MYIOC_s_ERR_FMT
"%s@%d::mptctl_do_mpt_command - Unable " "%s@%d::mptctl_do_mpt_command - Unable "
"to read user data " "to read user data "
"struct @ %p\n", "struct @ %p\n",
__FILE__, __LINE__,karg.dataOutBufPtr); ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
rc = -EFAULT; rc = -EFAULT;
goto done_free_mem; goto done_free_mem;
} }
@ -2187,15 +2190,20 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf); DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
if (mpt_send_handshake_request(mptctl_id, ioc, if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
sizeof(SCSITaskMgmt_t), (u32*)mf, (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
CAN_SLEEP) != 0) { mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "_send_handshake FAILED!" else {
" (ioc %p, mf %p) \n", ioc->name, rc =mpt_send_handshake_request(mptctl_id, ioc,
ioc, mf)); sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
mptctl_free_tm_flags(ioc); if (rc != 0) {
rc = -ENODATA; dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
goto done_free_mem; "_send_handshake FAILED! (ioc %p, mf %p)\n",
ioc->name, ioc, mf));
mptctl_free_tm_flags(ioc);
rc = -ENODATA;
goto done_free_mem;
}
} }
} else } else
@ -2233,10 +2241,10 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
if (sz > 0) { if (sz > 0) {
if (copy_to_user(karg.replyFrameBufPtr, if (copy_to_user(karg.replyFrameBufPtr,
&ioc->ioctl->ReplyFrame, sz)){ &ioc->ioctl->ReplyFrame, sz)){
printk(KERN_ERR printk(MYIOC_s_ERR_FMT
"%s@%d::mptctl_do_mpt_command - " "%s@%d::mptctl_do_mpt_command - "
"Unable to write out reply frame %p\n", "Unable to write out reply frame %p\n",
__FILE__, __LINE__, karg.replyFrameBufPtr); ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
rc = -ENODATA; rc = -ENODATA;
goto done_free_mem; goto done_free_mem;
} }
@ -2249,9 +2257,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE); sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
if (sz > 0) { if (sz > 0) {
if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) { if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Unable to write sense data to user %p\n", "Unable to write sense data to user %p\n",
__FILE__, __LINE__, ioc->name, __FILE__, __LINE__,
karg.senseDataPtr); karg.senseDataPtr);
rc = -ENODATA; rc = -ENODATA;
goto done_free_mem; goto done_free_mem;
@ -2267,9 +2275,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
if (copy_to_user(karg.dataInBufPtr, if (copy_to_user(karg.dataInBufPtr,
bufIn.kptr, karg.dataInSize)) { bufIn.kptr, karg.dataInSize)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
"Unable to write data to user %p\n", "Unable to write data to user %p\n",
__FILE__, __LINE__, ioc->name, __FILE__, __LINE__,
karg.dataInBufPtr); karg.dataInBufPtr);
rc = -ENODATA; rc = -ENODATA;
} }
@ -2340,7 +2348,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
return -EFAULT; return -EFAULT;
if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) { if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_host_info - " printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
"Unable to read in hp_host_info struct @ %p\n", "Unable to read in hp_host_info struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -2348,7 +2356,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
@ -2456,7 +2464,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
karg.soft_resets = 0; karg.soft_resets = 0;
karg.timeouts = 0; karg.timeouts = 0;
if (ioc->sh != NULL) { if (ioc->sh != NULL) {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
if (hd && (cim_rev == 1)) { if (hd && (cim_rev == 1)) {
karg.hard_resets = hd->hard_resets; karg.hard_resets = hd->hard_resets;
@ -2529,9 +2537,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
"Unable to write out hp_host_info @ %p\n", "Unable to write out hp_host_info @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
} }
@ -2567,7 +2575,7 @@ mptctl_hp_targetinfo(unsigned long arg)
int tmp, np, rc = 0; int tmp, np, rc = 0;
if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) { if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - " printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
"Unable to read in hp_host_targetinfo struct @ %p\n", "Unable to read in hp_host_targetinfo struct @ %p\n",
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
@ -2575,11 +2583,11 @@ mptctl_hp_targetinfo(unsigned long arg)
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
printk(KERN_DEBUG "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
__FILE__, __LINE__, iocnum); __FILE__, __LINE__, iocnum);
return -ENODEV; return -ENODEV;
} }
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_targetinfo called.\n", dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
ioc->name)); ioc->name));
/* There is nothing to do for FCP parts. /* There is nothing to do for FCP parts.
@ -2673,16 +2681,16 @@ mptctl_hp_targetinfo(unsigned long arg)
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma); pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
} }
} }
hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; hd = shost_priv(ioc->sh);
if (hd != NULL) if (hd != NULL)
karg.select_timeouts = hd->sel_timeout[karg.hdr.id]; karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) { if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
printk(KERN_ERR "%s@%d::mptctl_hp_target_info - " printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
"Unable to write out mpt_ioctl_targetinfo struct @ %p\n", "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, uarg); ioc->name, __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
} }
@ -2732,7 +2740,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (iocp == NULL)) {
printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
__LINE__, iocnumX); __LINE__, iocnumX);
return -ENODEV; return -ENODEV;
} }
@ -2772,7 +2780,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
(iocp == NULL)) { (iocp == NULL)) {
printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n", printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
__LINE__, iocnumX); __LINE__, iocnumX);
return -ENODEV; return -ENODEV;
} }
@ -2853,31 +2861,22 @@ static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long a
static int static int
mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id) mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
int err; MPT_IOCTL *mem;
int sz;
u8 *mem;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev); MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
/* /*
* Allocate and inite a MPT_IOCTL structure * Allocate and inite a MPT_IOCTL structure
*/ */
sz = sizeof (MPT_IOCTL); mem = kzalloc(sizeof(MPT_IOCTL), GFP_KERNEL);
mem = kmalloc(sz, GFP_KERNEL); if (!mem) {
if (mem == NULL) { mptctl_remove(pdev);
err = -ENOMEM; return -ENOMEM;
goto out_fail;
} }
memset(mem, 0, sz); ioc->ioctl = mem;
ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc; ioc->ioctl->ioc = ioc;
mutex_init(&ioc->ioctl->ioctl_mutex); mutex_init(&ioc->ioctl->ioctl_mutex);
return 0; return 0;
out_fail:
mptctl_remove(pdev);
return err;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@ -2924,7 +2923,8 @@ static int __init mptctl_init(void)
* Install our handler * Install our handler
*/ */
++where; ++where;
if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) { mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER);
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev); misc_deregister(&mptctl_miscdev);
err = -EBUSY; err = -EBUSY;

View file

@ -3,9 +3,9 @@
* Fusion MPT misc device (ioctl) driver. * Fusion MPT misc device (ioctl) driver.
* For use with PCI chip/adapter(s): * For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel * LSIFC9xx/LSI409xx Fibre Channel
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */

View file

@ -1,9 +1,9 @@
/* /*
* linux/drivers/message/fusion/mptfc.c * linux/drivers/message/fusion/mptfc.c
* For use with LSI Logic PCI chip/adapter(s) * For use with LSI PCI chip/adapter(s)
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -90,9 +90,9 @@ static int max_lun = MPTFC_MAX_LUN;
module_param(max_lun, int, 0); module_param(max_lun, int, 0);
MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
static int mptfcDoneCtx = -1; static u8 mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptfcTaskCtx = -1; static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptfcInternalCtx = -1; /* Used only for internal commands */ static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptfc_target_alloc(struct scsi_target *starget); static int mptfc_target_alloc(struct scsi_target *starget);
static int mptfc_slave_alloc(struct scsi_device *sdev); static int mptfc_slave_alloc(struct scsi_device *sdev);
@ -194,37 +194,36 @@ mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
unsigned long flags; unsigned long flags;
int ready; int ready;
MPT_ADAPTER *ioc;
hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; hd = shost_priv(SCpnt->device->host);
ioc = hd->ioc;
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) { while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) {
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
"mptfc_block_error_handler.%d: %d:%d, port status is " "mptfc_block_error_handler.%d: %d:%d, port status is "
"DID_IMM_RETRY, deferring %s recovery.\n", "DID_IMM_RETRY, deferring %s recovery.\n",
((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ioc->name, ioc->sh->host_no,
((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun, caller));
SCpnt->device->id,SCpnt->device->lun,caller));
msleep(1000); msleep(1000);
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
} }
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) { if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) {
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
"%s.%d: %d:%d, failing recovery, " "%s.%d: %d:%d, failing recovery, "
"port state %d, vdev %p.\n", caller, "port state %d, vdevice %p.\n", caller,
((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ioc->name, ioc->sh->host_no,
((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun, ready,
SCpnt->device->id,SCpnt->device->lun,ready,
SCpnt->device->hostdata)); SCpnt->device->hostdata));
return FAILED; return FAILED;
} }
dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
"%s.%d: %d:%d, executing recovery.\n", caller, "%s.%d: %d:%d, executing recovery.\n", caller,
((MPT_SCSI_HOST *) shost->hostdata)->ioc->name, ioc->name, ioc->sh->host_no,
((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no, SCpnt->device->id, SCpnt->device->lun));
SCpnt->device->id,SCpnt->device->lun));
return (*func)(SCpnt); return (*func)(SCpnt);
} }
@ -470,7 +469,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
/* /*
* if already mapped, remap here. If not mapped, * if already mapped, remap here. If not mapped,
* target_alloc will allocate vtarget and map, * target_alloc will allocate vtarget and map,
* slave_alloc will fill in vdev from vtarget. * slave_alloc will fill in vdevice from vtarget.
*/ */
if (ri->starget) { if (ri->starget) {
vtarget = ri->starget->hostdata; vtarget = ri->starget->hostdata;
@ -602,10 +601,10 @@ mptfc_slave_alloc(struct scsi_device *sdev)
{ {
MPT_SCSI_HOST *hd; MPT_SCSI_HOST *hd;
VirtTarget *vtarget; VirtTarget *vtarget;
VirtDevice *vdev; VirtDevice *vdevice;
struct scsi_target *starget; struct scsi_target *starget;
struct fc_rport *rport; struct fc_rport *rport;
MPT_ADAPTER *ioc;
starget = scsi_target(sdev); starget = scsi_target(sdev);
rport = starget_to_rport(starget); rport = starget_to_rport(starget);
@ -613,31 +612,32 @@ mptfc_slave_alloc(struct scsi_device *sdev)
if (!rport || fc_remote_port_chkready(rport)) if (!rport || fc_remote_port_chkready(rport))
return -ENXIO; return -ENXIO;
hd = (MPT_SCSI_HOST *)sdev->host->hostdata; hd = shost_priv(sdev->host);
ioc = hd->ioc;
vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdevice) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice)); ioc->name, sizeof(VirtDevice));
return -ENOMEM; return -ENOMEM;
} }
sdev->hostdata = vdev; sdev->hostdata = vdevice;
vtarget = starget->hostdata; vtarget = starget->hostdata;
if (vtarget->num_luns == 0) { if (vtarget->num_luns == 0) {
vtarget->ioc_id = hd->ioc->id; vtarget->ioc_id = ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
} }
vdev->vtarget = vtarget; vdevice->vtarget = vtarget;
vdev->lun = sdev->lun; vdevice->lun = sdev->lun;
vtarget->num_luns++; vtarget->num_luns++;
mptfc_dump_lun_info(hd->ioc, rport, sdev, vtarget); mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
return 0; return 0;
} }
@ -648,9 +648,9 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
struct mptfc_rport_info *ri; struct mptfc_rport_info *ri;
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
int err; int err;
VirtDevice *vdev = SCpnt->device->hostdata; VirtDevice *vdevice = SCpnt->device->hostdata;
if (!vdev || !vdev->vtarget) { if (!vdevice || !vdevice->vtarget) {
SCpnt->result = DID_NO_CONNECT << 16; SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt); done(SCpnt);
return 0; return 0;
@ -674,6 +674,50 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return mptscsih_qcmd(SCpnt,done); return mptscsih_qcmd(SCpnt,done);
} }
/*
* mptfc_display_port_link_speed - displaying link speed
* @ioc: Pointer to MPT_ADAPTER structure
* @portnum: IOC Port number
* @pp0dest: port page0 data payload
*
*/
static void
mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
{
u8 old_speed, new_speed, state;
char *old, *new;
if (portnum >= 2)
return;
old_speed = ioc->fc_link_speed[portnum];
new_speed = pp0dest->CurrentSpeed;
state = pp0dest->PortState;
if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
"Unknown";
new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
"Unknown";
if (old_speed == 0)
printk(MYIOC_s_NOTE_FMT
"FC Link Established, Speed = %s\n",
ioc->name, new);
else if (old_speed != new_speed)
printk(MYIOC_s_WARN_FMT
"FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
ioc->name, old, new);
ioc->fc_link_speed[portnum] = new_speed;
}
}
/* /*
* mptfc_GetFcPortPage0 - Fetch FCPort config Page0. * mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
* @ioc: Pointer to MPT_ADAPTER structure * @ioc: Pointer to MPT_ADAPTER structure
@ -773,6 +817,7 @@ mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
" complete.\n", " complete.\n",
ioc->name); ioc->name);
} }
mptfc_display_port_link_speed(ioc, portnum, pp0dest);
} }
pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
@ -1022,6 +1067,18 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
} }
static void
mptfc_link_status_change(struct work_struct *work)
{
MPT_ADAPTER *ioc =
container_of(work, MPT_ADAPTER, fc_rescan_work);
int ii;
for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
(void) mptfc_GetFcPortPage0(ioc, ii);
}
static void static void
mptfc_setup_reset(struct work_struct *work) mptfc_setup_reset(struct work_struct *work)
{ {
@ -1163,6 +1220,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&ioc->fc_rescan_work_lock); spin_lock_init(&ioc->fc_rescan_work_lock);
INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices); INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset); INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
@ -1218,20 +1276,21 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd = (MPT_SCSI_HOST *) sh->hostdata; hd = shost_priv(sh);
hd->ioc = ioc; hd->ioc = ioc;
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
if (!hd->ScsiLookup) { if (!ioc->ScsiLookup) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptfc_probe; goto out_mptfc_probe;
} }
spin_lock_init(&ioc->scsi_lookup_lock);
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup)); ioc->name, ioc->ScsiLookup));
/* Clear the TM flags /* Clear the TM flags
*/ */
@ -1262,8 +1321,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sh->transportt = mptfc_transport_template; sh->transportt = mptfc_transport_template;
error = scsi_add_host (sh, &ioc->pcidev->dev); error = scsi_add_host (sh, &ioc->pcidev->dev);
if(error) { if(error) {
dprintk(ioc, printk(KERN_ERR MYNAM dprintk(ioc, printk(MYIOC_s_ERR_FMT
"scsi_add_host failed\n")); "scsi_add_host failed\n", ioc->name));
goto out_mptfc_probe; goto out_mptfc_probe;
} }
@ -1325,7 +1384,7 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
ioc->name, event)); ioc->name, event));
if (ioc->sh == NULL || if (ioc->sh == NULL ||
((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) ((hd = shost_priv(ioc->sh)) == NULL))
return 1; return 1;
switch (event) { switch (event) {
@ -1337,6 +1396,14 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
} }
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
break; break;
case MPI_EVENT_LINK_STATUS_CHANGE:
spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
if (ioc->fc_rescan_work_q) {
queue_work(ioc->fc_rescan_work_q,
&ioc->fc_lsc_work);
}
spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
break;
default: default:
rc = mptscsih_event_process(ioc,pEvReply); rc = mptscsih_event_process(ioc,pEvReply);
break; break;

View file

@ -1,10 +1,10 @@
/* /*
* linux/drivers/message/fusion/mptlan.c * linux/drivers/message/fusion/mptlan.c
* IP Over Fibre Channel device driver. * IP Over Fibre Channel device driver.
* For use with LSI Logic Fibre Channel PCI chip/adapters * For use with LSI Fibre Channel PCI chip/adapters
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 2000-2007 LSI Logic Corporation * Copyright (c) 2000-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -154,7 +154,7 @@ static unsigned short mpt_lan_type_trans(struct sk_buff *skb,
/* /*
* Fusion MPT LAN private data * Fusion MPT LAN private data
*/ */
static int LanCtx = -1; static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS;
static u32 max_buckets_out = 127; static u32 max_buckets_out = 127;
static u32 tx_max_out_p = 127 - 16; static u32 tx_max_out_p = 127 - 16;
@ -164,12 +164,6 @@ static struct NAA_Hosed *mpt_bad_naa = NULL;
DEFINE_RWLOCK(bad_naa_lock); DEFINE_RWLOCK(bad_naa_lock);
#endif #endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Fusion MPT LAN external data
*/
extern int mpt_lan_index;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* lan_reply - Handle all data sent from the hardware. * lan_reply - Handle all data sent from the hardware.
@ -1230,6 +1224,8 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv)
} }
pRecvReq = (LANReceivePostRequest_t *) mf; pRecvReq = (LANReceivePostRequest_t *) mf;
i = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
mpt_dev->RequestNB[i] = 0;
count = buckets; count = buckets;
if (count > max) if (count > max)
count = max; count = max;
@ -1351,10 +1347,11 @@ mpt_lan_post_receive_buckets_work(struct work_struct *work)
static struct net_device * static struct net_device *
mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
{ {
struct net_device *dev = alloc_fcdev(sizeof(struct mpt_lan_priv)); struct net_device *dev;
struct mpt_lan_priv *priv = NULL; struct mpt_lan_priv *priv;
u8 HWaddr[FC_ALEN], *a; u8 HWaddr[FC_ALEN], *a;
dev = alloc_fcdev(sizeof(struct mpt_lan_priv));
if (!dev) if (!dev)
return NULL; return NULL;
@ -1366,7 +1363,6 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
priv->mpt_dev = mpt_dev; priv->mpt_dev = mpt_dev;
priv->pnum = pnum; priv->pnum = pnum;
memset(&priv->post_buckets_task, 0, sizeof(priv->post_buckets_task));
INIT_DELAYED_WORK(&priv->post_buckets_task, INIT_DELAYED_WORK(&priv->post_buckets_task,
mpt_lan_post_receive_buckets_work); mpt_lan_post_receive_buckets_work);
priv->post_buckets_active = 0; priv->post_buckets_active = 0;
@ -1391,8 +1387,6 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
spin_lock_init(&priv->txfidx_lock); spin_lock_init(&priv->txfidx_lock);
spin_lock_init(&priv->rxfidx_lock); spin_lock_init(&priv->rxfidx_lock);
memset(&priv->stats, 0, sizeof(priv->stats));
/* Grab pre-fetched LANPage1 stuff. :-) */ /* Grab pre-fetched LANPage1 stuff. :-) */
a = (u8 *) &mpt_dev->lan_cnfg_page1.HardwareAddressLow; a = (u8 *) &mpt_dev->lan_cnfg_page1.HardwareAddressLow;
@ -1508,9 +1502,6 @@ static int __init mpt_lan_init (void)
return -EBUSY; return -EBUSY;
} }
/* Set the callback index to be used by driver core for turbo replies */
mpt_lan_index = LanCtx;
dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx)); dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset)) { if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset)) {
@ -1531,10 +1522,9 @@ static void __exit mpt_lan_exit(void)
mpt_device_driver_deregister(MPTLAN_DRIVER); mpt_device_driver_deregister(MPTLAN_DRIVER);
mpt_reset_deregister(LanCtx); mpt_reset_deregister(LanCtx);
if (LanCtx >= 0) { if (LanCtx) {
mpt_deregister(LanCtx); mpt_deregister(LanCtx);
LanCtx = -1; LanCtx = MPT_MAX_PROTOCOL_DRIVERS;
mpt_lan_index = 0;
} }
} }

View file

@ -1,10 +1,10 @@
/* /*
* linux/drivers/message/fusion/mptlan.h * linux/drivers/message/fusion/mptlan.h
* IP Over Fibre Channel device driver. * IP Over Fibre Channel device driver.
* For use with LSI Logic Fibre Channel PCI chip/adapters * For use with LSI Fibre Channel PCI chip/adapters
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 2000-2007 LSI Logic Corporation * Copyright (c) 2000-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -75,7 +75,7 @@
#include <asm/io.h> #include <asm/io.h>
/* Override mptbase.h by pre-defining these! */ /* Override mptbase.h by pre-defining these! */
#define MODULEAUTHOR "LSI Logic Corporation" #define MODULEAUTHOR "LSI Corporation"
#include "mptbase.h" #include "mptbase.h"

View file

@ -1,11 +1,10 @@
/* /*
* linux/drivers/message/fusion/mptsas.c * linux/drivers/message/fusion/mptsas.c
* For use with LSI Logic PCI chip/adapter(s) * For use with LSI PCI chip/adapter(s)
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* Copyright (c) 2005-2007 Dell
*/ */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
@ -61,6 +60,7 @@
#include "mptbase.h" #include "mptbase.h"
#include "mptscsih.h" #include "mptscsih.h"
#include "mptsas.h"
#define my_NAME "Fusion MPT SAS Host driver" #define my_NAME "Fusion MPT SAS Host driver"
@ -89,134 +89,35 @@ static int max_lun = MPTSAS_MAX_LUN;
module_param(max_lun, int, 0); module_param(max_lun, int, 0);
MODULE_PARM_DESC(max_lun, " max lun, default=16895 "); MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
static int mptsasDoneCtx = -1; static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptsasTaskCtx = -1; static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptsasInternalCtx = -1; /* Used only for internal commands */ static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
static int mptsasMgmtCtx = -1; static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
static void mptsas_hotplug_work(struct work_struct *work); static void mptsas_hotplug_work(struct work_struct *work);
struct mptsas_target_reset_event {
struct list_head list;
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
u8 target_reset_issued;
};
enum mptsas_hotplug_action {
MPTSAS_ADD_DEVICE,
MPTSAS_DEL_DEVICE,
MPTSAS_ADD_RAID,
MPTSAS_DEL_RAID,
MPTSAS_ADD_INACTIVE_VOLUME,
MPTSAS_IGNORE_EVENT,
};
struct mptsas_hotplug_event {
struct work_struct work;
MPT_ADAPTER *ioc;
enum mptsas_hotplug_action event_type;
u64 sas_address;
u8 channel;
u8 id;
u32 device_info;
u16 handle;
u16 parent_handle;
u8 phy_id;
u8 phys_disk_num_valid; /* hrc (hidden raid component) */
u8 phys_disk_num; /* hrc - unique index*/
u8 hidden_raid_component; /* hrc - don't expose*/
};
struct mptsas_discovery_event {
struct work_struct work;
MPT_ADAPTER *ioc;
};
/*
* SAS topology structures
*
* The MPT Fusion firmware interface spreads information about the
* SAS topology over many manufacture pages, thus we need some data
* structure to collect it and process it for the SAS transport class.
*/
struct mptsas_devinfo {
u16 handle; /* unique id to address this device */
u16 handle_parent; /* unique id to address parent device */
u16 handle_enclosure; /* enclosure identifier of the enclosure */
u16 slot; /* physical slot in enclosure */
u8 phy_id; /* phy number of parent device */
u8 port_id; /* sas physical port this device
is assoc'd with */
u8 id; /* logical target id of this device */
u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
u8 channel; /* logical bus number of this device */
u64 sas_address; /* WWN of this device,
SATA is assigned by HBA,expander */
u32 device_info; /* bitfield detailed info about this device */
};
/*
* Specific details on ports, wide/narrow
*/
struct mptsas_portinfo_details{
u16 num_phys; /* number of phys belong to this port */
u64 phy_bitmask; /* TODO, extend support for 255 phys */
struct sas_rphy *rphy; /* transport layer rphy object */
struct sas_port *port; /* transport layer port object */
struct scsi_target *starget;
struct mptsas_portinfo *port_info;
};
struct mptsas_phyinfo {
u16 handle; /* unique id to address this */
u8 phy_id; /* phy index */
u8 port_id; /* firmware port identifier */
u8 negotiated_link_rate; /* nego'd link rate for this phy */
u8 hw_link_rate; /* hardware max/min phys link rate */
u8 programmed_link_rate; /* programmed max/min phy link rate */
u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/
struct mptsas_devinfo identify; /* point to phy device info */
struct mptsas_devinfo attached; /* point to attached device info */
struct sas_phy *phy; /* transport layer phy object */
struct mptsas_portinfo *portinfo;
struct mptsas_portinfo_details * port_details;
};
struct mptsas_portinfo {
struct list_head list;
u16 num_phys; /* number of phys */
struct mptsas_phyinfo *phy_info;
};
struct mptsas_enclosure {
u64 enclosure_logical_id; /* The WWN for the enclosure */
u16 enclosure_handle; /* unique id to address this */
u16 flags; /* details enclosure management */
u16 num_slot; /* num slots */
u16 start_slot; /* first slot */
u8 start_id; /* starting logical target id */
u8 start_channel; /* starting logical channel id */
u8 sep_id; /* SEP device logical target id */
u8 sep_channel; /* SEP channel logical channel id */
};
static void mptsas_print_phy_data(MPT_ADAPTER *ioc, static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
{ {
dsasprintk(ioc, printk(KERN_DEBUG "---- IO UNIT PAGE 0 ------------\n")); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n", "---- IO UNIT PAGE 0 ------------\n", ioc->name));
le16_to_cpu(phy_data->AttachedDeviceHandle))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Controller Handle=0x%X\n", ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
le16_to_cpu(phy_data->ControllerDevHandle))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Port=0x%X\n", phy_data->Port)); ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
dsasprintk(ioc, printk(KERN_DEBUG "Port Flags=0x%X\n", phy_data->PortFlags)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "PHY Flags=0x%X\n", phy_data->PhyFlags)); ioc->name, phy_data->Port));
dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Controller PHY Device Info=0x%X\n", ioc->name, phy_data->PortFlags));
le32_to_cpu(phy_data->ControllerPhyDeviceInfo))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "DiscoveryStatus=0x%X\n\n", ioc->name, phy_data->PhyFlags));
le32_to_cpu(phy_data->DiscoveryStatus))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
ioc->name, phy_data->NegotiatedLinkRate));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"Controller PHY Device Info=0x%X\n", ioc->name,
le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
} }
static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0) static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
@ -225,27 +126,41 @@ static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 0 ------------\n")); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n", "---- SAS PHY PAGE 0 ------------\n", ioc->name));
le16_to_cpu(pg0->AttachedDevHandle))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", "Attached Device Handle=0x%X\n", ioc->name,
(unsigned long long)le64_to_cpu(sas_address))); le16_to_cpu(pg0->AttachedDevHandle)));
dsasprintk(ioc, printk(KERN_DEBUG "Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Info=0x%X\n", ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
le32_to_cpu(pg0->AttachedDeviceInfo))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate)); "Attached PHY Identifier=0x%X\n", ioc->name,
dsasprintk(ioc, printk(KERN_DEBUG "Change Count=0x%X\n", pg0->ChangeCount)); pg0->AttachedPhyIdentifier));
dsasprintk(ioc, printk(KERN_DEBUG "PHY Info=0x%X\n\n", le32_to_cpu(pg0->PhyInfo))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
ioc->name, pg0->ProgrammedLinkRate));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
ioc->name, pg0->ChangeCount));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
ioc->name, le32_to_cpu(pg0->PhyInfo)));
} }
static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1) static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
{ {
dsasprintk(ioc, printk(KERN_DEBUG "---- SAS PHY PAGE 1 ------------\n")); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Invalid Dword Count=0x%x\n", pg1->InvalidDwordCount)); "---- SAS PHY PAGE 1 ------------\n", ioc->name));
dsasprintk(ioc, printk(KERN_DEBUG "Running Disparity Error Count=0x%x\n", dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
pg1->RunningDisparityErrorCount)); ioc->name, pg1->InvalidDwordCount));
dsasprintk(ioc, printk(KERN_DEBUG "Loss Dword Synch Count=0x%x\n", pg1->LossDwordSynchCount)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "PHY Reset Problem Count=0x%x\n\n", pg1->PhyResetProblemCount)); "Running Disparity Error Count=0x%x\n", ioc->name,
pg1->RunningDisparityErrorCount));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"Loss Dword Synch Count=0x%x\n", ioc->name,
pg1->LossDwordSynchCount));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"PHY Reset Problem Count=0x%x\n\n", ioc->name,
pg1->PhyResetProblemCount));
} }
static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0) static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
@ -254,37 +169,53 @@ static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
dsasprintk(ioc, printk(KERN_DEBUG "---- SAS DEVICE PAGE 0 ---------\n")); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle))); "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
dsasprintk(ioc, printk(KERN_DEBUG "Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle))); ioc->name, le16_to_cpu(pg0->DevHandle)));
dsasprintk(ioc, printk(KERN_DEBUG "Slot=0x%X\n", le16_to_cpu(pg0->Slot))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "SAS Address=0x%llX\n", (unsigned long long) ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
le64_to_cpu(sas_address))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Target ID=0x%X\n", pg0->TargetID)); ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
dsasprintk(ioc, printk(KERN_DEBUG "Bus=0x%X\n", pg0->Bus)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
/* The PhyNum field specifies the PHY number of the parent ioc->name, le16_to_cpu(pg0->Slot)));
* device this device is linked to dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
*/ ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
dsasprintk(ioc, printk(KERN_DEBUG "Parent Phy Num=0x%X\n", pg0->PhyNum)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Access Status=0x%X\n", le16_to_cpu(pg0->AccessStatus))); ioc->name, pg0->TargetID));
dsasprintk(ioc, printk(KERN_DEBUG "Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo))); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Flags=0x%X\n", le16_to_cpu(pg0->Flags))); ioc->name, pg0->Bus));
dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n\n", pg0->PhysicalPort)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
ioc->name, pg0->PhyNum));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
ioc->name, le16_to_cpu(pg0->AccessStatus)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
ioc->name, le32_to_cpu(pg0->DeviceInfo)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
ioc->name, le16_to_cpu(pg0->Flags)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
ioc->name, pg0->PhysicalPort));
} }
static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1) static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
{ {
dsasprintk(ioc, printk(KERN_DEBUG "---- SAS EXPANDER PAGE 1 ------------\n")); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dsasprintk(ioc, printk(KERN_DEBUG "Physical Port=0x%X\n", pg1->PhysicalPort)); "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
dsasprintk(ioc, printk(KERN_DEBUG "PHY Identifier=0x%X\n", pg1->PhyIdentifier)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate)); ioc->name, pg1->PhysicalPort));
dsasprintk(ioc, printk(KERN_DEBUG "Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate)); dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
dsasprintk(ioc, printk(KERN_DEBUG "Hardware Link Rate=0x%X\n", pg1->HwLinkRate)); ioc->name, pg1->PhyIdentifier));
dsasprintk(ioc, printk(KERN_DEBUG "Owner Device Handle=0x%X\n", dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
le16_to_cpu(pg1->OwnerDevHandle))); ioc->name, pg1->NegotiatedLinkRate));
dsasprintk(ioc, printk(KERN_DEBUG "Attached Device Handle=0x%X\n\n", dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
le16_to_cpu(pg1->AttachedDevHandle))); ioc->name, pg1->ProgrammedLinkRate));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
ioc->name, pg1->HwLinkRate));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"Attached Device Handle=0x%X\n\n", ioc->name,
le16_to_cpu(pg1->AttachedDevHandle)));
} }
static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy) static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
@ -354,8 +285,8 @@ mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_detai
port_info = port_details->port_info; port_info = port_details->port_info;
phy_info = port_info->phy_info; phy_info = port_info->phy_info;
dsaswideprintk(ioc, printk(KERN_DEBUG "%s: [%p]: num_phys=%02d " dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
"bitmask=0x%016llX\n", __FUNCTION__, port_details, "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details,
port_details->num_phys, (unsigned long long) port_details->num_phys, (unsigned long long)
port_details->phy_bitmask)); port_details->phy_bitmask));
@ -382,14 +313,15 @@ mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rp
{ {
if (phy_info->port_details) { if (phy_info->port_details) {
phy_info->port_details->rphy = rphy; phy_info->port_details->rphy = rphy;
dsaswideprintk(ioc, printk(KERN_DEBUG "sas_rphy_add: rphy=%p\n", rphy)); dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
ioc->name, rphy));
} }
if (rphy) { if (rphy) {
dsaswideprintk(ioc, dev_printk(KERN_DEBUG, dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
&rphy->dev, "add:")); &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
dsaswideprintk(ioc, printk(KERN_DEBUG "rphy=%p release=%p\n", dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
rphy, rphy->dev.release)); ioc->name, rphy, rphy->dev.release));
} }
} }
@ -410,9 +342,9 @@ mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_po
if (port) { if (port) {
dsaswideprintk(ioc, dev_printk(KERN_DEBUG, dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
&port->dev, "add:")); &port->dev, MYIOC_s_FMT "add:", ioc->name));
dsaswideprintk(ioc, printk(KERN_DEBUG "port=%p release=%p\n", dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
port, port->dev.release)); ioc->name, port, port->dev.release));
} }
} }
@ -463,9 +395,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
* Removing a phy from a port, letting the last * Removing a phy from a port, letting the last
* phy be removed by firmware events. * phy be removed by firmware events.
*/ */
dsaswideprintk(ioc, printk(KERN_DEBUG dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"%s: [%p]: deleting phy = %d\n", "%s: [%p]: deleting phy = %d\n",
__FUNCTION__, port_details, i)); ioc->name, __FUNCTION__, port_details, i));
port_details->num_phys--; port_details->num_phys--;
port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
@ -479,8 +411,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
phy_info = port_info->phy_info; phy_info = port_info->phy_info;
for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
sas_address = phy_info->attached.sas_address; sas_address = phy_info->attached.sas_address;
dsaswideprintk(ioc, printk(KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
i, (unsigned long long)sas_address)); ioc->name, i, (unsigned long long)sas_address));
if (!sas_address) if (!sas_address)
continue; continue;
port_details = phy_info->port_details; port_details = phy_info->port_details;
@ -498,9 +430,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
port_details->phy_bitmask |= port_details->phy_bitmask |=
(1 << phy_info->phy_id); (1 << phy_info->phy_id);
phy_info->sas_port_add_phy=1; phy_info->sas_port_add_phy=1;
dsaswideprintk(ioc, printk(KERN_DEBUG "\t\tForming port\n\t\t" dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
"phy_id=%d sas_address=0x%018llX\n", "phy_id=%d sas_address=0x%018llX\n",
i, (unsigned long long)sas_address)); ioc->name, i, (unsigned long long)sas_address));
phy_info->port_details = port_details; phy_info->port_details = port_details;
} }
@ -515,9 +447,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
continue; continue;
if (phy_info_cmp->port_details == port_details ) if (phy_info_cmp->port_details == port_details )
continue; continue;
dsaswideprintk(ioc, printk(KERN_DEBUG dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"\t\tphy_id=%d sas_address=0x%018llX\n", "\t\tphy_id=%d sas_address=0x%018llX\n",
j, (unsigned long long) ioc->name, j, (unsigned long long)
phy_info_cmp->attached.sas_address)); phy_info_cmp->attached.sas_address));
if (phy_info_cmp->port_details) { if (phy_info_cmp->port_details) {
port_details->rphy = port_details->rphy =
@ -549,15 +481,15 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
port_details = port_info->phy_info[i].port_details; port_details = port_info->phy_info[i].port_details;
if (!port_details) if (!port_details)
continue; continue;
dsaswideprintk(ioc, printk(KERN_DEBUG dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"%s: [%p]: phy_id=%02d num_phys=%02d " "%s: [%p]: phy_id=%02d num_phys=%02d "
"bitmask=0x%016llX\n", __FUNCTION__, "bitmask=0x%016llX\n", ioc->name, __FUNCTION__,
port_details, i, port_details->num_phys, port_details, i, port_details->num_phys,
(unsigned long long)port_details->phy_bitmask)); (unsigned long long)port_details->phy_bitmask));
dsaswideprintk(ioc, printk(KERN_DEBUG"\t\tport = %p rphy=%p\n", dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
port_details->port, port_details->rphy)); ioc->name, port_details->port, port_details->rphy));
} }
dsaswideprintk(ioc, printk(KERN_DEBUG"\n")); dsaswideprintk(ioc, printk("\n"));
mutex_unlock(&ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
} }
@ -573,15 +505,15 @@ static VirtTarget *
mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id) mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
VirtDevice *vdev; VirtDevice *vdevice;
VirtTarget *vtarget = NULL; VirtTarget *vtarget = NULL;
shost_for_each_device(sdev, ioc->sh) { shost_for_each_device(sdev, ioc->sh) {
if ((vdev = sdev->hostdata) == NULL) if ((vdevice = sdev->hostdata) == NULL)
continue; continue;
if (vdev->vtarget->id == id && if (vdevice->vtarget->id == id &&
vdev->vtarget->channel == channel) vdevice->vtarget->channel == channel)
vtarget = vdev->vtarget; vtarget = vdevice->vtarget;
} }
return vtarget; return vtarget;
} }
@ -623,13 +555,7 @@ mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf); DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
if (mpt_send_handshake_request(ioc->TaskCtx, ioc, mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) {
mpt_free_msg_frame(ioc, mf);
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n",
ioc->name,__FUNCTION__, __LINE__));
return 0;
}
return 1; return 1;
} }
@ -649,7 +575,7 @@ static void
mptsas_target_reset_queue(MPT_ADAPTER *ioc, mptsas_target_reset_queue(MPT_ADAPTER *ioc,
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data) EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
{ {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
VirtTarget *vtarget = NULL; VirtTarget *vtarget = NULL;
struct mptsas_target_reset_event *target_reset_list; struct mptsas_target_reset_event *target_reset_list;
u8 id, channel; u8 id, channel;
@ -696,7 +622,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc,
static void static void
mptsas_dev_reset_complete(MPT_ADAPTER *ioc) mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
{ {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
struct list_head *head = &hd->target_reset_list; struct list_head *head = &hd->target_reset_list;
struct mptsas_target_reset_event *target_reset_list; struct mptsas_target_reset_event *target_reset_list;
struct mptsas_hotplug_event *ev; struct mptsas_hotplug_event *ev;
@ -813,7 +739,7 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
if (!ioc->sh || !ioc->sh->hostdata) if (!ioc->sh || !ioc->sh->hostdata)
goto out; goto out;
hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; hd = shost_priv(ioc->sh);
if (!hd->ioc) if (!hd->ioc)
goto out; goto out;
@ -913,19 +839,20 @@ static int
mptsas_target_alloc(struct scsi_target *starget) mptsas_target_alloc(struct scsi_target *starget)
{ {
struct Scsi_Host *host = dev_to_shost(&starget->dev); struct Scsi_Host *host = dev_to_shost(&starget->dev);
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; MPT_SCSI_HOST *hd = shost_priv(host);
VirtTarget *vtarget; VirtTarget *vtarget;
u8 id, channel; u8 id, channel;
struct sas_rphy *rphy; struct sas_rphy *rphy;
struct mptsas_portinfo *p; struct mptsas_portinfo *p;
int i; int i;
MPT_ADAPTER *ioc = hd->ioc;
vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
if (!vtarget) if (!vtarget)
return -ENOMEM; return -ENOMEM;
vtarget->starget = starget; vtarget->starget = starget;
vtarget->ioc_id = hd->ioc->id; vtarget->ioc_id = ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
id = starget->id; id = starget->id;
channel = 0; channel = 0;
@ -934,15 +861,15 @@ mptsas_target_alloc(struct scsi_target *starget)
* RAID volumes placed beyond the last expected port. * RAID volumes placed beyond the last expected port.
*/ */
if (starget->channel == MPTSAS_RAID_CHANNEL) { if (starget->channel == MPTSAS_RAID_CHANNEL) {
for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
goto out; goto out;
} }
rphy = dev_to_rphy(starget->dev.parent); rphy = dev_to_rphy(starget->dev.parent);
mutex_lock(&hd->ioc->sas_topology_mutex); mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(p, &hd->ioc->sas_topology, list) { list_for_each_entry(p, &ioc->sas_topology, list) {
for (i = 0; i < p->num_phys; i++) { for (i = 0; i < p->num_phys; i++) {
if (p->phy_info[i].attached.sas_address != if (p->phy_info[i].attached.sas_address !=
rphy->identify.sas_address) rphy->identify.sas_address)
@ -954,18 +881,18 @@ mptsas_target_alloc(struct scsi_target *starget)
/* /*
* Exposing hidden raid components * Exposing hidden raid components
*/ */
if (mptscsih_is_phys_disk(hd->ioc, channel, id)) { if (mptscsih_is_phys_disk(ioc, channel, id)) {
id = mptscsih_raid_id_to_num(hd->ioc, id = mptscsih_raid_id_to_num(ioc,
channel, id); channel, id);
vtarget->tflags |= vtarget->tflags |=
MPT_TARGET_FLAGS_RAID_COMPONENT; MPT_TARGET_FLAGS_RAID_COMPONENT;
p->phy_info[i].attached.phys_disk_num = id; p->phy_info[i].attached.phys_disk_num = id;
} }
mutex_unlock(&hd->ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
goto out; goto out;
} }
} }
mutex_unlock(&hd->ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
kfree(vtarget); kfree(vtarget);
return -ENXIO; return -ENXIO;
@ -981,10 +908,11 @@ static void
mptsas_target_destroy(struct scsi_target *starget) mptsas_target_destroy(struct scsi_target *starget)
{ {
struct Scsi_Host *host = dev_to_shost(&starget->dev); struct Scsi_Host *host = dev_to_shost(&starget->dev);
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; MPT_SCSI_HOST *hd = shost_priv(host);
struct sas_rphy *rphy; struct sas_rphy *rphy;
struct mptsas_portinfo *p; struct mptsas_portinfo *p;
int i; int i;
MPT_ADAPTER *ioc = hd->ioc;
if (!starget->hostdata) if (!starget->hostdata)
return; return;
@ -993,7 +921,7 @@ mptsas_target_destroy(struct scsi_target *starget)
goto out; goto out;
rphy = dev_to_rphy(starget->dev.parent); rphy = dev_to_rphy(starget->dev.parent);
list_for_each_entry(p, &hd->ioc->sas_topology, list) { list_for_each_entry(p, &ioc->sas_topology, list) {
for (i = 0; i < p->num_phys; i++) { for (i = 0; i < p->num_phys; i++) {
if (p->phy_info[i].attached.sas_address != if (p->phy_info[i].attached.sas_address !=
rphy->identify.sas_address) rphy->identify.sas_address)
@ -1013,61 +941,62 @@ static int
mptsas_slave_alloc(struct scsi_device *sdev) mptsas_slave_alloc(struct scsi_device *sdev)
{ {
struct Scsi_Host *host = sdev->host; struct Scsi_Host *host = sdev->host;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; MPT_SCSI_HOST *hd = shost_priv(host);
struct sas_rphy *rphy; struct sas_rphy *rphy;
struct mptsas_portinfo *p; struct mptsas_portinfo *p;
VirtDevice *vdev; VirtDevice *vdevice;
struct scsi_target *starget; struct scsi_target *starget;
int i; int i;
MPT_ADAPTER *ioc = hd->ioc;
vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdevice) {
printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n", printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice)); ioc->name, sizeof(VirtDevice));
return -ENOMEM; return -ENOMEM;
} }
starget = scsi_target(sdev); starget = scsi_target(sdev);
vdev->vtarget = starget->hostdata; vdevice->vtarget = starget->hostdata;
if (sdev->channel == MPTSAS_RAID_CHANNEL) if (sdev->channel == MPTSAS_RAID_CHANNEL)
goto out; goto out;
rphy = dev_to_rphy(sdev->sdev_target->dev.parent); rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
mutex_lock(&hd->ioc->sas_topology_mutex); mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(p, &hd->ioc->sas_topology, list) { list_for_each_entry(p, &ioc->sas_topology, list) {
for (i = 0; i < p->num_phys; i++) { for (i = 0; i < p->num_phys; i++) {
if (p->phy_info[i].attached.sas_address != if (p->phy_info[i].attached.sas_address !=
rphy->identify.sas_address) rphy->identify.sas_address)
continue; continue;
vdev->lun = sdev->lun; vdevice->lun = sdev->lun;
/* /*
* Exposing hidden raid components * Exposing hidden raid components
*/ */
if (mptscsih_is_phys_disk(hd->ioc, if (mptscsih_is_phys_disk(ioc,
p->phy_info[i].attached.channel, p->phy_info[i].attached.channel,
p->phy_info[i].attached.id)) p->phy_info[i].attached.id))
sdev->no_uld_attach = 1; sdev->no_uld_attach = 1;
mutex_unlock(&hd->ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
goto out; goto out;
} }
} }
mutex_unlock(&hd->ioc->sas_topology_mutex); mutex_unlock(&ioc->sas_topology_mutex);
kfree(vdev); kfree(vdevice);
return -ENXIO; return -ENXIO;
out: out:
vdev->vtarget->num_luns++; vdevice->vtarget->num_luns++;
sdev->hostdata = vdev; sdev->hostdata = vdevice;
return 0; return 0;
} }
static int static int
mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{ {
VirtDevice *vdev = SCpnt->device->hostdata; VirtDevice *vdevice = SCpnt->device->hostdata;
if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) { if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
SCpnt->result = DID_NO_CONNECT << 16; SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt); done(SCpnt);
return 0; return 0;
@ -1239,10 +1168,8 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
/* process the completed Reply Message Frame */ /* process the completed Reply Message Frame */
reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
__FUNCTION__, ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo);
reply->IOCStatus,
reply->IOCLogInfo);
error = -ENXIO; error = -ENXIO;
goto out_unlock; goto out_unlock;
} }
@ -1328,16 +1255,16 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
u64 sas_address = 0; u64 sas_address = 0;
if (!rsp) { if (!rsp) {
printk(KERN_ERR "%s: the smp response space is missing\n", printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
__FUNCTION__); ioc->name, __FUNCTION__);
return -EINVAL; return -EINVAL;
} }
/* do we need to support multiple segments? */ /* do we need to support multiple segments? */
if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n", printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
__FUNCTION__, req->bio->bi_vcnt, req->data_len, ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len,
rsp->bio->bi_vcnt, rsp->data_len); rsp->bio->bi_vcnt, rsp->data_len);
return -EINVAL; return -EINVAL;
} }
@ -1402,7 +1329,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
if (!timeleft) { if (!timeleft) {
printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__); printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__);
/* On timeout reset the board */ /* On timeout reset the board */
mpt_HardResetHandler(ioc, CAN_SLEEP); mpt_HardResetHandler(ioc, CAN_SLEEP);
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
@ -1417,8 +1344,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
memcpy(req->sense, smprep, sizeof(*smprep)); memcpy(req->sense, smprep, sizeof(*smprep));
req->sense_len = sizeof(*smprep); req->sense_len = sizeof(*smprep);
} else { } else {
printk(KERN_ERR "%s: smp passthru reply failed to be returned\n", printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
__FUNCTION__); ioc->name, __FUNCTION__);
ret = -ENXIO; ret = -ENXIO;
} }
unmap: unmap:
@ -2062,12 +1989,12 @@ static int mptsas_probe_one_phy(struct device *dev,
goto out; goto out;
} }
mptsas_set_port(ioc, phy_info, port); mptsas_set_port(ioc, phy_info, port);
dsaswideprintk(ioc, printk(KERN_DEBUG dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"sas_port_alloc: port=%p dev=%p port_id=%d\n", "sas_port_alloc: port=%p dev=%p port_id=%d\n",
port, dev, port->port_identifier)); ioc->name, port, dev, port->port_identifier));
} }
dsaswideprintk(ioc, printk(KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
phy_info->phy_id)); ioc->name, phy_info->phy_id));
sas_port_add_phy(port, phy_info->phy); sas_port_add_phy(port, phy_info->phy);
phy_info->sas_port_add_phy = 0; phy_info->sas_port_add_phy = 0;
} }
@ -2369,8 +2296,9 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
expander_sas_address) expander_sas_address)
continue; continue;
dsaswideprintk(ioc, dsaswideprintk(ioc,
dev_printk(KERN_DEBUG, &port->dev, dev_printk(KERN_DEBUG, &port->dev,
"delete port (%d)\n", port->port_identifier)); MYIOC_s_FMT "delete port (%d)\n", ioc->name,
port->port_identifier));
sas_port_delete(port); sas_port_delete(port);
mptsas_port_delete(ioc, phy_info->port_details); mptsas_port_delete(ioc, phy_info->port_details);
} }
@ -2613,7 +2541,7 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
ev = kzalloc(sizeof(*ev), GFP_ATOMIC); ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) { if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n"); printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
goto out; goto out;
} }
@ -2754,8 +2682,8 @@ mptsas_hotplug_work(struct work_struct *work)
printk(MYIOC_s_INFO_FMT printk(MYIOC_s_INFO_FMT
"removing %s device, channel %d, id %d, phy %d\n", "removing %s device, channel %d, id %d, phy %d\n",
ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
dev_printk(KERN_DEBUG, &port->dev, dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
"delete port (%d)\n", port->port_identifier); "delete port (%d)\n", ioc->name, port->port_identifier);
sas_port_delete(port); sas_port_delete(port);
mptsas_port_delete(ioc, phy_info->port_details); mptsas_port_delete(ioc, phy_info->port_details);
break; break;
@ -2796,8 +2724,8 @@ mptsas_hotplug_work(struct work_struct *work)
if (!vtarget) { if (!vtarget) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name, "%s: exit at line=%d\n", ioc->name,
__FUNCTION__, __LINE__)); __FUNCTION__, __LINE__));
break; break;
} }
/* /*
@ -2930,7 +2858,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
ev = kzalloc(sizeof(*ev), GFP_ATOMIC); ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) { if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n"); printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
break; break;
} }
@ -2989,7 +2917,7 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc,
ev = kzalloc(sizeof(*ev), GFP_ATOMIC); ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) { if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n"); printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
return; return;
} }
@ -3288,20 +3216,22 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sh->sg_tablesize = numSGE; sh->sg_tablesize = numSGE;
} }
hd = (MPT_SCSI_HOST *) sh->hostdata; hd = shost_priv(sh);
hd->ioc = ioc; hd->ioc = ioc;
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
if (!hd->ScsiLookup) { if (!ioc->ScsiLookup) {
error = -ENOMEM; error = -ENOMEM;
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
goto out_mptsas_probe; goto out_mptsas_probe;
} }
spin_lock_init(&ioc->scsi_lookup_lock);
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup)); ioc->name, ioc->ScsiLookup));
/* Clear the TM flags /* Clear the TM flags
*/ */
@ -3340,8 +3270,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
error = scsi_add_host(sh, &ioc->pcidev->dev); error = scsi_add_host(sh, &ioc->pcidev->dev);
if (error) { if (error) {
dprintk(ioc, printk(KERN_ERR MYNAM dprintk(ioc, printk(MYIOC_s_ERR_FMT
"scsi_add_host failed\n")); "scsi_add_host failed\n", ioc->name));
goto out_mptsas_probe; goto out_mptsas_probe;
} }

View file

@ -0,0 +1,158 @@
/*
* linux/drivers/message/fusion/mptsas.h
* High performance SCSI + LAN / Fibre Channel device drivers.
* For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel
* running LSI MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
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.
NO WARRANTY
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
solely responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, damage to or loss of data,
programs or equipment, and unavailability or interruption of operations.
DISCLAIMER OF LIABILITY
NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MPTSAS_H_INCLUDED
#define MPTSAS_H_INCLUDED
/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
struct mptsas_target_reset_event {
struct list_head list;
EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
u8 target_reset_issued;
};
enum mptsas_hotplug_action {
MPTSAS_ADD_DEVICE,
MPTSAS_DEL_DEVICE,
MPTSAS_ADD_RAID,
MPTSAS_DEL_RAID,
MPTSAS_ADD_INACTIVE_VOLUME,
MPTSAS_IGNORE_EVENT,
};
struct mptsas_hotplug_event {
struct work_struct work;
MPT_ADAPTER *ioc;
enum mptsas_hotplug_action event_type;
u64 sas_address;
u8 channel;
u8 id;
u32 device_info;
u16 handle;
u16 parent_handle;
u8 phy_id;
u8 phys_disk_num_valid; /* hrc (hidden raid component) */
u8 phys_disk_num; /* hrc - unique index*/
u8 hidden_raid_component; /* hrc - don't expose*/
};
struct mptsas_discovery_event {
struct work_struct work;
MPT_ADAPTER *ioc;
};
/*
* SAS topology structures
*
* The MPT Fusion firmware interface spreads information about the
* SAS topology over many manufacture pages, thus we need some data
* structure to collect it and process it for the SAS transport class.
*/
struct mptsas_devinfo {
u16 handle; /* unique id to address this device */
u16 handle_parent; /* unique id to address parent device */
u16 handle_enclosure; /* enclosure identifier of the enclosure */
u16 slot; /* physical slot in enclosure */
u8 phy_id; /* phy number of parent device */
u8 port_id; /* sas physical port this device
is assoc'd with */
u8 id; /* logical target id of this device */
u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
u8 channel; /* logical bus number of this device */
u64 sas_address; /* WWN of this device,
SATA is assigned by HBA,expander */
u32 device_info; /* bitfield detailed info about this device */
};
/*
* Specific details on ports, wide/narrow
*/
struct mptsas_portinfo_details{
u16 num_phys; /* number of phys belong to this port */
u64 phy_bitmask; /* TODO, extend support for 255 phys */
struct sas_rphy *rphy; /* transport layer rphy object */
struct sas_port *port; /* transport layer port object */
struct scsi_target *starget;
struct mptsas_portinfo *port_info;
};
struct mptsas_phyinfo {
u16 handle; /* unique id to address this */
u8 phy_id; /* phy index */
u8 port_id; /* firmware port identifier */
u8 negotiated_link_rate; /* nego'd link rate for this phy */
u8 hw_link_rate; /* hardware max/min phys link rate */
u8 programmed_link_rate; /* programmed max/min phy link rate */
u8 sas_port_add_phy; /* flag to request sas_port_add_phy*/
struct mptsas_devinfo identify; /* point to phy device info */
struct mptsas_devinfo attached; /* point to attached device info */
struct sas_phy *phy; /* transport layer phy object */
struct mptsas_portinfo *portinfo;
struct mptsas_portinfo_details * port_details;
};
struct mptsas_portinfo {
struct list_head list;
u16 num_phys; /* number of phys */
struct mptsas_phyinfo *phy_info;
};
struct mptsas_enclosure {
u64 enclosure_logical_id; /* The WWN for the enclosure */
u16 enclosure_handle; /* unique id to address this */
u16 flags; /* details enclosure management */
u16 num_slot; /* num slots */
u16 start_slot; /* first slot */
u8 start_id; /* starting logical target id */
u8 start_channel; /* starting logical channel id */
u8 sep_id; /* SEP device logical target id */
u8 sep_channel; /* SEP channel logical channel id */
};
/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif

File diff suppressed because it is too large Load diff

View file

@ -3,9 +3,9 @@
* High performance SCSI / Fibre Channel SCSI Host device driver. * High performance SCSI / Fibre Channel SCSI Host device driver.
* For use with PCI chip/adapter(s): * For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel * LSIFC9xx/LSI409xx Fibre Channel
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */

View file

@ -1,9 +1,9 @@
/* /*
* linux/drivers/message/fusion/mptspi.c * linux/drivers/message/fusion/mptspi.c
* For use with LSI Logic PCI chip/adapter(s) * For use with LSI PCI chip/adapter(s)
* running LSI Logic Fusion MPT (Message Passing Technology) firmware. * running LSI Fusion MPT (Message Passing Technology) firmware.
* *
* Copyright (c) 1999-2007 LSI Logic Corporation * Copyright (c) 1999-2007 LSI Corporation
* (mailto:DL-MPTFusionLinux@lsi.com) * (mailto:DL-MPTFusionLinux@lsi.com)
* *
*/ */
@ -90,9 +90,9 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *,
static struct scsi_transport_template *mptspi_transport_template = NULL; static struct scsi_transport_template *mptspi_transport_template = NULL;
static int mptspiDoneCtx = -1; static u8 mptspiDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptspiTaskCtx = -1; static u8 mptspiTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
static int mptspiInternalCtx = -1; /* Used only for internal commands */ static u8 mptspiInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
/** /**
* mptspi_setTargetNegoParms - Update the target negotiation parameters * mptspi_setTargetNegoParms - Update the target negotiation parameters
@ -107,7 +107,8 @@ static void
mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
struct scsi_device *sdev) struct scsi_device *sdev)
{ {
SpiCfgData *pspi_data = &hd->ioc->spi_data; MPT_ADAPTER *ioc = hd->ioc;
SpiCfgData *pspi_data = &ioc->spi_data;
int id = (int) target->id; int id = (int) target->id;
int nvram; int nvram;
u8 width = MPT_NARROW; u8 width = MPT_NARROW;
@ -138,9 +139,10 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
else { else {
factor = MPT_ULTRA320; factor = MPT_ULTRA320;
if (scsi_device_qas(sdev)) { if (scsi_device_qas(sdev)) {
ddvprintk(hd->ioc, ddvprintk(ioc,
printk(KERN_DEBUG "Enabling QAS due to " printk(MYIOC_s_DEBUG_FMT "Enabling QAS due to "
"byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); "byte56=%02x on id=%d!\n", ioc->name,
scsi_device_qas(sdev), id));
noQas = 0; noQas = 0;
} }
if (sdev->type == TYPE_TAPE && if (sdev->type == TYPE_TAPE &&
@ -227,8 +229,8 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
/* Disable QAS in a mixed configuration case /* Disable QAS in a mixed configuration case
*/ */
ddvprintk(hd->ioc, printk(KERN_DEBUG ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); "Disabling QAS due to noQas=%02x on id=%d!\n", ioc->name, noQas, id));
} }
} }
@ -302,7 +304,7 @@ mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel)); ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel));
mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
@ -374,14 +376,15 @@ static int
mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id) mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
{ {
int i, rc = 0; int i, rc = 0;
MPT_ADAPTER *ioc = hd->ioc;
if (!hd->ioc->raid_data.pIocPg2) if (!ioc->raid_data.pIocPg2)
goto out; goto out;
if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes) if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
goto out; goto out;
for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) { if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) {
rc = 1; rc = 1;
goto out; goto out;
} }
@ -394,17 +397,19 @@ mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
static int mptspi_target_alloc(struct scsi_target *starget) static int mptspi_target_alloc(struct scsi_target *starget)
{ {
struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(shost);
VirtTarget *vtarget; VirtTarget *vtarget;
MPT_ADAPTER *ioc;
if (hd == NULL) if (hd == NULL)
return -ENODEV; return -ENODEV;
ioc = hd->ioc;
vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
if (!vtarget) if (!vtarget)
return -ENOMEM; return -ENOMEM;
vtarget->ioc_id = hd->ioc->id; vtarget->ioc_id = ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
vtarget->id = (u8)starget->id; vtarget->id = (u8)starget->id;
vtarget->channel = (u8)starget->channel; vtarget->channel = (u8)starget->channel;
@ -412,34 +417,34 @@ static int mptspi_target_alloc(struct scsi_target *starget)
starget->hostdata = vtarget; starget->hostdata = vtarget;
if (starget->channel == 1) { if (starget->channel == 1) {
if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0) if (mptscsih_is_phys_disk(ioc, 0, starget->id) == 0)
return 0; return 0;
vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
/* The real channel for this device is zero */ /* The real channel for this device is zero */
vtarget->channel = 0; vtarget->channel = 0;
/* The actual physdisknum (for RAID passthrough) */ /* The actual physdisknum (for RAID passthrough) */
vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0, vtarget->id = mptscsih_raid_id_to_num(ioc, 0,
starget->id); starget->id);
} }
if (starget->channel == 0 && if (starget->channel == 0 &&
mptspi_is_raid(hd, starget->id)) { mptspi_is_raid(hd, starget->id)) {
vtarget->raidVolume = 1; vtarget->raidVolume = 1;
ddvprintk(hd->ioc, printk(KERN_DEBUG ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"RAID Volume @ channel=%d id=%d\n", starget->channel, "RAID Volume @ channel=%d id=%d\n", ioc->name, starget->channel,
starget->id)); starget->id));
} }
if (hd->ioc->spi_data.nvram && if (ioc->spi_data.nvram &&
hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) { ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
u32 nvram = hd->ioc->spi_data.nvram[starget->id]; u32 nvram = ioc->spi_data.nvram[starget->id];
spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
} else { } else {
spi_min_period(starget) = hd->ioc->spi_data.minSyncFactor; spi_min_period(starget) = ioc->spi_data.minSyncFactor;
spi_max_width(starget) = hd->ioc->spi_data.maxBusWidth; spi_max_width(starget) = ioc->spi_data.maxBusWidth;
} }
spi_max_offset(starget) = hd->ioc->spi_data.maxSyncOffset; spi_max_offset(starget) = ioc->spi_data.maxSyncOffset;
spi_offset(starget) = 0; spi_offset(starget) = 0;
mptspi_write_width(starget, 0); mptspi_write_width(starget, 0);
@ -509,10 +514,10 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0) struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
{ {
struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(shost);
struct _MPT_ADAPTER *ioc = hd->ioc; struct _MPT_ADAPTER *ioc = hd->ioc;
struct _CONFIG_PAGE_SCSI_DEVICE_0 *pg0; struct _CONFIG_PAGE_SCSI_DEVICE_0 *spi_dev_pg0;
dma_addr_t pg0_dma; dma_addr_t spi_dev_pg0_dma;
int size; int size;
struct _x_config_parms cfg; struct _x_config_parms cfg;
struct _CONFIG_PAGE_HEADER hdr; struct _CONFIG_PAGE_HEADER hdr;
@ -530,9 +535,10 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
size += 2048; size += 2048;
*/ */
pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg0_dma, GFP_KERNEL); spi_dev_pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &spi_dev_pg0_dma, GFP_KERNEL);
if (pg0 == NULL) { if (spi_dev_pg0 == NULL) {
starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); starget_printk(KERN_ERR, starget, MYIOC_s_FMT
"dma_alloc_coherent for parameters failed\n", ioc->name);
return -EINVAL; return -EINVAL;
} }
@ -546,22 +552,22 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.cfghdr.hdr = &hdr; cfg.cfghdr.hdr = &hdr;
cfg.physAddr = pg0_dma; cfg.physAddr = spi_dev_pg0_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0; cfg.dir = 0;
cfg.pageAddr = starget->id; cfg.pageAddr = starget->id;
if (mpt_config(ioc, &cfg)) { if (mpt_config(ioc, &cfg)) {
starget_printk(KERN_ERR, starget, "mpt_config failed\n"); starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name);
goto out_free; goto out_free;
} }
err = 0; err = 0;
memcpy(pass_pg0, pg0, size); memcpy(pass_pg0, spi_dev_pg0, size);
mptspi_print_read_nego(hd, starget, le32_to_cpu(pg0->NegotiatedParameters)); mptspi_print_read_nego(hd, starget, le32_to_cpu(spi_dev_pg0->NegotiatedParameters));
out_free: out_free:
dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma); dma_free_coherent(&ioc->pcidev->dev, size, spi_dev_pg0, spi_dev_pg0_dma);
return err; return err;
} }
@ -588,11 +594,11 @@ static u32 mptspi_getRP(struct scsi_target *starget)
static void mptspi_read_parameters(struct scsi_target *starget) static void mptspi_read_parameters(struct scsi_target *starget)
{ {
int nego; int nego;
struct _CONFIG_PAGE_SCSI_DEVICE_0 pg0; struct _CONFIG_PAGE_SCSI_DEVICE_0 spi_dev_pg0;
mptspi_read_spi_device_pg0(starget, &pg0); mptspi_read_spi_device_pg0(starget, &spi_dev_pg0);
nego = le32_to_cpu(pg0.NegotiatedParameters); nego = le32_to_cpu(spi_dev_pg0.NegotiatedParameters);
spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0; spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0;
spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0; spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0;
@ -612,12 +618,13 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
{ {
MpiRaidActionRequest_t *pReq; MpiRaidActionRequest_t *pReq;
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
MPT_ADAPTER *ioc = hd->ioc;
/* Get and Populate a free Frame /* Get and Populate a free Frame
*/ */
if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
ddvprintk(hd->ioc, printk(MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", ddvprintk(ioc, printk(MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
hd->ioc->name)); ioc->name));
return -EAGAIN; return -EAGAIN;
} }
pReq = (MpiRaidActionRequest_t *)mf; pReq = (MpiRaidActionRequest_t *)mf;
@ -638,8 +645,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
mpt_add_sge((char *)&pReq->ActionDataSGE, mpt_add_sge((char *)&pReq->ActionDataSGE,
MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n", ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
hd->ioc->name, pReq->Action, channel, id)); ioc->name, pReq->Action, channel, id));
hd->pLocal = NULL; hd->pLocal = NULL;
hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
@ -651,7 +658,7 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
hd->cmdPtr = mf; hd->cmdPtr = mf;
add_timer(&hd->timer); add_timer(&hd->timer);
mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
wait_event(hd->scandv_waitq, hd->scandv_wait_done); wait_event(hd->scandv_waitq, hd->scandv_wait_done);
if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0)) if ((hd->pLocal == NULL) || (hd->pLocal->completion != 0))
@ -664,6 +671,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
struct scsi_device *sdev) struct scsi_device *sdev)
{ {
VirtTarget *vtarget = scsi_target(sdev)->hostdata; VirtTarget *vtarget = scsi_target(sdev)->hostdata;
MPT_ADAPTER *ioc = hd->ioc;
/* no DV on RAID devices */ /* no DV on RAID devices */
if (sdev->channel == 0 && if (sdev->channel == 0 &&
@ -673,8 +681,8 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
/* If this is a piece of a RAID, then quiesce first */ /* If this is a piece of a RAID, then quiesce first */
if (sdev->channel == 1 && if (sdev->channel == 1 &&
mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) { mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) {
starget_printk(KERN_ERR, scsi_target(sdev), starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT
"Integrated RAID quiesce failed\n"); "Integrated RAID quiesce failed\n", ioc->name);
return; return;
} }
@ -684,8 +692,8 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
if (sdev->channel == 1 && if (sdev->channel == 1 &&
mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
starget_printk(KERN_ERR, scsi_target(sdev), starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT
"Integrated RAID resume failed\n"); "Integrated RAID resume failed\n", ioc->name);
mptspi_read_parameters(sdev->sdev_target); mptspi_read_parameters(sdev->sdev_target);
spi_display_xfer_agreement(sdev->sdev_target); spi_display_xfer_agreement(sdev->sdev_target);
@ -694,28 +702,29 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
static int mptspi_slave_alloc(struct scsi_device *sdev) static int mptspi_slave_alloc(struct scsi_device *sdev)
{ {
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; MPT_SCSI_HOST *hd = shost_priv(sdev->host);
VirtTarget *vtarget; VirtTarget *vtarget;
VirtDevice *vdev; VirtDevice *vdevice;
struct scsi_target *starget; struct scsi_target *starget;
MPT_ADAPTER *ioc = hd->ioc;
if (sdev->channel == 1 && if (sdev->channel == 1 &&
mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0) mptscsih_is_phys_disk(ioc, 0, sdev->id) == 0)
return -ENXIO; return -ENXIO;
vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
if (!vdev) { if (!vdevice) {
printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
hd->ioc->name, sizeof(VirtDevice)); ioc->name, sizeof(VirtDevice));
return -ENOMEM; return -ENOMEM;
} }
vdev->lun = sdev->lun; vdevice->lun = sdev->lun;
sdev->hostdata = vdev; sdev->hostdata = vdevice;
starget = scsi_target(sdev); starget = scsi_target(sdev);
vtarget = starget->hostdata; vtarget = starget->hostdata;
vdev->vtarget = vtarget; vdevice->vtarget = vtarget;
vtarget->num_luns++; vtarget->num_luns++;
if (sdev->channel == 1) if (sdev->channel == 1)
@ -726,8 +735,7 @@ static int mptspi_slave_alloc(struct scsi_device *sdev)
static int mptspi_slave_configure(struct scsi_device *sdev) static int mptspi_slave_configure(struct scsi_device *sdev)
{ {
struct _MPT_SCSI_HOST *hd = struct _MPT_SCSI_HOST *hd = shost_priv(sdev->host);
(struct _MPT_SCSI_HOST *)sdev->host->hostdata;
VirtTarget *vtarget = scsi_target(sdev)->hostdata; VirtTarget *vtarget = scsi_target(sdev)->hostdata;
int ret; int ret;
@ -755,24 +763,25 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
static int static int
mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{ {
struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
VirtDevice *vdev = SCpnt->device->hostdata; VirtDevice *vdevice = SCpnt->device->hostdata;
MPT_ADAPTER *ioc = hd->ioc;
if (!vdev || !vdev->vtarget) { if (!vdevice || !vdevice->vtarget) {
SCpnt->result = DID_NO_CONNECT << 16; SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt); done(SCpnt);
return 0; return 0;
} }
if (SCpnt->device->channel == 1 && if (SCpnt->device->channel == 1 &&
mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) { mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) {
SCpnt->result = DID_NO_CONNECT << 16; SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt); done(SCpnt);
return 0; return 0;
} }
if (spi_dv_pending(scsi_target(SCpnt->device))) if (spi_dv_pending(scsi_target(SCpnt->device)))
ddvprintk(hd->ioc, scsi_print_command(SCpnt)); ddvprintk(ioc, scsi_print_command(SCpnt));
return mptscsih_qcmd(SCpnt,done); return mptscsih_qcmd(SCpnt,done);
} }
@ -829,7 +838,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1) struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
{ {
struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(shost);
struct _MPT_ADAPTER *ioc = hd->ioc; struct _MPT_ADAPTER *ioc = hd->ioc;
struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1; struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
dma_addr_t pg1_dma; dma_addr_t pg1_dma;
@ -847,7 +856,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL); pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
if (pg1 == NULL) { if (pg1 == NULL) {
starget_printk(KERN_ERR, starget, "dma_alloc_coherent for parameters failed\n"); starget_printk(KERN_ERR, starget, MYIOC_s_FMT
"dma_alloc_coherent for parameters failed\n", ioc->name);
return -EINVAL; return -EINVAL;
} }
@ -876,7 +886,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters)); mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));
if (mpt_config(ioc, &cfg)) { if (mpt_config(ioc, &cfg)) {
starget_printk(KERN_ERR, starget, "mpt_config failed\n"); starget_printk(KERN_ERR, starget, MYIOC_s_FMT
"mpt_config failed\n", ioc->name);
goto out_free; goto out_free;
} }
err = 0; err = 0;
@ -1015,7 +1026,7 @@ static void mptspi_write_qas(struct scsi_target *starget, int qas)
{ {
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
struct Scsi_Host *shost = dev_to_shost(&starget->dev); struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(shost);
VirtTarget *vtarget = starget->hostdata; VirtTarget *vtarget = starget->hostdata;
u32 nego; u32 nego;
@ -1067,15 +1078,16 @@ static void mpt_work_wrapper(struct work_struct *work)
struct work_queue_wrapper *wqw = struct work_queue_wrapper *wqw =
container_of(work, struct work_queue_wrapper, work); container_of(work, struct work_queue_wrapper, work);
struct _MPT_SCSI_HOST *hd = wqw->hd; struct _MPT_SCSI_HOST *hd = wqw->hd;
struct Scsi_Host *shost = hd->ioc->sh; MPT_ADAPTER *ioc = hd->ioc;
struct Scsi_Host *shost = ioc->sh;
struct scsi_device *sdev; struct scsi_device *sdev;
int disk = wqw->disk; int disk = wqw->disk;
struct _CONFIG_PAGE_IOC_3 *pg3; struct _CONFIG_PAGE_IOC_3 *pg3;
kfree(wqw); kfree(wqw);
mpt_findImVolumes(hd->ioc); mpt_findImVolumes(ioc);
pg3 = hd->ioc->raid_data.pIocPg3; pg3 = ioc->raid_data.pIocPg3;
if (!pg3) if (!pg3)
return; return;
@ -1092,24 +1104,25 @@ static void mpt_work_wrapper(struct work_struct *work)
if(vtarget->id != disk) if(vtarget->id != disk)
continue; continue;
starget_printk(KERN_INFO, vtarget->starget, starget_printk(KERN_INFO, vtarget->starget, MYIOC_s_FMT
"Integrated RAID requests DV of new device\n"); "Integrated RAID requests DV of new device\n", ioc->name);
mptspi_dv_device(hd, sdev); mptspi_dv_device(hd, sdev);
} }
shost_printk(KERN_INFO, shost, shost_printk(KERN_INFO, shost, MYIOC_s_FMT
"Integrated RAID detects new device %d\n", disk); "Integrated RAID detects new device %d\n", ioc->name, disk);
scsi_scan_target(&hd->ioc->sh->shost_gendev, 1, disk, 0, 1); scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1);
} }
static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
{ {
struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
MPT_ADAPTER *ioc = hd->ioc;
if (!wqw) { if (!wqw) {
shost_printk(KERN_ERR, hd->ioc->sh, shost_printk(KERN_ERR, ioc->sh, MYIOC_s_FMT
"Failed to act on RAID event for physical disk %d\n", "Failed to act on RAID event for physical disk %d\n",
disk); ioc->name, disk);
return; return;
} }
INIT_WORK(&wqw->work, mpt_work_wrapper); INIT_WORK(&wqw->work, mpt_work_wrapper);
@ -1123,7 +1136,7 @@ static int
mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
{ {
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
if (hd && event == MPI_EVENT_INTEGRATED_RAID) { if (hd && event == MPI_EVENT_INTEGRATED_RAID) {
int reason int reason
@ -1190,6 +1203,8 @@ static struct spi_function_template mptspi_transport_functions = {
static struct pci_device_id mptspi_pci_table[] = { static struct pci_device_id mptspi_pci_table[] = {
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030, { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_ATTO, MPI_MANUFACTPAGE_DEVID_53C1030,
PCI_ANY_ID, PCI_ANY_ID },
{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035, { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,
PCI_ANY_ID, PCI_ANY_ID }, PCI_ANY_ID, PCI_ANY_ID },
{0} /* Terminating entry */ {0} /* Terminating entry */
@ -1210,11 +1225,12 @@ mptspi_dv_renegotiate_work(struct work_struct *work)
struct scsi_target *starget; struct scsi_target *starget;
struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
u32 nego; u32 nego;
MPT_ADAPTER *ioc = hd->ioc;
kfree(wqw); kfree(wqw);
if (hd->spi_pending) { if (hd->spi_pending) {
shost_for_each_device(sdev, hd->ioc->sh) { shost_for_each_device(sdev, ioc->sh) {
if (hd->spi_pending & (1 << sdev->id)) if (hd->spi_pending & (1 << sdev->id))
continue; continue;
starget = scsi_target(sdev); starget = scsi_target(sdev);
@ -1225,7 +1241,7 @@ mptspi_dv_renegotiate_work(struct work_struct *work)
mptspi_write_spi_device_pg1(starget, &pg1); mptspi_write_spi_device_pg1(starget, &pg1);
} }
} else { } else {
shost_for_each_device(sdev, hd->ioc->sh) shost_for_each_device(sdev, ioc->sh)
mptspi_dv_device(hd, sdev); mptspi_dv_device(hd, sdev);
} }
} }
@ -1250,7 +1266,7 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
static int static int
mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
int rc; int rc;
rc = mptscsih_ioc_reset(ioc, reset_phase); rc = mptscsih_ioc_reset(ioc, reset_phase);
@ -1269,7 +1285,7 @@ static int
mptspi_resume(struct pci_dev *pdev) mptspi_resume(struct pci_dev *pdev)
{ {
MPT_ADAPTER *ioc = pci_get_drvdata(pdev); MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)ioc->sh->hostdata; struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
int rc; int rc;
rc = mptscsih_resume(pdev); rc = mptscsih_resume(pdev);
@ -1416,7 +1432,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (numSGE < sh->sg_tablesize) { if (numSGE < sh->sg_tablesize) {
/* Reset this value */ /* Reset this value */
dprintk(ioc, printk(MYIOC_s_INFO_FMT dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"Resetting sg_tablesize to %d from %d\n", "Resetting sg_tablesize to %d from %d\n",
ioc->name, numSGE, sh->sg_tablesize)); ioc->name, numSGE, sh->sg_tablesize));
sh->sg_tablesize = numSGE; sh->sg_tablesize = numSGE;
@ -1424,20 +1440,21 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd = (MPT_SCSI_HOST *) sh->hostdata; hd = shost_priv(sh);
hd->ioc = ioc; hd->ioc = ioc;
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
if (!hd->ScsiLookup) { if (!ioc->ScsiLookup) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptspi_probe; goto out_mptspi_probe;
} }
spin_lock_init(&ioc->scsi_lookup_lock);
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n", dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup)); ioc->name, ioc->ScsiLookup));
/* Clear the TM flags /* Clear the TM flags
*/ */
@ -1477,13 +1494,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Some versions of the firmware don't support page 0; without /* Some versions of the firmware don't support page 0; without
* that we can't get the parameters */ * that we can't get the parameters */
if (hd->ioc->spi_data.sdp0length != 0) if (ioc->spi_data.sdp0length != 0)
sh->transportt = mptspi_transport_template; sh->transportt = mptspi_transport_template;
error = scsi_add_host (sh, &ioc->pcidev->dev); error = scsi_add_host (sh, &ioc->pcidev->dev);
if(error) { if(error) {
dprintk(ioc, printk(KERN_ERR MYNAM dprintk(ioc, printk(MYIOC_s_ERR_FMT
"scsi_add_host failed\n")); "scsi_add_host failed\n", ioc->name));
goto out_mptspi_probe; goto out_mptspi_probe;
} }

View file

@ -891,7 +891,7 @@ zfcp_unit_dequeue(struct zfcp_unit *unit)
/* /*
* Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI * Allocates a combined QTCB/fsf_req buffer for erp actions and fcp/SCSI
* commands. * commands.
* It also genrates fcp-nameserver request/response buffer and unsolicited * It also genrates fcp-nameserver request/response buffer and unsolicited
* status read fsf_req buffers. * status read fsf_req buffers.
* *
* locks: must only be called with zfcp_data.config_sema taken * locks: must only be called with zfcp_data.config_sema taken
@ -982,7 +982,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter;
/* /*
* Note: It is safe to release the list_lock, as any list changes * Note: It is safe to release the list_lock, as any list changes
* are protected by the config_sema, which must be held to get here * are protected by the config_sema, which must be held to get here
*/ */
@ -1038,6 +1038,10 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
spin_lock_init(&adapter->san_dbf_lock); spin_lock_init(&adapter->san_dbf_lock);
spin_lock_init(&adapter->scsi_dbf_lock); spin_lock_init(&adapter->scsi_dbf_lock);
retval = zfcp_adapter_debug_register(adapter);
if (retval)
goto debug_register_failed;
/* initialize error recovery stuff */ /* initialize error recovery stuff */
rwlock_init(&adapter->erp_lock); rwlock_init(&adapter->erp_lock);
@ -1058,7 +1062,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
/* mark adapter unusable as long as sysfs registration is not complete */ /* mark adapter unusable as long as sysfs registration is not complete */
atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
adapter->ccw_device = ccw_device;
dev_set_drvdata(&ccw_device->dev, adapter); dev_set_drvdata(&ccw_device->dev, adapter);
if (zfcp_sysfs_adapter_create_files(&ccw_device->dev)) if (zfcp_sysfs_adapter_create_files(&ccw_device->dev))
@ -1085,6 +1088,8 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
generic_services_failed: generic_services_failed:
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
sysfs_failed: sysfs_failed:
zfcp_adapter_debug_unregister(adapter);
debug_register_failed:
dev_set_drvdata(&ccw_device->dev, NULL); dev_set_drvdata(&ccw_device->dev, NULL);
zfcp_reqlist_free(adapter); zfcp_reqlist_free(adapter);
failed_low_mem_buffers: failed_low_mem_buffers:
@ -1130,6 +1135,8 @@ zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
goto out; goto out;
} }
zfcp_adapter_debug_unregister(adapter);
/* remove specified adapter data structure from list */ /* remove specified adapter data structure from list */
write_lock_irq(&zfcp_data.config_lock); write_lock_irq(&zfcp_data.config_lock);
list_del(&adapter->list); list_del(&adapter->list);

View file

@ -148,15 +148,12 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
down(&zfcp_data.config_sema); down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev); adapter = dev_get_drvdata(&ccw_device->dev);
retval = zfcp_adapter_debug_register(adapter);
if (retval)
goto out;
retval = zfcp_erp_thread_setup(adapter); retval = zfcp_erp_thread_setup(adapter);
if (retval) { if (retval) {
ZFCP_LOG_INFO("error: start of error recovery thread for " ZFCP_LOG_INFO("error: start of error recovery thread for "
"adapter %s failed\n", "adapter %s failed\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
goto out_erp_thread; goto out;
} }
retval = zfcp_adapter_scsi_register(adapter); retval = zfcp_adapter_scsi_register(adapter);
@ -175,8 +172,6 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
out_scsi_register: out_scsi_register:
zfcp_erp_thread_kill(adapter); zfcp_erp_thread_kill(adapter);
out_erp_thread:
zfcp_adapter_debug_unregister(adapter);
out: out:
up(&zfcp_data.config_sema); up(&zfcp_data.config_sema);
return retval; return retval;
@ -199,7 +194,6 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter); zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema); up(&zfcp_data.config_sema);
return 0; return 0;
} }

View file

@ -1,23 +1,23 @@
/* /*
* This file is part of the zfcp device driver for * This file is part of the zfcp device driver for
* FCP adapters for IBM System z9 and zSeries. * FCP adapters for IBM System z9 and zSeries.
* *
* (C) Copyright IBM Corp. 2002, 2006 * (C) Copyright IBM Corp. 2002, 2006
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef ZFCP_DEF_H #ifndef ZFCP_DEF_H
#define ZFCP_DEF_H #define ZFCP_DEF_H
@ -90,7 +90,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
#define ZFCP_DEVICE_TYPE 0x1732 #define ZFCP_DEVICE_TYPE 0x1732
#define ZFCP_DEVICE_MODEL 0x03 #define ZFCP_DEVICE_MODEL 0x03
#define ZFCP_DEVICE_MODEL_PRIV 0x04 #define ZFCP_DEVICE_MODEL_PRIV 0x04
/* allow as many chained SBALs as are supported by hardware */ /* allow as many chained SBALs as are supported by hardware */
#define ZFCP_MAX_SBALS_PER_REQ FSF_MAX_SBALS_PER_REQ #define ZFCP_MAX_SBALS_PER_REQ FSF_MAX_SBALS_PER_REQ
#define ZFCP_MAX_SBALS_PER_CT_REQ FSF_MAX_SBALS_PER_REQ #define ZFCP_MAX_SBALS_PER_CT_REQ FSF_MAX_SBALS_PER_REQ
@ -508,7 +508,7 @@ struct zfcp_rc_entry {
/* /*
* this allows removal of logging code by the preprocessor * this allows removal of logging code by the preprocessor
* (the most detailed log level still to be compiled in is specified, * (the most detailed log level still to be compiled in is specified,
* higher log levels are removed) * higher log levels are removed)
*/ */
#define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_TRACE #define ZFCP_LOG_LEVEL_LIMIT ZFCP_LOG_LEVEL_TRACE
@ -546,7 +546,7 @@ do { \
if (ZFCP_LOG_CHECK(level)) \ if (ZFCP_LOG_CHECK(level)) \
_ZFCP_LOG(fmt, ##args); \ _ZFCP_LOG(fmt, ##args); \
} while (0) } while (0)
#if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL #if ZFCP_LOG_LEVEL_LIMIT < ZFCP_LOG_LEVEL_NORMAL
# define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0) # define ZFCP_LOG_NORMAL(fmt, args...) do { } while (0)
#else #else
@ -583,8 +583,8 @@ do { \
/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
/* /*
* Note, the leftmost status byte is common among adapter, port * Note, the leftmost status byte is common among adapter, port
* and unit * and unit
*/ */
#define ZFCP_COMMON_FLAGS 0xfff00000 #define ZFCP_COMMON_FLAGS 0xfff00000
@ -1007,8 +1007,8 @@ struct zfcp_fsf_req {
u32 fsf_command; /* FSF Command copy */ u32 fsf_command; /* FSF Command copy */
struct fsf_qtcb *qtcb; /* address of associated QTCB */ struct fsf_qtcb *qtcb; /* address of associated QTCB */
u32 seq_no; /* Sequence number of request */ u32 seq_no; /* Sequence number of request */
unsigned long data; /* private data of request */ unsigned long data; /* private data of request */
struct timer_list timer; /* used for erp or scsi er */ struct timer_list timer; /* used for erp or scsi er */
struct zfcp_erp_action *erp_action; /* used if this request is struct zfcp_erp_action *erp_action; /* used if this request is
issued on behalf of erp */ issued on behalf of erp */
mempool_t *pool; /* used if request was alloacted mempool_t *pool; /* used if request was alloacted

View file

@ -1,22 +1,22 @@
/* /*
* This file is part of the zfcp device driver for * This file is part of the zfcp device driver for
* FCP adapters for IBM System z9 and zSeries. * FCP adapters for IBM System z9 and zSeries.
* *
* (C) Copyright IBM Corp. 2002, 2006 * (C) Copyright IBM Corp. 2002, 2006
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP #define ZFCP_LOG_AREA ZFCP_LOG_AREA_ERP
@ -191,7 +191,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
} }
/* /*
* function: * function:
* *
* purpose: called if an adapter failed, * purpose: called if an adapter failed,
* initiates adapter recovery which is done * initiates adapter recovery which is done
@ -228,7 +228,7 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: Wrappper for zfcp_erp_adapter_reopen_internal * purpose: Wrappper for zfcp_erp_adapter_reopen_internal
* used to ensure the correct locking * used to ensure the correct locking
@ -476,7 +476,7 @@ zfcp_test_link(struct zfcp_port *port)
/* /*
* function: * function:
* *
* purpose: called if a port failed to be opened normally * purpose: called if a port failed to be opened normally
* initiates Forced Reopen recovery which is done * initiates Forced Reopen recovery which is done
@ -517,7 +517,7 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: Wrappper for zfcp_erp_port_forced_reopen_internal * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal
* used to ensure the correct locking * used to ensure the correct locking
@ -543,7 +543,7 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: called if a port is to be opened * purpose: called if a port is to be opened
* initiates Reopen recovery which is done * initiates Reopen recovery which is done
@ -612,7 +612,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: called if a unit is to be opened * purpose: called if a unit is to be opened
* initiates Reopen recovery which is done * initiates Reopen recovery which is done
@ -704,7 +704,7 @@ static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
} }
/* /*
* function: * function:
* *
* purpose: disable I/O, * purpose: disable I/O,
* return any open requests and clean them up, * return any open requests and clean them up,
@ -725,7 +725,7 @@ zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: enable I/O * purpose: enable I/O
* *
@ -742,7 +742,7 @@ zfcp_erp_port_unblock(struct zfcp_port *port)
} }
/* /*
* function: * function:
* *
* purpose: disable I/O, * purpose: disable I/O,
* return any open requests and clean them up, * return any open requests and clean them up,
@ -763,7 +763,7 @@ zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: enable I/O * purpose: enable I/O
* *
@ -792,7 +792,7 @@ zfcp_erp_action_ready(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
@ -967,7 +967,7 @@ static void zfcp_erp_timeout_handler(unsigned long data)
* zfcp_erp_action_dismiss - dismiss an erp_action * zfcp_erp_action_dismiss - dismiss an erp_action
* *
* adapter->erp_lock must be held * adapter->erp_lock must be held
* *
* Dismissal of an erp_action is usually required if an erp_action of * Dismissal of an erp_action is usually required if an erp_action of
* higher priority is generated. * higher priority is generated.
*/ */
@ -1005,9 +1005,9 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: * returns:
* *
@ -1094,7 +1094,7 @@ zfcp_erp_thread(void *data)
} }
/* /*
* function: * function:
* *
* purpose: drives single error recovery action and schedules higher and * purpose: drives single error recovery action and schedules higher and
* subordinate actions, if necessary * subordinate actions, if necessary
@ -1206,7 +1206,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
/* /*
* put this target through the erp mill again if someone has * put this target through the erp mill again if someone has
* requested to change the status of a target being online * requested to change the status of a target being online
* to offline or the other way around * to offline or the other way around
* (old retval is preserved if nothing has to be done here) * (old retval is preserved if nothing has to be done here)
*/ */
@ -1228,7 +1228,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
unlock: unlock:
write_unlock(&adapter->erp_lock); write_unlock(&adapter->erp_lock);
read_unlock_irqrestore(&zfcp_data.config_lock, flags); read_unlock_irqrestore(&zfcp_data.config_lock, flags);
if (retval != ZFCP_ERP_CONTINUES) if (retval != ZFCP_ERP_CONTINUES)
zfcp_erp_action_cleanup(action, adapter, port, unit, retval); zfcp_erp_action_cleanup(action, adapter, port, unit, retval);
@ -1250,9 +1250,9 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_DISMISSED - if action has been dismissed * returns: ZFCP_ERP_DISMISSED - if action has been dismissed
* retval - otherwise * retval - otherwise
@ -1322,7 +1322,7 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: triggers retry of this action after a certain amount of time * purpose: triggers retry of this action after a certain amount of time
* by means of timer provided by erp_action * by means of timer provided by erp_action
@ -1346,7 +1346,7 @@ zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
return retval; return retval;
} }
/* /*
* function: zfcp_erp_adapter_failed * function: zfcp_erp_adapter_failed
* *
* purpose: sets the adapter and all underlying devices to ERP_FAILED * purpose: sets the adapter and all underlying devices to ERP_FAILED
@ -1362,7 +1362,7 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
debug_text_event(adapter->erp_dbf, 2, "a_afail"); debug_text_event(adapter->erp_dbf, 2, "a_afail");
} }
/* /*
* function: zfcp_erp_port_failed * function: zfcp_erp_port_failed
* *
* purpose: sets the port and all underlying devices to ERP_FAILED * purpose: sets the port and all underlying devices to ERP_FAILED
@ -1386,7 +1386,7 @@ zfcp_erp_port_failed(struct zfcp_port *port)
debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t)); debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));
} }
/* /*
* function: zfcp_erp_unit_failed * function: zfcp_erp_unit_failed
* *
* purpose: sets the unit to ERP_FAILED * purpose: sets the unit to ERP_FAILED
@ -1417,7 +1417,7 @@ zfcp_erp_unit_failed(struct zfcp_unit *unit)
* successfully is reset. * successfully is reset.
* *
* returns: ZFCP_ERP_CONTINUES - action continues (not considered) * returns: ZFCP_ERP_CONTINUES - action continues (not considered)
* ZFCP_ERP_SUCCEEDED - action finished successfully * ZFCP_ERP_SUCCEEDED - action finished successfully
* ZFCP_ERP_EXIT - action failed and will not continue * ZFCP_ERP_EXIT - action failed and will not continue
*/ */
static int static int
@ -1646,7 +1646,7 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit)
} }
/* /*
* function: * function:
* *
* purpose: remaining things in good cases, * purpose: remaining things in good cases,
* escalation in bad cases * escalation in bad cases
@ -1687,8 +1687,8 @@ zfcp_erp_strategy_followup_actions(int action,
break; break;
case ZFCP_ERP_ACTION_REOPEN_UNIT: case ZFCP_ERP_ACTION_REOPEN_UNIT:
if (status == ZFCP_ERP_SUCCEEDED) ; /* no further action */ /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */
else if (status != ZFCP_ERP_SUCCEEDED)
zfcp_erp_port_reopen_internal(unit->port, 0); zfcp_erp_port_reopen_internal(unit->port, 0);
break; break;
} }
@ -1815,7 +1815,7 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
} }
/* /*
* function: * function:
* *
* purpose: Wrappper for zfcp_erp_port_reopen_all_internal * purpose: Wrappper for zfcp_erp_port_reopen_all_internal
* used to ensure the correct locking * used to ensure the correct locking
@ -1852,9 +1852,9 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: FIXME * returns: FIXME
*/ */
@ -1871,7 +1871,7 @@ zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask)
} }
/* /*
* function: * function:
* *
* purpose: this routine executes the 'Reopen Adapter' action * purpose: this routine executes the 'Reopen Adapter' action
* (the entire action is processed synchronously, since * (the entire action is processed synchronously, since
@ -1908,9 +1908,9 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_SUCCEEDED - action finished successfully * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -1930,9 +1930,9 @@ zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_SUCCEEDED - action finished successfully * returns: ZFCP_ERP_SUCCEEDED - action finished successfully
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -1957,7 +1957,7 @@ zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action)
* purpose: allocate the irq associated with this devno and register * purpose: allocate the irq associated with this devno and register
* the FSF adapter with the SCSI stack * the FSF adapter with the SCSI stack
* *
* returns: * returns:
*/ */
static int static int
zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close) zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
@ -2197,7 +2197,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
zfcp_erp_action_to_running(erp_action); zfcp_erp_action_to_running(erp_action);
write_unlock_irq(&adapter->erp_lock); write_unlock_irq(&adapter->erp_lock);
ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); ret = zfcp_fsf_exchange_port_data(erp_action);
if (ret == -EOPNOTSUPP) { if (ret == -EOPNOTSUPP) {
debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
@ -2249,7 +2249,7 @@ zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
} }
/* /*
* function: * function:
* *
* purpose: this routine executes the 'Reopen Physical Port' action * purpose: this routine executes the 'Reopen Physical Port' action
* *
@ -2308,7 +2308,7 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: this routine executes the 'Reopen Port' action * purpose: this routine executes the 'Reopen Port' action
* *
@ -2530,7 +2530,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: makes the erp thread continue with reopen (physical) port * purpose: makes the erp thread continue with reopen (physical) port
* actions which have been paused until the name server port * actions which have been paused until the name server port
@ -2570,9 +2570,9 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2626,9 +2626,9 @@ zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2663,9 +2663,9 @@ zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2700,9 +2700,9 @@ zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2737,7 +2737,7 @@ zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: this routine executes the 'Reopen Unit' action * purpose: this routine executes the 'Reopen Unit' action
* currently no retries * currently no retries
@ -2825,9 +2825,9 @@ zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2865,9 +2865,9 @@ zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
} }
/* /*
* function: * function:
* *
* purpose: * purpose:
* *
* returns: ZFCP_ERP_CONTINUES - action continues (asynchronously) * returns: ZFCP_ERP_CONTINUES - action continues (asynchronously)
* ZFCP_ERP_FAILED - action finished unsuccessfully * ZFCP_ERP_FAILED - action finished unsuccessfully
@ -2913,7 +2913,7 @@ void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req)
} }
/* /*
* function: * function:
* *
* purpose: enqueue the specified error recovery action, if needed * purpose: enqueue the specified error recovery action, if needed
* *
@ -2992,7 +2992,7 @@ zfcp_erp_action_enqueue(int action,
port->erp_action.action); port->erp_action.action);
debug_text_event(adapter->erp_dbf, 4, debug_text_event(adapter->erp_dbf, 4,
"pf_actenq_drp"); "pf_actenq_drp");
} else } else
debug_text_event(adapter->erp_dbf, 4, debug_text_event(adapter->erp_dbf, 4,
"pf_actenq_drpcp"); "pf_actenq_drpcp");
debug_event(adapter->erp_dbf, 4, &port->wwpn, debug_event(adapter->erp_dbf, 4, &port->wwpn,

View file

@ -1,22 +1,22 @@
/* /*
* This file is part of the zfcp device driver for * This file is part of the zfcp device driver for
* FCP adapters for IBM System z9 and zSeries. * FCP adapters for IBM System z9 and zSeries.
* *
* (C) Copyright IBM Corp. 2002, 2006 * (C) Copyright IBM Corp. 2002, 2006
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef ZFCP_EXT_H #ifndef ZFCP_EXT_H
@ -82,9 +82,11 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_close_unit(struct zfcp_erp_action *); extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *, extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *,
struct zfcp_adapter *, struct fsf_qtcb_bottom_config *);
struct fsf_qtcb_bottom_port *); extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *,
struct fsf_qtcb_bottom_port *);
extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **, extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *); u32, u32, struct zfcp_sg_list *);
extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long); extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long);

View file

@ -80,10 +80,10 @@ static const char zfcp_act_subtable_type[5][8] = {
/* /*
* function: zfcp_fsf_req_alloc * function: zfcp_fsf_req_alloc
* *
* purpose: Obtains an fsf_req and potentially a qtcb (for all but * purpose: Obtains an fsf_req and potentially a qtcb (for all but
* unsolicited requests) via helper functions * unsolicited requests) via helper functions
* Does some initial fsf request set-up. * Does some initial fsf request set-up.
* *
* returns: pointer to allocated fsf_req if successfull * returns: pointer to allocated fsf_req if successfull
* NULL otherwise * NULL otherwise
* *
@ -192,7 +192,7 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
* returns: 0 - success * returns: 0 - success
* !0 - failure * !0 - failure
* *
* context: * context:
*/ */
int int
zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req) zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req)
@ -214,8 +214,8 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req)
} }
/* /*
* fsf_req may be deleted due to waking up functions, so * fsf_req may be deleted due to waking up functions, so
* cleanup is saved here and used later * cleanup is saved here and used later
*/ */
if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) if (likely(fsf_req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
cleanup = 1; cleanup = 1;
@ -259,9 +259,9 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req)
* and initiates appropriate actions * and initiates appropriate actions
* (usually calling FSF command specific handlers) * (usually calling FSF command specific handlers)
* *
* returns: * returns:
* *
* context: * context:
* *
* locks: * locks:
*/ */
@ -638,7 +638,7 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
* *
* purpose: calls the appropriate command specific handler * purpose: calls the appropriate command specific handler
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
@ -854,7 +854,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req)
* *
* purpose: is called for finished Open Port command * purpose: is called for finished Open Port command
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
@ -1088,7 +1088,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
* returns: address of initiated FSF request * returns: address of initiated FSF request
* NULL - request could not be initiated * NULL - request could not be initiated
* *
* FIXME(design): should be watched by a timeout !!! * FIXME(design): should be watched by a timeout !!!
* FIXME(design) shouldn't this be modified to return an int * FIXME(design) shouldn't this be modified to return an int
* also...don't know how though * also...don't know how though
*/ */
@ -1157,7 +1157,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
* *
* purpose: is called for finished Abort FCP Command request * purpose: is called for finished Abort FCP Command request
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
@ -1941,25 +1941,28 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
{ {
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req; struct zfcp_fsf_req *fsf_req;
struct zfcp_adapter *adapter = erp_action->adapter;
unsigned long lock_flags; unsigned long lock_flags;
int retval = 0; int retval;
/* setup new FSF request */ /* setup new FSF request */
retval = zfcp_fsf_req_create(erp_action->adapter, retval = zfcp_fsf_req_create(adapter,
FSF_QTCB_EXCHANGE_CONFIG_DATA, FSF_QTCB_EXCHANGE_CONFIG_DATA,
ZFCP_REQ_AUTO_CLEANUP, ZFCP_REQ_AUTO_CLEANUP,
erp_action->adapter->pool.fsf_req_erp, adapter->pool.fsf_req_erp,
&lock_flags, &fsf_req); &lock_flags, &fsf_req);
if (retval < 0) { if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration " ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n", "data request for adapter %s.\n",
zfcp_get_busid_by_adapter(erp_action->adapter)); zfcp_get_busid_by_adapter(adapter));
goto out; write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
return retval;
} }
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
fsf_req->qtcb->bottom.config.feature_selection = fsf_req->qtcb->bottom.config.feature_selection =
FSF_FEATURE_CFDC | FSF_FEATURE_CFDC |
@ -1971,23 +1974,71 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
zfcp_erp_start_timer(fsf_req); zfcp_erp_start_timer(fsf_req);
retval = zfcp_fsf_req_send(fsf_req); retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
if (retval) { if (retval) {
ZFCP_LOG_INFO ZFCP_LOG_INFO("error: Could not send exchange configuration "
("error: Could not send exchange configuration data " "data command on the adapter %s\n",
"command on the adapter %s\n", zfcp_get_busid_by_adapter(adapter));
zfcp_get_busid_by_adapter(erp_action->adapter));
zfcp_fsf_req_free(fsf_req); zfcp_fsf_req_free(fsf_req);
erp_action->fsf_req = NULL; erp_action->fsf_req = NULL;
goto out; }
else
ZFCP_LOG_DEBUG("exchange configuration data request initiated "
"(adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
return retval;
}
int
zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_config *data)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
unsigned long lock_flags;
int retval;
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
0, NULL, &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
return retval;
} }
ZFCP_LOG_DEBUG("exchange configuration data request initiated " sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
"(adapter %s)\n", sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
zfcp_get_busid_by_adapter(erp_action->adapter)); sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
out: fsf_req->qtcb->bottom.config.feature_selection =
write_unlock_irqrestore(&erp_action->adapter->request_queue.queue_lock, FSF_FEATURE_CFDC |
FSF_FEATURE_LUN_SHARING |
FSF_FEATURE_NOTIFICATION_LOST |
FSF_FEATURE_UPDATE_ALERT;
if (data)
fsf_req->data = (unsigned long) data;
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags); lock_flags);
if (retval)
ZFCP_LOG_INFO("error: Could not send exchange configuration "
"data command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
else
wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
zfcp_fsf_req_free(fsf_req);
return retval; return retval;
} }
@ -2016,11 +2067,17 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
adapter->peer_d_id = 0; adapter->peer_d_id = 0;
if (xchg_ok) { if (xchg_ok) {
if (fsf_req->data)
memcpy((struct fsf_qtcb_bottom_config *) fsf_req->data,
bottom, sizeof (struct fsf_qtcb_bottom_config));
fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
fc_host_speed(shost) = bottom->fc_link_speed; fc_host_speed(shost) = bottom->fc_link_speed;
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; fc_host_supported_classes(shost) =
FC_COS_CLASS2 | FC_COS_CLASS3;
adapter->hydra_version = bottom->adapter_type; adapter->hydra_version = bottom->adapter_type;
if (fc_host_permanent_port_name(shost) == -1) if (fc_host_permanent_port_name(shost) == -1)
fc_host_permanent_port_name(shost) = fc_host_permanent_port_name(shost) =
@ -2053,7 +2110,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
min(FC_SERIAL_NUMBER_SIZE, 17)); min(FC_SERIAL_NUMBER_SIZE, 17));
} }
ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" ZFCP_LOG_NORMAL("The adapter %s reported the following "
"characteristics:\n"
"WWNN 0x%016Lx, " "WWNN 0x%016Lx, "
"WWPN 0x%016Lx, " "WWPN 0x%016Lx, "
"S_ID 0x%06x,\n" "S_ID 0x%06x,\n"
@ -2090,7 +2148,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
return 0; return 0;
} }
/* /**
* function: zfcp_fsf_exchange_config_data_handler * function: zfcp_fsf_exchange_config_data_handler
* *
* purpose: is called for finished Exchange Configuration Data command * purpose: is called for finished Exchange Configuration Data command
@ -2125,7 +2183,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
adapter->peer_wwpn, adapter->peer_wwpn,
adapter->peer_d_id); adapter->peer_d_id);
debug_text_event(fsf_req->adapter->erp_dbf, 0, debug_text_event(fsf_req->adapter->erp_dbf, 0,
"top-p-to-p"); "top-p-to-p");
break; break;
case FC_PORTTYPE_NLPORT: case FC_PORTTYPE_NLPORT:
ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
@ -2138,8 +2196,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
return -EIO; return -EIO;
case FC_PORTTYPE_NPORT: case FC_PORTTYPE_NPORT:
ZFCP_LOG_NORMAL("Switched fabric fibrechannel " ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
"network detected at adapter %s.\n", "network detected at adapter %s.\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
break; break;
default: default:
ZFCP_LOG_NORMAL("bug: The fibrechannel topology " ZFCP_LOG_NORMAL("bug: The fibrechannel topology "
@ -2179,7 +2237,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
return -EIO; return -EIO;
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
&adapter->status);
zfcp_fsf_link_down_info_eval(adapter, zfcp_fsf_link_down_info_eval(adapter,
&qtcb->header.fsf_status_qual.link_down_info); &qtcb->header.fsf_status_qual.link_down_info);
@ -2187,7 +2246,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
default: default:
debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng");
debug_event(fsf_req->adapter->erp_dbf, 0, debug_event(fsf_req->adapter->erp_dbf, 0,
&fsf_req->qtcb->header.fsf_status, sizeof (u32)); &fsf_req->qtcb->header.fsf_status, sizeof(u32));
zfcp_erp_adapter_shutdown(adapter, 0); zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO; return -EIO;
} }
@ -2197,34 +2256,91 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
/** /**
* zfcp_fsf_exchange_port_data - request information about local port * zfcp_fsf_exchange_port_data - request information about local port
* @erp_action: ERP action for the adapter for which port data is requested * @erp_action: ERP action for the adapter for which port data is requested
* @adapter: for which port data is requested
* @data: response to exchange port data request
*/ */
int int
zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{ {
volatile struct qdio_buffer_element *sbale; volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req; struct zfcp_fsf_req *fsf_req;
struct zfcp_adapter *adapter = erp_action->adapter;
unsigned long lock_flags; unsigned long lock_flags;
int retval = 0; int retval;
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
ZFCP_LOG_INFO("error: exchange port data " ZFCP_LOG_INFO("error: exchange port data "
"command not supported by adapter %s\n", "command not supported by adapter %s\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
/* setup new FSF request */ /* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0, ZFCP_REQ_AUTO_CLEANUP,
NULL, &lock_flags, &fsf_req); adapter->pool.fsf_req_erp,
if (retval < 0) { &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Out of resources. Could not create an " ZFCP_LOG_INFO("error: Out of resources. Could not create an "
"exchange port data request for" "exchange port data request for"
"the adapter %s.\n", "the adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
return retval;
}
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
erp_action->fsf_req = fsf_req;
fsf_req->erp_action = erp_action;
zfcp_erp_start_timer(fsf_req);
retval = zfcp_fsf_req_send(fsf_req);
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
if (retval) {
ZFCP_LOG_INFO("error: Could not send an exchange port data "
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_fsf_req_free(fsf_req);
erp_action->fsf_req = NULL;
}
else
ZFCP_LOG_DEBUG("exchange port data request initiated "
"(adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
return retval;
}
/**
* zfcp_fsf_exchange_port_data_sync - request information about local port
* and wait until information is ready
*/
int
zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
unsigned long lock_flags;
int retval;
if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
ZFCP_LOG_INFO("error: exchange port data "
"command not supported by adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
return -EOPNOTSUPP;
}
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
0, NULL, &lock_flags, &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Out of resources. Could not create an "
"exchange port data request for"
"the adapter %s.\n",
zfcp_get_busid_by_adapter(adapter)); zfcp_get_busid_by_adapter(adapter));
write_unlock_irqrestore(&adapter->request_queue.queue_lock, write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags); lock_flags);
@ -2235,36 +2351,23 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
fsf_req->data = (unsigned long) data; fsf_req->data = (unsigned long) data;
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
if (erp_action) {
erp_action->fsf_req = fsf_req;
fsf_req->erp_action = erp_action;
zfcp_erp_start_timer(fsf_req);
} else
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
retval = zfcp_fsf_req_send(fsf_req); retval = zfcp_fsf_req_send(fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Could not send an exchange port data "
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_fsf_req_free(fsf_req);
if (erp_action)
erp_action->fsf_req = NULL;
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
return retval;
}
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
if (!erp_action) { if (retval)
ZFCP_LOG_INFO("error: Could not send an exchange port data "
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
else
wait_event(fsf_req->completion_wq, wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
zfcp_fsf_req_free(fsf_req);
} zfcp_fsf_req_free(fsf_req);
return retval; return retval;
} }
@ -2277,18 +2380,16 @@ static void
zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
{ {
struct zfcp_adapter *adapter; struct zfcp_adapter *adapter;
struct fsf_qtcb *qtcb; struct fsf_qtcb_bottom_port *bottom;
struct fsf_qtcb_bottom_port *bottom, *data;
struct Scsi_Host *shost; struct Scsi_Host *shost;
adapter = fsf_req->adapter; adapter = fsf_req->adapter;
qtcb = fsf_req->qtcb; bottom = &fsf_req->qtcb->bottom.port;
bottom = &qtcb->bottom.port;
shost = adapter->scsi_host; shost = adapter->scsi_host;
data = (struct fsf_qtcb_bottom_port*) fsf_req->data; if (fsf_req->data)
if (data) memcpy((struct fsf_qtcb_bottom_port*) fsf_req->data, bottom,
memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); sizeof(struct fsf_qtcb_bottom_port));
if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
fc_host_permanent_port_name(shost) = bottom->wwpn; fc_host_permanent_port_name(shost) = bottom->wwpn;
@ -2336,10 +2437,10 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
/* /*
* function: zfcp_fsf_open_port * function: zfcp_fsf_open_port
* *
* purpose: * purpose:
* *
* returns: address of initiated FSF request * returns: address of initiated FSF request
* NULL - request could not be initiated * NULL - request could not be initiated
*/ */
int int
zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
@ -2400,7 +2501,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
* *
* purpose: is called for finished Open Port command * purpose: is called for finished Open Port command
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
@ -3002,7 +3103,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
* *
* purpose: is called for finished Open LUN command * purpose: is called for finished Open LUN command
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
@ -3265,7 +3366,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
* purpose: * purpose:
* *
* returns: address of fsf_req - request successfully initiated * returns: address of fsf_req - request successfully initiated
* NULL - * NULL -
* *
* assumptions: This routine does not check whether the associated * assumptions: This routine does not check whether the associated
* remote port/lun has already been opened. This should be * remote port/lun has already been opened. This should be
@ -3586,17 +3687,17 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
ZFCP_LOG_DEBUG( ZFCP_LOG_DEBUG(
"Data did not fit into available buffer(s), " "Data did not fit into available buffer(s), "
"waiting for more...\n"); "waiting for more...\n");
retval = -EIO; retval = -EIO;
} else { } else {
ZFCP_LOG_NORMAL("error: No truncation implemented but " ZFCP_LOG_NORMAL("error: No truncation implemented but "
"required. Shutting down unit " "required. Shutting down unit "
"(adapter %s, port 0x%016Lx, " "(adapter %s, port 0x%016Lx, "
"unit 0x%016Lx)\n", "unit 0x%016Lx)\n",
zfcp_get_busid_by_unit(unit), zfcp_get_busid_by_unit(unit),
unit->port->wwpn, unit->port->wwpn,
unit->fcp_lun); unit->fcp_lun);
zfcp_erp_unit_shutdown(unit, 0); zfcp_erp_unit_shutdown(unit, 0);
retval = -EINVAL; retval = -EINVAL;
} }
goto no_fit; goto no_fit;
} }
@ -3727,7 +3828,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
* *
* purpose: is called for finished Send FCP Command * purpose: is called for finished Send FCP Command
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
@ -3964,7 +4065,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
* *
* purpose: evaluates FCP_RSP IU * purpose: evaluates FCP_RSP IU
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
@ -4192,7 +4293,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
* *
* purpose: evaluates FCP_RSP IU * purpose: evaluates FCP_RSP IU
* *
* returns: * returns:
*/ */
static int static int
zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
@ -4635,7 +4736,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
INIT_LIST_HEAD(&fsf_req->list); INIT_LIST_HEAD(&fsf_req->list);
init_timer(&fsf_req->timer); init_timer(&fsf_req->timer);
/* initialize waitqueue which may be used to wait on /* initialize waitqueue which may be used to wait on
this request completion */ this request completion */
init_waitqueue_head(&fsf_req->completion_wq); init_waitqueue_head(&fsf_req->completion_wq);

View file

@ -1,22 +1,22 @@
/* /*
* This file is part of the zfcp device driver for * This file is part of the zfcp device driver for
* FCP adapters for IBM System z9 and zSeries. * FCP adapters for IBM System z9 and zSeries.
* *
* (C) Copyright IBM Corp. 2002, 2006 * (C) Copyright IBM Corp. 2002, 2006
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef FSF_H #ifndef FSF_H

View file

@ -174,10 +174,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
* That is why we need to clear the link-down flag * That is why we need to clear the link-down flag
* which is set again in case we have missed by a mile. * which is set again in case we have missed by a mile.
*/ */
zfcp_erp_adapter_reopen( zfcp_erp_adapter_reopen(adapter,
adapter, ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_COMMON_ERP_FAILED);
ZFCP_STATUS_COMMON_ERP_FAILED);
} }
return retval; return retval;
} }

View file

@ -1,22 +1,22 @@
/* /*
* This file is part of the zfcp device driver for * This file is part of the zfcp device driver for
* FCP adapters for IBM System z9 and zSeries. * FCP adapters for IBM System z9 and zSeries.
* *
* (C) Copyright IBM Corp. 2002, 2006 * (C) Copyright IBM Corp. 2002, 2006
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI
@ -101,7 +101,7 @@ zfcp_get_fcp_dl_ptr(struct fcp_cmnd_iu * fcp_cmd)
((unsigned char *) fcp_cmd + ((unsigned char *) fcp_cmd +
sizeof (struct fcp_cmnd_iu) + additional_length); sizeof (struct fcp_cmnd_iu) + additional_length);
/* /*
* fcp_dl_addr = start address of fcp_cmnd structure + * fcp_dl_addr = start address of fcp_cmnd structure +
* size of fixed part + size of dynamically sized add_dcp_cdb field * size of fixed part + size of dynamically sized add_dcp_cdb field
* SEE FCP-2 documentation * SEE FCP-2 documentation
*/ */
@ -189,13 +189,12 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
unit->device = NULL; unit->device = NULL;
zfcp_erp_unit_failed(unit); zfcp_erp_unit_failed(unit);
zfcp_unit_put(unit); zfcp_unit_put(unit);
} else { } else
ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at "
"address %p\n", sdpnt); "address %p\n", sdpnt);
}
} }
/* /*
* called from scsi midlayer to allow finetuning of a device. * called from scsi midlayer to allow finetuning of a device.
*/ */
static int static int
@ -361,12 +360,11 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
list_for_each_entry(port, &adapter->port_list_head, list) { list_for_each_entry(port, &adapter->port_list_head, list) {
if (!port->rport || (id != port->rport->scsi_target_id)) if (!port->rport || (id != port->rport->scsi_target_id))
continue; continue;
list_for_each_entry(unit, &port->unit_list_head, list) { list_for_each_entry(unit, &port->unit_list_head, list)
if (lun == unit->scsi_lun) { if (lun == unit->scsi_lun) {
retval = unit; retval = unit;
goto out; goto out;
} }
}
} }
out: out:
return retval; return retval;
@ -374,7 +372,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
/** /**
* zfcp_scsi_eh_abort_handler - abort the specified SCSI command * zfcp_scsi_eh_abort_handler - abort the specified SCSI command
* @scpnt: pointer to scsi_cmnd to be aborted * @scpnt: pointer to scsi_cmnd to be aborted
* Return: SUCCESS - command has been aborted and cleaned up in internal * Return: SUCCESS - command has been aborted and cleaned up in internal
* bookkeeping, SCSI stack won't be called for aborted command * bookkeeping, SCSI stack won't be called for aborted command
* FAILED - otherwise * FAILED - otherwise
@ -733,7 +731,7 @@ zfcp_get_fc_host_stats(struct Scsi_Host *shost)
if (!data) if (!data)
return NULL; return NULL;
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
if (ret) { if (ret) {
kfree(data); kfree(data);
return NULL; /* XXX return zeroed fc_stats? */ return NULL; /* XXX return zeroed fc_stats? */
@ -763,7 +761,7 @@ zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
if (!data) if (!data)
return; return;
ret = zfcp_fsf_exchange_port_data(NULL, adapter, data); ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
if (ret) { if (ret) {
kfree(data); kfree(data);
} else { } else {
@ -802,6 +800,7 @@ struct fc_function_template zfcp_transport_functions = {
.show_host_port_type = 1, .show_host_port_type = 1,
.show_host_speed = 1, .show_host_speed = 1,
.show_host_port_id = 1, .show_host_port_id = 1,
.disable_target_scan = 1,
}; };
/** /**

View file

@ -139,7 +139,7 @@ static struct attribute_group zfcp_unit_attr_group = {
.attrs = zfcp_unit_attrs, .attrs = zfcp_unit_attrs,
}; };
/** /**
* zfcp_sysfs_create_unit_files - create sysfs unit files * zfcp_sysfs_create_unit_files - create sysfs unit files
* @dev: pointer to belonging device * @dev: pointer to belonging device
* *
@ -151,7 +151,7 @@ zfcp_sysfs_unit_create_files(struct device *dev)
return sysfs_create_group(&dev->kobj, &zfcp_unit_attr_group); return sysfs_create_group(&dev->kobj, &zfcp_unit_attr_group);
} }
/** /**
* zfcp_sysfs_remove_unit_files - remove sysfs unit files * zfcp_sysfs_remove_unit_files - remove sysfs unit files
* @dev: pointer to belonging device * @dev: pointer to belonging device
* *

View file

@ -272,6 +272,13 @@ config SCSI_FC_ATTRS
each attached FiberChannel device to sysfs, say Y. each attached FiberChannel device to sysfs, say Y.
Otherwise, say N. Otherwise, say N.
config SCSI_FC_TGT_ATTRS
bool "SCSI target support for FiberChannel Transport Attributes"
depends on SCSI_FC_ATTRS
depends on SCSI_TGT = y || SCSI_TGT = SCSI_FC_ATTRS
help
If you want to use SCSI target mode drivers enable this option.
config SCSI_ISCSI_ATTRS config SCSI_ISCSI_ATTRS
tristate "iSCSI Transport Attributes" tristate "iSCSI Transport Attributes"
depends on SCSI && NET depends on SCSI && NET
@ -289,6 +296,20 @@ config SCSI_SAS_ATTRS
source "drivers/scsi/libsas/Kconfig" source "drivers/scsi/libsas/Kconfig"
config SCSI_SRP_ATTRS
tristate "SRP Transport Attributes"
depends on SCSI
help
If you wish to export transport-specific information about
each attached SRP device to sysfs, say Y.
config SCSI_SRP_TGT_ATTRS
bool "SCSI target support for SRP Transport Attributes"
depends on SCSI_SRP_ATTRS
depends on SCSI_TGT = y || SCSI_TGT = SCSI_SRP_ATTRS
help
If you want to use SCSI target mode drivers enable this option.
endmenu endmenu
menuconfig SCSI_LOWLEVEL menuconfig SCSI_LOWLEVEL
@ -502,7 +523,6 @@ config SCSI_ADVANSYS
tristate "AdvanSys SCSI support" tristate "AdvanSys SCSI support"
depends on SCSI depends on SCSI
depends on ISA || EISA || PCI depends on ISA || EISA || PCI
depends on BROKEN || X86_32
help help
This is a driver for all SCSI host adapters manufactured by This is a driver for all SCSI host adapters manufactured by
AdvanSys. It is documented in the kernel source in AdvanSys. It is documented in the kernel source in
@ -524,19 +544,32 @@ config SCSI_IN2000
module will be called in2000. module will be called in2000.
config SCSI_ARCMSR config SCSI_ARCMSR
tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" tristate "ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID Host Adapter"
depends on PCI && SCSI depends on PCI && SCSI
help help
This driver supports all of ARECA's SATA RAID controller cards. This driver supports all of ARECA's SATA/SAS RAID controller cards.
This is an ARECA-maintained driver by Erich Chen. This is an ARECA-maintained driver by Erich Chen.
If you have any problems, please mail to: < erich@areca.com.tw > If you have any problems, please mail to: <erich@areca.com.tw>.
Areca supports Linux RAID config tools. Areca supports Linux RAID config tools.
Please link <http://www.areca.com.tw>
< http://www.areca.com.tw >
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called arcmsr (modprobe arcmsr). module will be called arcmsr (modprobe arcmsr).
config SCSI_ARCMSR_AER
bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)"
depends on SCSI_ARCMSR && PCIEAER
default n
help
The advanced error reporting(AER) capability is "NOT" provided by
ARC1200/1201/1202 SATA RAID controllers cards.
If your card is one of ARC1200/1201/1202, please use the default setting, n.
If your card is other models, you could pick it
on condition that the kernel version is greater than 2.6.19.
This function is maintained driver by Nick Cheng. If you have any
problems or suggestion, you are welcome to contact with <nick.cheng@areca.com.tw>.
To enable this function, choose Y here.
source "drivers/scsi/megaraid/Kconfig.megaraid" source "drivers/scsi/megaraid/Kconfig.megaraid"
config SCSI_HPTIOP config SCSI_HPTIOP
@ -836,6 +869,7 @@ config SCSI_IPS
config SCSI_IBMVSCSI config SCSI_IBMVSCSI
tristate "IBM Virtual SCSI support" tristate "IBM Virtual SCSI support"
depends on PPC_PSERIES || PPC_ISERIES depends on PPC_PSERIES || PPC_ISERIES
select SCSI_SRP_ATTRS
help help
This is the IBM POWER Virtual SCSI Client This is the IBM POWER Virtual SCSI Client
@ -844,7 +878,7 @@ config SCSI_IBMVSCSI
config SCSI_IBMVSCSIS config SCSI_IBMVSCSIS
tristate "IBM Virtual SCSI Server support" tristate "IBM Virtual SCSI Server support"
depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP depends on PPC_PSERIES && SCSI_SRP && SCSI_SRP_TGT_ATTRS
help help
This is the SRP target driver for IBM pSeries virtual environments. This is the SRP target driver for IBM pSeries virtual environments.

View file

@ -34,6 +34,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o
obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o
obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o
obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/ obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/
obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o

View file

@ -1542,9 +1542,7 @@ part2:
hostdata->connected = cmd; hostdata->connected = cmd;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
if (cmd->SCp.ptr != (char *)cmd->sense_buffer) { initialize_SCp(cmd);
initialize_SCp(cmd);
}
return 0; return 0;
@ -2133,7 +2131,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->done(cmd); cmd->scsi_done(cmd);
return; return;
#endif #endif
/* /*
@ -2196,7 +2194,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->done(cmd); cmd->scsi_done(cmd);
/* XXX - need to source or sink data here, as appropriate */ /* XXX - need to source or sink data here, as appropriate */
} else } else
cmd->SCp.this_residual -= transfersize - len; cmd->SCp.this_residual -= transfersize - len;
@ -2280,19 +2278,16 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
#ifdef AUTOSENSE #ifdef AUTOSENSE
if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { if ((cmd->cmnd[0] == REQUEST_SENSE) &&
dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no)); hostdata->ses.cmd_len) {
cmd->cmnd[0] = REQUEST_SENSE; scsi_eh_restore_cmnd(cmd, &hostdata->ses);
cmd->cmnd[1] &= 0xe0; hostdata->ses.cmd_len = 0 ;
cmd->cmnd[2] = 0; }
cmd->cmnd[3] = 0;
cmd->cmnd[4] = sizeof(cmd->sense_buffer);
cmd->cmnd[5] = 0;
cmd->SCp.buffer = NULL; if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
cmd->SCp.buffers_residual = 0; scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
cmd->SCp.ptr = (char *) cmd->sense_buffer;
cmd->SCp.this_residual = sizeof(cmd->sense_buffer); dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no));
LIST(cmd, hostdata->issue_queue); LIST(cmd, hostdata->issue_queue);
cmd->host_scribble = (unsigned char *) cmd->host_scribble = (unsigned char *)
@ -2740,7 +2735,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
tmp->host_scribble = NULL; tmp->host_scribble = NULL;
tmp->result = DID_ABORT << 16; tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no)); dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no));
tmp->done(tmp); tmp->scsi_done(tmp);
return SUCCESS; return SUCCESS;
} }
#if (NDEBUG & NDEBUG_ABORT) #if (NDEBUG & NDEBUG_ABORT)
@ -2805,7 +2800,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
*prev = (Scsi_Cmnd *) tmp->host_scribble; *prev = (Scsi_Cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL; tmp->host_scribble = NULL;
tmp->result = DID_ABORT << 16; tmp->result = DID_ABORT << 16;
tmp->done(tmp); tmp->scsi_done(tmp);
return SUCCESS; return SUCCESS;
} }
} }

View file

@ -30,6 +30,10 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#ifdef AUTOSENSE
#include <scsi/scsi_eh.h>
#endif
#define NCR5380_PUBLIC_RELEASE 7 #define NCR5380_PUBLIC_RELEASE 7
#define NCR53C400_PUBLIC_RELEASE 2 #define NCR53C400_PUBLIC_RELEASE 2
@ -281,6 +285,9 @@ struct NCR5380_hostdata {
unsigned pendingr; unsigned pendingr;
unsigned pendingw; unsigned pendingw;
#endif #endif
#ifdef AUTOSENSE
struct scsi_eh_save ses;
#endif
}; };
#ifdef __KERNEL__ #ifdef __KERNEL__

View file

@ -1385,7 +1385,7 @@ int esp_abort(Scsi_Cmnd *SCptr)
this->host_scribble = NULL; this->host_scribble = NULL;
esp_release_dmabufs(esp, this); esp_release_dmabufs(esp, this);
this->result = DID_ABORT << 16; this->result = DID_ABORT << 16;
this->done(this); this->scsi_done(this);
if(don) if(don)
esp->dma_ints_on(esp); esp->dma_ints_on(esp);
return SUCCESS; return SUCCESS;

View file

@ -97,7 +97,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mca.h> #include <linux/mca.h>
#include <linux/interrupt.h>
#include <asm/io.h> #include <asm/io.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
@ -314,10 +313,10 @@ NCR_D700_probe(struct device *dev)
break; break;
} }
p = kmalloc(sizeof(*p), GFP_KERNEL); p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
memset(p, '\0', sizeof(*p));
p->dev = dev; p->dev = dev;
snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id); snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id);
if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) { if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) {

View file

@ -37,7 +37,7 @@ static struct platform_device *a4000t_scsi_device;
static int __devinit a4000t_probe(struct device *dev) static int __devinit a4000t_probe(struct device *dev)
{ {
struct Scsi_Host * host = NULL; struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata; struct NCR_700_Host_Parameters *hostdata;
if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI)))
@ -47,12 +47,11 @@ static int __devinit a4000t_probe(struct device *dev)
"A4000T builtin SCSI")) "A4000T builtin SCSI"))
goto out; goto out;
hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
if (hostdata == NULL) { if (!hostdata) {
printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n");
goto out_release; goto out_release;
} }
memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
/* Fill in the required pieces of hostdata */ /* Fill in the required pieces of hostdata */
hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR);

View file

@ -177,9 +177,9 @@ int check_interval = 24 * 60 * 60;
module_param(check_interval, int, S_IRUGO|S_IWUSR); module_param(check_interval, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks.");
int check_reset = 1; int aac_check_reset = 1;
module_param(check_reset, int, S_IRUGO|S_IWUSR); module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the adapter."); MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter.");
int expose_physicals = -1; int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR); module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
@ -1305,7 +1305,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
(int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid),
dev->supplement_adapter_info.VpdInfo.Tsid); dev->supplement_adapter_info.VpdInfo.Tsid);
} }
if (!check_reset || if (!aac_check_reset ||
(dev->supplement_adapter_info.SupportedOptions2 & (dev->supplement_adapter_info.SupportedOptions2 &
le32_to_cpu(AAC_OPTION_IGNORE_RESET))) { le32_to_cpu(AAC_OPTION_IGNORE_RESET))) {
printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",

View file

@ -1871,4 +1871,4 @@ extern int aac_reset_devices;
extern int aac_commit; extern int aac_commit;
extern int update_interval; extern int update_interval;
extern int check_interval; extern int check_interval;
extern int check_reset; extern int aac_check_reset;

View file

@ -1372,8 +1372,9 @@ int aac_check_health(struct aac_dev * aac)
printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
if (!check_reset || (aac->supplement_adapter_info.SupportedOptions2 & if (!aac_check_reset ||
le32_to_cpu(AAC_OPTION_IGNORE_RESET))) (aac->supplement_adapter_info.SupportedOptions2 &
le32_to_cpu(AAC_OPTION_IGNORE_RESET)))
goto out; goto out;
host = aac->scsi_host_ptr; host = aac->scsi_host_ptr;
if (aac->thread->pid != current->pid) if (aac->thread->pid != current->pid)

File diff suppressed because it is too large Load diff

View file

@ -907,9 +907,10 @@ out_host_put:
void aha152x_release(struct Scsi_Host *shpnt) void aha152x_release(struct Scsi_Host *shpnt)
{ {
if(!shpnt) if (!shpnt)
return; return;
scsi_remove_host(shpnt);
if (shpnt->irq) if (shpnt->irq)
free_irq(shpnt->irq, shpnt); free_irq(shpnt->irq, shpnt);
@ -923,7 +924,6 @@ void aha152x_release(struct Scsi_Host *shpnt)
pnp_device_detach(HOSTDATA(shpnt)->pnpdev); pnp_device_detach(HOSTDATA(shpnt)->pnpdev);
#endif #endif
scsi_remove_host(shpnt);
list_del(&HOSTDATA(shpnt)->host_list); list_del(&HOSTDATA(shpnt)->host_list);
scsi_host_put(shpnt); scsi_host_put(shpnt);
} }

View file

@ -8416,10 +8416,9 @@ aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp)
*p = *temp; *p = *temp;
p->host = host; p->host = host;
p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC); p->scb_data = kzalloc(sizeof(scb_data_type), GFP_ATOMIC);
if (p->scb_data != NULL) if (!p->scb_data)
{ {
memset(p->scb_data, 0, sizeof(scb_data_type));
scbq_init (&p->scb_data->free_scbs); scbq_init (&p->scb_data->free_scbs);
} }
else else
@ -9196,10 +9195,9 @@ aic7xxx_detect(struct scsi_host_template *template)
printk(KERN_INFO " this driver, we are ignoring it.\n"); printk(KERN_INFO " this driver, we are ignoring it.\n");
} }
} }
else if ( (temp_p = kmalloc(sizeof(struct aic7xxx_host), else if ( (temp_p = kzalloc(sizeof(struct aic7xxx_host),
GFP_ATOMIC)) != NULL ) GFP_ATOMIC)) != NULL )
{ {
memset(temp_p, 0, sizeof(struct aic7xxx_host));
temp_p->chip = aic_pdevs[i].chip | AHC_PCI; temp_p->chip = aic_pdevs[i].chip | AHC_PCI;
temp_p->flags = aic_pdevs[i].flags; temp_p->flags = aic_pdevs[i].flags;
temp_p->features = aic_pdevs[i].features; temp_p->features = aic_pdevs[i].features;

View file

@ -40,18 +40,6 @@
#define ASD_MAX_PHYS 8 #define ASD_MAX_PHYS 8
#define ASD_PCBA_SN_SIZE 12 #define ASD_PCBA_SN_SIZE 12
/* Those are to be further named properly, the "RAZORx" part, and
* subsequently included in include/linux/pci_ids.h.
*/
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E
#define PCI_DEVICE_ID_ADAPTEC2_RAZOR3F 0x43F
struct asd_ha_addrspace { struct asd_ha_addrspace {
void __iomem *addr; void __iomem *addr;
unsigned long start; /* pci resource start */ unsigned long start; /* pci resource start */

View file

@ -583,7 +583,7 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL);
if (!asd_ha) { if (!asd_ha) {
asd_printk("out of memory\n"); asd_printk("out of memory\n");
goto Err; goto Err_put;
} }
asd_ha->pcidev = dev; asd_ha->pcidev = dev;
asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; asd_ha->sas_ha.dev = &asd_ha->pcidev->dev;
@ -600,14 +600,12 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
err = scsi_add_host(shost, &dev->dev); err = scsi_add_host(shost, &dev->dev);
if (err) { if (err)
scsi_host_put(shost);
goto Err_free; goto Err_free;
}
err = asd_dev->setup(asd_ha); err = asd_dev->setup(asd_ha);
if (err) if (err)
goto Err_free; goto Err_remove;
err = -ENODEV; err = -ENODEV;
if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)
@ -618,14 +616,14 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
; ;
else { else {
asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); asd_printk("no suitable DMA mask for %s\n", pci_name(dev));
goto Err_free; goto Err_remove;
} }
pci_set_drvdata(dev, asd_ha); pci_set_drvdata(dev, asd_ha);
err = asd_map_ha(asd_ha); err = asd_map_ha(asd_ha);
if (err) if (err)
goto Err_free; goto Err_remove;
err = asd_create_ha_caches(asd_ha); err = asd_create_ha_caches(asd_ha);
if (err) if (err)
@ -692,9 +690,12 @@ Err_free_cache:
asd_destroy_ha_caches(asd_ha); asd_destroy_ha_caches(asd_ha);
Err_unmap: Err_unmap:
asd_unmap_ha(asd_ha); asd_unmap_ha(asd_ha);
Err_remove:
scsi_remove_host(shost);
Err_free: Err_free:
kfree(asd_ha); kfree(asd_ha);
scsi_remove_host(shost); Err_put:
scsi_host_put(shost);
Err: Err:
pci_disable_device(dev); pci_disable_device(dev);
return err; return err;
@ -829,22 +830,15 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
}; };
static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR10), {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1},
0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR12), {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1},
0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41E),0, 0, 1},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41F),0, 0, 1},
0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x430),0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x432),0, 0, 2},
0, 0, 1}, {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43E),0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43F),0, 0, 2},
0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32),
0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3E),
0, 0, 2},
{PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3F),
0, 0, 2},
{} {}
}; };

View file

@ -207,7 +207,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb,
"stat(0x%x) is not CHECK_CONDITION" "stat(0x%x) is not CHECK_CONDITION"
"\n", "\n",
SAS_ADDR(task->dev->sas_addr), SAS_ADDR(task->dev->sas_addr),
ts->stat); iu->status);
} }
} }
} else { } else {

View file

@ -9,7 +9,7 @@
** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved.
** **
** Web site: www.areca.com.tw ** Web site: www.areca.com.tw
** E-mail: erich@areca.com.tw ** E-mail: support@areca.com.tw
** **
** This program is free software; you can redistribute it and/or modify ** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 2 as ** it under the terms of the GNU General Public License version 2 as
@ -45,19 +45,26 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
struct class_device_attribute; struct class_device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_OUTSTANDING_CMD 256
#define ARCMSR_MAX_FREECCB_NUM 288 #define ARCMSR_MAX_FREECCB_NUM 320
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.14" #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/08/30"
#define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096 #define ARCMSR_MAX_XFER_SECTORS_B 4096
#define ARCMSR_MAX_TARGETID 17 #define ARCMSR_MAX_TARGETID 17
#define ARCMSR_MAX_TARGETLUN 8 #define ARCMSR_MAX_TARGETLUN 8
#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD
#define ARCMSR_MAX_QBUFFER 4096 #define ARCMSR_MAX_QBUFFER 4096
#define ARCMSR_MAX_SG_ENTRIES 38 #define ARCMSR_MAX_SG_ENTRIES 38
#define ARCMSR_MAX_HBB_POSTQUEUE 264
/*
**********************************************************************************
**
**********************************************************************************
*/
#define ARC_SUCCESS 0
#define ARC_FAILURE 1
/* /*
******************************************************************************* *******************************************************************************
** split 64bits dma addressing ** split 64bits dma addressing
@ -90,7 +97,7 @@ struct CMD_MESSAGE_FIELD
uint8_t messagedatabuffer[1032]; uint8_t messagedatabuffer[1032];
}; };
/* IOP message transfer */ /* IOP message transfer */
#define ARCMSR_MESSAGE_FAIL 0x0001 #define ARCMSR_MESSAGE_FAIL 0x0001
/* DeviceType */ /* DeviceType */
#define ARECA_SATA_RAID 0x90000000 #define ARECA_SATA_RAID 0x90000000
/* FunctionCode */ /* FunctionCode */
@ -163,27 +170,27 @@ struct QBUFFER
}; };
/* /*
******************************************************************************* *******************************************************************************
** FIRMWARE INFO ** FIRMWARE INFO for Intel IOP R 80331 processor (Type A)
******************************************************************************* *******************************************************************************
*/ */
struct FIRMWARE_INFO struct FIRMWARE_INFO
{ {
uint32_t signature; /*0, 00-03*/ uint32_t signature; /*0, 00-03*/
uint32_t request_len; /*1, 04-07*/ uint32_t request_len; /*1, 04-07*/
uint32_t numbers_queue; /*2, 08-11*/ uint32_t numbers_queue; /*2, 08-11*/
uint32_t sdram_size; /*3, 12-15*/ uint32_t sdram_size; /*3, 12-15*/
uint32_t ide_channels; /*4, 16-19*/ uint32_t ide_channels; /*4, 16-19*/
char vendor[40]; /*5, 20-59*/ char vendor[40]; /*5, 20-59*/
char model[8]; /*15, 60-67*/ char model[8]; /*15, 60-67*/
char firmware_ver[16]; /*17, 68-83*/ char firmware_ver[16]; /*17, 68-83*/
char device_map[16]; /*21, 84-99*/ char device_map[16]; /*21, 84-99*/
}; };
/* signature of set and get firmware config */ /* signature of set and get firmware config */
#define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060
#define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 #define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063
/* message code of inbound message register */ /* message code of inbound message register */
#define ARCMSR_INBOUND_MESG0_NOP 0x00000000 #define ARCMSR_INBOUND_MESG0_NOP 0x00000000
#define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 #define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001
#define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 #define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002
#define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 #define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003
#define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 #define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004
@ -203,6 +210,60 @@ struct FIRMWARE_INFO
#define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000
/* outbound firmware ok */ /* outbound firmware ok */
#define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000
/*
************************************************************************
** SPEC. for Areca Type B adapter
************************************************************************
*/
/* ARECA HBB COMMAND for its FIRMWARE */
/* window of "instruction flags" from driver to iop */
#define ARCMSR_DRV2IOP_DOORBELL 0x00020400
#define ARCMSR_DRV2IOP_DOORBELL_MASK 0x00020404
/* window of "instruction flags" from iop to driver */
#define ARCMSR_IOP2DRV_DOORBELL 0x00020408
#define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C
/* ARECA FLAG LANGUAGE */
/* ioctl transfer */
#define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001
/* ioctl transfer */
#define ARCMSR_IOP2DRV_DATA_READ_OK 0x00000002
#define ARCMSR_IOP2DRV_CDB_DONE 0x00000004
#define ARCMSR_IOP2DRV_MESSAGE_CMD_DONE 0x00000008
#define ARCMSR_DOORBELL_HANDLE_INT 0x0000000F
#define ARCMSR_DOORBELL_INT_CLEAR_PATTERN 0xFF00FFF0
#define ARCMSR_MESSAGE_INT_CLEAR_PATTERN 0xFF00FFF7
/* (ARCMSR_INBOUND_MESG0_GET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_GET_CONFIG 0x00010008
/* (ARCMSR_INBOUND_MESG0_SET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_SET_CONFIG 0x00020008
/* (ARCMSR_INBOUND_MESG0_ABORT_CMD<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_ABORT_CMD 0x00030008
/* (ARCMSR_INBOUND_MESG0_STOP_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_STOP_BGRB 0x00040008
/* (ARCMSR_INBOUND_MESG0_FLUSH_CACHE<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_FLUSH_CACHE 0x00050008
/* (ARCMSR_INBOUND_MESG0_START_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */
#define ARCMSR_MESSAGE_START_BGRB 0x00060008
#define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008
#define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008
/* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */
#define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000
/* ioctl transfer */
#define ARCMSR_DRV2IOP_DATA_WRITE_OK 0x00000001
/* ioctl transfer */
#define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002
#define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004
#define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008
/* data tunnel buffer between user space program and its firmware */
/* user space data to iop 128bytes */
#define ARCMSR_IOCTL_WBUFFER 0x0000fe00
/* iop data to user space 128bytes */
#define ARCMSR_IOCTL_RBUFFER 0x0000ff00
/* iop message_rwbuffer for message command */
#define ARCMSR_MSGCODE_RWBUFFER 0x0000fa00
/* /*
******************************************************************************* *******************************************************************************
** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
@ -214,7 +275,6 @@ struct ARCMSR_CDB
uint8_t TargetID; uint8_t TargetID;
uint8_t LUN; uint8_t LUN;
uint8_t Function; uint8_t Function;
uint8_t CdbLength; uint8_t CdbLength;
uint8_t sgcount; uint8_t sgcount;
uint8_t Flags; uint8_t Flags;
@ -224,20 +284,18 @@ struct ARCMSR_CDB
#define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 #define ARCMSR_CDB_FLAG_SIMPLEQ 0x00
#define ARCMSR_CDB_FLAG_HEADQ 0x08 #define ARCMSR_CDB_FLAG_HEADQ 0x08
#define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 #define ARCMSR_CDB_FLAG_ORDEREDQ 0x10
uint8_t Reserved1;
uint8_t Reserved1;
uint32_t Context; uint32_t Context;
uint32_t DataLength; uint32_t DataLength;
uint8_t Cdb[16]; uint8_t Cdb[16];
uint8_t DeviceStatus; uint8_t DeviceStatus;
#define ARCMSR_DEV_CHECK_CONDITION 0x02 #define ARCMSR_DEV_CHECK_CONDITION 0x02
#define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 #define ARCMSR_DEV_SELECT_TIMEOUT 0xF0
#define ARCMSR_DEV_ABORTED 0xF1 #define ARCMSR_DEV_ABORTED 0xF1
#define ARCMSR_DEV_INIT_FAIL 0xF2 #define ARCMSR_DEV_INIT_FAIL 0xF2
uint8_t SenseData[15];
uint8_t SenseData[15];
union union
{ {
struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES];
@ -246,10 +304,10 @@ struct ARCMSR_CDB
}; };
/* /*
******************************************************************************* *******************************************************************************
** Messaging Unit (MU) of the Intel R 80331 I/O processor (80331) ** Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor
******************************************************************************* *******************************************************************************
*/ */
struct MessageUnit struct MessageUnit_A
{ {
uint32_t resrved0[4]; /*0000 000F*/ uint32_t resrved0[4]; /*0000 000F*/
uint32_t inbound_msgaddr0; /*0010 0013*/ uint32_t inbound_msgaddr0; /*0010 0013*/
@ -274,6 +332,30 @@ struct MessageUnit
uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/
uint32_t reserved6[32]; /*0F80 0FFF 32*/ uint32_t reserved6[32]; /*0F80 0FFF 32*/
}; };
struct MessageUnit_B
{
uint32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
uint32_t postq_index;
uint32_t doneq_index;
uint32_t *drv2iop_doorbell_reg;
uint32_t *drv2iop_doorbell_mask_reg;
uint32_t *iop2drv_doorbell_reg;
uint32_t *iop2drv_doorbell_mask_reg;
uint32_t *msgcode_rwbuffer_reg;
uint32_t *ioctl_wbuffer_reg;
uint32_t *ioctl_rbuffer_reg;
};
struct MessageUnit
{
union
{
struct MessageUnit_A pmu_A;
struct MessageUnit_B pmu_B;
} u;
};
/* /*
******************************************************************************* *******************************************************************************
** Adapter Control Block ** Adapter Control Block
@ -281,37 +363,45 @@ struct MessageUnit
*/ */
struct AdapterControlBlock struct AdapterControlBlock
{ {
uint32_t adapter_type; /* adapter A,B..... */
#define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */
#define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */
#define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc P IOP */
#define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */
struct pci_dev * pdev; struct pci_dev * pdev;
struct Scsi_Host * host; struct Scsi_Host * host;
unsigned long vir2phy_offset; unsigned long vir2phy_offset;
/* Offset is used in making arc cdb physical to virtual calculations */ /* Offset is used in making arc cdb physical to virtual calculations */
uint32_t outbound_int_enable; uint32_t outbound_int_enable;
struct MessageUnit __iomem * pmu; struct MessageUnit * pmu;
/* message unit ATU inbound base address0 */ /* message unit ATU inbound base address0 */
uint32_t acb_flags; uint32_t acb_flags;
#define ACB_F_SCSISTOPADAPTER 0x0001 #define ACB_F_SCSISTOPADAPTER 0x0001
#define ACB_F_MSG_STOP_BGRB 0x0002 #define ACB_F_MSG_STOP_BGRB 0x0002
/* stop RAID background rebuild */ /* stop RAID background rebuild */
#define ACB_F_MSG_START_BGRB 0x0004 #define ACB_F_MSG_START_BGRB 0x0004
/* stop RAID background rebuild */ /* stop RAID background rebuild */
#define ACB_F_IOPDATA_OVERFLOW 0x0008 #define ACB_F_IOPDATA_OVERFLOW 0x0008
/* iop message data rqbuffer overflow */ /* iop message data rqbuffer overflow */
#define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 #define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010
/* message clear wqbuffer */ /* message clear wqbuffer */
#define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 #define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020
/* message clear rqbuffer */ /* message clear rqbuffer */
#define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040
#define ACB_F_BUS_RESET 0x0080 #define ACB_F_BUS_RESET 0x0080
#define ACB_F_IOP_INITED 0x0100 #define ACB_F_IOP_INITED 0x0100
/* iop init */ /* iop init */
struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */ /* used for memory free */
struct list_head ccb_free_list; struct list_head ccb_free_list;
/* head of free ccb list */ /* head of free ccb list */
atomic_t ccboutstandingcount; atomic_t ccboutstandingcount;
/*The present outstanding command number that in the IOP that
waiting for being handled by FW*/
void * dma_coherent; void * dma_coherent;
/* dma_coherent used for memory free */ /* dma_coherent used for memory free */
@ -353,7 +443,7 @@ struct CommandControlBlock
{ {
struct ARCMSR_CDB arcmsr_cdb; struct ARCMSR_CDB arcmsr_cdb;
/* /*
** 0-503 (size of CDB=504): ** 0-503 (size of CDB = 504):
** arcmsr messenger scsi command descriptor size 504 bytes ** arcmsr messenger scsi command descriptor size 504 bytes
*/ */
uint32_t cdb_shifted_phyaddr; uint32_t cdb_shifted_phyaddr;
@ -466,7 +556,9 @@ struct SENSE_DATA
#define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 #define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01
#define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F #define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F
extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb); extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *);
extern void arcmsr_iop_message_read(struct AdapterControlBlock *);
extern struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *);
extern struct class_device_attribute *arcmsr_host_attrs[]; extern struct class_device_attribute *arcmsr_host_attrs[];
extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *);
void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb);

View file

@ -8,7 +8,7 @@
** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved
** **
** Web site: www.areca.com.tw ** Web site: www.areca.com.tw
** E-mail: erich@areca.com.tw ** E-mail: support@areca.com.tw
** **
** This program is free software; you can redistribute it and/or modify ** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License version 2 as ** it under the terms of the GNU General Public License version 2 as
@ -49,6 +49,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pci.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
@ -58,15 +59,14 @@
struct class_device_attribute *arcmsr_host_attrs[]; struct class_device_attribute *arcmsr_host_attrs[];
static ssize_t static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj,
arcmsr_sysfs_iop_message_read(struct kobject *kobj, struct bin_attribute *bin,
struct bin_attribute *bin_attr, char *buf, loff_t off,
char *buf, loff_t off, size_t count) size_t count)
{ {
struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct class_device *cdev = container_of(kobj,struct class_device,kobj);
struct Scsi_Host *host = class_to_shost(cdev); struct Scsi_Host *host = class_to_shost(cdev);
struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
struct MessageUnit __iomem *reg = acb->pmu;
uint8_t *pQbuffer,*ptmpQbuffer; uint8_t *pQbuffer,*ptmpQbuffer;
int32_t allxfer_len = 0; int32_t allxfer_len = 0;
@ -85,12 +85,13 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj,
allxfer_len++; allxfer_len++;
} }
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) struct QBUFFER *prbuffer;
&reg->message_rbuffer; uint8_t *iop_data;
uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data;
int32_t iop_len; int32_t iop_len;
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
iop_data = (uint8_t *)prbuffer->data;
iop_len = readl(&prbuffer->data_len); iop_len = readl(&prbuffer->data_len);
while (iop_len > 0) { while (iop_len > 0) {
acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
@ -99,16 +100,15 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj,
iop_data++; iop_data++;
iop_len--; iop_len--;
} }
writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, arcmsr_iop_message_read(acb);
&reg->inbound_doorbell);
} }
return (allxfer_len); return (allxfer_len);
} }
static ssize_t static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj,
arcmsr_sysfs_iop_message_write(struct kobject *kobj, struct bin_attribute *bin,
struct bin_attribute *bin_attr, char *buf, loff_t off,
char *buf, loff_t off, size_t count) size_t count)
{ {
struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct class_device *cdev = container_of(kobj,struct class_device,kobj);
struct Scsi_Host *host = class_to_shost(cdev); struct Scsi_Host *host = class_to_shost(cdev);
@ -126,7 +126,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj,
wqbuf_lastindex = acb->wqbuf_lastindex; wqbuf_lastindex = acb->wqbuf_lastindex;
wqbuf_firstindex = acb->wqbuf_firstindex; wqbuf_firstindex = acb->wqbuf_firstindex;
if (wqbuf_lastindex != wqbuf_firstindex) { if (wqbuf_lastindex != wqbuf_firstindex) {
arcmsr_post_Qbuffer(acb); arcmsr_post_ioctldata2iop(acb);
return 0; /*need retry*/ return 0; /*need retry*/
} else { } else {
my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
@ -144,7 +144,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj,
if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
acb->acb_flags &= acb->acb_flags &=
~ACB_F_MESSAGE_WQBUFFER_CLEARED; ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
arcmsr_post_Qbuffer(acb); arcmsr_post_ioctldata2iop(acb);
} }
return count; return count;
} else { } else {
@ -153,15 +153,14 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj,
} }
} }
static ssize_t static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj,
arcmsr_sysfs_iop_message_clear(struct kobject *kobj, struct bin_attribute *bin,
struct bin_attribute *bin_attr, char *buf, loff_t off,
char *buf, loff_t off, size_t count) size_t count)
{ {
struct class_device *cdev = container_of(kobj,struct class_device,kobj); struct class_device *cdev = container_of(kobj,struct class_device,kobj);
struct Scsi_Host *host = class_to_shost(cdev); struct Scsi_Host *host = class_to_shost(cdev);
struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
struct MessageUnit __iomem *reg = acb->pmu;
uint8_t *pQbuffer; uint8_t *pQbuffer;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
@ -169,8 +168,7 @@ arcmsr_sysfs_iop_message_clear(struct kobject *kobj,
if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK arcmsr_iop_message_read(acb);
, &reg->inbound_doorbell);
} }
acb->acb_flags |= acb->acb_flags |=
(ACB_F_MESSAGE_WQBUFFER_CLEARED (ACB_F_MESSAGE_WQBUFFER_CLEARED
@ -191,6 +189,7 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = {
.attr = { .attr = {
.name = "mu_read", .name = "mu_read",
.mode = S_IRUSR , .mode = S_IRUSR ,
.owner = THIS_MODULE,
}, },
.size = 1032, .size = 1032,
.read = arcmsr_sysfs_iop_message_read, .read = arcmsr_sysfs_iop_message_read,
@ -200,6 +199,7 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = {
.attr = { .attr = {
.name = "mu_write", .name = "mu_write",
.mode = S_IWUSR, .mode = S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = 1032, .size = 1032,
.write = arcmsr_sysfs_iop_message_write, .write = arcmsr_sysfs_iop_message_write,
@ -209,6 +209,7 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = {
.attr = { .attr = {
.name = "mu_clear", .name = "mu_clear",
.mode = S_IWUSR, .mode = S_IWUSR,
.owner = THIS_MODULE,
}, },
.size = 1, .size = 1,
.write = arcmsr_sysfs_iop_message_clear, .write = arcmsr_sysfs_iop_message_clear,
@ -219,31 +220,26 @@ int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb)
struct Scsi_Host *host = acb->host; struct Scsi_Host *host = acb->host;
int error; int error;
error = sysfs_create_bin_file(&host->shost_classdev.kobj, error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr);
&arcmsr_sysfs_message_read_attr);
if (error) { if (error) {
printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n");
goto error_bin_file_message_read; goto error_bin_file_message_read;
} }
error = sysfs_create_bin_file(&host->shost_classdev.kobj, error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr);
&arcmsr_sysfs_message_write_attr);
if (error) { if (error) {
printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n");
goto error_bin_file_message_write; goto error_bin_file_message_write;
} }
error = sysfs_create_bin_file(&host->shost_classdev.kobj, error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr);
&arcmsr_sysfs_message_clear_attr);
if (error) { if (error) {
printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n");
goto error_bin_file_message_clear; goto error_bin_file_message_clear;
} }
return 0; return 0;
error_bin_file_message_clear: error_bin_file_message_clear:
sysfs_remove_bin_file(&host->shost_classdev.kobj, sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr);
&arcmsr_sysfs_message_write_attr);
error_bin_file_message_write: error_bin_file_message_write:
sysfs_remove_bin_file(&host->shost_classdev.kobj, sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr);
&arcmsr_sysfs_message_read_attr);
error_bin_file_message_read: error_bin_file_message_read:
return error; return error;
} }
@ -252,12 +248,9 @@ void
arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) {
struct Scsi_Host *host = acb->host; struct Scsi_Host *host = acb->host;
sysfs_remove_bin_file(&host->shost_classdev.kobj, sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr);
&arcmsr_sysfs_message_clear_attr); sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr);
sysfs_remove_bin_file(&host->shost_classdev.kobj, sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr);
&arcmsr_sysfs_message_write_attr);
sysfs_remove_bin_file(&host->shost_classdev.kobj,
&arcmsr_sysfs_message_read_attr);
} }

File diff suppressed because it is too large Load diff

View file

@ -2041,7 +2041,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->done(cmd); cmd->scsi_done(cmd);
return; return;
#endif #endif
case PHASE_DATAIN: case PHASE_DATAIN:
@ -2100,7 +2100,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->done(cmd); cmd->scsi_done(cmd);
/* XXX - need to source or sink data here, as appropriate */ /* XXX - need to source or sink data here, as appropriate */
} else { } else {
#ifdef REAL_DMA #ifdef REAL_DMA
@ -2235,24 +2235,17 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
#ifdef AUTOSENSE #ifdef AUTOSENSE
if ((cmd->cmnd[0] == REQUEST_SENSE) &&
hostdata->ses.cmd_len) {
scsi_eh_restore_cmnd(cmd, &hostdata->ses);
hostdata->ses.cmd_len = 0 ;
}
if ((cmd->cmnd[0] != REQUEST_SENSE) && if ((cmd->cmnd[0] != REQUEST_SENSE) &&
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
cmd->cmnd[0] = REQUEST_SENSE;
cmd->cmnd[1] &= 0xe0;
cmd->cmnd[2] = 0;
cmd->cmnd[3] = 0;
cmd->cmnd[4] = sizeof(cmd->sense_buffer);
cmd->cmnd[5] = 0;
cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
cmd->use_sg = 0; ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO);
/* this is initialized from initialize_SCp
cmd->SCp.buffer = NULL;
cmd->SCp.buffers_residual = 0;
*/
cmd->request_buffer = (char *) cmd->sense_buffer;
cmd->request_bufflen = sizeof(cmd->sense_buffer);
local_irq_save(flags); local_irq_save(flags);
LIST(cmd,hostdata->issue_queue); LIST(cmd,hostdata->issue_queue);

View file

@ -36,19 +36,18 @@ static struct platform_device *bvme6000_scsi_device;
static __devinit int static __devinit int
bvme6000_probe(struct device *dev) bvme6000_probe(struct device *dev)
{ {
struct Scsi_Host * host = NULL; struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata; struct NCR_700_Host_Parameters *hostdata;
if (!MACH_IS_BVME6000) if (!MACH_IS_BVME6000)
goto out; goto out;
hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
if (hostdata == NULL) { if (!hostdata) {
printk(KERN_ERR "bvme6000-scsi: " printk(KERN_ERR "bvme6000-scsi: "
"Failed to allocate host data\n"); "Failed to allocate host data\n");
goto out; goto out;
} }
memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
/* Fill in the required pieces of hostdata */ /* Fill in the required pieces of hostdata */
hostdata->base = (void __iomem *)BVME_NCR53C710_BASE; hostdata->base = (void __iomem *)BVME_NCR53C710_BASE;

View file

@ -1235,7 +1235,21 @@ scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
} }
EXPORT_SYMBOL(scsi_print_sense_hdr); EXPORT_SYMBOL(scsi_print_sense_hdr);
/*
* Print normalized SCSI sense header with device information and a prefix.
*/
void void
scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const char *desc,
struct scsi_sense_hdr *sshdr)
{
scmd_printk(KERN_INFO, scmd, "%s: ", desc);
scsi_show_sense_hdr(sshdr);
scmd_printk(KERN_INFO, scmd, "%s: ", desc);
scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
}
EXPORT_SYMBOL(scsi_cmd_print_sense_hdr);
static void
scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
struct scsi_sense_hdr *sshdr) struct scsi_sense_hdr *sshdr)
{ {
@ -1258,7 +1272,7 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
} }
} }
void static void
scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len,
struct scsi_sense_hdr *sshdr) struct scsi_sense_hdr *sshdr)
{ {

View file

@ -778,7 +778,7 @@ static void srb_waiting_insert(struct DeviceCtlBlk *dcb,
struct ScsiReqBlk *srb) struct ScsiReqBlk *srb)
{ {
dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_add(&srb->list, &dcb->srb_waiting_list); list_add(&srb->list, &dcb->srb_waiting_list);
} }
@ -787,7 +787,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb,
struct ScsiReqBlk *srb) struct ScsiReqBlk *srb)
{ {
dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_add_tail(&srb->list, &dcb->srb_waiting_list); list_add_tail(&srb->list, &dcb->srb_waiting_list);
} }
@ -795,7 +795,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb,
static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{ {
dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_add_tail(&srb->list, &dcb->srb_going_list); list_add_tail(&srb->list, &dcb->srb_going_list);
} }
@ -805,7 +805,7 @@ static void srb_going_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
struct ScsiReqBlk *i; struct ScsiReqBlk *i;
struct ScsiReqBlk *tmp; struct ScsiReqBlk *tmp;
dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list)
if (i == srb) { if (i == srb) {
@ -821,7 +821,7 @@ static void srb_waiting_remove(struct DeviceCtlBlk *dcb,
struct ScsiReqBlk *i; struct ScsiReqBlk *i;
struct ScsiReqBlk *tmp; struct ScsiReqBlk *tmp;
dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list)
if (i == srb) { if (i == srb) {
@ -836,7 +836,7 @@ static void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb,
{ {
dprintkdbg(DBG_0, dprintkdbg(DBG_0,
"srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n", "srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_move(&srb->list, &dcb->srb_waiting_list); list_move(&srb->list, &dcb->srb_waiting_list);
} }
@ -846,7 +846,7 @@ static void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb,
{ {
dprintkdbg(DBG_0, dprintkdbg(DBG_0,
"srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n", "srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
list_move(&srb->list, &dcb->srb_going_list); list_move(&srb->list, &dcb->srb_going_list);
} }
@ -982,7 +982,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
int nseg; int nseg;
enum dma_data_direction dir = cmd->sc_data_direction; enum dma_data_direction dir = cmd->sc_data_direction;
dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n",
cmd->pid, dcb->target_id, dcb->target_lun); cmd->serial_number, dcb->target_id, dcb->target_lun);
srb->dcb = dcb; srb->dcb = dcb;
srb->cmd = cmd; srb->cmd = cmd;
@ -1086,7 +1086,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_
struct AdapterCtlBlk *acb = struct AdapterCtlBlk *acb =
(struct AdapterCtlBlk *)cmd->device->host->hostdata; (struct AdapterCtlBlk *)cmd->device->host->hostdata;
dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n", dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n",
cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
/* Assume BAD_TARGET; will be cleared later */ /* Assume BAD_TARGET; will be cleared later */
cmd->result = DID_BAD_TARGET << 16; cmd->result = DID_BAD_TARGET << 16;
@ -1139,7 +1139,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_
/* process immediately */ /* process immediately */
send_srb(acb, srb); send_srb(acb, srb);
} }
dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->pid); dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->serial_number);
return 0; return 0;
complete: complete:
@ -1203,7 +1203,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb,
else else
dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) " dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) "
"cmnd=0x%02x <%02i-%i>\n", "cmnd=0x%02x <%02i-%i>\n",
srb, srb->cmd, srb->cmd->pid, srb, srb->cmd, srb->cmd->serial_number,
srb->cmd->cmnd[0], srb->cmd->device->id, srb->cmd->cmnd[0], srb->cmd->device->id,
srb->cmd->device->lun); srb->cmd->device->lun);
printk(" sglist=%p cnt=%i idx=%i len=%zu\n", printk(" sglist=%p cnt=%i idx=%i len=%zu\n",
@ -1300,7 +1300,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
(struct AdapterCtlBlk *)cmd->device->host->hostdata; (struct AdapterCtlBlk *)cmd->device->host->hostdata;
dprintkl(KERN_INFO, dprintkl(KERN_INFO,
"eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n", "eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n",
cmd->pid, cmd->device->id, cmd->device->lun, cmd); cmd->serial_number, cmd->device->id, cmd->device->lun, cmd);
if (timer_pending(&acb->waiting_timer)) if (timer_pending(&acb->waiting_timer))
del_timer(&acb->waiting_timer); del_timer(&acb->waiting_timer);
@ -1367,7 +1367,7 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd)
struct DeviceCtlBlk *dcb; struct DeviceCtlBlk *dcb;
struct ScsiReqBlk *srb; struct ScsiReqBlk *srb;
dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n", dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n",
cmd->pid, cmd->device->id, cmd->device->lun, cmd); cmd->serial_number, cmd->device->id, cmd->device->lun, cmd);
dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); dcb = find_dcb(acb, cmd->device->id, cmd->device->lun);
if (!dcb) { if (!dcb) {
@ -1494,7 +1494,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
u8 s_stat, scsicommand, i, identify_message; u8 s_stat, scsicommand, i, identify_message;
u8 *ptr; u8 *ptr;
dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n", dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */ srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */
@ -1504,7 +1504,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
#if 1 #if 1
if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) { if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) {
dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n", dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n",
srb->cmd->pid, s_stat, s_stat2); srb->cmd->serial_number, s_stat, s_stat2);
/* /*
* Try anyway? * Try anyway?
* *
@ -1522,14 +1522,14 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
if (acb->active_dcb) { if (acb->active_dcb) {
dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a" dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a"
"command while another command (pid#%li) is active.", "command while another command (pid#%li) is active.",
srb->cmd->pid, srb->cmd->serial_number,
acb->active_dcb->active_srb ? acb->active_dcb->active_srb ?
acb->active_dcb->active_srb->cmd->pid : 0); acb->active_dcb->active_srb->cmd->serial_number : 0);
return 1; return 1;
} }
if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) { if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) {
dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n", dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n",
srb->cmd->pid); srb->cmd->serial_number);
return 1; return 1;
} }
/* Allow starting of SCSI commands half a second before we allow the mid-level /* Allow starting of SCSI commands half a second before we allow the mid-level
@ -1603,7 +1603,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
if (tag_number >= dcb->max_command) { if (tag_number >= dcb->max_command) {
dprintkl(KERN_WARNING, "start_scsi: (pid#%li) " dprintkl(KERN_WARNING, "start_scsi: (pid#%li) "
"Out of tags target=<%02i-%i>)\n", "Out of tags target=<%02i-%i>)\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->serial_number, srb->cmd->device->id,
srb->cmd->device->lun); srb->cmd->device->lun);
srb->state = SRB_READY; srb->state = SRB_READY;
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DC395x_write16(acb, TRM_S1040_SCSI_CONTROL,
@ -1622,7 +1622,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
/*polling:*/ /*polling:*/
/* Send CDB ..command block ......... */ /* Send CDB ..command block ......... */
dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n", dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun,
srb->cmd->cmnd[0], srb->tag_number); srb->cmd->cmnd[0], srb->tag_number);
if (srb->flag & AUTO_REQSENSE) { if (srb->flag & AUTO_REQSENSE) {
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE);
@ -1647,7 +1647,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
* : Let's process it first! * : Let's process it first!
*/ */
dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n", dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun); srb->cmd->serial_number, dcb->target_id, dcb->target_lun);
srb->state = SRB_READY; srb->state = SRB_READY;
free_tag(dcb, srb); free_tag(dcb, srb);
srb->msg_count = 0; srb->msg_count = 0;
@ -1842,7 +1842,7 @@ static irqreturn_t dc395x_interrupt(int irq, void *dev_id)
static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->serial_number);
if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT))
*pscsi_status = PH_BUS_FREE; /*.. initial phase */ *pscsi_status = PH_BUS_FREE; /*.. initial phase */
@ -1856,18 +1856,18 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
{ {
u16 i; u16 i;
u8 *ptr; u8 *ptr;
dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->serial_number);
clear_fifo(acb, "msgout_phase1"); clear_fifo(acb, "msgout_phase1");
if (!(srb->state & SRB_MSGOUT)) { if (!(srb->state & SRB_MSGOUT)) {
srb->state |= SRB_MSGOUT; srb->state |= SRB_MSGOUT;
dprintkl(KERN_DEBUG, dprintkl(KERN_DEBUG,
"msgout_phase1: (pid#%li) Phase unexpected\n", "msgout_phase1: (pid#%li) Phase unexpected\n",
srb->cmd->pid); /* So what ? */ srb->cmd->serial_number); /* So what ? */
} }
if (!srb->msg_count) { if (!srb->msg_count) {
dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n", dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n",
srb->cmd->pid); srb->cmd->serial_number);
DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP); DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP);
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
@ -1887,7 +1887,7 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->serial_number);
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
} }
@ -1898,7 +1898,7 @@ static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
struct DeviceCtlBlk *dcb; struct DeviceCtlBlk *dcb;
u8 *ptr; u8 *ptr;
u16 i; u16 i;
dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->serial_number);
clear_fifo(acb, "command_phase1"); clear_fifo(acb, "command_phase1");
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN); DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN);
@ -2042,7 +2042,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 scsi_status = *pscsi_status; u16 scsi_status = *pscsi_status;
u32 d_left_counter = 0; u32 d_left_counter = 0;
dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
/* /*
* KG: We need to drain the buffers before we draw any conclusions! * KG: We need to drain the buffers before we draw any conclusions!
@ -2172,7 +2172,7 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
clear_fifo(acb, "data_out_phase1"); clear_fifo(acb, "data_out_phase1");
/* do prepare before transfer when data out phase */ /* do prepare before transfer when data out phase */
data_io_transfer(acb, srb, XFERDATAOUT); data_io_transfer(acb, srb, XFERDATAOUT);
@ -2184,7 +2184,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 scsi_status = *pscsi_status; u16 scsi_status = *pscsi_status;
dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
/* /*
* KG: DataIn is much more tricky than DataOut. When the device is finished * KG: DataIn is much more tricky than DataOut. When the device is finished
@ -2205,7 +2205,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
if (scsi_status & PARITYERROR) { if (scsi_status & PARITYERROR) {
dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) "
"Parity Error\n", srb->cmd->pid); "Parity Error\n", srb->cmd->serial_number);
srb->status |= PARITY_ERROR; srb->status |= PARITY_ERROR;
} }
/* /*
@ -2395,7 +2395,7 @@ static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
data_io_transfer(acb, srb, XFERDATAIN); data_io_transfer(acb, srb, XFERDATAIN);
} }
@ -2407,7 +2407,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb,
u8 bval; u8 bval;
dprintkdbg(DBG_0, dprintkdbg(DBG_0,
"data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n", "data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun,
((io_dir & DMACMD_DIR) ? 'r' : 'w'), ((io_dir & DMACMD_DIR) ? 'r' : 'w'),
srb->total_xfer_length, srb->sg_index, srb->sg_count); srb->total_xfer_length, srb->sg_index, srb->sg_count);
if (srb == acb->tmp_srb) if (srb == acb->tmp_srb)
@ -2580,7 +2580,7 @@ static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */ srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */
srb->state = SRB_COMPLETED; srb->state = SRB_COMPLETED;
@ -2594,7 +2594,7 @@ static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
srb->state = SRB_STATUS; srb->state = SRB_STATUS;
DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */
DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP); DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
@ -2636,7 +2636,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
struct ScsiReqBlk *srb = NULL; struct ScsiReqBlk *srb = NULL;
struct ScsiReqBlk *i; struct ScsiReqBlk *i;
dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n", dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n",
srb->cmd->pid, tag, srb); srb->cmd->serial_number, tag, srb);
if (!(dcb->tag_mask & (1 << tag))) if (!(dcb->tag_mask & (1 << tag)))
dprintkl(KERN_DEBUG, dprintkl(KERN_DEBUG,
@ -2655,7 +2655,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
goto mingx0; goto mingx0;
dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n",
srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun); srb->cmd->serial_number, srb->dcb->target_id, srb->dcb->target_lun);
if (dcb->flag & ABORT_DEV_) { if (dcb->flag & ABORT_DEV_) {
/*srb->state = SRB_ABORT_SENT; */ /*srb->state = SRB_ABORT_SENT; */
enable_msgout_abort(acb, srb); enable_msgout_abort(acb, srb);
@ -2865,7 +2865,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
struct DeviceCtlBlk *dcb = acb->active_dcb; struct DeviceCtlBlk *dcb = acb->active_dcb;
dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->serial_number);
srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
if (msgin_completed(srb->msgin_buf, acb->msg_len)) { if (msgin_completed(srb->msgin_buf, acb->msg_len)) {
@ -2933,7 +2933,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
*/ */
dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
"SAVE POINTER rem=%i Ignore\n", "SAVE POINTER rem=%i Ignore\n",
srb->cmd->pid, srb->total_xfer_length); srb->cmd->serial_number, srb->total_xfer_length);
break; break;
case RESTORE_POINTERS: case RESTORE_POINTERS:
@ -2943,7 +2943,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
case ABORT: case ABORT:
dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
"<%02i-%i> ABORT msg\n", "<%02i-%i> ABORT msg\n",
srb->cmd->pid, dcb->target_id, srb->cmd->serial_number, dcb->target_id,
dcb->target_lun); dcb->target_lun);
dcb->flag |= ABORT_DEV_; dcb->flag |= ABORT_DEV_;
enable_msgout_abort(acb, srb); enable_msgout_abort(acb, srb);
@ -2975,7 +2975,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
u16 *pscsi_status) u16 *pscsi_status)
{ {
dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->serial_number);
clear_fifo(acb, "msgin_phase1"); clear_fifo(acb, "msgin_phase1");
DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1);
if (!(srb->state & SRB_MSGIN)) { if (!(srb->state & SRB_MSGIN)) {
@ -3041,7 +3041,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
} }
srb = dcb->active_srb; srb = dcb->active_srb;
acb->active_dcb = NULL; acb->active_dcb = NULL;
dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->pid); dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->serial_number);
srb->scsi_phase = PH_BUS_FREE; /* initial phase */ srb->scsi_phase = PH_BUS_FREE; /* initial phase */
clear_fifo(acb, "disconnect"); clear_fifo(acb, "disconnect");
@ -3072,13 +3072,13 @@ static void disconnect(struct AdapterCtlBlk *acb)
srb->state = SRB_READY; srb->state = SRB_READY;
dprintkl(KERN_DEBUG, dprintkl(KERN_DEBUG,
"disconnect: (pid#%li) Unexpected\n", "disconnect: (pid#%li) Unexpected\n",
srb->cmd->pid); srb->cmd->serial_number);
srb->target_status = SCSI_STAT_SEL_TIMEOUT; srb->target_status = SCSI_STAT_SEL_TIMEOUT;
goto disc1; goto disc1;
} else { } else {
/* Normal selection timeout */ /* Normal selection timeout */
dprintkdbg(DBG_KG, "disconnect: (pid#%li) " dprintkdbg(DBG_KG, "disconnect: (pid#%li) "
"<%02i-%i> SelTO\n", srb->cmd->pid, "<%02i-%i> SelTO\n", srb->cmd->serial_number,
dcb->target_id, dcb->target_lun); dcb->target_id, dcb->target_lun);
if (srb->retry_count++ > DC395x_MAX_RETRIES if (srb->retry_count++ > DC395x_MAX_RETRIES
|| acb->scan_devices) { || acb->scan_devices) {
@ -3090,7 +3090,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
srb_going_to_waiting_move(dcb, srb); srb_going_to_waiting_move(dcb, srb);
dprintkdbg(DBG_KG, dprintkdbg(DBG_KG,
"disconnect: (pid#%li) Retry\n", "disconnect: (pid#%li) Retry\n",
srb->cmd->pid); srb->cmd->serial_number);
waiting_set_timer(acb, HZ / 20); waiting_set_timer(acb, HZ / 20);
} }
} else if (srb->state & SRB_DISCONNECT) { } else if (srb->state & SRB_DISCONNECT) {
@ -3144,7 +3144,7 @@ static void reselect(struct AdapterCtlBlk *acb)
if (!acb->scan_devices) { if (!acb->scan_devices) {
dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> " dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> "
"Arb lost but Resel win rsel=%i stat=0x%04x\n", "Arb lost but Resel win rsel=%i stat=0x%04x\n",
srb->cmd->pid, dcb->target_id, srb->cmd->serial_number, dcb->target_id,
dcb->target_lun, rsel_tar_lun_id, dcb->target_lun, rsel_tar_lun_id,
DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); DC395x_read16(acb, TRM_S1040_SCSI_STATUS));
arblostflag = 1; arblostflag = 1;
@ -3318,7 +3318,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
enum dma_data_direction dir = cmd->sc_data_direction; enum dma_data_direction dir = cmd->sc_data_direction;
int ckc_only = 1; int ckc_only = 1;
dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->serial_number,
srb->cmd->device->id, srb->cmd->device->lun); srb->cmd->device->id, srb->cmd->device->lun);
dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n",
srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count, srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count,
@ -3499,7 +3499,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (srb->total_xfer_length) if (srb->total_xfer_length)
dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> " dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> "
"cmnd=0x%02x Missed %i bytes\n", "cmnd=0x%02x Missed %i bytes\n",
cmd->pid, cmd->device->id, cmd->device->lun, cmd->serial_number, cmd->device->id, cmd->device->lun,
cmd->cmnd[0], srb->total_xfer_length); cmd->cmnd[0], srb->total_xfer_length);
} }
@ -3509,7 +3509,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n");
else { else {
dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n", dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n",
cmd->pid, cmd->result); cmd->serial_number, cmd->result);
srb_free_insert(acb, srb); srb_free_insert(acb, srb);
} }
pci_unmap_srb(acb, srb); pci_unmap_srb(acb, srb);
@ -3538,7 +3538,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p = srb->cmd; p = srb->cmd;
dir = p->sc_data_direction; dir = p->sc_data_direction;
result = MK_RES(0, did_flag, 0, 0); result = MK_RES(0, did_flag, 0, 0);
printk("G:%li(%02i-%i) ", p->pid, printk("G:%li(%02i-%i) ", p->serial_number,
p->device->id, p->device->lun); p->device->id, p->device->lun);
srb_going_remove(dcb, srb); srb_going_remove(dcb, srb);
free_tag(dcb, srb); free_tag(dcb, srb);
@ -3568,7 +3568,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p = srb->cmd; p = srb->cmd;
result = MK_RES(0, did_flag, 0, 0); result = MK_RES(0, did_flag, 0, 0);
printk("W:%li<%02i-%i>", p->pid, p->device->id, printk("W:%li<%02i-%i>", p->serial_number, p->device->id,
p->device->lun); p->device->lun);
srb_waiting_remove(dcb, srb); srb_waiting_remove(dcb, srb);
srb_free_insert(acb, srb); srb_free_insert(acb, srb);
@ -3678,7 +3678,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
{ {
struct scsi_cmnd *cmd = srb->cmd; struct scsi_cmnd *cmd = srb->cmd;
dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n", dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n",
cmd->pid, cmd->device->id, cmd->device->lun); cmd->serial_number, cmd->device->id, cmd->device->lun);
srb->flag |= AUTO_REQSENSE; srb->flag |= AUTO_REQSENSE;
srb->adapter_status = 0; srb->adapter_status = 0;
@ -3709,7 +3709,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */ if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */
dprintkl(KERN_DEBUG, dprintkl(KERN_DEBUG,
"request_sense: (pid#%li) failed <%02i-%i>\n", "request_sense: (pid#%li) failed <%02i-%i>\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun); srb->cmd->serial_number, dcb->target_id, dcb->target_lun);
srb_going_to_waiting_move(dcb, srb); srb_going_to_waiting_move(dcb, srb);
waiting_set_timer(acb, HZ / 100); waiting_set_timer(acb, HZ / 100);
} }
@ -4717,13 +4717,13 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
dcb->target_id, dcb->target_lun, dcb->target_id, dcb->target_lun,
list_size(&dcb->srb_waiting_list)); list_size(&dcb->srb_waiting_list));
list_for_each_entry(srb, &dcb->srb_waiting_list, list) list_for_each_entry(srb, &dcb->srb_waiting_list, list)
SPRINTF(" %li", srb->cmd->pid); SPRINTF(" %li", srb->cmd->serial_number);
if (!list_empty(&dcb->srb_going_list)) if (!list_empty(&dcb->srb_going_list))
SPRINTF("\nDCB (%02i-%i): Going : %i:", SPRINTF("\nDCB (%02i-%i): Going : %i:",
dcb->target_id, dcb->target_lun, dcb->target_id, dcb->target_lun,
list_size(&dcb->srb_going_list)); list_size(&dcb->srb_going_list));
list_for_each_entry(srb, &dcb->srb_going_list, list) list_for_each_entry(srb, &dcb->srb_going_list, list)
SPRINTF(" %li", srb->cmd->pid); SPRINTF(" %li", srb->cmd->serial_number);
if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list))
SPRINTF("\n"); SPRINTF("\n");
} }

View file

@ -949,16 +949,14 @@ static int adpt_install_hba(struct pci_dev* pDev)
} }
// Allocate and zero the data structure // Allocate and zero the data structure
pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL); pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL);
if( pHba == NULL) { if (!pHba) {
if(msg_addr_virt != base_addr_virt){ if (msg_addr_virt != base_addr_virt)
iounmap(msg_addr_virt); iounmap(msg_addr_virt);
}
iounmap(base_addr_virt); iounmap(base_addr_virt);
pci_release_regions(pDev); pci_release_regions(pDev);
return -ENOMEM; return -ENOMEM;
} }
memset(pHba, 0, sizeof(adpt_hba));
mutex_lock(&adpt_configuration_lock); mutex_lock(&adpt_configuration_lock);
@ -2622,14 +2620,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
msg=(u32 __iomem *)(pHba->msg_addr_virt+m); msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
status = kmalloc(4,GFP_KERNEL|ADDR32); status = kzalloc(4, GFP_KERNEL|ADDR32);
if (status==NULL) { if (!status) {
adpt_send_nop(pHba, m); adpt_send_nop(pHba, m);
printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
pHba->name); pHba->name);
return -ENOMEM; return -ENOMEM;
} }
memset(status, 0, 4);
writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
@ -2668,12 +2665,11 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
kfree(pHba->reply_pool); kfree(pHba->reply_pool);
pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
if(!pHba->reply_pool){ if (!pHba->reply_pool) {
printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name); printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
return -1; return -ENOMEM;
} }
memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
ptr = pHba->reply_pool; ptr = pHba->reply_pool;
for(i = 0; i < pHba->reply_fifo_size; i++) { for(i = 0; i < pHba->reply_fifo_size; i++) {
@ -2884,12 +2880,11 @@ static int adpt_i2o_build_sys_table(void)
kfree(sys_tbl); kfree(sys_tbl);
sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32); sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
if(!sys_tbl) { if (!sys_tbl) {
printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");
return -ENOMEM; return -ENOMEM;
} }
memset(sys_tbl, 0, sys_tbl_len);
sys_tbl->num_entries = hba_count; sys_tbl->num_entries = hba_count;
sys_tbl->version = I2OVERSION; sys_tbl->version = I2OVERSION;
@ -3351,7 +3346,7 @@ static int __init adpt_init(void)
return count > 0 ? 0 : -ENODEV; return count > 0 ? 0 : -ENODEV;
} }
static void __exit adpt_exit(void) static void adpt_exit(void)
{ {
while (hba_chain) while (hba_chain)
adpt_release(hba_chain); adpt_release(hba_chain);

View file

@ -137,11 +137,9 @@ static struct override {
#ifdef OVERRIDE #ifdef OVERRIDE
[] __initdata = OVERRIDE; [] __initdata = OVERRIDE;
#else #else
[4] __initdata = { { [4] __initdata = {
0, IRQ_AUTO}, { { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }
0, IRQ_AUTO}, { };
0, IRQ_AUTO}, {
0, IRQ_AUTO}};
#endif #endif
#define NO_OVERRIDES ARRAY_SIZE(overrides) #define NO_OVERRIDES ARRAY_SIZE(overrides)
@ -176,7 +174,7 @@ static const struct signature {
* Inputs : str - unused, ints - array of integer parameters with ints[0] * Inputs : str - unused, ints - array of integer parameters with ints[0]
* equal to the number of ints. * equal to the number of ints.
* *
*/ */
static void __init dtc_setup(char *str, int *ints) static void __init dtc_setup(char *str, int *ints)
{ {
@ -233,7 +231,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
} else } else
for (; !addr && (current_base < NO_BASES); ++current_base) { for (; !addr && (current_base < NO_BASES); ++current_base) {
#if (DTCDEBUG & DTCDEBUG_INIT) #if (DTCDEBUG & DTCDEBUG_INIT)
printk("scsi-dtc : probing address %08x\n", bases[current_base].address); printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
#endif #endif
if (bases[current_base].noauto) if (bases[current_base].noauto)
continue; continue;
@ -244,7 +242,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
addr = bases[current_base].address; addr = bases[current_base].address;
#if (DTCDEBUG & DTCDEBUG_INIT) #if (DTCDEBUG & DTCDEBUG_INIT)
printk("scsi-dtc : detected board.\n"); printk(KERN_DEBUG "scsi-dtc : detected board.\n");
#endif #endif
goto found; goto found;
} }
@ -253,7 +251,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt)
} }
#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
printk("scsi-dtc : base = %08x\n", addr); printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
#endif #endif
if (!addr) if (!addr)

View file

@ -1758,7 +1758,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
if (SCpnt->host_scribble) if (SCpnt->host_scribble)
panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
ha->board_name, SCpnt->pid, SCpnt); ha->board_name, SCpnt->serial_number, SCpnt);
/* i is the mailbox number, look for the first free mailbox /* i is the mailbox number, look for the first free mailbox
starting from last_cp_used */ starting from last_cp_used */
@ -1792,7 +1792,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
if (do_trace) if (do_trace)
scmd_printk(KERN_INFO, SCpnt, scmd_printk(KERN_INFO, SCpnt,
"qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid); "qcomm, mbox %d, pid %ld.\n", i, SCpnt->serial_number);
cpp->reqsen = 1; cpp->reqsen = 1;
cpp->dispri = 1; cpp->dispri = 1;
@ -1825,7 +1825,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
unmap_dma(i, ha); unmap_dma(i, ha);
SCpnt->host_scribble = NULL; SCpnt->host_scribble = NULL;
scmd_printk(KERN_INFO, SCpnt, scmd_printk(KERN_INFO, SCpnt,
"qcomm, pid %ld, adapter busy.\n", SCpnt->pid); "qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number);
return 1; return 1;
} }
@ -1841,13 +1841,13 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
if (SCarg->host_scribble == NULL) { if (SCarg->host_scribble == NULL) {
scmd_printk(KERN_INFO, SCarg, scmd_printk(KERN_INFO, SCarg,
"abort, pid %ld inactive.\n", SCarg->pid); "abort, pid %ld inactive.\n", SCarg->serial_number);
return SUCCESS; return SUCCESS;
} }
i = *(unsigned int *)SCarg->host_scribble; i = *(unsigned int *)SCarg->host_scribble;
scmd_printk(KERN_WARNING, SCarg, scmd_printk(KERN_WARNING, SCarg,
"abort, mbox %d, pid %ld.\n", i, SCarg->pid); "abort, mbox %d, pid %ld.\n", i, SCarg->serial_number);
if (i >= shost->can_queue) if (i >= shost->can_queue)
panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
@ -1892,7 +1892,7 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
SCarg->host_scribble = NULL; SCarg->host_scribble = NULL;
ha->cp_stat[i] = FREE; ha->cp_stat[i] = FREE;
printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
ha->board_name, i, SCarg->pid); ha->board_name, i, SCarg->serial_number);
SCarg->scsi_done(SCarg); SCarg->scsi_done(SCarg);
return SUCCESS; return SUCCESS;
} }
@ -1909,12 +1909,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
struct hostdata *ha = (struct hostdata *)shost->hostdata; struct hostdata *ha = (struct hostdata *)shost->hostdata;
scmd_printk(KERN_INFO, SCarg, scmd_printk(KERN_INFO, SCarg,
"reset, enter, pid %ld.\n", SCarg->pid); "reset, enter, pid %ld.\n", SCarg->serial_number);
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
if (SCarg->host_scribble == NULL) if (SCarg->host_scribble == NULL)
printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid); printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->serial_number);
if (ha->in_reset) { if (ha->in_reset) {
printk("%s: reset, exit, already in reset.\n", ha->board_name); printk("%s: reset, exit, already in reset.\n", ha->board_name);
@ -1954,13 +1954,13 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
ha->cp_stat[i] = ABORTING; ha->cp_stat[i] = ABORTING;
printk("%s: reset, mbox %d aborting, pid %ld.\n", printk("%s: reset, mbox %d aborting, pid %ld.\n",
ha->board_name, i, SCpnt->pid); ha->board_name, i, SCpnt->serial_number);
} }
else { else {
ha->cp_stat[i] = IN_RESET; ha->cp_stat[i] = IN_RESET;
printk("%s: reset, mbox %d in reset, pid %ld.\n", printk("%s: reset, mbox %d in reset, pid %ld.\n",
ha->board_name, i, SCpnt->pid); ha->board_name, i, SCpnt->serial_number);
} }
if (SCpnt->host_scribble == NULL) if (SCpnt->host_scribble == NULL)
@ -2015,7 +2015,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
printk printk
("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
ha->board_name, i, SCpnt->pid); ha->board_name, i, SCpnt->serial_number);
} }
else if (ha->cp_stat[i] == ABORTING) { else if (ha->cp_stat[i] == ABORTING) {
@ -2029,7 +2029,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
printk printk
("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
ha->board_name, i, SCpnt->pid); ha->board_name, i, SCpnt->serial_number);
} }
else else
@ -2043,7 +2043,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
do_trace = 0; do_trace = 0;
if (arg_done) if (arg_done)
printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->pid); printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->serial_number);
else else
printk("%s: reset, exit.\n", ha->board_name); printk("%s: reset, exit.\n", ha->board_name);
@ -2182,7 +2182,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
cpp = &ha->cp[k]; cpp = &ha->cp[k];
SCpnt = cpp->SCpnt; SCpnt = cpp->SCpnt;
ll[n] = SCpnt->request->nr_sectors; ll[n] = SCpnt->request->nr_sectors;
pl[n] = SCpnt->pid; pl[n] = SCpnt->serial_number;
if (!n) if (!n)
continue; continue;
@ -2230,7 +2230,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec,
"%s pid %ld mb %d fc %d nr %d sec %ld ns %ld" "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld"
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
(ihdlr ? "ihdlr" : "qcomm"), (ihdlr ? "ihdlr" : "qcomm"),
SCpnt->pid, k, flushcount, SCpnt->serial_number, k, flushcount,
n_ready, SCpnt->request->sector, n_ready, SCpnt->request->sector,
SCpnt->request->nr_sectors, cursec, YESNO(s), SCpnt->request->nr_sectors, cursec, YESNO(s),
YESNO(r), YESNO(rev), YESNO(input_only), YESNO(r), YESNO(rev), YESNO(input_only),
@ -2277,7 +2277,7 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec,
"%s, pid %ld, mbox %d, adapter" "%s, pid %ld, mbox %d, adapter"
" busy, will abort.\n", " busy, will abort.\n",
(ihdlr ? "ihdlr" : "qcomm"), (ihdlr ? "ihdlr" : "qcomm"),
SCpnt->pid, k); SCpnt->serial_number, k);
ha->cp_stat[k] = ABORTING; ha->cp_stat[k] = ABORTING;
continue; continue;
} }
@ -2391,11 +2391,11 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
if (SCpnt->host_scribble == NULL) if (SCpnt->host_scribble == NULL)
panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name, panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name,
i, SCpnt->pid, SCpnt); i, SCpnt->serial_number, SCpnt);
if (*(unsigned int *)SCpnt->host_scribble != i) if (*(unsigned int *)SCpnt->host_scribble != i)
panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
ha->board_name, i, SCpnt->pid, ha->board_name, i, SCpnt->serial_number,
*(unsigned int *)SCpnt->host_scribble); *(unsigned int *)SCpnt->host_scribble);
sync_dma(i, ha); sync_dma(i, ha);
@ -2445,12 +2445,12 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
"target_status 0x%x, sense key 0x%x.\n", "target_status 0x%x, sense key 0x%x.\n",
ha->board_name, ha->board_name,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->channel, SCpnt->device->id,
SCpnt->device->lun, SCpnt->pid, SCpnt->device->lun, SCpnt->serial_number,
spp->target_status, SCpnt->sense_buffer[2]); spp->target_status, SCpnt->sense_buffer[2]);
ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
if (ha->last_retried_pid == SCpnt->pid) if (ha->last_retried_pid == SCpnt->serial_number)
ha->retries = 0; ha->retries = 0;
break; break;
@ -2485,7 +2485,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
#endif #endif
ha->retries++; ha->retries++;
ha->last_retried_pid = SCpnt->pid; ha->last_retried_pid = SCpnt->serial_number;
} else } else
status = DID_ERROR << 16; status = DID_ERROR << 16;
@ -2516,7 +2516,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"
" pid %ld, reg 0x%x, count %d.\n", " pid %ld, reg 0x%x, count %d.\n",
i, spp->adapter_status, spp->target_status, i, spp->adapter_status, spp->target_status,
SCpnt->pid, reg, ha->iocount); SCpnt->serial_number, reg, ha->iocount);
unmap_dma(i, ha); unmap_dma(i, ha);

View file

@ -107,59 +107,44 @@ static struct scsi_host_template driver_template;
static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset,
int length, int rw) int length, int rw)
{ {
static u8 buff[512]; int len = 0;
int size, len = 0; off_t begin = 0, pos = 0;
off_t begin = 0, pos = 0;
if (rw) if (rw)
return -ENOSYS; return -ENOSYS;
if (offset == 0)
memset(buff, 0, sizeof(buff));
size = sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " len += sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: "
"%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB);
len += size; pos = begin + len; len += sprintf(buffer + len, "queued commands: %10ld\n"
size = sprintf(buffer + len, "queued commands: %10ld\n"
"processed interrupts:%10ld\n", queue_counter, int_counter); "processed interrupts:%10ld\n", queue_counter, int_counter);
len += size; pos = begin + len; len += sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n",
size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n",
shost->host_no, SD(shost)->name); shost->host_no, SD(shost)->name);
len += size; len += sprintf(buffer + len, "Firmware revision: v%s\n",
pos = begin + len;
size = sprintf(buffer + len, "Firmware revision: v%s\n",
SD(shost)->revision); SD(shost)->revision);
len += size; len += sprintf(buffer + len, "IO: PIO\n");
pos = begin + len; len += sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base);
size = sprintf(buffer + len, "IO: PIO\n"); len += sprintf(buffer + len, "Host Bus: %s\n",
len += size;
pos = begin + len;
size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base);
len += size;
pos = begin + len;
size = sprintf(buffer + len, "Host Bus: %s\n",
(SD(shost)->bustype == 'P')?"PCI ": (SD(shost)->bustype == 'P')?"PCI ":
(SD(shost)->bustype == 'E')?"EISA":"ISA "); (SD(shost)->bustype == 'E')?"EISA":"ISA ");
len += size; pos = begin + len;
pos = begin + len;
if (pos < offset) { if (pos < offset) {
len = 0; len = 0;
begin = pos; begin = pos;
} }
if (pos > offset + length) if (pos > offset + length)
goto stop_output; goto stop_output;
stop_output: stop_output:
DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
*start=buffer+(offset-begin); /* Start of wanted data */ *start = buffer + (offset - begin); /* Start of wanted data */
len-=(offset-begin); /* Start slop */ len -= (offset - begin); /* Start slop */
if(len>length) if (len > length)
len = length; /* Ending slop */ len = length; /* Ending slop */
DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
return (len); return len;
} }
static int eata_pio_release(struct Scsi_Host *sh) static int eata_pio_release(struct Scsi_Host *sh)
@ -390,7 +375,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
"eata_pio_queue pid %ld, y %d\n", "eata_pio_queue pid %ld, y %d\n",
cmd->pid, y)); cmd->serial_number, y));
cmd->scsi_done = (void *) done; cmd->scsi_done = (void *) done;
@ -435,10 +420,10 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
cmd->result = DID_BUS_BUSY << 16; cmd->result = DID_BUS_BUSY << 16;
scmd_printk(KERN_NOTICE, cmd, scmd_printk(KERN_NOTICE, cmd,
"eata_pio_queue pid %ld, HBA busy, " "eata_pio_queue pid %ld, HBA busy, "
"returning DID_BUS_BUSY, done.\n", cmd->pid); "returning DID_BUS_BUSY, done.\n", cmd->serial_number);
done(cmd); done(cmd);
cp->status = FREE; cp->status = FREE;
return (0); return 0;
} }
/* FIXME: timeout */ /* FIXME: timeout */
while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
@ -450,9 +435,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
"Queued base %#.4lx pid: %ld " "Queued base %#.4lx pid: %ld "
"slot %d irq %d\n", sh->base, cmd->pid, y, sh->irq)); "slot %d irq %d\n", sh->base, cmd->serial_number, y, sh->irq));
return (0); return 0;
} }
static int eata_pio_abort(struct scsi_cmnd *cmd) static int eata_pio_abort(struct scsi_cmnd *cmd)
@ -461,7 +446,7 @@ static int eata_pio_abort(struct scsi_cmnd *cmd)
DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
"eata_pio_abort called pid: %ld\n", "eata_pio_abort called pid: %ld\n",
cmd->pid)); cmd->serial_number));
while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
if (--loop == 0) { if (--loop == 0) {
@ -497,7 +482,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
"eata_pio_reset called pid:%ld\n", "eata_pio_reset called pid:%ld\n",
cmd->pid)); cmd->serial_number));
spin_lock_irq(host->host_lock); spin_lock_irq(host->host_lock);
@ -516,7 +501,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
sp = HD(cmd)->ccb[x].cmd; sp = HD(cmd)->ccb[x].cmd;
HD(cmd)->ccb[x].status = RESET; HD(cmd)->ccb[x].status = RESET;
printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->pid); printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->serial_number);
if (sp == NULL) if (sp == NULL)
panic("eata_pio_reset: slot %d, sp==NULL.\n", x); panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
@ -589,23 +574,28 @@ static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned i
cp.cp_cdb[5] = 0; cp.cp_cdb[5] = 0;
if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP))
return (NULL); return NULL;
while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
cpu_relax();
outsw(base + HA_RDATA, &cp, cplen); outsw(base + HA_RDATA, &cp, cplen);
outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
for (z = 0; z < cppadlen; z++) for (z = 0; z < cppadlen; z++)
outw(0, base + HA_RDATA); outw(0, base + HA_RDATA);
while (inb(base + HA_RSTATUS) & HA_SBUSY); while (inb(base + HA_RSTATUS) & HA_SBUSY)
cpu_relax();
if (inb(base + HA_RSTATUS) & HA_SERROR) if (inb(base + HA_RSTATUS) & HA_SERROR)
return (NULL); return NULL;
else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) else if (!(inb(base + HA_RSTATUS) & HA_SDRQ))
return (NULL); return NULL;
else { else {
insw(base + HA_RDATA, &buff, 127); insw(base + HA_RDATA, &buff, 127);
while (inb(base + HA_RSTATUS) & HA_SDRQ) while (inb(base + HA_RSTATUS) & HA_SDRQ)
inw(base + HA_RDATA); inw(base + HA_RDATA);
return (buff); return buff;
} }
} }

View file

@ -2138,7 +2138,7 @@ irqreturn_t scsi_esp_intr(int irq, void *dev_id)
} }
EXPORT_SYMBOL(scsi_esp_intr); EXPORT_SYMBOL(scsi_esp_intr);
static void __devinit esp_get_revision(struct esp *esp) static void esp_get_revision(struct esp *esp)
{ {
u8 val; u8 val;
@ -2187,7 +2187,7 @@ static void __devinit esp_get_revision(struct esp *esp)
} }
} }
static void __devinit esp_init_swstate(struct esp *esp) static void esp_init_swstate(struct esp *esp)
{ {
int i; int i;
@ -2233,7 +2233,7 @@ static void esp_bootup_reset(struct esp *esp)
esp_read8(ESP_INTRPT); esp_read8(ESP_INTRPT);
} }
static void __devinit esp_set_clock_params(struct esp *esp) static void esp_set_clock_params(struct esp *esp)
{ {
int fmhz; int fmhz;
u8 ccf; u8 ccf;
@ -2306,7 +2306,7 @@ static const char *esp_chip_names[] = {
static struct scsi_transport_template *esp_transport_template; static struct scsi_transport_template *esp_transport_template;
int __devinit scsi_esp_register(struct esp *esp, struct device *dev) int scsi_esp_register(struct esp *esp, struct device *dev)
{ {
static int instance; static int instance;
int err; int err;
@ -2346,7 +2346,7 @@ int __devinit scsi_esp_register(struct esp *esp, struct device *dev)
} }
EXPORT_SYMBOL(scsi_esp_register); EXPORT_SYMBOL(scsi_esp_register);
void __devexit scsi_esp_unregister(struct esp *esp) void scsi_esp_unregister(struct esp *esp)
{ {
scsi_remove_host(esp->host); scsi_remove_host(esp->host);
} }

View file

@ -387,7 +387,9 @@ static void __iomem * bios_mem;
static int bios_major; static int bios_major;
static int bios_minor; static int bios_minor;
static int PCI_bus; static int PCI_bus;
#ifdef CONFIG_PCI
static struct pci_dev *PCI_dev; static struct pci_dev *PCI_dev;
#endif
static int Quantum; /* Quantum board variant */ static int Quantum; /* Quantum board variant */
static int interrupt_level; static int interrupt_level;
static volatile int in_command; static volatile int in_command;
@ -1764,6 +1766,7 @@ struct scsi_host_template fdomain_driver_template = {
}; };
#ifndef PCMCIA #ifndef PCMCIA
#ifdef CONFIG_PCI
static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { static struct pci_device_id fdomain_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70,
@ -1771,7 +1774,7 @@ static struct pci_device_id fdomain_pci_tbl[] __devinitdata = {
{ } { }
}; };
MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
#endif
#define driver_template fdomain_driver_template #define driver_template fdomain_driver_template
#include "scsi_module.c" #include "scsi_module.c"

View file

@ -556,7 +556,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
} }
#endif #endif
#if NCR53C400_PSEUDO_DMA #ifdef NCR53C400_PSEUDO_DMA
/** /**
* NCR5380_pread - pseudo DMA read * NCR5380_pread - pseudo DMA read

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,6 @@
* $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $
*/ */
#include <linux/version.h>
#include <linux/types.h> #include <linux/types.h>
#ifndef TRUE #ifndef TRUE
@ -304,15 +303,8 @@
#define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */ #define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */
#define EISAREG 0x0cc0 /* EISA configuration */ #define EISAREG 0x0cc0 /* EISA configuration */
/* DMA memory mappings */
#define GDTH_MAP_NONE 0
#define GDTH_MAP_SINGLE 1
#define GDTH_MAP_SG 2
#define GDTH_MAP_IOCTL 3
/* other defines */ /* other defines */
#define LINUX_OS 8 /* used for cache optim. */ #define LINUX_OS 8 /* used for cache optim. */
#define SCATTER_GATHER 1 /* s/g feature */
#define SECS32 0x1f /* round capacity */ #define SECS32 0x1f /* round capacity */
#define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ #define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */
#define LOCALBOARD 0 /* board node always 0 */ #define LOCALBOARD 0 /* board node always 0 */
@ -854,6 +846,9 @@ typedef struct {
/* controller information structure */ /* controller information structure */
typedef struct { typedef struct {
struct Scsi_Host *shost;
struct list_head list;
ushort hanum;
ushort oem_id; /* OEM */ ushort oem_id; /* OEM */
ushort type; /* controller class */ ushort type; /* controller class */
ulong32 stype; /* subtype (PCI: device ID) */ ulong32 stype; /* subtype (PCI: device ID) */
@ -865,6 +860,7 @@ typedef struct {
void __iomem *brd; /* DPRAM address */ void __iomem *brd; /* DPRAM address */
ulong32 brd_phys; /* slot number/BIOS address */ ulong32 brd_phys; /* slot number/BIOS address */
gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */
gdth_cmd_str cmdext;
gdth_cmd_str *pccb; /* address command structure */ gdth_cmd_str *pccb; /* address command structure */
ulong32 ccb_phys; /* phys. address */ ulong32 ccb_phys; /* phys. address */
#ifdef INT_COAL #ifdef INT_COAL
@ -916,6 +912,19 @@ typedef struct {
Scsi_Cmnd *cmnd; /* pending request */ Scsi_Cmnd *cmnd; /* pending request */
ushort service; /* service */ ushort service; /* service */
} cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */ } cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */
struct gdth_cmndinfo { /* per-command private info */
int index;
int internal_command; /* don't call scsi_done */
dma_addr_t sense_paddr; /* sense dma-addr */
unchar priority;
int timeout;
volatile int wait_for_completion;
ushort status;
ulong32 info;
enum dma_data_direction dma_dir;
int phase; /* ???? */
int OpCode;
} cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */
unchar bus_cnt; /* SCSI bus count */ unchar bus_cnt; /* SCSI bus count */
unchar tid_cnt; /* Target ID count */ unchar tid_cnt; /* Target ID count */
unchar bus_id[MAXBUS]; /* IOP IDs */ unchar bus_id[MAXBUS]; /* IOP IDs */
@ -938,19 +947,10 @@ typedef struct {
struct scsi_device *sdev; struct scsi_device *sdev;
} gdth_ha_str; } gdth_ha_str;
/* structure for scsi_register(), SCSI bus != 0 */ static inline struct gdth_cmndinfo *gdth_cmnd_priv(struct scsi_cmnd* cmd)
typedef struct { {
ushort hanum; return (struct gdth_cmndinfo *)cmd->host_scribble;
ushort busnum; }
} gdth_num_str;
/* structure for scsi_register() */
typedef struct {
gdth_num_str numext; /* must be the first element */
gdth_ha_str haext;
gdth_cmd_str cmdext;
} gdth_ext_str;
/* INQUIRY data format */ /* INQUIRY data format */
typedef struct { typedef struct {

View file

@ -1,31 +0,0 @@
#ifndef IRQ_HANDLED
typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#endif
#ifndef MODULE_LICENSE
#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
#ifndef READ_16
#define READ_16 0x88
#endif
#ifndef WRITE_16
#define WRITE_16 0x8a
#endif

View file

@ -4,62 +4,32 @@
#include <linux/completion.h> #include <linux/completion.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,
int inout) int inout)
{ {
int hanum,busnum; gdth_ha_str *ha = shost_priv(host);
TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", TRACE2(("gdth_proc_info() length %d offs %d inout %d\n",
length,(int)offset,inout)); length,(int)offset,inout));
hanum = NUMDATA(host)->hanum;
busnum= NUMDATA(host)->busnum;
if (inout) if (inout)
return(gdth_set_info(buffer,length,host,hanum,busnum)); return(gdth_set_info(buffer,length,host,ha));
else else
return(gdth_get_info(buffer,start,offset,length,host,hanum,busnum)); return(gdth_get_info(buffer,start,offset,length,host,ha));
} }
#else
int gdth_proc_info(char *buffer,char **start,off_t offset,int length,int hostno,
int inout)
{
int hanum,busnum,i;
TRACE2(("gdth_proc_info() length %d offs %d inout %d\n",
length,(int)offset,inout));
for (i = 0; i < gdth_ctr_vcount; ++i) {
if (gdth_ctr_vtab[i]->host_no == hostno)
break;
}
if (i == gdth_ctr_vcount)
return(-EINVAL);
hanum = NUMDATA(gdth_ctr_vtab[i])->hanum;
busnum= NUMDATA(gdth_ctr_vtab[i])->busnum;
if (inout)
return(gdth_set_info(buffer,length,gdth_ctr_vtab[i],hanum,busnum));
else
return(gdth_get_info(buffer,start,offset,length,
gdth_ctr_vtab[i],hanum,busnum));
}
#endif
static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
int hanum,int busnum) gdth_ha_str *ha)
{ {
int ret_val = -EINVAL; int ret_val = -EINVAL;
TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); TRACE2(("gdth_set_info() ha %d\n",ha->hanum,));
if (length >= 4) { if (length >= 4) {
if (strncmp(buffer,"gdth",4) == 0) { if (strncmp(buffer,"gdth",4) == 0) {
buffer += 5; buffer += 5;
length -= 5; length -= 5;
ret_val = gdth_set_asc_info(host, buffer, length, hanum); ret_val = gdth_set_asc_info(host, buffer, length, ha);
} }
} }
@ -67,11 +37,10 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
} }
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int length,int hanum) int length, gdth_ha_str *ha)
{ {
int orig_length, drive, wb_mode; int orig_length, drive, wb_mode;
int i, found; int i, found;
gdth_ha_str *ha;
gdth_cmd_str gdtcmd; gdth_cmd_str gdtcmd;
gdth_cpar_str *pcpar; gdth_cpar_str *pcpar;
ulong64 paddr; ulong64 paddr;
@ -80,8 +49,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
memset(cmnd, 0xff, 12); memset(cmnd, 0xff, 12);
memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
TRACE2(("gdth_set_asc_info() ha %d\n",hanum)); TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum));
ha = HADATA(gdth_ctr_tab[hanum]);
orig_length = length + 5; orig_length = length + 5;
drive = -1; drive = -1;
wb_mode = 0; wb_mode = 0;
@ -157,7 +125,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
} }
if (wb_mode) { if (wb_mode) {
if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE, &paddr)) if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr))
return(-EBUSY); return(-EBUSY);
pcpar = (gdth_cpar_str *)ha->pscratch; pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
@ -171,7 +139,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdth_execute(host, &gdtcmd, cmnd, 30, NULL); gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr); gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr);
printk("Done.\n"); printk("Done.\n");
return(orig_length); return(orig_length);
} }
@ -181,11 +149,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
} }
static int gdth_get_info(char *buffer,char **start,off_t offset,int length, static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
struct Scsi_Host *host,int hanum,int busnum) struct Scsi_Host *host, gdth_ha_str *ha)
{ {
int size = 0,len = 0; int size = 0,len = 0;
off_t begin = 0,pos = 0; off_t begin = 0,pos = 0;
gdth_ha_str *ha;
int id, i, j, k, sec, flag; int id, i, j, k, sec, flag;
int no_mdrv = 0, drv_no, is_mirr; int no_mdrv = 0, drv_no, is_mirr;
ulong32 cnt; ulong32 cnt;
@ -214,8 +181,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
memset(cmnd, 0xff, 12); memset(cmnd, 0xff, 12);
memset(gdtcmd, 0, sizeof(gdth_cmd_str)); memset(gdtcmd, 0, sizeof(gdth_cmd_str));
TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); TRACE2(("gdth_get_info() ha %d\n",ha->hanum));
ha = HADATA(gdth_ctr_tab[hanum]);
/* request is i.e. "cat /proc/scsi/gdth/0" */ /* request is i.e. "cat /proc/scsi/gdth/0" */
@ -245,13 +211,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
/* controller information */ /* controller information */
size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); size = sprintf(buffer+len,"\nDisk Array Controller Information:\n");
len += size; pos = begin + len; len += size; pos = begin + len;
if (virt_ctr) strcpy(hrec, ha->binfo.type_string);
sprintf(hrec, "%s (Bus %d)", ha->binfo.type_string, busnum);
else
strcpy(hrec, ha->binfo.type_string);
size = sprintf(buffer+len, size = sprintf(buffer+len,
" Number: \t%d \tName: \t%s\n", " Number: \t%d \tName: \t%s\n",
hanum, hrec); ha->hanum, hrec);
len += size; pos = begin + len; len += size; pos = begin + len;
if (ha->more_proc) if (ha->more_proc)
@ -301,7 +264,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) { for (i = 0; i < ha->bus_cnt; ++i) {
@ -404,7 +367,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
goto stop_output; goto stop_output;
} }
} }
gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
@ -416,7 +379,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
@ -510,7 +473,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
if (pos > offset + length) if (pos > offset + length)
goto stop_output; goto stop_output;
} }
gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
@ -522,7 +485,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
@ -581,7 +544,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
goto stop_output; goto stop_output;
} }
} }
gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
if (!flag) { if (!flag) {
size = sprintf(buffer+len, "\n --\n"); size = sprintf(buffer+len, "\n --\n");
@ -593,7 +556,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
len += size; pos = begin + len; len += size; pos = begin + len;
flag = FALSE; flag = FALSE;
buf = gdth_ioctl_alloc(hanum, sizeof(gdth_hget_str), FALSE, &paddr); buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr);
if (!buf) if (!buf)
goto stop_output; goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) { for (i = 0; i < MAX_LDRIVES; ++i) {
@ -626,7 +589,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
} }
} }
} }
gdth_ioctl_free(hanum, sizeof(gdth_hget_str), buf, paddr); gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr);
for (i = 0; i < MAX_HDRIVES; ++i) { for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present)) if (!(ha->hdr[i].present))
@ -664,7 +627,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
id = gdth_read_event(ha, id, estr); id = gdth_read_event(ha, id, estr);
if (estr->event_source == 0) if (estr->event_source == 0)
break; break;
if (estr->event_data.eu.driver.ionode == hanum && if (estr->event_data.eu.driver.ionode == ha->hanum &&
estr->event_source == ES_ASYNC) { estr->event_source == ES_ASYNC) {
gdth_log_event(&estr->event_data, hrec); gdth_log_event(&estr->event_data, hrec);
do_gettimeofday(&tv); do_gettimeofday(&tv);
@ -699,17 +662,15 @@ free_fail:
return rc; return rc;
} }
static char *gdth_ioctl_alloc(int hanum, int size, int scratch, static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
ulong64 *paddr) ulong64 *paddr)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
char *ret_val; char *ret_val;
if (size == 0) if (size == 0)
return NULL; return NULL;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
if (!ha->scratch_busy && size <= GDTH_SCRATCH) { if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
@ -729,12 +690,10 @@ static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
return ret_val; return ret_val;
} }
static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
if (buf == ha->pscratch) { if (buf == ha->pscratch) {
@ -747,13 +706,11 @@ static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr)
} }
#ifdef GDTH_IOCTL_PROC #ifdef GDTH_IOCTL_PROC
static int gdth_ioctl_check_bin(int hanum, ushort size) static int gdth_ioctl_check_bin(gdth_ha_str *ha, ushort size)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
int ret_val; int ret_val;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
ret_val = FALSE; ret_val = FALSE;
@ -766,27 +723,27 @@ static int gdth_ioctl_check_bin(int hanum, ushort size)
} }
#endif #endif
static void gdth_wait_completion(int hanum, int busnum, int id) static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
int i; int i;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
struct gdth_cmndinfo *cmndinfo;
unchar b, t; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
for (i = 0; i < GDTH_MAXCMDS; ++i) { for (i = 0; i < GDTH_MAXCMDS; ++i) {
scp = ha->cmd_tab[i].cmnd; scp = ha->cmd_tab[i].cmnd;
cmndinfo = gdth_cmnd_priv(scp);
b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; b = scp->device->channel;
t = scp->device->id; t = scp->device->id;
if (!SPECIAL_SCP(scp) && t == (unchar)id && if (!SPECIAL_SCP(scp) && t == (unchar)id &&
b == (unchar)busnum) { b == (unchar)busnum) {
scp->SCp.have_data_in = 0; cmndinfo->wait_for_completion = 0;
spin_unlock_irqrestore(&ha->smp_lock, flags); spin_unlock_irqrestore(&ha->smp_lock, flags);
while (!scp->SCp.have_data_in) while (!cmndinfo->wait_for_completion)
barrier(); barrier();
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
} }
@ -794,55 +751,51 @@ static void gdth_wait_completion(int hanum, int busnum, int id)
spin_unlock_irqrestore(&ha->smp_lock, flags); spin_unlock_irqrestore(&ha->smp_lock, flags);
} }
static void gdth_stop_timeout(int hanum, int busnum, int id) static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
unchar b, t; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
if (scp->done != gdth_scsi_done) { struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
b = virt_ctr ? if (!cmndinfo->internal_command) {
NUMDATA(scp->device->host)->busnum : scp->device->channel; b = scp->device->channel;
t = scp->device->id; t = scp->device->id;
if (t == (unchar)id && b == (unchar)busnum) { if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_stop_timeout(): update_timeout()\n")); TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); cmndinfo->timeout = gdth_update_timeout(scp, 0);
} }
} }
} }
spin_unlock_irqrestore(&ha->smp_lock, flags); spin_unlock_irqrestore(&ha->smp_lock, flags);
} }
static void gdth_start_timeout(int hanum, int busnum, int id) static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id)
{ {
gdth_ha_str *ha;
ulong flags; ulong flags;
Scsi_Cmnd *scp; Scsi_Cmnd *scp;
unchar b, t; unchar b, t;
ha = HADATA(gdth_ctr_tab[hanum]);
spin_lock_irqsave(&ha->smp_lock, flags); spin_lock_irqsave(&ha->smp_lock, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
if (scp->done != gdth_scsi_done) { struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
b = virt_ctr ? if (!cmndinfo->internal_command) {
NUMDATA(scp->device->host)->busnum : scp->device->channel; b = scp->device->channel;
t = scp->device->id; t = scp->device->id;
if (t == (unchar)id && b == (unchar)busnum) { if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_start_timeout(): update_timeout()\n")); TRACE2(("gdth_start_timeout(): update_timeout()\n"));
gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); gdth_update_timeout(scp, cmndinfo->timeout);
} }
} }
} }
spin_unlock_irqrestore(&ha->smp_lock, flags); spin_unlock_irqrestore(&ha->smp_lock, flags);
} }
static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout) static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout)
{ {
int oldto; int oldto;

View file

@ -9,20 +9,20 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
int timeout, u32 *info); int timeout, u32 *info);
static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host,
int hanum,int busnum); gdth_ha_str *ha);
static int gdth_get_info(char *buffer,char **start,off_t offset,int length, static int gdth_get_info(char *buffer,char **start,off_t offset,int length,
struct Scsi_Host *host,int hanum,int busnum); struct Scsi_Host *host, gdth_ha_str *ha);
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int length, int hanum); int length, gdth_ha_str *ha);
static char *gdth_ioctl_alloc(int hanum, int size, int scratch, static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
ulong64 *paddr); ulong64 *paddr);
static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr); static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr);
static void gdth_wait_completion(int hanum, int busnum, int id); static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
static void gdth_stop_timeout(int hanum, int busnum, int id); static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id);
static void gdth_start_timeout(int hanum, int busnum, int id); static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id);
static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout); static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout);
#endif #endif

View file

@ -342,6 +342,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->unchecked_isa_dma = sht->unchecked_isa_dma; shost->unchecked_isa_dma = sht->unchecked_isa_dma;
shost->use_clustering = sht->use_clustering; shost->use_clustering = sht->use_clustering;
shost->ordered_tag = sht->ordered_tag; shost->ordered_tag = sht->ordered_tag;
shost->active_mode = sht->supported_mode;
if (sht->max_host_blocked) if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked; shost->max_host_blocked = sht->max_host_blocked;

View file

@ -1,6 +1,6 @@
/* /*
* HighPoint RR3xxx controller driver for Linux * HighPoint RR3xxx controller driver for Linux
* Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -42,7 +42,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver");
static char driver_name[] = "hptiop"; static char driver_name[] = "hptiop";
static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
static const char driver_ver[] = "v1.0 (060426)"; static const char driver_ver[] = "v1.2 (070830)";
static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
@ -76,7 +76,7 @@ static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec)
static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag)
{ {
if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) if (tag & IOPMU_QUEUE_ADDR_HOST_BIT)
return hptiop_host_request_callback(hba, return hptiop_host_request_callback(hba,
tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); tag & ~IOPMU_QUEUE_ADDR_HOST_BIT);
else else
@ -323,12 +323,22 @@ static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req)
hba->req_list = req; hba->req_list = req;
} }
static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 _tag)
{ {
struct hpt_iop_request_scsi_command *req; struct hpt_iop_request_scsi_command *req;
struct scsi_cmnd *scp; struct scsi_cmnd *scp;
u32 tag;
if (hba->iopintf_v2) {
tag = _tag & ~ IOPMU_QUEUE_REQUEST_RESULT_BIT;
req = hba->reqs[tag].req_virt;
if (likely(_tag & IOPMU_QUEUE_REQUEST_RESULT_BIT))
req->header.result = IOP_RESULT_SUCCESS;
} else {
tag = _tag;
req = hba->reqs[tag].req_virt;
}
req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt;
dprintk("hptiop_host_request_callback: req=%p, type=%d, " dprintk("hptiop_host_request_callback: req=%p, type=%d, "
"result=%d, context=0x%x tag=%d\n", "result=%d, context=0x%x tag=%d\n",
req, req->header.type, req->header.result, req, req->header.type, req->header.result,
@ -497,7 +507,7 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
goto cmd_done; goto cmd_done;
} }
req = (struct hpt_iop_request_scsi_command *)_req->req_virt; req = _req->req_virt;
/* build S/G table */ /* build S/G table */
sg_count = hptiop_buildsgl(scp, req->sg_list); sg_count = hptiop_buildsgl(scp, req->sg_list);
@ -521,8 +531,19 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); memcpy(req->cdb, scp->cmnd, sizeof(req->cdb));
writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, if (hba->iopintf_v2) {
&hba->iop->inbound_queue); u32 size_bits;
if (req->header.size < 256)
size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT;
else if (req->header.size < 512)
size_bits = IOPMU_QUEUE_ADDR_HOST_BIT;
else
size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT |
IOPMU_QUEUE_ADDR_HOST_BIT;
writel(_req->req_shifted_phy | size_bits, &hba->iop->inbound_queue);
} else
writel(_req->req_shifted_phy | IOPMU_QUEUE_ADDR_HOST_BIT,
&hba->iop->inbound_queue);
return 0; return 0;
@ -688,6 +709,7 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
hba->pcidev = pcidev; hba->pcidev = pcidev;
hba->host = host; hba->host = host;
hba->initialized = 0; hba->initialized = 0;
hba->iopintf_v2 = 0;
atomic_set(&hba->resetting, 0); atomic_set(&hba->resetting, 0);
atomic_set(&hba->reset_count, 0); atomic_set(&hba->reset_count, 0);
@ -722,8 +744,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
hba->max_request_size = le32_to_cpu(iop_config.request_size); hba->max_request_size = le32_to_cpu(iop_config.request_size);
hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count);
hba->firmware_version = le32_to_cpu(iop_config.firmware_version); hba->firmware_version = le32_to_cpu(iop_config.firmware_version);
hba->interface_version = le32_to_cpu(iop_config.interface_version);
hba->sdram_size = le32_to_cpu(iop_config.sdram_size); hba->sdram_size = le32_to_cpu(iop_config.sdram_size);
if (hba->firmware_version > 0x01020000 ||
hba->interface_version > 0x01020000)
hba->iopintf_v2 = 1;
host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9;
host->max_id = le32_to_cpu(iop_config.max_devices); host->max_id = le32_to_cpu(iop_config.max_devices);
host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count);
@ -731,8 +758,15 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
host->max_cmd_len = 16; host->max_cmd_len = 16;
set_config.vbus_id = cpu_to_le32(host->host_no); req_size = sizeof(struct hpt_iop_request_scsi_command)
+ sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
if ((req_size & 0x1f) != 0)
req_size = (req_size + 0x1f) & ~0x1f;
memset(&set_config, 0, sizeof(struct hpt_iop_request_set_config));
set_config.iop_id = cpu_to_le32(host->host_no); set_config.iop_id = cpu_to_le32(host->host_no);
set_config.vbus_id = cpu_to_le16(host->host_no);
set_config.max_host_request_size = cpu_to_le16(req_size);
if (iop_set_config(hba, &set_config)) { if (iop_set_config(hba, &set_config)) {
printk(KERN_ERR "scsi%d: set config failed\n", printk(KERN_ERR "scsi%d: set config failed\n",
@ -750,10 +784,6 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
} }
/* Allocate request mem */ /* Allocate request mem */
req_size = sizeof(struct hpt_iop_request_scsi_command)
+ sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
if ((req_size& 0x1f) != 0)
req_size = (req_size + 0x1f) & ~0x1f;
dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests);
@ -879,8 +909,10 @@ static void hptiop_remove(struct pci_dev *pcidev)
} }
static struct pci_device_id hptiop_id_table[] = { static struct pci_device_id hptiop_id_table[] = {
{ PCI_DEVICE(0x1103, 0x3220) }, { PCI_VDEVICE(TTI, 0x3220) },
{ PCI_DEVICE(0x1103, 0x3320) }, { PCI_VDEVICE(TTI, 0x3320) },
{ PCI_VDEVICE(TTI, 0x3520) },
{ PCI_VDEVICE(TTI, 0x4320) },
{}, {},
}; };
@ -910,3 +942,4 @@ module_init(hptiop_module_init);
module_exit(hptiop_module_exit); module_exit(hptiop_module_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View file

@ -1,6 +1,6 @@
/* /*
* HighPoint RR3xxx controller driver for Linux * HighPoint RR3xxx controller driver for Linux
* Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,219 +18,6 @@
#ifndef _HPTIOP_H_ #ifndef _HPTIOP_H_
#define _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 struct hpt_iopmu
{ {
__le32 resrved0[4]; __le32 resrved0[4];
@ -252,6 +39,8 @@ struct hpt_iopmu
#define IOPMU_QUEUE_EMPTY 0xffffffff #define IOPMU_QUEUE_EMPTY 0xffffffff
#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 #define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000
#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 #define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000
#define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000
#define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000
#define IOPMU_OUTBOUND_INT_MSG0 1 #define IOPMU_OUTBOUND_INT_MSG0 1
#define IOPMU_OUTBOUND_INT_MSG1 2 #define IOPMU_OUTBOUND_INT_MSG1 2
@ -336,7 +125,8 @@ struct hpt_iop_request_set_config
{ {
struct hpt_iop_request_header header; struct hpt_iop_request_header header;
__le32 iop_id; __le32 iop_id;
__le32 vbus_id; __le16 vbus_id;
__le16 max_host_request_size;
__le32 reserve[6]; __le32 reserve[6];
}; };
@ -412,9 +202,8 @@ struct hptiop_hba {
struct Scsi_Host * host; struct Scsi_Host * host;
struct pci_dev * pcidev; struct pci_dev * pcidev;
struct list_head link;
/* IOP config info */ /* IOP config info */
u32 interface_version;
u32 firmware_version; u32 firmware_version;
u32 sdram_size; u32 sdram_size;
u32 max_devices; u32 max_devices;
@ -423,8 +212,10 @@ struct hptiop_hba {
u32 max_sg_descriptors; u32 max_sg_descriptors;
u32 req_size; /* host-allocated request buffer size */ u32 req_size; /* host-allocated request buffer size */
int initialized;
int msg_done; int iopintf_v2: 1;
int initialized: 1;
int msg_done: 1;
struct hptiop_request * req_list; struct hptiop_request * req_list;
struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; struct hptiop_request reqs[HPTIOP_MAX_REQUESTS];

View file

@ -460,13 +460,6 @@ module_param(boot_options, charp, 0);
module_param_array(io_port, int, NULL, 0); module_param_array(io_port, int, NULL, 0);
module_param_array(scsi_id, int, NULL, 0); module_param_array(scsi_id, int, NULL, 0);
#if 0 /* FIXME: No longer exist? --RR */
MODULE_PARM(display, "1i");
MODULE_PARM(adisplay, "1i");
MODULE_PARM(normal, "1i");
MODULE_PARM(ansi, "1i");
#endif
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#endif #endif
/*counter of concurrent disk read/writes, to turn on/off disk led */ /*counter of concurrent disk read/writes, to turn on/off disk led */
@ -1693,6 +1686,7 @@ static int __devexit ibmmca_remove(struct device *dev)
scsi_remove_host(shpnt); scsi_remove_host(shpnt);
release_region(shpnt->io_port, shpnt->n_io_port); release_region(shpnt->io_port, shpnt->n_io_port);
free_irq(shpnt->irq, dev); free_irq(shpnt->irq, dev);
scsi_host_put(shpnt);
return 0; return 0;
} }

View file

@ -1,9 +1,7 @@
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
ibmvscsic-y += ibmvscsi.o ibmvscsic-y += ibmvscsi.o
ifndef CONFIG_PPC_PSERIES
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
endif
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o

View file

@ -70,11 +70,13 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <asm/firmware.h>
#include <asm/vio.h> #include <asm/vio.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_transport_srp.h>
#include "ibmvscsi.h" #include "ibmvscsi.h"
/* The values below are somewhat arbitrary default values, but /* The values below are somewhat arbitrary default values, but
@ -87,8 +89,12 @@ static int max_channel = 3;
static int init_timeout = 5; static int init_timeout = 5;
static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT;
static struct scsi_transport_template *ibmvscsi_transport_template;
#define IBMVSCSI_VERSION "1.5.8" #define IBMVSCSI_VERSION "1.5.8"
static struct ibmvscsi_ops *ibmvscsi_ops;
MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_DESCRIPTION("IBM Virtual SCSI");
MODULE_AUTHOR("Dave Boutcher"); MODULE_AUTHOR("Dave Boutcher");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -506,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
atomic_set(&hostdata->request_limit, 0); atomic_set(&hostdata->request_limit, 0);
purge_requests(hostdata, DID_ERROR); purge_requests(hostdata, DID_ERROR);
if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) ||
(ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) ||
(vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) {
atomic_set(&hostdata->request_limit, -1); atomic_set(&hostdata->request_limit, -1);
dev_err(hostdata->dev, "error after reset\n"); dev_err(hostdata->dev, "error after reset\n");
@ -612,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
} }
if ((rc = if ((rc =
ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
list_del(&evt_struct->list); list_del(&evt_struct->list);
del_timer(&evt_struct->timer); del_timer(&evt_struct->timer);
@ -1211,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
case 0x01: /* Initialization message */ case 0x01: /* Initialization message */
dev_info(hostdata->dev, "partner initialized\n"); dev_info(hostdata->dev, "partner initialized\n");
/* Send back a response */ /* Send back a response */
if ((rc = ibmvscsi_send_crq(hostdata, if ((rc = ibmvscsi_ops->send_crq(hostdata,
0xC002000000000000LL, 0)) == 0) { 0xC002000000000000LL, 0)) == 0) {
/* Now login */ /* Now login */
send_srp_login(hostdata); send_srp_login(hostdata);
} else { } else {
@ -1237,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
/* We need to re-setup the interpartition connection */ /* We need to re-setup the interpartition connection */
dev_info(hostdata->dev, "Re-enabling adapter!\n"); dev_info(hostdata->dev, "Re-enabling adapter!\n");
purge_requests(hostdata, DID_REQUEUE); purge_requests(hostdata, DID_REQUEUE);
if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue,
hostdata)) || hostdata)) ||
(ibmvscsi_send_crq(hostdata, (ibmvscsi_ops->send_crq(hostdata,
0xC001000000000000LL, 0))) { 0xC001000000000000LL, 0))) {
atomic_set(&hostdata->request_limit, atomic_set(&hostdata->request_limit,
-1); -1);
dev_err(hostdata->dev, "error after enable\n"); dev_err(hostdata->dev, "error after enable\n");
@ -1250,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
crq->format); crq->format);
purge_requests(hostdata, DID_ERROR); purge_requests(hostdata, DID_ERROR);
if ((ibmvscsi_reset_crq_queue(&hostdata->queue, if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue,
hostdata)) || hostdata)) ||
(ibmvscsi_send_crq(hostdata, (ibmvscsi_ops->send_crq(hostdata,
0xC001000000000000LL, 0))) { 0xC001000000000000LL, 0))) {
atomic_set(&hostdata->request_limit, atomic_set(&hostdata->request_limit,
-1); -1);
dev_err(hostdata->dev, "error after reset\n"); dev_err(hostdata->dev, "error after reset\n");
@ -1553,6 +1559,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
struct ibmvscsi_host_data *hostdata; struct ibmvscsi_host_data *hostdata;
struct Scsi_Host *host; struct Scsi_Host *host;
struct device *dev = &vdev->dev; struct device *dev = &vdev->dev;
struct srp_rport_identifiers ids;
struct srp_rport *rport;
unsigned long wait_switch = 0; unsigned long wait_switch = 0;
int rc; int rc;
@ -1565,6 +1573,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
goto scsi_host_alloc_failed; goto scsi_host_alloc_failed;
} }
host->transportt = ibmvscsi_transport_template;
hostdata = shost_priv(host); hostdata = shost_priv(host);
memset(hostdata, 0x00, sizeof(*hostdata)); memset(hostdata, 0x00, sizeof(*hostdata));
INIT_LIST_HEAD(&hostdata->sent); INIT_LIST_HEAD(&hostdata->sent);
@ -1573,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
atomic_set(&hostdata->request_limit, -1); atomic_set(&hostdata->request_limit, -1);
hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests);
if (rc != 0 && rc != H_RESOURCE) { if (rc != 0 && rc != H_RESOURCE) {
dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc);
goto init_crq_failed; goto init_crq_failed;
@ -1590,11 +1599,19 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
if (scsi_add_host(hostdata->host, hostdata->dev)) if (scsi_add_host(hostdata->host, hostdata->dev))
goto add_host_failed; goto add_host_failed;
/* we don't have a proper target_port_id so let's use the fake one */
memcpy(ids.port_id, hostdata->madapter_info.partition_name,
sizeof(ids.port_id));
ids.roles = SRP_RPORT_ROLE_TARGET;
rport = srp_rport_add(host, &ids);
if (IS_ERR(rport))
goto add_srp_port_failed;
/* Try to send an initialization message. Note that this is allowed /* Try to send an initialization message. Note that this is allowed
* to fail if the other end is not acive. In that case we don't * to fail if the other end is not acive. In that case we don't
* want to scan * want to scan
*/ */
if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0
|| rc == H_RESOURCE) { || rc == H_RESOURCE) {
/* /*
* Wait around max init_timeout secs for the adapter to finish * Wait around max init_timeout secs for the adapter to finish
@ -1617,10 +1634,12 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
vdev->dev.driver_data = hostdata; vdev->dev.driver_data = hostdata;
return 0; return 0;
add_srp_port_failed:
scsi_remove_host(hostdata->host);
add_host_failed: add_host_failed:
release_event_pool(&hostdata->pool, hostdata); release_event_pool(&hostdata->pool, hostdata);
init_pool_failed: init_pool_failed:
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests);
init_crq_failed: init_crq_failed:
scsi_host_put(host); scsi_host_put(host);
scsi_host_alloc_failed: scsi_host_alloc_failed:
@ -1631,9 +1650,10 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
{ {
struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data;
release_event_pool(&hostdata->pool, hostdata); release_event_pool(&hostdata->pool, hostdata);
ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata,
max_requests); max_requests);
srp_remove_host(hostdata->host);
scsi_remove_host(hostdata->host); scsi_remove_host(hostdata->host);
scsi_host_put(hostdata->host); scsi_host_put(hostdata->host);
@ -1660,14 +1680,35 @@ static struct vio_driver ibmvscsi_driver = {
} }
}; };
static struct srp_function_template ibmvscsi_transport_functions = {
};
int __init ibmvscsi_module_init(void) int __init ibmvscsi_module_init(void)
{ {
return vio_register_driver(&ibmvscsi_driver); int ret;
if (firmware_has_feature(FW_FEATURE_ISERIES))
ibmvscsi_ops = &iseriesvscsi_ops;
else if (firmware_has_feature(FW_FEATURE_VIO))
ibmvscsi_ops = &rpavscsi_ops;
else
return -ENODEV;
ibmvscsi_transport_template =
srp_attach_transport(&ibmvscsi_transport_functions);
if (!ibmvscsi_transport_template)
return -ENOMEM;
ret = vio_register_driver(&ibmvscsi_driver);
if (ret)
srp_release_transport(ibmvscsi_transport_template);
return ret;
} }
void __exit ibmvscsi_module_exit(void) void __exit ibmvscsi_module_exit(void)
{ {
vio_unregister_driver(&ibmvscsi_driver); vio_unregister_driver(&ibmvscsi_driver);
srp_release_transport(ibmvscsi_transport_template);
} }
module_init(ibmvscsi_module_init); module_init(ibmvscsi_module_init);

View file

@ -98,21 +98,25 @@ struct ibmvscsi_host_data {
}; };
/* routines for managing a command/response queue */ /* routines for managing a command/response queue */
int ibmvscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
void ibmvscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
void ibmvscsi_handle_crq(struct viosrp_crq *crq, void ibmvscsi_handle_crq(struct viosrp_crq *crq,
struct ibmvscsi_host_data *hostdata); struct ibmvscsi_host_data *hostdata);
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2); struct ibmvscsi_ops {
int (*init_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
void (*release_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests);
int (*reset_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int (*reenable_crq_queue)(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata);
int (*send_crq)(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2);
};
extern struct ibmvscsi_ops iseriesvscsi_ops;
extern struct ibmvscsi_ops rpavscsi_ops;
#endif /* IBMVSCSI_H */ #endif /* IBMVSCSI_H */

View file

@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_transport_srp.h>
#include <scsi/scsi_tgt.h> #include <scsi/scsi_tgt.h>
#include <scsi/libsrp.h> #include <scsi/libsrp.h>
#include <asm/hvcall.h> #include <asm/hvcall.h>
@ -68,9 +69,12 @@ struct vio_port {
unsigned long liobn; unsigned long liobn;
unsigned long riobn; unsigned long riobn;
struct srp_target *target; struct srp_target *target;
struct srp_rport *rport;
}; };
static struct workqueue_struct *vtgtd; static struct workqueue_struct *vtgtd;
static struct scsi_transport_template *ibmvstgt_transport_template;
/* /*
* These are fixed for the system and come from the Open Firmware device tree. * These are fixed for the system and come from the Open Firmware device tree.
@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc,
static void handle_cmd_queue(struct srp_target *target) static void handle_cmd_queue(struct srp_target *target)
{ {
struct Scsi_Host *shost = target->shost; struct Scsi_Host *shost = target->shost;
struct srp_rport *rport = target_to_port(target)->rport;
struct iu_entry *iue; struct iu_entry *iue;
struct srp_cmd *cmd; struct srp_cmd *cmd;
unsigned long flags; unsigned long flags;
@ -200,7 +205,8 @@ retry:
if (!test_and_set_bit(V_FLYING, &iue->flags)) { if (!test_and_set_bit(V_FLYING, &iue->flags)) {
spin_unlock_irqrestore(&target->lock, flags); spin_unlock_irqrestore(&target->lock, flags);
cmd = iue->sbuf->buf; cmd = iue->sbuf->buf;
err = srp_cmd_queue(shost, cmd, iue, 0); err = srp_cmd_queue(shost, cmd, iue,
(unsigned long)rport, 0);
if (err) { if (err) {
eprintk("cannot queue cmd %p %d\n", cmd, err); eprintk("cannot queue cmd %p %d\n", cmd, err);
srp_iu_put(iue); srp_iu_put(iue);
@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue)
union viosrp_iu *iu = vio_iu(iue); union viosrp_iu *iu = vio_iu(iue);
struct srp_login_rsp *rsp = &iu->srp.login_rsp; struct srp_login_rsp *rsp = &iu->srp.login_rsp;
uint64_t tag = iu->srp.rsp.tag; uint64_t tag = iu->srp.rsp.tag;
struct Scsi_Host *shost = iue->target->shost;
struct srp_target *target = host_to_srp_target(shost);
struct vio_port *vport = target_to_port(target);
struct srp_rport_identifiers ids;
memset(&ids, 0, sizeof(ids));
sprintf(ids.port_id, "%x", vport->dma_dev->unit_address);
ids.roles = SRP_RPORT_ROLE_INITIATOR;
if (!vport->rport)
vport->rport = srp_rport_add(shost, &ids);
/* TODO handle case that requested size is wrong and /* TODO handle case that requested size is wrong and
* buffer format is wrong * buffer format is wrong
@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue)
fn = 0; fn = 0;
} }
if (fn) if (fn)
scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, scsi_tgt_tsk_mgmt_request(iue->target->shost,
(unsigned long)iue->target->shost,
fn,
iu->srp.tsk_mgmt.task_tag, iu->srp.tsk_mgmt.task_tag,
(struct scsi_lun *) &iu->srp.tsk_mgmt.lun, (struct scsi_lun *) &iu->srp.tsk_mgmt.lun,
iue); iue);
@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc)
return 0; return 0;
} }
static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost,
u64 itn_id, u64 mid, int result)
{ {
struct iu_entry *iue = (struct iu_entry *) ((void *) mid); struct iu_entry *iue = (struct iu_entry *) ((void *) mid);
union viosrp_iu *iu = vio_iu(iue); union viosrp_iu *iu = vio_iu(iue);
@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result)
return 0; return 0;
} }
static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id,
int result)
{
struct srp_target *target = host_to_srp_target(shost);
struct vio_port *vport = target_to_port(target);
if (result) {
eprintk("%p %d\n", shost, result);
srp_rport_del(vport->rport);
vport->rport = NULL;
}
return 0;
}
static ssize_t system_id_show(struct class_device *cdev, char *buf) static ssize_t system_id_show(struct class_device *cdev, char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", system_id); return snprintf(buf, PAGE_SIZE, "%s\n", system_id);
@ -785,9 +818,9 @@ static struct scsi_host_template ibmvstgt_sht = {
.max_sectors = DEFAULT_MAX_SECTORS, .max_sectors = DEFAULT_MAX_SECTORS,
.transfer_response = ibmvstgt_cmd_done, .transfer_response = ibmvstgt_cmd_done,
.eh_abort_handler = ibmvstgt_eh_abort_handler, .eh_abort_handler = ibmvstgt_eh_abort_handler,
.tsk_mgmt_response = ibmvstgt_tsk_mgmt_response,
.shost_attrs = ibmvstgt_attrs, .shost_attrs = ibmvstgt_attrs,
.proc_name = TGT_NAME, .proc_name = TGT_NAME,
.supported_mode = MODE_TARGET,
}; };
static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target));
if (!shost) if (!shost)
goto free_vport; goto free_vport;
shost->transportt = ibmvstgt_transport_template;
err = scsi_tgt_alloc_queue(shost); err = scsi_tgt_alloc_queue(shost);
if (err) if (err)
goto put_host; goto put_host;
@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id)
err = scsi_add_host(shost, target->dev); err = scsi_add_host(shost, target->dev);
if (err) if (err)
goto destroy_queue; goto destroy_queue;
return 0;
return 0;
destroy_queue: destroy_queue:
crq_queue_destroy(target); crq_queue_destroy(target);
free_srp_target: free_srp_target:
@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev)
struct vio_port *vport = target->ldata; struct vio_port *vport = target->ldata;
crq_queue_destroy(target); crq_queue_destroy(target);
srp_remove_host(shost);
scsi_remove_host(shost); scsi_remove_host(shost);
scsi_tgt_free_queue(shost); scsi_tgt_free_queue(shost);
srp_target_free(target); srp_target_free(target);
@ -909,15 +944,25 @@ static int get_system_info(void)
return 0; return 0;
} }
static struct srp_function_template ibmvstgt_transport_functions = {
.tsk_mgmt_response = ibmvstgt_tsk_mgmt_response,
.it_nexus_response = ibmvstgt_it_nexus_response,
};
static int ibmvstgt_init(void) static int ibmvstgt_init(void)
{ {
int err = -ENOMEM; int err = -ENOMEM;
printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n");
ibmvstgt_transport_template =
srp_attach_transport(&ibmvstgt_transport_functions);
if (!ibmvstgt_transport_template)
return err;
vtgtd = create_workqueue("ibmvtgtd"); vtgtd = create_workqueue("ibmvtgtd");
if (!vtgtd) if (!vtgtd)
return err; goto release_transport;
err = get_system_info(); err = get_system_info();
if (err) if (err)
@ -928,9 +973,10 @@ static int ibmvstgt_init(void)
goto destroy_wq; goto destroy_wq;
return 0; return 0;
destroy_wq: destroy_wq:
destroy_workqueue(vtgtd); destroy_workqueue(vtgtd);
release_transport:
srp_release_transport(ibmvstgt_transport_template);
return err; return err;
} }
@ -940,6 +986,7 @@ static void ibmvstgt_exit(void)
destroy_workqueue(vtgtd); destroy_workqueue(vtgtd);
vio_unregister_driver(&ibmvstgt_driver); vio_unregister_driver(&ibmvstgt_driver);
srp_release_transport(ibmvstgt_transport_template);
} }
MODULE_DESCRIPTION("IBM Virtual SCSI Target"); MODULE_DESCRIPTION("IBM Virtual SCSI Target");

View file

@ -53,7 +53,7 @@ struct srp_lp_event {
/** /**
* standard interface for handling logical partition events. * standard interface for handling logical partition events.
*/ */
static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt)
{ {
struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; struct srp_lp_event *evt = (struct srp_lp_event *)lpevt;
@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt)
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* Routines for driver initialization * Routines for driver initialization
*/ */
int ibmvscsi_init_crq_queue(struct crq_queue *queue, static int iseriesvscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
int rc; int rc;
@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
goto viopath_open_failed; goto viopath_open_failed;
} }
rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event);
if (rc < 0) { if (rc < 0) {
printk("vio_setHandler failed with rc %d in open_event_path\n", printk("vio_setHandler failed with rc %d in open_event_path\n",
rc); rc);
@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
return -1; return -1;
} }
void ibmvscsi_release_crq_queue(struct crq_queue *queue, static void iseriesvscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
vio_clearHandler(viomajorsubtype_scsi); vio_clearHandler(viomajorsubtype_scsi);
viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests);
@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue,
* *
* no-op for iSeries * no-op for iSeries
*/ */
int ibmvscsi_reset_crq_queue(struct crq_queue *queue, static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
return 0; return 0;
} }
@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
* *
* no-op for iSeries * no-op for iSeries
*/ */
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
return 0; return 0;
} }
/** /**
* ibmvscsi_send_crq: - Send a CRQ * iseriesvscsi_send_crq: - Send a CRQ
* @hostdata: the adapter * @hostdata: the adapter
* @word1: the first 64 bits of the data * @word1: the first 64 bits of the data
* @word2: the second 64 bits of the data * @word2: the second 64 bits of the data
*/ */
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2)
{ {
single_host_data = hostdata; single_host_data = hostdata;
return HvCallEvent_signalLpEventFast(viopath_hostLp, return HvCallEvent_signalLpEventFast(viopath_hostLp,
@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
VIOVERSION << 16, word1, word2, 0, VIOVERSION << 16, word1, word2, 0,
0); 0);
} }
struct ibmvscsi_ops iseriesvscsi_ops = {
.init_crq_queue = iseriesvscsi_init_crq_queue,
.release_crq_queue = iseriesvscsi_release_crq_queue,
.reset_crq_queue = iseriesvscsi_reset_crq_queue,
.reenable_crq_queue = iseriesvscsi_reenable_crq_queue,
.send_crq = iseriesvscsi_send_crq,
};

View file

@ -42,14 +42,14 @@ static unsigned int partition_number = -1;
* Routines for managing the command/response queue * Routines for managing the command/response queue
*/ */
/** /**
* ibmvscsi_handle_event: - Interrupt handler for crq events * rpavscsi_handle_event: - Interrupt handler for crq events
* @irq: number of irq to handle, not used * @irq: number of irq to handle, not used
* @dev_instance: ibmvscsi_host_data of host that received interrupt * @dev_instance: ibmvscsi_host_data of host that received interrupt
* *
* Disables interrupts and schedules srp_task * Disables interrupts and schedules srp_task
* Always returns IRQ_HANDLED * Always returns IRQ_HANDLED
*/ */
static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance)
{ {
struct ibmvscsi_host_data *hostdata = struct ibmvscsi_host_data *hostdata =
(struct ibmvscsi_host_data *)dev_instance; (struct ibmvscsi_host_data *)dev_instance;
@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance)
* Frees irq, deallocates a page for messages, unmaps dma, and unregisters * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
* the crq with the hypervisor. * the crq with the hypervisor.
*/ */
void ibmvscsi_release_crq_queue(struct crq_queue *queue, static void rpavscsi_release_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata, struct ibmvscsi_host_data *hostdata,
int max_requests) int max_requests)
{ {
long rc; long rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
} }
/** /**
* ibmvscsi_send_crq: - Send a CRQ * rpavscsi_send_crq: - Send a CRQ
* @hostdata: the adapter * @hostdata: the adapter
* @word1: the first 64 bits of the data * @word1: the first 64 bits of the data
* @word2: the second 64 bits of the data * @word2: the second 64 bits of the data
*/ */
int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata,
u64 word1, u64 word2)
{ {
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
} }
/** /**
* ibmvscsi_task: - Process srps asynchronously * rpavscsi_task: - Process srps asynchronously
* @data: ibmvscsi_host_data of host * @data: ibmvscsi_host_data of host
*/ */
static void ibmvscsi_task(void *data) static void rpavscsi_task(void *data)
{ {
struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@ -189,122 +190,14 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
hostdata->madapter_info.os_type = 2; hostdata->madapter_info.os_type = 2;
} }
/**
* initialize_crq_queue: - Initializes and registers CRQ with hypervisor
* @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host
*
* Allocates a page for messages, maps it for dma, and registers
* the crq with the hypervisor.
* Returns zero on success.
*/
int ibmvscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests)
{
int rc;
int retrc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
if (!queue->msgs)
goto malloc_failed;
queue->size = PAGE_SIZE / sizeof(*queue->msgs);
queue->msg_token = dma_map_single(hostdata->dev, queue->msgs,
queue->size * sizeof(*queue->msgs),
DMA_BIDIRECTIONAL);
if (dma_mapping_error(queue->msg_token))
goto map_failed;
gather_partition_info();
set_adapter_info(hostdata);
retrc = rc = plpar_hcall_norets(H_REG_CRQ,
vdev->unit_address,
queue->msg_token, PAGE_SIZE);
if (rc == H_RESOURCE)
/* maybe kexecing and resource is busy. try a reset */
rc = ibmvscsi_reset_crq_queue(queue,
hostdata);
if (rc == 2) {
/* Adapter is good, but other end is not ready */
dev_warn(hostdata->dev, "Partner adapter not ready\n");
retrc = 0;
} else if (rc != 0) {
dev_warn(hostdata->dev, "Error %d opening adapter\n", rc);
goto reg_crq_failed;
}
if (request_irq(vdev->irq,
ibmvscsi_handle_event,
0, "ibmvscsi", (void *)hostdata) != 0) {
dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
vdev->irq);
goto req_irq_failed;
}
rc = vio_enable_interrupts(vdev);
if (rc != 0) {
dev_err(hostdata->dev, "Error %d enabling interrupts!!!\n", rc);
goto req_irq_failed;
}
queue->cur = 0;
spin_lock_init(&queue->lock);
tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task,
(unsigned long)hostdata);
return retrc;
req_irq_failed:
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
reg_crq_failed:
dma_unmap_single(hostdata->dev,
queue->msg_token,
queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
map_failed:
free_page((unsigned long)queue->msgs);
malloc_failed:
return -1;
}
/**
* reenable_crq_queue: - reenables a crq after
* @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host
*
*/
int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata)
{
int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
/* Re-enable the CRQ */
do {
rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
} while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
if (rc)
dev_err(hostdata->dev, "Error %d enabling adapter\n", rc);
return rc;
}
/** /**
* reset_crq_queue: - resets a crq after a failure * reset_crq_queue: - resets a crq after a failure
* @queue: crq_queue to initialize and register * @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host * @hostdata: ibmvscsi_host_data of host
* *
*/ */
int ibmvscsi_reset_crq_queue(struct crq_queue *queue, static int rpavscsi_reset_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata) struct ibmvscsi_host_data *hostdata)
{ {
int rc; int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev); struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@ -332,3 +225,119 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
} }
return rc; return rc;
} }
/**
* initialize_crq_queue: - Initializes and registers CRQ with hypervisor
* @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host
*
* Allocates a page for messages, maps it for dma, and registers
* the crq with the hypervisor.
* Returns zero on success.
*/
static int rpavscsi_init_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata,
int max_requests)
{
int rc;
int retrc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);
if (!queue->msgs)
goto malloc_failed;
queue->size = PAGE_SIZE / sizeof(*queue->msgs);
queue->msg_token = dma_map_single(hostdata->dev, queue->msgs,
queue->size * sizeof(*queue->msgs),
DMA_BIDIRECTIONAL);
if (dma_mapping_error(queue->msg_token))
goto map_failed;
gather_partition_info();
set_adapter_info(hostdata);
retrc = rc = plpar_hcall_norets(H_REG_CRQ,
vdev->unit_address,
queue->msg_token, PAGE_SIZE);
if (rc == H_RESOURCE)
/* maybe kexecing and resource is busy. try a reset */
rc = rpavscsi_reset_crq_queue(queue,
hostdata);
if (rc == 2) {
/* Adapter is good, but other end is not ready */
dev_warn(hostdata->dev, "Partner adapter not ready\n");
retrc = 0;
} else if (rc != 0) {
dev_warn(hostdata->dev, "Error %d opening adapter\n", rc);
goto reg_crq_failed;
}
if (request_irq(vdev->irq,
rpavscsi_handle_event,
0, "ibmvscsi", (void *)hostdata) != 0) {
dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
vdev->irq);
goto req_irq_failed;
}
rc = vio_enable_interrupts(vdev);
if (rc != 0) {
dev_err(hostdata->dev, "Error %d enabling interrupts!!!\n", rc);
goto req_irq_failed;
}
queue->cur = 0;
spin_lock_init(&queue->lock);
tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
(unsigned long)hostdata);
return retrc;
req_irq_failed:
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
reg_crq_failed:
dma_unmap_single(hostdata->dev,
queue->msg_token,
queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL);
map_failed:
free_page((unsigned long)queue->msgs);
malloc_failed:
return -1;
}
/**
* reenable_crq_queue: - reenables a crq after
* @queue: crq_queue to initialize and register
* @hostdata: ibmvscsi_host_data of host
*
*/
static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
struct ibmvscsi_host_data *hostdata)
{
int rc;
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
/* Re-enable the CRQ */
do {
rc = plpar_hcall_norets(H_ENABLE_CRQ, vdev->unit_address);
} while ((rc == H_IN_PROGRESS) || (rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
if (rc)
dev_err(hostdata->dev, "Error %d enabling adapter\n", rc);
return rc;
}
struct ibmvscsi_ops rpavscsi_ops = {
.init_crq_queue = rpavscsi_init_crq_queue,
.release_crq_queue = rpavscsi_release_crq_queue,
.reset_crq_queue = rpavscsi_reset_crq_queue,
.reenable_crq_queue = rpavscsi_reenable_crq_queue,
.send_crq = rpavscsi_send_crq,
};

View file

@ -82,14 +82,12 @@ typedef struct idescsi_pc_s {
*/ */
#define PC_DMA_IN_PROGRESS 0 /* 1 while DMA in progress */ #define PC_DMA_IN_PROGRESS 0 /* 1 while DMA in progress */
#define PC_WRITING 1 /* Data direction */ #define PC_WRITING 1 /* Data direction */
#define PC_TRANSFORM 2 /* transform SCSI commands */
#define PC_TIMEDOUT 3 /* command timed out */ #define PC_TIMEDOUT 3 /* command timed out */
#define PC_DMA_OK 4 /* Use DMA */ #define PC_DMA_OK 4 /* Use DMA */
/* /*
* SCSI command transformation layer * SCSI command transformation layer
*/ */
#define IDESCSI_TRANSFORM 0 /* Enable/Disable transformation */
#define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ #define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */
/* /*
@ -175,7 +173,8 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
char *buf; char *buf;
while (bcount) { while (bcount) {
if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { if (pc->sg - scsi_sglist(pc->scsi_cmd) >
scsi_sg_count(pc->scsi_cmd)) {
printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
idescsi_discard_data (drive, bcount); idescsi_discard_data (drive, bcount);
return; return;
@ -210,7 +209,8 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
char *buf; char *buf;
while (bcount) { while (bcount) {
if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { if (pc->sg - scsi_sglist(pc->scsi_cmd) >
scsi_sg_count(pc->scsi_cmd)) {
printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
idescsi_output_zeros (drive, bcount); idescsi_output_zeros (drive, bcount);
return; return;
@ -239,77 +239,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
} }
} }
/*
* Most of the SCSI commands are supported directly by ATAPI devices.
* idescsi_transform_pc handles the few exceptions.
*/
static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
{
u8 *c = pc->c, *scsi_buf = pc->buffer, *sc = pc->scsi_cmd->cmnd;
char *atapi_buf;
if (!test_bit(PC_TRANSFORM, &pc->flags))
return;
if (drive->media == ide_cdrom || drive->media == ide_optical) {
if (c[0] == READ_6 || c[0] == WRITE_6) {
c[8] = c[4]; c[5] = c[3]; c[4] = c[2];
c[3] = c[1] & 0x1f; c[2] = 0; c[1] &= 0xe0;
c[0] += (READ_10 - READ_6);
}
if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
unsigned short new_len;
if (!scsi_buf)
return;
if ((atapi_buf = kmalloc(pc->buffer_size + 4, GFP_ATOMIC)) == NULL)
return;
memset(atapi_buf, 0, pc->buffer_size + 4);
memset (c, 0, 12);
c[0] = sc[0] | 0x40;
c[1] = sc[1];
c[2] = sc[2];
new_len = sc[4] + 4;
c[8] = new_len;
c[7] = new_len >> 8;
c[9] = sc[5];
if (c[0] == MODE_SELECT_10) {
atapi_buf[1] = scsi_buf[0]; /* Mode data length */
atapi_buf[2] = scsi_buf[1]; /* Medium type */
atapi_buf[3] = scsi_buf[2]; /* Device specific parameter */
atapi_buf[7] = scsi_buf[3]; /* Block descriptor length */
memcpy(atapi_buf + 8, scsi_buf + 4, pc->buffer_size - 4);
}
pc->buffer = atapi_buf;
pc->request_transfer += 4;
pc->buffer_size += 4;
}
}
}
static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
{
u8 *atapi_buf = pc->buffer;
u8 *sc = pc->scsi_cmd->cmnd;
u8 *scsi_buf = pc->scsi_cmd->request_buffer;
if (!test_bit(PC_TRANSFORM, &pc->flags))
return;
if (drive->media == ide_cdrom || drive->media == ide_optical) {
if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) {
scsi_buf[0] = atapi_buf[1]; /* Mode data length */
scsi_buf[1] = atapi_buf[2]; /* Medium type */
scsi_buf[2] = atapi_buf[3]; /* Device specific parameter */
scsi_buf[3] = atapi_buf[7]; /* Block descriptor length */
memcpy(scsi_buf + 4, atapi_buf + 8, pc->request_transfer - 8);
}
if (pc->c[0] == INQUIRY) {
scsi_buf[2] |= 2; /* ansi_revision */
scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; /* response data format */
}
}
if (atapi_buf && atapi_buf != scsi_buf)
kfree(atapi_buf);
}
static void hexdump(u8 *x, int len) static void hexdump(u8 *x, int len)
{ {
int i; int i;
@ -393,7 +322,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; idescsi_pc_t *pc = (idescsi_pc_t *) rq->special;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
struct Scsi_Host *host; struct Scsi_Host *host;
u8 *scsi_buf;
int errors = rq->errors; int errors = rq->errors;
unsigned long flags; unsigned long flags;
@ -434,15 +362,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
} else { } else {
pc->scsi_cmd->result = DID_OK << 16; pc->scsi_cmd->result = DID_OK << 16;
idescsi_transform_pc2 (drive, pc);
if (log) {
printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number);
if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
printk(", rst = ");
scsi_buf = pc->scsi_cmd->request_buffer;
hexdump(scsi_buf, min_t(unsigned, 16, pc->scsi_cmd->request_bufflen));
} else printk("\n");
}
} }
host = pc->scsi_cmd->device->host; host = pc->scsi_cmd->device->host;
spin_lock_irqsave(host->host_lock, flags); spin_lock_irqsave(host->host_lock, flags);
@ -637,19 +556,14 @@ static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc)
return 1; return 1;
sg = hwif->sg_table; sg = hwif->sg_table;
scsi_sg = pc->scsi_cmd->request_buffer; scsi_sg = scsi_sglist(pc->scsi_cmd);
segments = pc->scsi_cmd->use_sg; segments = scsi_sg_count(pc->scsi_cmd);
if (segments > hwif->sg_max_nents) if (segments > hwif->sg_max_nents)
return 1; return 1;
if (!segments) { hwif->sg_nents = segments;
hwif->sg_nents = 1; memcpy(sg, scsi_sg, sizeof(*sg) * segments);
sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer);
} else {
hwif->sg_nents = segments;
memcpy(sg, scsi_sg, sizeof(*sg) * segments);
}
return 0; return 0;
} }
@ -744,7 +658,6 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
{ {
if (drive->id && (drive->id->config & 0x0060) == 0x20) if (drive->id && (drive->id->config & 0x0060) == 0x20)
set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
set_bit(IDESCSI_TRANSFORM, &scsi->transform);
clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
set_bit(IDESCSI_LOG_CMD, &scsi->log); set_bit(IDESCSI_LOG_CMD, &scsi->log);
@ -758,6 +671,7 @@ static void ide_scsi_remove(ide_drive_t *drive)
struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
struct gendisk *g = scsi->disk; struct gendisk *g = scsi->disk;
scsi_remove_host(scsihost);
ide_proc_unregister_driver(drive, scsi->driver); ide_proc_unregister_driver(drive, scsi->driver);
ide_unregister_region(g); ide_unregister_region(g);
@ -766,7 +680,6 @@ static void ide_scsi_remove(ide_drive_t *drive)
g->private_data = NULL; g->private_data = NULL;
put_disk(g); put_disk(g);
scsi_remove_host(scsihost);
ide_scsi_put(scsi); ide_scsi_put(scsi);
} }
@ -838,6 +751,8 @@ static struct block_device_operations idescsi_ops = {
static int idescsi_slave_configure(struct scsi_device * sdp) static int idescsi_slave_configure(struct scsi_device * sdp)
{ {
/* Configure detected device */ /* Configure detected device */
sdp->use_10_for_rw = 1;
sdp->use_10_for_ms = 1;
scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);
return 0; return 0;
} }
@ -862,24 +777,6 @@ static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)
return -EINVAL; return -EINVAL;
} }
static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
/* this was a layering violation and we can't support it
anymore, sorry. */
#if 0
struct gendisk *disk = cmd->request->rq_disk;
if (disk) {
struct struct scsi_device_Template **p = disk->private_data;
if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
}
#endif
return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
}
static int idescsi_queue (struct scsi_cmnd *cmd, static int idescsi_queue (struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)) void (*done)(struct scsi_cmnd *))
{ {
@ -905,23 +802,14 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
pc->flags = 0; pc->flags = 0;
pc->rq = rq; pc->rq = rq;
memcpy (pc->c, cmd->cmnd, cmd->cmd_len); memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
if (cmd->use_sg) { pc->buffer = NULL;
pc->buffer = NULL; pc->sg = scsi_sglist(cmd);
pc->sg = cmd->request_buffer;
} else {
pc->buffer = cmd->request_buffer;
pc->sg = NULL;
}
pc->b_count = 0; pc->b_count = 0;
pc->request_transfer = pc->buffer_size = cmd->request_bufflen; pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd);
pc->scsi_cmd = cmd; pc->scsi_cmd = cmd;
pc->done = done; pc->done = done;
pc->timeout = jiffies + cmd->timeout_per_command; pc->timeout = jiffies + cmd->timeout_per_command;
if (should_transform(drive, cmd))
set_bit(PC_TRANSFORM, &pc->flags);
idescsi_transform_pc1 (drive, pc);
if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
hexdump(cmd->cmnd, cmd->cmd_len); hexdump(cmd->cmnd, cmd->cmd_len);

View file

@ -740,10 +740,6 @@ static void imm_interrupt(struct work_struct *work)
struct Scsi_Host *host = cmd->device->host; struct Scsi_Host *host = cmd->device->host;
unsigned long flags; unsigned long flags;
if (!cmd) {
printk("IMM: bug in imm_interrupt\n");
return;
}
if (imm_engine(dev, cmd)) { if (imm_engine(dev, cmd)) {
schedule_delayed_work(&dev->imm_tq, 1); schedule_delayed_work(&dev->imm_tq, 1);
return; return;

View file

@ -343,7 +343,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
instance = cmd->device->host; instance = cmd->device->host;
hostdata = (struct IN2000_hostdata *) instance->hostdata; hostdata = (struct IN2000_hostdata *) instance->hostdata;
DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->pid)) DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->serial_number))
/* Set up a few fields in the Scsi_Cmnd structure for our own use: /* Set up a few fields in the Scsi_Cmnd structure for our own use:
* - host_scribble is the pointer to the next cmd in the input queue * - host_scribble is the pointer to the next cmd in the input queue
@ -427,7 +427,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
in2000_execute(cmd->device->host); in2000_execute(cmd->device->host);
DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number))
return 0; return 0;
} }
@ -703,7 +703,7 @@ static void in2000_execute(struct Scsi_Host *instance)
* to search the input_Q again... * to search the input_Q again...
*/ */
DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid)) DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number))
} }
@ -1147,7 +1147,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
case CSR_XFER_DONE | PHS_COMMAND: case CSR_XFER_DONE | PHS_COMMAND:
case CSR_UNEXP | PHS_COMMAND: case CSR_UNEXP | PHS_COMMAND:
case CSR_SRV_REQ | PHS_COMMAND: case CSR_SRV_REQ | PHS_COMMAND:
DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid)) DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number))
transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata); transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
hostdata->state = S_CONNECTED; hostdata->state = S_CONNECTED;
break; break;
@ -1189,7 +1189,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
switch (msg) { switch (msg) {
case COMMAND_COMPLETE: case COMMAND_COMPLETE:
DB(DB_INTR, printk("CCMP-%ld", cmd->pid)) DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number))
write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
hostdata->state = S_PRE_CMP_DISC; hostdata->state = S_PRE_CMP_DISC;
break; break;
@ -1327,7 +1327,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
if (phs == 0x60) { if (phs == 0x60) {
DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid)) DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number))
cmd->SCp.Message = COMMAND_COMPLETE; cmd->SCp.Message = COMMAND_COMPLETE;
lun = read_3393(hostdata, WD_TARGET_LUN); lun = read_3393(hostdata, WD_TARGET_LUN);
DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
@ -1348,7 +1348,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
in2000_execute(instance); in2000_execute(instance);
} else { } else {
printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->pid); printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->serial_number);
} }
break; break;
@ -1415,7 +1415,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
spin_unlock_irqrestore(instance->host_lock, flags); spin_unlock_irqrestore(instance->host_lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number))
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
hostdata->state = S_UNCONNECTED; hostdata->state = S_UNCONNECTED;
@ -1440,7 +1440,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
*/ */
write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
DB(DB_INTR, printk("DISC-%ld", cmd->pid)) DB(DB_INTR, printk("DISC-%ld", cmd->serial_number))
if (cmd == NULL) { if (cmd == NULL) {
printk(" - Already disconnected! "); printk(" - Already disconnected! ");
hostdata->state = S_UNCONNECTED; hostdata->state = S_UNCONNECTED;
@ -1573,7 +1573,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id)
} else } else
hostdata->state = S_CONNECTED; hostdata->state = S_CONNECTED;
DB(DB_INTR, printk("-%ld", cmd->pid)) DB(DB_INTR, printk("-%ld", cmd->serial_number))
break; break;
default: default:
@ -1702,7 +1702,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd)
prev->host_scribble = cmd->host_scribble; prev->host_scribble = cmd->host_scribble;
cmd->host_scribble = NULL; cmd->host_scribble = NULL;
cmd->result = DID_ABORT << 16; cmd->result = DID_ABORT << 16;
printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->pid); printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->serial_number);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
return SUCCESS; return SUCCESS;
} }
@ -1723,7 +1723,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd)
if (hostdata->connected == cmd) { if (hostdata->connected == cmd) {
printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->pid); printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->serial_number);
printk("sending wd33c93 ABORT command - "); printk("sending wd33c93 ABORT command - ");
write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED); write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
@ -2268,7 +2268,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start,
strcat(bp, "\nconnected: "); strcat(bp, "\nconnected: ");
if (hd->connected) { if (hd->connected) {
cmd = (Scsi_Cmnd *) hd->connected; cmd = (Scsi_Cmnd *) hd->connected;
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
strcat(bp, tbuf); strcat(bp, tbuf);
} }
} }
@ -2276,7 +2276,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start,
strcat(bp, "\ninput_Q: "); strcat(bp, "\ninput_Q: ");
cmd = (Scsi_Cmnd *) hd->input_Q; cmd = (Scsi_Cmnd *) hd->input_Q;
while (cmd) { while (cmd) {
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
strcat(bp, tbuf); strcat(bp, tbuf);
cmd = (Scsi_Cmnd *) cmd->host_scribble; cmd = (Scsi_Cmnd *) cmd->host_scribble;
} }
@ -2285,7 +2285,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start,
strcat(bp, "\ndisconnected_Q:"); strcat(bp, "\ndisconnected_Q:");
cmd = (Scsi_Cmnd *) hd->disconnected_Q; cmd = (Scsi_Cmnd *) hd->disconnected_Q;
while (cmd) { while (cmd) {
sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
strcat(bp, tbuf); strcat(bp, tbuf);
cmd = (Scsi_Cmnd *) cmd->host_scribble; cmd = (Scsi_Cmnd *) cmd->host_scribble;
} }

View file

@ -204,8 +204,8 @@ module_param(ips, charp, 0);
/* /*
* DRIVER_VER * DRIVER_VER
*/ */
#define IPS_VERSION_HIGH "7.12" #define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
#define IPS_VERSION_LOW ".05 " #define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
#warning "This driver has only been tested on the x86/ia64/x86_64 platforms" #warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
@ -656,6 +656,8 @@ ips_release(struct Scsi_Host *sh)
METHOD_TRACE("ips_release", 1); METHOD_TRACE("ips_release", 1);
scsi_remove_host(sh);
for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
if (i == IPS_MAX_ADAPTERS) { if (i == IPS_MAX_ADAPTERS) {
@ -707,7 +709,6 @@ ips_release(struct Scsi_Host *sh)
/* free IRQ */ /* free IRQ */
free_irq(ha->irq, ha); free_irq(ha->irq, ha);
scsi_remove_host(sh);
scsi_host_put(sh); scsi_host_put(sh);
ips_released_controllers++; ips_released_controllers++;
@ -6946,7 +6947,7 @@ module_exit(ips_module_exit);
static int __devinit static int __devinit
ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
{ {
int index; int uninitialized_var(index);
int rc; int rc;
METHOD_TRACE("ips_insert_device", 1); METHOD_TRACE("ips_insert_device", 1);

View file

@ -1172,12 +1172,13 @@ typedef struct {
*************************************************************************/ *************************************************************************/
#define IPS_VER_MAJOR 7 #define IPS_VER_MAJOR 7
#define IPS_VER_MAJOR_STRING "7" #define IPS_VER_MAJOR_STRING __stringify(IPS_VER_MAJOR)
#define IPS_VER_MINOR 12 #define IPS_VER_MINOR 12
#define IPS_VER_MINOR_STRING "12" #define IPS_VER_MINOR_STRING __stringify(IPS_VER_MINOR)
#define IPS_VER_BUILD 02 #define IPS_VER_BUILD 05
#define IPS_VER_BUILD_STRING "02" #define IPS_VER_BUILD_STRING __stringify(IPS_VER_BUILD)
#define IPS_VER_STRING "7.12.02" #define IPS_VER_STRING IPS_VER_MAJOR_STRING "." \
IPS_VER_MINOR_STRING "." IPS_VER_BUILD_STRING
#define IPS_RELEASE_ID 0x00020000 #define IPS_RELEASE_ID 0x00020000
#define IPS_BUILD_IDENT 761 #define IPS_BUILD_IDENT 761
#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."

View file

@ -392,7 +392,7 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir)
} }
int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
u64 addr) u64 itn_id, u64 addr)
{ {
enum dma_data_direction dir; enum dma_data_direction dir;
struct scsi_cmnd *sc; struct scsi_cmnd *sc;
@ -428,7 +428,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info,
sc->request_bufflen = len; sc->request_bufflen = len;
sc->request_buffer = (void *) (unsigned long) addr; sc->request_buffer = (void *) (unsigned long) addr;
sc->tag = tag; sc->tag = tag;
err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun,
cmd->tag);
if (err) if (err)
scsi_host_put_command(shost, sc); scsi_host_put_command(shost, sc);

View file

@ -43,7 +43,6 @@
#include "lpfc_crtn.h" #include "lpfc_crtn.h"
#include "lpfc_vport.h" #include "lpfc_vport.h"
#include "lpfc_version.h" #include "lpfc_version.h"
#include "lpfc_vport.h"
#include "lpfc_debugfs.h" #include "lpfc_debugfs.h"
#ifdef CONFIG_LPFC_DEBUG_FS #ifdef CONFIG_LPFC_DEBUG_FS
@ -902,7 +901,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
} }
} }
vport->disc_trc = kmalloc( vport->disc_trc = kmzlloc(
(sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
GFP_KERNEL); GFP_KERNEL);
@ -913,8 +912,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
goto debug_failed; goto debug_failed;
} }
atomic_set(&vport->disc_trc_cnt, 0); atomic_set(&vport->disc_trc_cnt, 0);
memset(vport->disc_trc, 0,
(sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
snprintf(name, sizeof(name), "discovery_trace"); snprintf(name, sizeof(name), "discovery_trace");
vport->debug_disc_trc = vport->debug_disc_trc =

View file

@ -43,7 +43,6 @@
#include "lpfc_crtn.h" #include "lpfc_crtn.h"
#include "lpfc_vport.h" #include "lpfc_vport.h"
#include "lpfc_version.h" #include "lpfc_version.h"
#include "lpfc_vport.h"
static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int);
static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *);
@ -1266,11 +1265,10 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
uint32_t *HashWorking; uint32_t *HashWorking;
uint32_t *pwwnn = (uint32_t *) phba->wwnn; uint32_t *pwwnn = (uint32_t *) phba->wwnn;
HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); HashWorking = kcalloc(80, sizeof(uint32_t), GFP_KERNEL);
if (!HashWorking) if (!HashWorking)
return; return;
memset(HashWorking, 0, (80 * sizeof(uint32_t)));
HashWorking[0] = HashWorking[78] = *pwwnn++; HashWorking[0] = HashWorking[78] = *pwwnn++;
HashWorking[1] = HashWorking[79] = *pwwnn; HashWorking[1] = HashWorking[79] = *pwwnn;

View file

@ -202,10 +202,9 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
dma_addr_t pdma_phys; dma_addr_t pdma_phys;
uint16_t iotag; uint16_t iotag;
psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
if (!psb) if (!psb)
return NULL; return NULL;
memset(psb, 0, sizeof (struct lpfc_scsi_buf));
/* /*
* Get memory from the pci pool to map the virt space to pci bus space * Get memory from the pci pool to map the virt space to pci bus space

Some files were not shown because too many files have changed in this diff Show more