SCSI for-linus on 20140609
This patch consists of the usual driver updates (qla2xxx, qla4xxx, lpfc, be2iscsi, fnic, ufs, NCR5380) The NCR5380 is the addition to maintained status of a long neglected driver for older hardware. In addition there are a lot of minor fixes and cleanups and some more updates to make scsi mq ready. Signed-off-by: James Bottomley <JBottomley@Parallels.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJTlcwiAAoJEDeqqVYsXL0M5qsIALzVPLd4yxA16zCiaPQUeIV5 mfYmwISFlN+qW3AcUeSH4D13YgegCjEBfqaDMWvIkgouxLy/7jpxtChutq3MCzUE cDT1B9+ZrzoqBISRNHEh/gx5F1MOF2VPuqG2pe0J90wyRCNzJscB6PbtWMAo86CA 2eu7wq3K9FXxCC1qY0PzwBLXHqUcgk5GWiK9CM/k4W0NiTVeNmwPeh5i91IQnBHx E2l7NAXgNLyCf5tyeswvZ4pW0T3hlaswNmBB4qC8oJm4U6UqMN+tk4ML63Pz7uPe 4mlHG0uI8Vbdi13iv1EDUZ9Vo8iqVrzP2UAhakgP9poKSGqE4d/MD0EKNGQB2Es= =cBY8 -----END PGP SIGNATURE----- Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull SCSI updates from James Bottomley: "This patch consists of the usual driver updates (qla2xxx, qla4xxx, lpfc, be2iscsi, fnic, ufs, NCR5380) The NCR5380 is the addition to maintained status of a long neglected driver for older hardware. In addition there are a lot of minor fixes and cleanups and some more updates to make scsi mq ready" * tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (130 commits) include/scsi/osd_protocol.h: remove unnecessary __constant mvsas: Recognise device/subsystem 9485/9485 as 88SE9485 Revert "be2iscsi: Fix processing cqe for cxn whose endpoint is freed" mptfusion: fix msgContext in mptctl_hp_hostinfo acornscsi: remove linked command support scsi/NCR5380: dprintk macro fusion: Remove use of DEF_SCSI_QCMD fusion: Add free msg frames to the head, not tail of list mpt2sas: Add free smids to the head, not tail of list mpt2sas: Remove use of DEF_SCSI_QCMD mpt2sas: Remove uses of serial_number mpt3sas: Remove use of DEF_SCSI_QCMD mpt3sas: Remove uses of serial_number qla2xxx: Use kmemdup instead of kmalloc + memcpy qla4xxx: Use kmemdup instead of kmalloc + memcpy qla2xxx: fix incorrect debug printk be2iscsi: Bump the driver version be2iscsi: Fix processing cqe for cxn whose endpoint is freed be2iscsi: Fix destroy MCC-CQ before MCC-EQ is destroyed be2iscsi: Fix memory corruption in MBX path ...
This commit is contained in:
commit
1c54fc1efe
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2003-2013 QLogic Corporation
|
Copyright (c) 2003-2014 QLogic Corporation
|
||||||
QLogic Linux FC-FCoE Driver
|
QLogic Linux FC-FCoE Driver
|
||||||
|
|
||||||
This program includes a device driver for Linux 3.x.
|
This program includes a device driver for Linux 3.x.
|
||||||
|
|
38
MAINTAINERS
38
MAINTAINERS
|
@ -4390,7 +4390,7 @@ S: Supported
|
||||||
F: drivers/crypto/nx/
|
F: drivers/crypto/nx/
|
||||||
|
|
||||||
IBM Power 842 compression accelerator
|
IBM Power 842 compression accelerator
|
||||||
M: Robert Jennings <rcj@linux.vnet.ibm.com>
|
M: Nathan Fontenot <nfont@linux.vnet.ibm.com>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/crypto/nx/nx-842.c
|
F: drivers/crypto/nx/nx-842.c
|
||||||
F: include/linux/nx842.h
|
F: include/linux/nx842.h
|
||||||
|
@ -4406,12 +4406,18 @@ L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/net/ethernet/ibm/ibmveth.*
|
F: drivers/net/ethernet/ibm/ibmveth.*
|
||||||
|
|
||||||
IBM Power Virtual SCSI/FC Device Drivers
|
IBM Power Virtual SCSI Device Drivers
|
||||||
M: Robert Jennings <rcj@linux.vnet.ibm.com>
|
M: Nathan Fontenot <nfont@linux.vnet.ibm.com>
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/scsi/ibmvscsi/
|
F: drivers/scsi/ibmvscsi/ibmvscsi*
|
||||||
X: drivers/scsi/ibmvscsi/ibmvstgt.c
|
F: drivers/scsi/ibmvscsi/viosrp.h
|
||||||
|
|
||||||
|
IBM Power Virtual FC Device Drivers
|
||||||
|
M: Brian King <brking@linux.vnet.ibm.com>
|
||||||
|
L: linux-scsi@vger.kernel.org
|
||||||
|
S: Supported
|
||||||
|
F: drivers/scsi/ibmvscsi/ibmvfc*
|
||||||
|
|
||||||
IBM ServeRAID RAID DRIVER
|
IBM ServeRAID RAID DRIVER
|
||||||
P: Jack Hammer
|
P: Jack Hammer
|
||||||
|
@ -6028,6 +6034,28 @@ M: Petr Vandrovec <petr@vandrovec.name>
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: fs/ncpfs/
|
F: fs/ncpfs/
|
||||||
|
|
||||||
|
NCR 5380 SCSI DRIVERS
|
||||||
|
M: Finn Thain <fthain@telegraphics.com.au>
|
||||||
|
M: Michael Schmitz <schmitzmic@gmail.com>
|
||||||
|
L: linux-scsi@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/scsi/g_NCR5380.txt
|
||||||
|
F: drivers/scsi/NCR5380.*
|
||||||
|
F: drivers/scsi/arm/cumana_1.c
|
||||||
|
F: drivers/scsi/arm/oak.c
|
||||||
|
F: drivers/scsi/atari_NCR5380.c
|
||||||
|
F: drivers/scsi/atari_scsi.*
|
||||||
|
F: drivers/scsi/dmx3191d.c
|
||||||
|
F: drivers/scsi/dtc.*
|
||||||
|
F: drivers/scsi/g_NCR5380.*
|
||||||
|
F: drivers/scsi/g_NCR5380_mmio.c
|
||||||
|
F: drivers/scsi/mac_scsi.*
|
||||||
|
F: drivers/scsi/pas16.*
|
||||||
|
F: drivers/scsi/sun3_NCR5380.c
|
||||||
|
F: drivers/scsi/sun3_scsi.*
|
||||||
|
F: drivers/scsi/sun3_scsi_vme.c
|
||||||
|
F: drivers/scsi/t128.*
|
||||||
|
|
||||||
NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
|
NCR DUAL 700 SCSI DRIVER (MICROCHANNEL)
|
||||||
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
|
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
|
||||||
L: linux-scsi@vger.kernel.org
|
L: linux-scsi@vger.kernel.org
|
||||||
|
|
|
@ -1037,7 +1037,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
|
||||||
goto out;
|
goto out;
|
||||||
/* signature to know if this mf is freed */
|
/* signature to know if this mf is freed */
|
||||||
mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
|
mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
|
||||||
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
|
list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
|
||||||
#ifdef MFCNT
|
#ifdef MFCNT
|
||||||
ioc->mfcnt--;
|
ioc->mfcnt--;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2432,9 +2432,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
|
||||||
int rc, cim_rev;
|
int rc, cim_rev;
|
||||||
ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
|
ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
|
||||||
MPT_FRAME_HDR *mf = NULL;
|
MPT_FRAME_HDR *mf = NULL;
|
||||||
MPIHeader_t *mpi_hdr;
|
|
||||||
unsigned long timeleft;
|
unsigned long timeleft;
|
||||||
int retval;
|
int retval;
|
||||||
|
u32 msgcontext;
|
||||||
|
|
||||||
/* Reset long to int. Should affect IA64 and SPARC only
|
/* Reset long to int. Should affect IA64 and SPARC only
|
||||||
*/
|
*/
|
||||||
|
@ -2581,11 +2581,11 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
|
IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
|
||||||
mpi_hdr = (MPIHeader_t *) mf;
|
msgcontext = IstwiRWRequest->MsgContext;
|
||||||
memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
|
memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
|
||||||
|
IstwiRWRequest->MsgContext = msgcontext;
|
||||||
IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
|
IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
|
||||||
IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
|
IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
|
||||||
IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
|
|
||||||
IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
|
IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
|
||||||
IstwiRWRequest->NumAddressBytes = 0x01;
|
IstwiRWRequest->NumAddressBytes = 0x01;
|
||||||
IstwiRWRequest->DataLength = cpu_to_le16(0x04);
|
IstwiRWRequest->DataLength = cpu_to_le16(0x04);
|
||||||
|
|
|
@ -649,7 +649,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
|
||||||
{
|
{
|
||||||
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));
|
||||||
|
@ -658,14 +658,14 @@ mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||||
|
|
||||||
if (!vdevice || !vdevice->vtarget) {
|
if (!vdevice || !vdevice->vtarget) {
|
||||||
SCpnt->result = DID_NO_CONNECT << 16;
|
SCpnt->result = DID_NO_CONNECT << 16;
|
||||||
done(SCpnt);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fc_remote_port_chkready(rport);
|
err = fc_remote_port_chkready(rport);
|
||||||
if (unlikely(err)) {
|
if (unlikely(err)) {
|
||||||
SCpnt->result = err;
|
SCpnt->result = err;
|
||||||
done(SCpnt);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,15 +673,13 @@ mptfc_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||||
ri = *((struct mptfc_rport_info **)rport->dd_data);
|
ri = *((struct mptfc_rport_info **)rport->dd_data);
|
||||||
if (unlikely(!ri)) {
|
if (unlikely(!ri)) {
|
||||||
SCpnt->result = DID_IMM_RETRY << 16;
|
SCpnt->result = DID_IMM_RETRY << 16;
|
||||||
done(SCpnt);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mptscsih_qcmd(SCpnt,done);
|
return mptscsih_qcmd(SCpnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEF_SCSI_QCMD(mptfc_qcmd)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mptfc_display_port_link_speed - displaying link speed
|
* mptfc_display_port_link_speed - displaying link speed
|
||||||
* @ioc: Pointer to MPT_ADAPTER structure
|
* @ioc: Pointer to MPT_ADAPTER structure
|
||||||
|
|
|
@ -1896,7 +1896,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
mptsas_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
|
||||||
{
|
{
|
||||||
MPT_SCSI_HOST *hd;
|
MPT_SCSI_HOST *hd;
|
||||||
MPT_ADAPTER *ioc;
|
MPT_ADAPTER *ioc;
|
||||||
|
@ -1904,11 +1904,11 @@ mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||||
|
|
||||||
if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
|
if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
|
||||||
SCpnt->result = DID_NO_CONNECT << 16;
|
SCpnt->result = DID_NO_CONNECT << 16;
|
||||||
done(SCpnt);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hd = shost_priv(SCpnt->device->host);
|
hd = shost_priv(shost);
|
||||||
ioc = hd->ioc;
|
ioc = hd->ioc;
|
||||||
|
|
||||||
if (ioc->sas_discovery_quiesce_io)
|
if (ioc->sas_discovery_quiesce_io)
|
||||||
|
@ -1917,11 +1917,9 @@ mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||||
if (ioc->debug_level & MPT_DEBUG_SCSI)
|
if (ioc->debug_level & MPT_DEBUG_SCSI)
|
||||||
scsi_print_command(SCpnt);
|
scsi_print_command(SCpnt);
|
||||||
|
|
||||||
return mptscsih_qcmd(SCpnt,done);
|
return mptscsih_qcmd(SCpnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEF_SCSI_QCMD(mptsas_qcmd)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
|
* mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
|
||||||
* if the device under question is currently in the
|
* if the device under question is currently in the
|
||||||
|
|
|
@ -1304,7 +1304,6 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
|
||||||
/**
|
/**
|
||||||
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
|
* mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
|
||||||
* @SCpnt: Pointer to scsi_cmnd structure
|
* @SCpnt: Pointer to scsi_cmnd structure
|
||||||
* @done: Pointer SCSI mid-layer IO completion function
|
|
||||||
*
|
*
|
||||||
* (linux scsi_host_template.queuecommand routine)
|
* (linux scsi_host_template.queuecommand routine)
|
||||||
* This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
|
* This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
|
||||||
|
@ -1313,7 +1312,7 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
|
||||||
* Returns 0. (rtn value discarded by linux scsi mid-layer)
|
* Returns 0. (rtn value discarded by linux scsi mid-layer)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
mptscsih_qcmd(struct scsi_cmnd *SCpnt)
|
||||||
{
|
{
|
||||||
MPT_SCSI_HOST *hd;
|
MPT_SCSI_HOST *hd;
|
||||||
MPT_FRAME_HDR *mf;
|
MPT_FRAME_HDR *mf;
|
||||||
|
@ -1329,10 +1328,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
||||||
|
|
||||||
hd = shost_priv(SCpnt->device->host);
|
hd = shost_priv(SCpnt->device->host);
|
||||||
ioc = hd->ioc;
|
ioc = hd->ioc;
|
||||||
SCpnt->scsi_done = done;
|
|
||||||
|
|
||||||
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
|
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
|
||||||
ioc->name, SCpnt, done));
|
ioc->name, SCpnt));
|
||||||
|
|
||||||
if (ioc->taskmgmt_quiesce_io)
|
if (ioc->taskmgmt_quiesce_io)
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
|
|
@ -113,7 +113,7 @@ extern int mptscsih_resume(struct pci_dev *pdev);
|
||||||
#endif
|
#endif
|
||||||
extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
|
extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
|
||||||
extern const char * mptscsih_info(struct Scsi_Host *SChost);
|
extern const char * mptscsih_info(struct Scsi_Host *SChost);
|
||||||
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
|
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt);
|
||||||
extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
|
extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
|
||||||
u8 id, int lun, int ctx2abort, ulong timeout);
|
u8 id, int lun, int ctx2abort, ulong timeout);
|
||||||
extern void mptscsih_slave_destroy(struct scsi_device *device);
|
extern void mptscsih_slave_destroy(struct scsi_device *device);
|
||||||
|
|
|
@ -780,33 +780,31 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mptspi_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
|
mptspi_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
|
||||||
{
|
{
|
||||||
struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
|
struct _MPT_SCSI_HOST *hd = shost_priv(shost);
|
||||||
VirtDevice *vdevice = SCpnt->device->hostdata;
|
VirtDevice *vdevice = SCpnt->device->hostdata;
|
||||||
MPT_ADAPTER *ioc = hd->ioc;
|
MPT_ADAPTER *ioc = hd->ioc;
|
||||||
|
|
||||||
if (!vdevice || !vdevice->vtarget) {
|
if (!vdevice || !vdevice->vtarget) {
|
||||||
SCpnt->result = DID_NO_CONNECT << 16;
|
SCpnt->result = DID_NO_CONNECT << 16;
|
||||||
done(SCpnt);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SCpnt->device->channel == 1 &&
|
if (SCpnt->device->channel == 1 &&
|
||||||
mptscsih_is_phys_disk(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);
|
SCpnt->scsi_done(SCpnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spi_dv_pending(scsi_target(SCpnt->device)))
|
if (spi_dv_pending(scsi_target(SCpnt->device)))
|
||||||
ddvprintk(ioc, scsi_print_command(SCpnt));
|
ddvprintk(ioc, scsi_print_command(SCpnt));
|
||||||
|
|
||||||
return mptscsih_qcmd(SCpnt,done);
|
return mptscsih_qcmd(SCpnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEF_SCSI_QCMD(mptspi_qcmd)
|
|
||||||
|
|
||||||
static void mptspi_slave_destroy(struct scsi_device *sdev)
|
static void mptspi_slave_destroy(struct scsi_device *sdev)
|
||||||
{
|
{
|
||||||
struct scsi_target *starget = scsi_target(sdev);
|
struct scsi_target *starget = scsi_target(sdev);
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: NCR5380.c,v $
|
|
||||||
|
|
||||||
* Revision 1.10 1998/9/2 Alan Cox
|
* Revision 1.10 1998/9/2 Alan Cox
|
||||||
* (alan@lxorguk.ukuu.org.uk)
|
* (alan@lxorguk.ukuu.org.uk)
|
||||||
* Fixed up the timer lockups reported so far. Things still suck. Looking
|
* Fixed up the timer lockups reported so far. Things still suck. Looking
|
||||||
|
@ -89,13 +87,6 @@
|
||||||
#include <scsi/scsi_dbg.h>
|
#include <scsi/scsi_dbg.h>
|
||||||
#include <scsi/scsi_transport_spi.h>
|
#include <scsi/scsi_transport_spi.h>
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define NDEBUG 0
|
|
||||||
#endif
|
|
||||||
#ifndef NDEBUG_ABORT
|
|
||||||
#define NDEBUG_ABORT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (NDEBUG & NDEBUG_LISTS)
|
#if (NDEBUG & NDEBUG_LISTS)
|
||||||
#define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
|
#define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
|
||||||
#define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
|
#define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
|
||||||
|
@ -1005,7 +996,7 @@ static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)
|
||||||
LIST(cmd, tmp);
|
LIST(cmd, tmp);
|
||||||
tmp->host_scribble = (unsigned char *) cmd;
|
tmp->host_scribble = (unsigned char *) cmd;
|
||||||
}
|
}
|
||||||
dprintk(NDEBUG_QUEUES, ("scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"));
|
dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
|
||||||
|
|
||||||
/* Run the coroutine if it isn't already running. */
|
/* Run the coroutine if it isn't already running. */
|
||||||
/* Kick off command processing */
|
/* Kick off command processing */
|
||||||
|
@ -1040,7 +1031,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
/* Lock held here */
|
/* Lock held here */
|
||||||
done = 1;
|
done = 1;
|
||||||
if (!hostdata->connected && !hostdata->selecting) {
|
if (!hostdata->connected && !hostdata->selecting) {
|
||||||
dprintk(NDEBUG_MAIN, ("scsi%d : not connected\n", instance->host_no));
|
dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
|
||||||
/*
|
/*
|
||||||
* Search through the issue_queue for a command destined
|
* Search through the issue_queue for a command destined
|
||||||
* for a target that's not busy.
|
* for a target that's not busy.
|
||||||
|
@ -1048,7 +1039,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
||||||
{
|
{
|
||||||
if (prev != tmp)
|
if (prev != tmp)
|
||||||
dprintk(NDEBUG_LISTS, ("MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun));
|
dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
|
||||||
/* When we find one, remove it from the issue queue. */
|
/* When we find one, remove it from the issue queue. */
|
||||||
if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
|
if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
@ -1066,7 +1057,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
* On failure, we must add the command back to the
|
* On failure, we must add the command back to the
|
||||||
* issue queue so we can keep trying.
|
* issue queue so we can keep trying.
|
||||||
*/
|
*/
|
||||||
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, ("scsi%d : main() : command for target %d lun %d removed from issue_queue\n", instance->host_no, tmp->target, tmp->lun));
|
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %d removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A successful selection is defined as one that
|
* A successful selection is defined as one that
|
||||||
|
@ -1095,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
|
tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
|
||||||
hostdata->issue_queue = tmp;
|
hostdata->issue_queue = tmp;
|
||||||
done = 0;
|
done = 0;
|
||||||
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, ("scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no));
|
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
|
||||||
}
|
}
|
||||||
/* lock held here still */
|
/* lock held here still */
|
||||||
} /* if target/lun is not busy */
|
} /* if target/lun is not busy */
|
||||||
|
@ -1125,9 +1116,9 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
#endif
|
#endif
|
||||||
&& (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies))
|
&& (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies))
|
||||||
) {
|
) {
|
||||||
dprintk(NDEBUG_MAIN, ("scsi%d : main() : performing information transfer\n", instance->host_no));
|
dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
|
||||||
NCR5380_information_transfer(instance);
|
NCR5380_information_transfer(instance);
|
||||||
dprintk(NDEBUG_MAIN, ("scsi%d : main() : done set false\n", instance->host_no));
|
dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
|
||||||
done = 0;
|
done = 0;
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
|
@ -1159,8 +1150,8 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
|
||||||
unsigned char basr;
|
unsigned char basr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n",
|
dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
|
||||||
instance->irq));
|
instance->irq);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
done = 1;
|
done = 1;
|
||||||
|
@ -1173,14 +1164,14 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
|
||||||
NCR5380_dprint(NDEBUG_INTR, instance);
|
NCR5380_dprint(NDEBUG_INTR, instance);
|
||||||
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
|
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
|
||||||
done = 0;
|
done = 0;
|
||||||
dprintk(NDEBUG_INTR, ("scsi%d : SEL interrupt\n", instance->host_no));
|
dprintk(NDEBUG_INTR, "scsi%d : SEL interrupt\n", instance->host_no);
|
||||||
NCR5380_reselect(instance);
|
NCR5380_reselect(instance);
|
||||||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else if (basr & BASR_PARITY_ERROR) {
|
} else if (basr & BASR_PARITY_ERROR) {
|
||||||
dprintk(NDEBUG_INTR, ("scsi%d : PARITY interrupt\n", instance->host_no));
|
dprintk(NDEBUG_INTR, "scsi%d : PARITY interrupt\n", instance->host_no);
|
||||||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
|
} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
|
||||||
dprintk(NDEBUG_INTR, ("scsi%d : RESET interrupt\n", instance->host_no));
|
dprintk(NDEBUG_INTR, "scsi%d : RESET interrupt\n", instance->host_no);
|
||||||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else {
|
} else {
|
||||||
#if defined(REAL_DMA)
|
#if defined(REAL_DMA)
|
||||||
|
@ -1210,7 +1201,7 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
dprintk(NDEBUG_INTR, ("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)));
|
dprintk(NDEBUG_INTR, "scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
|
||||||
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1304,7 +1295,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
hostdata->restart_select = 0;
|
hostdata->restart_select = 0;
|
||||||
|
|
||||||
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
|
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
|
||||||
dprintk(NDEBUG_ARBITRATION, ("scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id));
|
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the phase bits to 0, otherwise the NCR5380 won't drive the
|
* Set the phase bits to 0, otherwise the NCR5380 won't drive the
|
||||||
|
@ -1333,7 +1324,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk(NDEBUG_ARBITRATION, ("scsi%d : arbitration complete\n", instance->host_no));
|
dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The arbitration delay is 2.2us, but this is a minimum and there is
|
* The arbitration delay is 2.2us, but this is a minimum and there is
|
||||||
|
@ -1347,7 +1338,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
/* Check for lost arbitration */
|
/* Check for lost arbitration */
|
||||||
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
|
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
dprintk(NDEBUG_ARBITRATION, ("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no));
|
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
|
||||||
|
@ -1360,7 +1351,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
|
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
dprintk(NDEBUG_ARBITRATION, ("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no));
|
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1370,7 +1361,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
|
|
||||||
udelay(2);
|
udelay(2);
|
||||||
|
|
||||||
dprintk(NDEBUG_ARBITRATION, ("scsi%d : won arbitration\n", instance->host_no));
|
dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we have won arbitration, start Selection process, asserting
|
* Now that we have won arbitration, start Selection process, asserting
|
||||||
|
@ -1422,7 +1413,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
|
||||||
|
|
||||||
udelay(1);
|
udelay(1);
|
||||||
|
|
||||||
dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd)));
|
dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The SCSI specification calls for a 250 ms timeout for the actual
|
* The SCSI specification calls for a 250 ms timeout for the actual
|
||||||
|
@ -1487,7 +1478,7 @@ part2:
|
||||||
collect_stats(hostdata, cmd);
|
collect_stats(hostdata, cmd);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||||
dprintk(NDEBUG_SELECTION, ("scsi%d : target did not respond within 250ms\n", instance->host_no));
|
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
|
||||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1520,7 +1511,7 @@ part2:
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id));
|
dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
|
||||||
tmp[0] = IDENTIFY(((instance->irq == SCSI_IRQ_NONE) ? 0 : 1), cmd->device->lun);
|
tmp[0] = IDENTIFY(((instance->irq == SCSI_IRQ_NONE) ? 0 : 1), cmd->device->lun);
|
||||||
|
|
||||||
len = 1;
|
len = 1;
|
||||||
|
@ -1530,7 +1521,7 @@ part2:
|
||||||
data = tmp;
|
data = tmp;
|
||||||
phase = PHASE_MSGOUT;
|
phase = PHASE_MSGOUT;
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
dprintk(NDEBUG_SELECTION, ("scsi%d : nexus established.\n", instance->host_no));
|
dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
|
||||||
/* XXX need to handle errors here */
|
/* XXX need to handle errors here */
|
||||||
hostdata->connected = cmd;
|
hostdata->connected = cmd;
|
||||||
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
||||||
|
@ -1583,9 +1574,9 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
|
||||||
NCR5380_setup(instance);
|
NCR5380_setup(instance);
|
||||||
|
|
||||||
if (!(p & SR_IO))
|
if (!(p & SR_IO))
|
||||||
dprintk(NDEBUG_PIO, ("scsi%d : pio write %d bytes\n", instance->host_no, c));
|
dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
|
||||||
else
|
else
|
||||||
dprintk(NDEBUG_PIO, ("scsi%d : pio read %d bytes\n", instance->host_no, c));
|
dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NCR5380 chip will only drive the SCSI bus when the
|
* The NCR5380 chip will only drive the SCSI bus when the
|
||||||
|
@ -1620,11 +1611,11 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk(NDEBUG_HANDSHAKE, ("scsi%d : REQ detected\n", instance->host_no));
|
dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
|
||||||
|
|
||||||
/* Check for phase mismatch */
|
/* Check for phase mismatch */
|
||||||
if ((tmp & PHASE_MASK) != p) {
|
if ((tmp & PHASE_MASK) != p) {
|
||||||
dprintk(NDEBUG_HANDSHAKE, ("scsi%d : phase mismatch\n", instance->host_no));
|
dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
|
||||||
NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
|
NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1660,7 +1651,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
|
||||||
|
|
||||||
/* FIXME - if this fails bus reset ?? */
|
/* FIXME - if this fails bus reset ?? */
|
||||||
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
|
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ);
|
||||||
dprintk(NDEBUG_HANDSHAKE, ("scsi%d : req false, handshake complete\n", instance->host_no));
|
dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have several special cases to consider during REQ/ACK handshaking :
|
* We have several special cases to consider during REQ/ACK handshaking :
|
||||||
|
@ -1681,7 +1672,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
|
||||||
}
|
}
|
||||||
} while (--c);
|
} while (--c);
|
||||||
|
|
||||||
dprintk(NDEBUG_PIO, ("scsi%d : residual %d\n", instance->host_no, c));
|
dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c);
|
||||||
|
|
||||||
*count = c;
|
*count = c;
|
||||||
*data = d;
|
*data = d;
|
||||||
|
@ -1828,7 +1819,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
c -= 2;
|
c -= 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dprintk(NDEBUG_DMA, ("scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d));
|
dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
|
||||||
hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
|
hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1857,7 +1848,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
|
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
|
||||||
#endif /* def REAL_DMA */
|
#endif /* def REAL_DMA */
|
||||||
|
|
||||||
dprintk(NDEBUG_DMA, ("scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG)));
|
dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On the PAS16 at least I/O recovery delays are not needed here.
|
* On the PAS16 at least I/O recovery delays are not needed here.
|
||||||
|
@ -1934,7 +1925,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk(NDEBUG_DMA, ("scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG)));
|
dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
|
||||||
|
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
|
@ -1948,7 +1939,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
#ifdef READ_OVERRUNS
|
#ifdef READ_OVERRUNS
|
||||||
if (*phase == p && (p & SR_IO) && residue == 0) {
|
if (*phase == p && (p & SR_IO) && residue == 0) {
|
||||||
if (overrun) {
|
if (overrun) {
|
||||||
dprintk(NDEBUG_DMA, ("Got an input overrun, using saved byte\n"));
|
dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
|
||||||
**data = saved_data;
|
**data = saved_data;
|
||||||
*data += 1;
|
*data += 1;
|
||||||
*count -= 1;
|
*count -= 1;
|
||||||
|
@ -1957,13 +1948,13 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
printk("No overrun??\n");
|
printk("No overrun??\n");
|
||||||
cnt = toPIO = 2;
|
cnt = toPIO = 2;
|
||||||
}
|
}
|
||||||
dprintk(NDEBUG_DMA, ("Doing %d-byte PIO to 0x%X\n", cnt, *data));
|
dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%X\n", cnt, *data);
|
||||||
NCR5380_transfer_pio(instance, phase, &cnt, data);
|
NCR5380_transfer_pio(instance, phase, &cnt, data);
|
||||||
*count -= toPIO - cnt;
|
*count -= toPIO - cnt;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dprintk(NDEBUG_DMA, ("Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count)));
|
dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#elif defined(REAL_DMA)
|
#elif defined(REAL_DMA)
|
||||||
|
@ -2013,7 +2004,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
foo = NCR5380_pwrite(instance, d, c);
|
foo = NCR5380_pwrite(instance, d, c);
|
||||||
#else
|
#else
|
||||||
int timeout;
|
int timeout;
|
||||||
dprintk(NDEBUG_C400_PWRITE, ("About to pwrite %d bytes\n", c));
|
dprintk(NDEBUG_C400_PWRITE, "About to pwrite %d bytes\n", c);
|
||||||
if (!(foo = NCR5380_pwrite(instance, d, c))) {
|
if (!(foo = NCR5380_pwrite(instance, d, c))) {
|
||||||
/*
|
/*
|
||||||
* Wait for the last byte to be sent. If REQ is being asserted for
|
* Wait for the last byte to be sent. If REQ is being asserted for
|
||||||
|
@ -2024,19 +2015,19 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
|
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH));
|
||||||
|
|
||||||
if (!timeout)
|
if (!timeout)
|
||||||
dprintk(NDEBUG_LAST_BYTE_SENT, ("scsi%d : timed out on last byte\n", instance->host_no));
|
dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : timed out on last byte\n", instance->host_no);
|
||||||
|
|
||||||
if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
|
if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
|
||||||
hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
|
hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
|
||||||
if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
|
if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
|
||||||
hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
|
hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
|
||||||
dprintk(NDEBUG_LAST_WRITE_SENT, ("scsi%d : last bit sent works\n", instance->host_no));
|
dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : last byte sent works\n", instance->host_no);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dprintk(NDEBUG_C400_PWRITE, ("Waiting for LASTBYTE\n"));
|
dprintk(NDEBUG_C400_PWRITE, "Waiting for LASTBYTE\n");
|
||||||
while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
|
while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
|
||||||
dprintk(NDEBUG_C400_PWRITE, ("Got LASTBYTE\n"));
|
dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2045,9 +2036,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
|
|
||||||
if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
|
if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
|
||||||
dprintk(NDEBUG_C400_PWRITE, ("53C400w: Checking for IRQ\n"));
|
dprintk(NDEBUG_C400_PWRITE, "53C400w: Checking for IRQ\n");
|
||||||
if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
|
if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
|
||||||
dprintk(NDEBUG_C400_PWRITE, ("53C400w: got it, reading reset interrupt reg\n"));
|
dprintk(NDEBUG_C400_PWRITE, "53C400w: got it, reading reset interrupt reg\n");
|
||||||
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else {
|
} else {
|
||||||
printk("53C400w: IRQ NOT THERE!\n");
|
printk("53C400w: IRQ NOT THERE!\n");
|
||||||
|
@ -2139,7 +2130,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
--cmd->SCp.buffers_residual;
|
--cmd->SCp.buffers_residual;
|
||||||
cmd->SCp.this_residual = cmd->SCp.buffer->length;
|
cmd->SCp.this_residual = cmd->SCp.buffer->length;
|
||||||
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
|
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
|
||||||
dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
|
dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* The preferred transfer method is going to be
|
* The preferred transfer method is going to be
|
||||||
|
@ -2219,7 +2210,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
case LINKED_FLG_CMD_COMPLETE:
|
case LINKED_FLG_CMD_COMPLETE:
|
||||||
/* Accept message by clearing ACK */
|
/* Accept message by clearing ACK */
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun));
|
dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun);
|
||||||
/*
|
/*
|
||||||
* Sanity check : A linked command should only terminate with
|
* Sanity check : A linked command should only terminate with
|
||||||
* one of these messages if there are more linked commands
|
* one of these messages if there are more linked commands
|
||||||
|
@ -2235,7 +2226,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
/* The next command is still part of this process */
|
/* The next command is still part of this process */
|
||||||
cmd->next_link->tag = cmd->tag;
|
cmd->next_link->tag = cmd->tag;
|
||||||
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
|
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
|
||||||
dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun));
|
dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun);
|
||||||
collect_stats(hostdata, cmd);
|
collect_stats(hostdata, cmd);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
cmd = hostdata->connected;
|
cmd = hostdata->connected;
|
||||||
|
@ -2247,7 +2238,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
sink = 1;
|
sink = 1;
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
hostdata->connected = NULL;
|
hostdata->connected = NULL;
|
||||||
dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun));
|
dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
|
||||||
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
|
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2281,13 +2272,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
|
if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
|
||||||
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
|
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
|
||||||
|
|
||||||
dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no));
|
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 *)
|
||||||
hostdata->issue_queue;
|
hostdata->issue_queue;
|
||||||
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
|
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
|
||||||
dprintk(NDEBUG_QUEUES, ("scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no));
|
dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no);
|
||||||
} else
|
} else
|
||||||
#endif /* def AUTOSENSE */
|
#endif /* def AUTOSENSE */
|
||||||
{
|
{
|
||||||
|
@ -2327,7 +2318,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
hostdata->disconnected_queue;
|
hostdata->disconnected_queue;
|
||||||
hostdata->connected = NULL;
|
hostdata->connected = NULL;
|
||||||
hostdata->disconnected_queue = cmd;
|
hostdata->disconnected_queue = cmd;
|
||||||
dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun));
|
dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
|
||||||
/*
|
/*
|
||||||
* Restore phase bits to 0 so an interrupted selection,
|
* Restore phase bits to 0 so an interrupted selection,
|
||||||
* arbitration can resume.
|
* arbitration can resume.
|
||||||
|
@ -2373,14 +2364,14 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
extended_msg[0] = EXTENDED_MESSAGE;
|
extended_msg[0] = EXTENDED_MESSAGE;
|
||||||
/* Accept first byte by clearing ACK */
|
/* Accept first byte by clearing ACK */
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
dprintk(NDEBUG_EXTENDED, ("scsi%d : receiving extended message\n", instance->host_no));
|
dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
|
||||||
|
|
||||||
len = 2;
|
len = 2;
|
||||||
data = extended_msg + 1;
|
data = extended_msg + 1;
|
||||||
phase = PHASE_MSGIN;
|
phase = PHASE_MSGIN;
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
|
|
||||||
dprintk(NDEBUG_EXTENDED, ("scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]));
|
dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
|
||||||
|
|
||||||
if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
|
if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {
|
||||||
/* Accept third byte by clearing ACK */
|
/* Accept third byte by clearing ACK */
|
||||||
|
@ -2390,7 +2381,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
phase = PHASE_MSGIN;
|
phase = PHASE_MSGIN;
|
||||||
|
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
dprintk(NDEBUG_EXTENDED, ("scsi%d : message received, residual %d\n", instance->host_no, len));
|
dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len);
|
||||||
|
|
||||||
switch (extended_msg[2]) {
|
switch (extended_msg[2]) {
|
||||||
case EXTENDED_SDTR:
|
case EXTENDED_SDTR:
|
||||||
|
@ -2456,7 +2447,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
|
if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
|
||||||
NCR5380_set_timer(hostdata, USLEEP_SLEEP);
|
NCR5380_set_timer(hostdata, USLEEP_SLEEP);
|
||||||
dprintk(NDEBUG_USLEEP, ("scsi%d : issued command, sleeping until %ul\n", instance->host_no, hostdata->time_expires));
|
dprintk(NDEBUG_USLEEP, "scsi%d : issued command, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2468,7 +2459,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("scsi%d : unknown phase\n", instance->host_no);
|
printk("scsi%d : unknown phase\n", instance->host_no);
|
||||||
NCR5380_dprint(NDEBUG_ALL, instance);
|
NCR5380_dprint(NDEBUG_ANY, instance);
|
||||||
} /* switch(phase) */
|
} /* switch(phase) */
|
||||||
} /* if (tmp * SR_REQ) */
|
} /* if (tmp * SR_REQ) */
|
||||||
else {
|
else {
|
||||||
|
@ -2476,7 +2467,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
|
||||||
*/
|
*/
|
||||||
if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
|
if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
|
||||||
NCR5380_set_timer(hostdata, USLEEP_SLEEP);
|
NCR5380_set_timer(hostdata, USLEEP_SLEEP);
|
||||||
dprintk(NDEBUG_USLEEP, ("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no, hostdata->time_expires));
|
dprintk(NDEBUG_USLEEP, "scsi%d : poll timed out, sleeping until %lu\n", instance->host_no, hostdata->time_expires);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2517,7 +2508,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
|
||||||
hostdata->restart_select = 1;
|
hostdata->restart_select = 1;
|
||||||
|
|
||||||
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
|
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
|
||||||
dprintk(NDEBUG_SELECTION, ("scsi%d : reselect\n", instance->host_no));
|
dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we have detected that our SCSI ID is on the bus,
|
* At this point, we have detected that our SCSI ID is on the bus,
|
||||||
|
@ -2597,7 +2588,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
|
||||||
do_abort(instance);
|
do_abort(instance);
|
||||||
} else {
|
} else {
|
||||||
hostdata->connected = tmp;
|
hostdata->connected = tmp;
|
||||||
dprintk(NDEBUG_RESELECTION, ("scsi%d : nexus established, target = %d, lun = %d, tag = %d\n", instance->host_no, tmp->target, tmp->lun, tmp->tag));
|
dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %d, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2682,8 +2673,8 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
|
||||||
|
|
||||||
NCR5380_setup(instance);
|
NCR5380_setup(instance);
|
||||||
|
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : abort called\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
|
||||||
dprintk(NDEBUG_ABORT, (" basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG)));
|
dprintk(NDEBUG_ABORT, " basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
|
@ -2693,7 +2684,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hostdata->connected == cmd) {
|
if (hostdata->connected == cmd) {
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : aborting connected command\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no);
|
||||||
hostdata->aborted = 1;
|
hostdata->aborted = 1;
|
||||||
/*
|
/*
|
||||||
* We should perform BSY checking, and make sure we haven't slipped
|
* We should perform BSY checking, and make sure we haven't slipped
|
||||||
|
@ -2721,14 +2712,14 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
|
||||||
* from the issue queue.
|
* from the issue queue.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : abort going into loop.\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no);
|
||||||
for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue), tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
for (prev = (Scsi_Cmnd **) & (hostdata->issue_queue), tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; prev = (Scsi_Cmnd **) & (tmp->host_scribble), tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
||||||
if (cmd == tmp) {
|
if (cmd == tmp) {
|
||||||
REMOVE(5, *prev, tmp, tmp->host_scribble);
|
REMOVE(5, *prev, tmp, tmp->host_scribble);
|
||||||
(*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;
|
||||||
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->scsi_done(tmp);
|
tmp->scsi_done(tmp);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2750,7 +2741,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hostdata->connected) {
|
if (hostdata->connected) {
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : abort failed, command connected.\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -2780,11 +2771,11 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
|
||||||
|
|
||||||
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; tmp = (Scsi_Cmnd *) tmp->host_scribble)
|
||||||
if (cmd == tmp) {
|
if (cmd == tmp) {
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : aborting disconnected command.\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
|
||||||
|
|
||||||
if (NCR5380_select(instance, cmd, (int) cmd->tag))
|
if (NCR5380_select(instance, cmd, (int) cmd->tag))
|
||||||
return FAILED;
|
return FAILED;
|
||||||
dprintk(NDEBUG_ABORT, ("scsi%d : nexus reestablished.\n", instance->host_no));
|
dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
|
||||||
|
|
||||||
do_abort(instance);
|
do_abort(instance);
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,6 @@
|
||||||
* 1+ (800) 334-5454
|
* 1+ (800) 334-5454
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: NCR5380.h,v $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NCR5380_H
|
#ifndef NCR5380_H
|
||||||
#define NCR5380_H
|
#define NCR5380_H
|
||||||
|
|
||||||
|
@ -60,6 +56,9 @@
|
||||||
#define NDEBUG_C400_PREAD 0x100000
|
#define NDEBUG_C400_PREAD 0x100000
|
||||||
#define NDEBUG_C400_PWRITE 0x200000
|
#define NDEBUG_C400_PWRITE 0x200000
|
||||||
#define NDEBUG_LISTS 0x400000
|
#define NDEBUG_LISTS 0x400000
|
||||||
|
#define NDEBUG_ABORT 0x800000
|
||||||
|
#define NDEBUG_TAGS 0x1000000
|
||||||
|
#define NDEBUG_MERGING 0x2000000
|
||||||
|
|
||||||
#define NDEBUG_ANY 0xFFFFFFFFUL
|
#define NDEBUG_ANY 0xFFFFFFFFUL
|
||||||
|
|
||||||
|
@ -292,9 +291,24 @@ struct NCR5380_hostdata {
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#define dprintk(a,b) do {} while(0)
|
#ifndef NDEBUG
|
||||||
#define NCR5380_dprint(a,b) do {} while(0)
|
#define NDEBUG (0)
|
||||||
#define NCR5380_dprint_phase(a,b) do {} while(0)
|
#endif
|
||||||
|
|
||||||
|
#define dprintk(flg, fmt, ...) \
|
||||||
|
do { if ((NDEBUG) & (flg)) pr_debug(fmt, ## __VA_ARGS__); } while (0)
|
||||||
|
|
||||||
|
#if NDEBUG
|
||||||
|
#define NCR5380_dprint(flg, arg) \
|
||||||
|
do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0)
|
||||||
|
#define NCR5380_dprint_phase(flg, arg) \
|
||||||
|
do { if ((NDEBUG) & (flg)) NCR5380_print_phase(arg); } while (0)
|
||||||
|
static void NCR5380_print_phase(struct Scsi_Host *instance);
|
||||||
|
static void NCR5380_print(struct Scsi_Host *instance);
|
||||||
|
#else
|
||||||
|
#define NCR5380_dprint(flg, arg) do {} while (0)
|
||||||
|
#define NCR5380_dprint_phase(flg, arg) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(AUTOPROBE_IRQ)
|
#if defined(AUTOPROBE_IRQ)
|
||||||
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
|
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
|
||||||
|
@ -307,10 +321,6 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id);
|
||||||
#endif
|
#endif
|
||||||
static void NCR5380_main(struct work_struct *work);
|
static void NCR5380_main(struct work_struct *work);
|
||||||
static void __maybe_unused NCR5380_print_options(struct Scsi_Host *instance);
|
static void __maybe_unused NCR5380_print_options(struct Scsi_Host *instance);
|
||||||
#ifdef NDEBUG
|
|
||||||
static void NCR5380_print_phase(struct Scsi_Host *instance);
|
|
||||||
static void NCR5380_print(struct Scsi_Host *instance);
|
|
||||||
#endif
|
|
||||||
static int NCR5380_abort(Scsi_Cmnd * cmd);
|
static int NCR5380_abort(Scsi_Cmnd * cmd);
|
||||||
static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
|
static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
|
||||||
static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
|
static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);
|
||||||
|
|
|
@ -827,7 +827,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
|
||||||
for (bit = 0; bit < 8; bit++) {
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
|
||||||
if ((pci_status[i] & (0x1 << bit)) != 0) {
|
if ((pci_status[i] & (0x1 << bit)) != 0) {
|
||||||
static const char *s;
|
const char *s;
|
||||||
|
|
||||||
s = pci_status_strings[bit];
|
s = pci_status_strings[bit];
|
||||||
if (i == 7/*TARG*/ && bit == 3)
|
if (i == 7/*TARG*/ && bit == 3)
|
||||||
|
@ -887,23 +887,15 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
|
||||||
|
|
||||||
for (bit = 0; bit < 8; bit++) {
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
|
||||||
if ((split_status[i] & (0x1 << bit)) != 0) {
|
if ((split_status[i] & (0x1 << bit)) != 0)
|
||||||
static const char *s;
|
printk(split_status_strings[bit], ahd_name(ahd),
|
||||||
|
|
||||||
s = split_status_strings[bit];
|
|
||||||
printk(s, ahd_name(ahd),
|
|
||||||
split_status_source[i]);
|
split_status_source[i]);
|
||||||
}
|
|
||||||
|
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((sg_split_status[i] & (0x1 << bit)) != 0) {
|
if ((sg_split_status[i] & (0x1 << bit)) != 0)
|
||||||
static const char *s;
|
printk(split_status_strings[bit], ahd_name(ahd), "SG");
|
||||||
|
|
||||||
s = split_status_strings[bit];
|
|
||||||
printk(s, ahd_name(ahd), "SG");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -61,13 +61,6 @@
|
||||||
* comment out the undef.
|
* comment out the undef.
|
||||||
*/
|
*/
|
||||||
#undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
#undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
||||||
/*
|
|
||||||
* SCSI-II Linked command support.
|
|
||||||
*
|
|
||||||
* The higher level code doesn't support linked commands yet, and so the option
|
|
||||||
* is undef'd here.
|
|
||||||
*/
|
|
||||||
#undef CONFIG_SCSI_ACORNSCSI_LINK
|
|
||||||
/*
|
/*
|
||||||
* SCSI-II Synchronous transfer support.
|
* SCSI-II Synchronous transfer support.
|
||||||
*
|
*
|
||||||
|
@ -160,10 +153,6 @@
|
||||||
#error "Yippee! ABORT TAG is now defined! Remove this error!"
|
#error "Yippee! ABORT TAG is now defined! Remove this error!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
|
|
||||||
#error SCSI2 LINKed commands not supported (yet)!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_DMAC
|
#ifdef USE_DMAC
|
||||||
/*
|
/*
|
||||||
* DMAC setup parameters
|
* DMAC setup parameters
|
||||||
|
@ -1668,42 +1657,6 @@ void acornscsi_message(AS_Host *host)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
|
|
||||||
case LINKED_CMD_COMPLETE:
|
|
||||||
case LINKED_FLG_CMD_COMPLETE:
|
|
||||||
/*
|
|
||||||
* We don't support linked commands yet
|
|
||||||
*/
|
|
||||||
if (0) {
|
|
||||||
#if (DEBUG & DEBUG_LINK)
|
|
||||||
printk("scsi%d.%c: lun %d tag %d linked command complete\n",
|
|
||||||
host->host->host_no, acornscsi_target(host), host->SCpnt->tag);
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* A linked command should only terminate with one of these messages
|
|
||||||
* if there are more linked commands available.
|
|
||||||
*/
|
|
||||||
if (!host->SCpnt->next_link) {
|
|
||||||
printk(KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n",
|
|
||||||
instance->host_no, acornscsi_target(host), host->SCpnt->tag);
|
|
||||||
acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
|
|
||||||
msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
|
|
||||||
} else {
|
|
||||||
struct scsi_cmnd *SCpnt = host->SCpnt;
|
|
||||||
|
|
||||||
acornscsi_dma_cleanup(host);
|
|
||||||
|
|
||||||
host->SCpnt = host->SCpnt->next_link;
|
|
||||||
host->SCpnt->tag = SCpnt->tag;
|
|
||||||
SCpnt->result = DID_OK | host->scsi.SCp.Message << 8 | host->Scsi.SCp.Status;
|
|
||||||
SCpnt->done(SCpnt);
|
|
||||||
|
|
||||||
/* initialise host->SCpnt->SCp */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default: /* reject message */
|
default: /* reject message */
|
||||||
printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
|
printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
|
||||||
host->host->host_no, acornscsi_target(host),
|
host->host->host_no, acornscsi_target(host),
|
||||||
|
@ -2825,9 +2778,6 @@ char *acornscsi_info(struct Scsi_Host *host)
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
||||||
" TAG"
|
" TAG"
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
|
|
||||||
" LINK"
|
|
||||||
#endif
|
|
||||||
#if (DEBUG & DEBUG_NO_WRITE)
|
#if (DEBUG & DEBUG_NO_WRITE)
|
||||||
" NOWRITE (" __stringify(NO_WRITE) ")"
|
" NOWRITE (" __stringify(NO_WRITE) ")"
|
||||||
#endif
|
#endif
|
||||||
|
@ -2851,9 +2801,6 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
|
||||||
" TAG"
|
" TAG"
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
|
|
||||||
" LINK"
|
|
||||||
#endif
|
|
||||||
#if (DEBUG & DEBUG_NO_WRITE)
|
#if (DEBUG & DEBUG_NO_WRITE)
|
||||||
" NOWRITE (" __stringify(NO_WRITE) ")"
|
" NOWRITE (" __stringify(NO_WRITE) ")"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,9 +36,6 @@
|
||||||
void __iomem *base; \
|
void __iomem *base; \
|
||||||
void __iomem *dma
|
void __iomem *dma
|
||||||
|
|
||||||
#define BOARD_NORMAL 0
|
|
||||||
#define BOARD_NCR53C400 1
|
|
||||||
|
|
||||||
#include "../NCR5380.h"
|
#include "../NCR5380.h"
|
||||||
|
|
||||||
void cumanascsi_setup(char *str, int *ints)
|
void cumanascsi_setup(char *str, int *ints)
|
||||||
|
|
|
@ -37,9 +37,6 @@
|
||||||
#define NCR5380_implementation_fields \
|
#define NCR5380_implementation_fields \
|
||||||
void __iomem *base
|
void __iomem *base
|
||||||
|
|
||||||
#define BOARD_NORMAL 0
|
|
||||||
#define BOARD_NCR53C400 1
|
|
||||||
|
|
||||||
#include "../NCR5380.h"
|
#include "../NCR5380.h"
|
||||||
|
|
||||||
#undef START_DMA_INITIATOR_RECEIVE_REG
|
#undef START_DMA_INITIATOR_RECEIVE_REG
|
||||||
|
|
|
@ -370,7 +370,7 @@ static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged)
|
||||||
return 0;
|
return 0;
|
||||||
if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
|
if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
|
||||||
TagAlloc[cmd->device->id][cmd->device->lun].queue_size) {
|
TagAlloc[cmd->device->id][cmd->device->lun].queue_size) {
|
||||||
TAG_PRINTK("scsi%d: target %d lun %d: no free tags\n",
|
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
|
||||||
H_NO(cmd), cmd->device->id, cmd->device->lun);
|
H_NO(cmd), cmd->device->id, cmd->device->lun);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
|
||||||
!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
|
!setup_use_tagged_queuing || !cmd->device->tagged_supported) {
|
||||||
cmd->tag = TAG_NONE;
|
cmd->tag = TAG_NONE;
|
||||||
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
||||||
TAG_PRINTK("scsi%d: target %d lun %d now allocated by untagged "
|
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
|
||||||
"command\n", H_NO(cmd), cmd->device->id, cmd->device->lun);
|
"command\n", H_NO(cmd), cmd->device->id, cmd->device->lun);
|
||||||
} else {
|
} else {
|
||||||
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
||||||
|
@ -402,7 +402,7 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
|
||||||
cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
|
cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
|
||||||
set_bit(cmd->tag, ta->allocated);
|
set_bit(cmd->tag, ta->allocated);
|
||||||
ta->nr_allocated++;
|
ta->nr_allocated++;
|
||||||
TAG_PRINTK("scsi%d: using tag %d for target %d lun %d "
|
dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
|
||||||
"(now %d tags in use)\n",
|
"(now %d tags in use)\n",
|
||||||
H_NO(cmd), cmd->tag, cmd->device->id,
|
H_NO(cmd), cmd->tag, cmd->device->id,
|
||||||
cmd->device->lun, ta->nr_allocated);
|
cmd->device->lun, ta->nr_allocated);
|
||||||
|
@ -420,7 +420,7 @@ static void cmd_free_tag(Scsi_Cmnd *cmd)
|
||||||
|
|
||||||
if (cmd->tag == TAG_NONE) {
|
if (cmd->tag == TAG_NONE) {
|
||||||
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
|
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
|
||||||
TAG_PRINTK("scsi%d: target %d lun %d untagged cmd finished\n",
|
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
|
||||||
H_NO(cmd), cmd->device->id, cmd->device->lun);
|
H_NO(cmd), cmd->device->id, cmd->device->lun);
|
||||||
} else if (cmd->tag >= MAX_TAGS) {
|
} else if (cmd->tag >= MAX_TAGS) {
|
||||||
printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
|
printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
|
||||||
|
@ -429,7 +429,7 @@ static void cmd_free_tag(Scsi_Cmnd *cmd)
|
||||||
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
||||||
clear_bit(cmd->tag, ta->allocated);
|
clear_bit(cmd->tag, ta->allocated);
|
||||||
ta->nr_allocated--;
|
ta->nr_allocated--;
|
||||||
TAG_PRINTK("scsi%d: freed tag %d for target %d lun %d\n",
|
dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
|
||||||
H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun);
|
H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,7 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
|
||||||
for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
|
for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
|
||||||
cmd->SCp.buffers_residual &&
|
cmd->SCp.buffers_residual &&
|
||||||
virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
|
virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
|
||||||
MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
|
dprintk(NDEBUG_MERGING, "VTOP(%p) == %08lx -> merging\n",
|
||||||
page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
|
page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
|
||||||
#if (NDEBUG & NDEBUG_MERGING)
|
#if (NDEBUG & NDEBUG_MERGING)
|
||||||
++cnt;
|
++cnt;
|
||||||
|
@ -490,7 +490,7 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
|
||||||
}
|
}
|
||||||
#if (NDEBUG & NDEBUG_MERGING)
|
#if (NDEBUG & NDEBUG_MERGING)
|
||||||
if (oldlen != cmd->SCp.this_residual)
|
if (oldlen != cmd->SCp.this_residual)
|
||||||
MER_PRINTK("merged %d buffers from %p, new length %08x\n",
|
dprintk(NDEBUG_MERGING, "merged %d buffers from %p, new length %08x\n",
|
||||||
cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
|
cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -626,16 +626,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !NDEBUG */
|
|
||||||
|
|
||||||
/* dummies... */
|
|
||||||
static inline void NCR5380_print(struct Scsi_Host *instance)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
static inline void NCR5380_print_phase(struct Scsi_Host *instance)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -676,7 +666,7 @@ static inline void NCR5380_all_init(void)
|
||||||
{
|
{
|
||||||
static int done = 0;
|
static int done = 0;
|
||||||
if (!done) {
|
if (!done) {
|
||||||
INI_PRINTK("scsi : NCR5380_all_init()\n");
|
dprintk(NDEBUG_INIT, "scsi : NCR5380_all_init()\n");
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,8 +729,8 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
|
||||||
Scsi_Cmnd *ptr;
|
Scsi_Cmnd *ptr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
NCR_PRINT(NDEBUG_ANY);
|
NCR5380_dprint(NDEBUG_ANY, instance);
|
||||||
NCR_PRINT_PHASE(NDEBUG_ANY);
|
NCR5380_dprint_phase(NDEBUG_ANY, instance);
|
||||||
|
|
||||||
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
|
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
|
||||||
|
|
||||||
|
@ -984,7 +974,7 @@ static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
|
||||||
}
|
}
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd),
|
dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
|
||||||
(cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
|
(cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
|
||||||
|
|
||||||
/* If queue_command() is called from an interrupt (real one or bottom
|
/* If queue_command() is called from an interrupt (real one or bottom
|
||||||
|
@ -1054,7 +1044,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
done = 1;
|
done = 1;
|
||||||
|
|
||||||
if (!hostdata->connected) {
|
if (!hostdata->connected) {
|
||||||
MAIN_PRINTK("scsi%d: not connected\n", HOSTNO);
|
dprintk(NDEBUG_MAIN, "scsi%d: not connected\n", HOSTNO);
|
||||||
/*
|
/*
|
||||||
* Search through the issue_queue for a command destined
|
* Search through the issue_queue for a command destined
|
||||||
* for a target that's not busy.
|
* for a target that's not busy.
|
||||||
|
@ -1107,7 +1097,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
* On failure, we must add the command back to the
|
* On failure, we must add the command back to the
|
||||||
* issue queue so we can keep trying.
|
* issue queue so we can keep trying.
|
||||||
*/
|
*/
|
||||||
MAIN_PRINTK("scsi%d: main(): command for target %d "
|
dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
|
||||||
"lun %d removed from issue_queue\n",
|
"lun %d removed from issue_queue\n",
|
||||||
HOSTNO, tmp->device->id, tmp->device->lun);
|
HOSTNO, tmp->device->id, tmp->device->lun);
|
||||||
/*
|
/*
|
||||||
|
@ -1140,7 +1130,7 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
#endif
|
#endif
|
||||||
falcon_dont_release--;
|
falcon_dont_release--;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
MAIN_PRINTK("scsi%d: main(): select() failed, "
|
dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
|
||||||
"returned to issue_queue\n", HOSTNO);
|
"returned to issue_queue\n", HOSTNO);
|
||||||
if (hostdata->connected)
|
if (hostdata->connected)
|
||||||
break;
|
break;
|
||||||
|
@ -1155,10 +1145,10 @@ static void NCR5380_main(struct work_struct *work)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
MAIN_PRINTK("scsi%d: main: performing information transfer\n",
|
dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
|
||||||
HOSTNO);
|
HOSTNO);
|
||||||
NCR5380_information_transfer(instance);
|
NCR5380_information_transfer(instance);
|
||||||
MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO);
|
dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO);
|
||||||
done = 0;
|
done = 0;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
@ -1204,12 +1194,12 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
|
||||||
(BASR_PHASE_MATCH|BASR_ACK)) {
|
(BASR_PHASE_MATCH|BASR_ACK)) {
|
||||||
saved_data = NCR5380_read(INPUT_DATA_REG);
|
saved_data = NCR5380_read(INPUT_DATA_REG);
|
||||||
overrun = 1;
|
overrun = 1;
|
||||||
DMA_PRINTK("scsi%d: read overrun handled\n", HOSTNO);
|
dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
|
dprintk(NDEBUG_DMA, "scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
|
||||||
HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
|
HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
|
||||||
NCR5380_read(STATUS_REG));
|
NCR5380_read(STATUS_REG));
|
||||||
|
|
||||||
|
@ -1229,13 +1219,13 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
|
||||||
if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
|
if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
|
||||||
cnt = toPIO = atari_read_overruns;
|
cnt = toPIO = atari_read_overruns;
|
||||||
if (overrun) {
|
if (overrun) {
|
||||||
DMA_PRINTK("Got an input overrun, using saved byte\n");
|
dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
|
||||||
*(*data)++ = saved_data;
|
*(*data)++ = saved_data;
|
||||||
(*count)--;
|
(*count)--;
|
||||||
cnt--;
|
cnt--;
|
||||||
toPIO--;
|
toPIO--;
|
||||||
}
|
}
|
||||||
DMA_PRINTK("Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
|
dprintk(NDEBUG_DMA, "Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
|
||||||
NCR5380_transfer_pio(instance, &p, &cnt, data);
|
NCR5380_transfer_pio(instance, &p, &cnt, data);
|
||||||
*count -= toPIO - cnt;
|
*count -= toPIO - cnt;
|
||||||
}
|
}
|
||||||
|
@ -1261,25 +1251,25 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
|
||||||
int done = 1, handled = 0;
|
int done = 1, handled = 0;
|
||||||
unsigned char basr;
|
unsigned char basr;
|
||||||
|
|
||||||
INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: NCR5380 irq triggered\n", HOSTNO);
|
||||||
|
|
||||||
/* Look for pending interrupts */
|
/* Look for pending interrupts */
|
||||||
basr = NCR5380_read(BUS_AND_STATUS_REG);
|
basr = NCR5380_read(BUS_AND_STATUS_REG);
|
||||||
INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr);
|
dprintk(NDEBUG_INTR, "scsi%d: BASR=%02x\n", HOSTNO, basr);
|
||||||
/* dispatch to appropriate routine if found and done=0 */
|
/* dispatch to appropriate routine if found and done=0 */
|
||||||
if (basr & BASR_IRQ) {
|
if (basr & BASR_IRQ) {
|
||||||
NCR_PRINT(NDEBUG_INTR);
|
NCR5380_dprint(NDEBUG_INTR, instance);
|
||||||
if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
|
if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
|
||||||
done = 0;
|
done = 0;
|
||||||
ENABLE_IRQ();
|
ENABLE_IRQ();
|
||||||
INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO);
|
||||||
NCR5380_reselect(instance);
|
NCR5380_reselect(instance);
|
||||||
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else if (basr & BASR_PARITY_ERROR) {
|
} else if (basr & BASR_PARITY_ERROR) {
|
||||||
INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: PARITY interrupt\n", HOSTNO);
|
||||||
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
|
} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
|
||||||
INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: RESET interrupt\n", HOSTNO);
|
||||||
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -1298,7 +1288,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
|
||||||
((basr & BASR_END_DMA_TRANSFER) ||
|
((basr & BASR_END_DMA_TRANSFER) ||
|
||||||
!(basr & BASR_PHASE_MATCH))) {
|
!(basr & BASR_PHASE_MATCH))) {
|
||||||
|
|
||||||
INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
|
||||||
NCR5380_dma_complete( instance );
|
NCR5380_dma_complete( instance );
|
||||||
done = 0;
|
done = 0;
|
||||||
ENABLE_IRQ();
|
ENABLE_IRQ();
|
||||||
|
@ -1323,7 +1313,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO);
|
dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO);
|
||||||
/* Put a call to NCR5380_main() on the queue... */
|
/* Put a call to NCR5380_main() on the queue... */
|
||||||
queue_main();
|
queue_main();
|
||||||
}
|
}
|
||||||
|
@ -1396,8 +1386,8 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
hostdata->restart_select = 0;
|
hostdata->restart_select = 0;
|
||||||
NCR_PRINT(NDEBUG_ARBITRATION);
|
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
|
||||||
ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO,
|
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
|
||||||
instance->this_id);
|
instance->this_id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1442,7 +1432,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
;
|
;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO);
|
dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
|
||||||
|
|
||||||
if (hostdata->connected) {
|
if (hostdata->connected) {
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
|
@ -1463,7 +1453,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
|
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
|
||||||
hostdata->connected) {
|
hostdata->connected) {
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
|
dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
|
||||||
HOSTNO);
|
HOSTNO);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1478,7 +1468,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
hostdata->connected) {
|
hostdata->connected) {
|
||||||
NCR5380_write(MODE_REG, MR_BASE);
|
NCR5380_write(MODE_REG, MR_BASE);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
|
dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
|
||||||
HOSTNO);
|
HOSTNO);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1501,7 +1491,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO);
|
dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we have won arbitration, start Selection process, asserting
|
* Now that we have won arbitration, start Selection process, asserting
|
||||||
|
@ -1561,7 +1551,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
|
|
||||||
udelay(1);
|
udelay(1);
|
||||||
|
|
||||||
SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
|
dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The SCSI specification calls for a 250 ms timeout for the actual
|
* The SCSI specification calls for a 250 ms timeout for the actual
|
||||||
|
@ -1617,7 +1607,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
|
printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
|
||||||
if (hostdata->restart_select)
|
if (hostdata->restart_select)
|
||||||
printk(KERN_NOTICE "\trestart select\n");
|
printk(KERN_NOTICE "\trestart select\n");
|
||||||
NCR_PRINT(NDEBUG_ANY);
|
NCR5380_dprint(NDEBUG_ANY, instance);
|
||||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1630,7 +1620,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
#endif
|
#endif
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||||
SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO);
|
dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
|
||||||
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1656,7 +1646,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
while (!(NCR5380_read(STATUS_REG) & SR_REQ))
|
while (!(NCR5380_read(STATUS_REG) & SR_REQ))
|
||||||
;
|
;
|
||||||
|
|
||||||
SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
|
dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
|
||||||
HOSTNO, cmd->device->id);
|
HOSTNO, cmd->device->id);
|
||||||
tmp[0] = IDENTIFY(1, cmd->device->lun);
|
tmp[0] = IDENTIFY(1, cmd->device->lun);
|
||||||
|
|
||||||
|
@ -1676,7 +1666,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
|
||||||
data = tmp;
|
data = tmp;
|
||||||
phase = PHASE_MSGOUT;
|
phase = PHASE_MSGOUT;
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO);
|
dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
|
||||||
/* XXX need to handle errors here */
|
/* XXX need to handle errors here */
|
||||||
hostdata->connected = cmd;
|
hostdata->connected = cmd;
|
||||||
#ifndef SUPPORT_TAGS
|
#ifndef SUPPORT_TAGS
|
||||||
|
@ -1737,12 +1727,12 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
|
||||||
while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
|
while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
|
||||||
;
|
;
|
||||||
|
|
||||||
HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO);
|
dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
|
||||||
|
|
||||||
/* Check for phase mismatch */
|
/* Check for phase mismatch */
|
||||||
if ((tmp & PHASE_MASK) != p) {
|
if ((tmp & PHASE_MASK) != p) {
|
||||||
PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO);
|
dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
|
||||||
NCR_PRINT_PHASE(NDEBUG_PIO);
|
NCR5380_dprint_phase(NDEBUG_PIO, instance);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1764,25 +1754,25 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
|
||||||
if (!(p & SR_IO)) {
|
if (!(p & SR_IO)) {
|
||||||
if (!((p & SR_MSG) && c > 1)) {
|
if (!((p & SR_MSG) && c > 1)) {
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
|
||||||
NCR_PRINT(NDEBUG_PIO);
|
NCR5380_dprint(NDEBUG_PIO, instance);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
||||||
ICR_ASSERT_DATA | ICR_ASSERT_ACK);
|
ICR_ASSERT_DATA | ICR_ASSERT_ACK);
|
||||||
} else {
|
} else {
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
||||||
ICR_ASSERT_DATA | ICR_ASSERT_ATN);
|
ICR_ASSERT_DATA | ICR_ASSERT_ATN);
|
||||||
NCR_PRINT(NDEBUG_PIO);
|
NCR5380_dprint(NDEBUG_PIO, instance);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
|
||||||
ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
|
ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NCR_PRINT(NDEBUG_PIO);
|
NCR5380_dprint(NDEBUG_PIO, instance);
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (NCR5380_read(STATUS_REG) & SR_REQ)
|
while (NCR5380_read(STATUS_REG) & SR_REQ)
|
||||||
;
|
;
|
||||||
|
|
||||||
HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO);
|
dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have several special cases to consider during REQ/ACK handshaking :
|
* We have several special cases to consider during REQ/ACK handshaking :
|
||||||
|
@ -1803,7 +1793,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
|
||||||
}
|
}
|
||||||
} while (--c);
|
} while (--c);
|
||||||
|
|
||||||
PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c);
|
dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
|
||||||
|
|
||||||
*count = c;
|
*count = c;
|
||||||
*data = d;
|
*data = d;
|
||||||
|
@ -1917,7 +1907,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
|
||||||
if (atari_read_overruns && (p & SR_IO))
|
if (atari_read_overruns && (p & SR_IO))
|
||||||
c -= atari_read_overruns;
|
c -= atari_read_overruns;
|
||||||
|
|
||||||
DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n",
|
dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
|
||||||
HOSTNO, (p & SR_IO) ? "reading" : "writing",
|
HOSTNO, (p & SR_IO) ? "reading" : "writing",
|
||||||
c, (p & SR_IO) ? "to" : "from", d);
|
c, (p & SR_IO) ? "to" : "from", d);
|
||||||
|
|
||||||
|
@ -1997,7 +1987,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
phase = (tmp & PHASE_MASK);
|
phase = (tmp & PHASE_MASK);
|
||||||
if (phase != old_phase) {
|
if (phase != old_phase) {
|
||||||
old_phase = phase;
|
old_phase = phase;
|
||||||
NCR_PRINT_PHASE(NDEBUG_INFORMATION);
|
NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink && (phase != PHASE_MSGOUT)) {
|
if (sink && (phase != PHASE_MSGOUT)) {
|
||||||
|
@ -2039,7 +2029,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
* they are at contiguous physical addresses.
|
* they are at contiguous physical addresses.
|
||||||
*/
|
*/
|
||||||
merge_contiguous_buffers(cmd);
|
merge_contiguous_buffers(cmd);
|
||||||
INF_PRINTK("scsi%d: %d bytes and %d buffers left\n",
|
dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n",
|
||||||
HOSTNO, cmd->SCp.this_residual,
|
HOSTNO, cmd->SCp.this_residual,
|
||||||
cmd->SCp.buffers_residual);
|
cmd->SCp.buffers_residual);
|
||||||
}
|
}
|
||||||
|
@ -2123,7 +2113,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
/* Accept message by clearing ACK */
|
/* Accept message by clearing ACK */
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
|
|
||||||
LNK_PRINTK("scsi%d: target %d lun %d linked command "
|
dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked command "
|
||||||
"complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
|
"complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
|
||||||
|
|
||||||
/* Enable reselect interrupts */
|
/* Enable reselect interrupts */
|
||||||
|
@ -2148,7 +2138,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
* and don't free it! */
|
* and don't free it! */
|
||||||
cmd->next_link->tag = cmd->tag;
|
cmd->next_link->tag = cmd->tag;
|
||||||
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
|
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
|
||||||
LNK_PRINTK("scsi%d: target %d lun %d linked request "
|
dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %d linked request "
|
||||||
"done, calling scsi_done().\n",
|
"done, calling scsi_done().\n",
|
||||||
HOSTNO, cmd->device->id, cmd->device->lun);
|
HOSTNO, cmd->device->id, cmd->device->lun);
|
||||||
#ifdef NCR5380_STATS
|
#ifdef NCR5380_STATS
|
||||||
|
@ -2165,7 +2155,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
/* ++guenther: possible race with Falcon locking */
|
/* ++guenther: possible race with Falcon locking */
|
||||||
falcon_dont_release++;
|
falcon_dont_release++;
|
||||||
hostdata->connected = NULL;
|
hostdata->connected = NULL;
|
||||||
QU_PRINTK("scsi%d: command for target %d, lun %d "
|
dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %d "
|
||||||
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
|
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
|
||||||
#ifdef SUPPORT_TAGS
|
#ifdef SUPPORT_TAGS
|
||||||
cmd_free_tag(cmd);
|
cmd_free_tag(cmd);
|
||||||
|
@ -2179,7 +2169,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
/* ++Andreas: the mid level code knows about
|
/* ++Andreas: the mid level code knows about
|
||||||
QUEUE_FULL now. */
|
QUEUE_FULL now. */
|
||||||
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
|
||||||
TAG_PRINTK("scsi%d: target %d lun %d returned "
|
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d returned "
|
||||||
"QUEUE_FULL after %d commands\n",
|
"QUEUE_FULL after %d commands\n",
|
||||||
HOSTNO, cmd->device->id, cmd->device->lun,
|
HOSTNO, cmd->device->id, cmd->device->lun,
|
||||||
ta->nr_allocated);
|
ta->nr_allocated);
|
||||||
|
@ -2224,14 +2214,14 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
|
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
|
||||||
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
|
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
|
||||||
|
|
||||||
ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO);
|
dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO);
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
LIST(cmd,hostdata->issue_queue);
|
LIST(cmd,hostdata->issue_queue);
|
||||||
SET_NEXT(cmd, hostdata->issue_queue);
|
SET_NEXT(cmd, hostdata->issue_queue);
|
||||||
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
|
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
|
dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of "
|
||||||
"issue queue\n", H_NO(cmd));
|
"issue queue\n", H_NO(cmd));
|
||||||
} else
|
} else
|
||||||
#endif /* def AUTOSENSE */
|
#endif /* def AUTOSENSE */
|
||||||
|
@ -2277,7 +2267,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
cmd->device->tagged_supported = 0;
|
cmd->device->tagged_supported = 0;
|
||||||
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
|
||||||
cmd->tag = TAG_NONE;
|
cmd->tag = TAG_NONE;
|
||||||
TAG_PRINTK("scsi%d: target %d lun %d rejected "
|
dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d rejected "
|
||||||
"QUEUE_TAG message; tagged queuing "
|
"QUEUE_TAG message; tagged queuing "
|
||||||
"disabled\n",
|
"disabled\n",
|
||||||
HOSTNO, cmd->device->id, cmd->device->lun);
|
HOSTNO, cmd->device->id, cmd->device->lun);
|
||||||
|
@ -2294,7 +2284,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
hostdata->connected = NULL;
|
hostdata->connected = NULL;
|
||||||
hostdata->disconnected_queue = cmd;
|
hostdata->disconnected_queue = cmd;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
QU_PRINTK("scsi%d: command for target %d lun %d was "
|
dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %d was "
|
||||||
"moved from connected to the "
|
"moved from connected to the "
|
||||||
"disconnected_queue\n", HOSTNO,
|
"disconnected_queue\n", HOSTNO,
|
||||||
cmd->device->id, cmd->device->lun);
|
cmd->device->id, cmd->device->lun);
|
||||||
|
@ -2344,13 +2334,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
/* Accept first byte by clearing ACK */
|
/* Accept first byte by clearing ACK */
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
|
|
||||||
EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO);
|
dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
|
||||||
|
|
||||||
len = 2;
|
len = 2;
|
||||||
data = extended_msg + 1;
|
data = extended_msg + 1;
|
||||||
phase = PHASE_MSGIN;
|
phase = PHASE_MSGIN;
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO,
|
dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
|
||||||
(int)extended_msg[1], (int)extended_msg[2]);
|
(int)extended_msg[1], (int)extended_msg[2]);
|
||||||
|
|
||||||
if (!len && extended_msg[1] <=
|
if (!len && extended_msg[1] <=
|
||||||
|
@ -2362,7 +2352,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
phase = PHASE_MSGIN;
|
phase = PHASE_MSGIN;
|
||||||
|
|
||||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||||
EXT_PRINTK("scsi%d: message received, residual %d\n",
|
dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n",
|
||||||
HOSTNO, len);
|
HOSTNO, len);
|
||||||
|
|
||||||
switch (extended_msg[2]) {
|
switch (extended_msg[2]) {
|
||||||
|
@ -2451,7 +2441,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("scsi%d: unknown phase\n", HOSTNO);
|
printk("scsi%d: unknown phase\n", HOSTNO);
|
||||||
NCR_PRINT(NDEBUG_ANY);
|
NCR5380_dprint(NDEBUG_ANY, instance);
|
||||||
} /* switch(phase) */
|
} /* switch(phase) */
|
||||||
} /* if (tmp * SR_REQ) */
|
} /* if (tmp * SR_REQ) */
|
||||||
} /* while (1) */
|
} /* while (1) */
|
||||||
|
@ -2493,7 +2483,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
|
||||||
|
|
||||||
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
|
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
|
||||||
|
|
||||||
RSL_PRINTK("scsi%d: reselect\n", HOSTNO);
|
dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we have detected that our SCSI ID is on the bus,
|
* At this point, we have detected that our SCSI ID is on the bus,
|
||||||
|
@ -2544,7 +2534,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
|
||||||
if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
|
if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
|
||||||
msg[1] == SIMPLE_QUEUE_TAG)
|
msg[1] == SIMPLE_QUEUE_TAG)
|
||||||
tag = msg[2];
|
tag = msg[2];
|
||||||
TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at "
|
dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at "
|
||||||
"reselection\n", HOSTNO, target_mask, lun, tag);
|
"reselection\n", HOSTNO, target_mask, lun, tag);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2598,7 +2588,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
|
||||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||||
|
|
||||||
hostdata->connected = tmp;
|
hostdata->connected = tmp;
|
||||||
RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
|
dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
|
||||||
HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
|
HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
|
||||||
falcon_dont_release--;
|
falcon_dont_release--;
|
||||||
}
|
}
|
||||||
|
@ -2640,7 +2630,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n",
|
printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n",
|
||||||
HOSTNO);
|
HOSTNO);
|
||||||
|
|
||||||
ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
|
dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
|
||||||
NCR5380_read(BUS_AND_STATUS_REG),
|
NCR5380_read(BUS_AND_STATUS_REG),
|
||||||
NCR5380_read(STATUS_REG));
|
NCR5380_read(STATUS_REG));
|
||||||
|
|
||||||
|
@ -2653,7 +2643,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
|
|
||||||
if (hostdata->connected == cmd) {
|
if (hostdata->connected == cmd) {
|
||||||
|
|
||||||
ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO);
|
dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO);
|
||||||
/*
|
/*
|
||||||
* We should perform BSY checking, and make sure we haven't slipped
|
* We should perform BSY checking, and make sure we haven't slipped
|
||||||
* into BUS FREE.
|
* into BUS FREE.
|
||||||
|
@ -2683,11 +2673,11 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
falcon_release_lock_if_possible(hostdata);
|
falcon_release_lock_if_possible(hostdata);
|
||||||
return SCSI_ABORT_SUCCESS;
|
return SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
/* local_irq_restore(flags); */
|
/* local_irq_restore(flags); */
|
||||||
printk("scsi%d: abort of connected command failed!\n", HOSTNO);
|
printk("scsi%d: abort of connected command failed!\n", HOSTNO);
|
||||||
return SCSI_ABORT_ERROR;
|
return FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2705,13 +2695,13 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
SET_NEXT(tmp, NULL);
|
SET_NEXT(tmp, NULL);
|
||||||
tmp->result = DID_ABORT << 16;
|
tmp->result = DID_ABORT << 16;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n",
|
dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
|
||||||
HOSTNO);
|
HOSTNO);
|
||||||
/* Tagged queuing note: no tag to free here, hasn't been assigned
|
/* Tagged queuing note: no tag to free here, hasn't been assigned
|
||||||
* yet... */
|
* yet... */
|
||||||
tmp->scsi_done(tmp);
|
tmp->scsi_done(tmp);
|
||||||
falcon_release_lock_if_possible(hostdata);
|
falcon_release_lock_if_possible(hostdata);
|
||||||
return SCSI_ABORT_SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2728,8 +2718,8 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
|
|
||||||
if (hostdata->connected) {
|
if (hostdata->connected) {
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
|
dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
|
||||||
return SCSI_ABORT_SNOOZE;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2761,12 +2751,12 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
tmp = NEXT(tmp)) {
|
tmp = NEXT(tmp)) {
|
||||||
if (cmd == tmp) {
|
if (cmd == tmp) {
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO);
|
dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
|
||||||
|
|
||||||
if (NCR5380_select(instance, cmd, (int)cmd->tag))
|
if (NCR5380_select(instance, cmd, (int)cmd->tag))
|
||||||
return SCSI_ABORT_BUSY;
|
return FAILED;
|
||||||
|
|
||||||
ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO);
|
dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
|
||||||
|
|
||||||
do_abort(instance);
|
do_abort(instance);
|
||||||
|
|
||||||
|
@ -2791,7 +2781,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
tmp->scsi_done(tmp);
|
tmp->scsi_done(tmp);
|
||||||
falcon_release_lock_if_possible(hostdata);
|
falcon_release_lock_if_possible(hostdata);
|
||||||
return SCSI_ABORT_SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2816,7 +2806,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
*/
|
*/
|
||||||
falcon_release_lock_if_possible(hostdata);
|
falcon_release_lock_if_possible(hostdata);
|
||||||
|
|
||||||
return SCSI_ABORT_NOT_RUNNING;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2825,7 +2815,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
|
||||||
*
|
*
|
||||||
* Purpose : reset the SCSI bus.
|
* Purpose : reset the SCSI bus.
|
||||||
*
|
*
|
||||||
* Returns : SCSI_RESET_WAKEUP
|
* Returns : SUCCESS or FAILURE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -2834,7 +2824,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
SETUP_HOSTDATA(cmd->device->host);
|
SETUP_HOSTDATA(cmd->device->host);
|
||||||
int i;
|
int i;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
#if 1
|
#if defined(RESET_RUN_DONE)
|
||||||
Scsi_Cmnd *connected, *disconnected_queue;
|
Scsi_Cmnd *connected, *disconnected_queue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2859,7 +2849,14 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
* through anymore ... */
|
* through anymore ... */
|
||||||
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
|
||||||
|
|
||||||
#if 1 /* XXX Should now be done by midlevel code, but it's broken XXX */
|
/* MSch 20140115 - looking at the generic NCR5380 driver, all of this
|
||||||
|
* should go.
|
||||||
|
* Catch-22: if we don't clear all queues, the SCSI driver lock will
|
||||||
|
* not be reset by atari_scsi_reset()!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(RESET_RUN_DONE)
|
||||||
|
/* XXX Should now be done by midlevel code, but it's broken XXX */
|
||||||
/* XXX see below XXX */
|
/* XXX see below XXX */
|
||||||
|
|
||||||
/* MSch: old-style reset: actually abort all command processing here */
|
/* MSch: old-style reset: actually abort all command processing here */
|
||||||
|
@ -2890,7 +2887,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((cmd = connected)) {
|
if ((cmd = connected)) {
|
||||||
ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
|
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
|
||||||
cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
|
cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
|
@ -2902,7 +2899,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i);
|
dprintk(NDEBUG_ABORT, "scsi: reset aborted %d disconnected command(s)\n", i);
|
||||||
|
|
||||||
/* The Falcon lock should be released after a reset...
|
/* The Falcon lock should be released after a reset...
|
||||||
*/
|
*/
|
||||||
|
@ -2915,7 +2912,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
* the midlevel code that the reset was SUCCESSFUL, and there is no
|
* the midlevel code that the reset was SUCCESSFUL, and there is no
|
||||||
* need to 'wake up' the commands by a request_sense
|
* need to 'wake up' the commands by a request_sense
|
||||||
*/
|
*/
|
||||||
return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
|
return SUCCESS;
|
||||||
#else /* 1 */
|
#else /* 1 */
|
||||||
|
|
||||||
/* MSch: new-style reset handling: let the mid-level do what it can */
|
/* MSch: new-style reset handling: let the mid-level do what it can */
|
||||||
|
@ -2942,11 +2939,11 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hostdata->issue_queue)
|
if (hostdata->issue_queue)
|
||||||
ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
|
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
|
||||||
if (hostdata->connected)
|
if (hostdata->connected)
|
||||||
ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
|
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
|
||||||
if (hostdata->disconnected_queue)
|
if (hostdata->disconnected_queue)
|
||||||
ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
|
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
hostdata->issue_queue = NULL;
|
hostdata->issue_queue = NULL;
|
||||||
|
@ -2963,6 +2960,6 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
/* we did no complete reset of all commands, so a wakeup is required */
|
/* we did no complete reset of all commands, so a wakeup is required */
|
||||||
return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET;
|
return SUCCESS;
|
||||||
#endif /* 1 */
|
#endif /* 1 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,12 +67,6 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#define NDEBUG (0)
|
|
||||||
|
|
||||||
#define NDEBUG_ABORT 0x00100000
|
|
||||||
#define NDEBUG_TAGS 0x00200000
|
|
||||||
#define NDEBUG_MERGING 0x00400000
|
|
||||||
|
|
||||||
#define AUTOSENSE
|
#define AUTOSENSE
|
||||||
/* For the Atari version, use only polled IO or REAL_DMA */
|
/* For the Atari version, use only polled IO or REAL_DMA */
|
||||||
#define REAL_DMA
|
#define REAL_DMA
|
||||||
|
@ -314,7 +308,7 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
|
||||||
|
|
||||||
dma_stat = tt_scsi_dma.dma_ctrl;
|
dma_stat = tt_scsi_dma.dma_ctrl;
|
||||||
|
|
||||||
INT_PRINTK("scsi%d: NCR5380 interrupt, DMA status = %02x\n",
|
dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n",
|
||||||
atari_scsi_host->host_no, dma_stat & 0xff);
|
atari_scsi_host->host_no, dma_stat & 0xff);
|
||||||
|
|
||||||
/* Look if it was the DMA that has interrupted: First possibility
|
/* Look if it was the DMA that has interrupted: First possibility
|
||||||
|
@ -340,7 +334,7 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
|
||||||
if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
|
if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
|
||||||
atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
|
atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr);
|
||||||
|
|
||||||
DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n",
|
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
|
||||||
atari_dma_residual);
|
atari_dma_residual);
|
||||||
|
|
||||||
if ((signed int)atari_dma_residual < 0)
|
if ((signed int)atari_dma_residual < 0)
|
||||||
|
@ -371,7 +365,7 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
|
||||||
* other command. These shouldn't disconnect anyway.
|
* other command. These shouldn't disconnect anyway.
|
||||||
*/
|
*/
|
||||||
if (atari_dma_residual & 0x1ff) {
|
if (atari_dma_residual & 0x1ff) {
|
||||||
DMA_PRINTK("SCSI DMA: DMA bug corrected, "
|
dprintk(NDEBUG_DMA, "SCSI DMA: DMA bug corrected, "
|
||||||
"difference %ld bytes\n",
|
"difference %ld bytes\n",
|
||||||
512 - (atari_dma_residual & 0x1ff));
|
512 - (atari_dma_residual & 0x1ff));
|
||||||
atari_dma_residual = (atari_dma_residual + 511) & ~0x1ff;
|
atari_dma_residual = (atari_dma_residual + 511) & ~0x1ff;
|
||||||
|
@ -438,7 +432,7 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy)
|
||||||
"ST-DMA fifo\n", transferred & 15);
|
"ST-DMA fifo\n", transferred & 15);
|
||||||
|
|
||||||
atari_dma_residual = HOSTDATA_DMALEN - transferred;
|
atari_dma_residual = HOSTDATA_DMALEN - transferred;
|
||||||
DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n",
|
dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n",
|
||||||
atari_dma_residual);
|
atari_dma_residual);
|
||||||
} else
|
} else
|
||||||
atari_dma_residual = 0;
|
atari_dma_residual = 0;
|
||||||
|
@ -474,11 +468,11 @@ static void atari_scsi_fetch_restbytes(void)
|
||||||
/* there are 'nr' bytes left for the last long address
|
/* there are 'nr' bytes left for the last long address
|
||||||
before the DMA pointer */
|
before the DMA pointer */
|
||||||
phys_dst ^= nr;
|
phys_dst ^= nr;
|
||||||
DMA_PRINTK("SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
|
dprintk(NDEBUG_DMA, "SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
|
||||||
nr, phys_dst);
|
nr, phys_dst);
|
||||||
/* The content of the DMA pointer is a physical address! */
|
/* The content of the DMA pointer is a physical address! */
|
||||||
dst = phys_to_virt(phys_dst);
|
dst = phys_to_virt(phys_dst);
|
||||||
DMA_PRINTK(" = virt addr %p\n", dst);
|
dprintk(NDEBUG_DMA, " = virt addr %p\n", dst);
|
||||||
for (src = (char *)&tt_scsi_dma.dma_restdata; nr != 0; --nr)
|
for (src = (char *)&tt_scsi_dma.dma_restdata; nr != 0; --nr)
|
||||||
*dst++ = *src++;
|
*dst++ = *src++;
|
||||||
}
|
}
|
||||||
|
@ -827,7 +821,7 @@ static int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
|
||||||
} else {
|
} else {
|
||||||
atari_turnon_irq(IRQ_MFP_FSCSI);
|
atari_turnon_irq(IRQ_MFP_FSCSI);
|
||||||
}
|
}
|
||||||
if ((rv & SCSI_RESET_ACTION) == SCSI_RESET_SUCCESS)
|
if (rv == SUCCESS)
|
||||||
falcon_release_lock_if_possible(hostdata);
|
falcon_release_lock_if_possible(hostdata);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -883,7 +877,7 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
|
||||||
{
|
{
|
||||||
unsigned long addr = virt_to_phys(data);
|
unsigned long addr = virt_to_phys(data);
|
||||||
|
|
||||||
DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
|
dprintk(NDEBUG_DMA, "scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, "
|
||||||
"dir = %d\n", instance->host_no, data, addr, count, dir);
|
"dir = %d\n", instance->host_no, data, addr, count, dir);
|
||||||
|
|
||||||
if (!IS_A_TT() && !STRAM_ADDR(addr)) {
|
if (!IS_A_TT() && !STRAM_ADDR(addr)) {
|
||||||
|
@ -1063,7 +1057,7 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
|
||||||
possible_len = limit;
|
possible_len = limit;
|
||||||
|
|
||||||
if (possible_len != wanted_len)
|
if (possible_len != wanted_len)
|
||||||
DMA_PRINTK("Sorry, must cut DMA transfer size to %ld bytes "
|
dprintk(NDEBUG_DMA, "Sorry, must cut DMA transfer size to %ld bytes "
|
||||||
"instead of %ld\n", possible_len, wanted_len);
|
"instead of %ld\n", possible_len, wanted_len);
|
||||||
|
|
||||||
return possible_len;
|
return possible_len;
|
||||||
|
|
|
@ -54,125 +54,6 @@
|
||||||
#define NCR5380_dma_xfer_len(i,cmd,phase) \
|
#define NCR5380_dma_xfer_len(i,cmd,phase) \
|
||||||
atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1)
|
atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1)
|
||||||
|
|
||||||
/* former generic SCSI error handling stuff */
|
|
||||||
|
|
||||||
#define SCSI_ABORT_SNOOZE 0
|
|
||||||
#define SCSI_ABORT_SUCCESS 1
|
|
||||||
#define SCSI_ABORT_PENDING 2
|
|
||||||
#define SCSI_ABORT_BUSY 3
|
|
||||||
#define SCSI_ABORT_NOT_RUNNING 4
|
|
||||||
#define SCSI_ABORT_ERROR 5
|
|
||||||
|
|
||||||
#define SCSI_RESET_SNOOZE 0
|
|
||||||
#define SCSI_RESET_PUNT 1
|
|
||||||
#define SCSI_RESET_SUCCESS 2
|
|
||||||
#define SCSI_RESET_PENDING 3
|
|
||||||
#define SCSI_RESET_WAKEUP 4
|
|
||||||
#define SCSI_RESET_NOT_RUNNING 5
|
|
||||||
#define SCSI_RESET_ERROR 6
|
|
||||||
|
|
||||||
#define SCSI_RESET_SYNCHRONOUS 0x01
|
|
||||||
#define SCSI_RESET_ASYNCHRONOUS 0x02
|
|
||||||
#define SCSI_RESET_SUGGEST_BUS_RESET 0x04
|
|
||||||
#define SCSI_RESET_SUGGEST_HOST_RESET 0x08
|
|
||||||
|
|
||||||
#define SCSI_RESET_BUS_RESET 0x100
|
|
||||||
#define SCSI_RESET_HOST_RESET 0x200
|
|
||||||
#define SCSI_RESET_ACTION 0xff
|
|
||||||
|
|
||||||
/* Debugging printk definitions:
|
|
||||||
*
|
|
||||||
* ARB -> arbitration
|
|
||||||
* ASEN -> auto-sense
|
|
||||||
* DMA -> DMA
|
|
||||||
* HSH -> PIO handshake
|
|
||||||
* INF -> information transfer
|
|
||||||
* INI -> initialization
|
|
||||||
* INT -> interrupt
|
|
||||||
* LNK -> linked commands
|
|
||||||
* MAIN -> NCR5380_main() control flow
|
|
||||||
* NDAT -> no data-out phase
|
|
||||||
* NWR -> no write commands
|
|
||||||
* PIO -> PIO transfers
|
|
||||||
* PDMA -> pseudo DMA (unused on Atari)
|
|
||||||
* QU -> queues
|
|
||||||
* RSL -> reselections
|
|
||||||
* SEL -> selections
|
|
||||||
* USL -> usleep cpde (unused on Atari)
|
|
||||||
* LBS -> last byte sent (unused on Atari)
|
|
||||||
* RSS -> restarting of selections
|
|
||||||
* EXT -> extended messages
|
|
||||||
* ABRT -> aborting and resetting
|
|
||||||
* TAG -> queue tag handling
|
|
||||||
* MER -> merging of consec. buffers
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define dprint(flg, format...) \
|
|
||||||
({ \
|
|
||||||
if (NDEBUG & (flg)) \
|
|
||||||
printk(KERN_DEBUG format); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define ARB_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_ARBITRATION, format , ## args)
|
|
||||||
#define ASEN_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_AUTOSENSE, format , ## args)
|
|
||||||
#define DMA_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_DMA, format , ## args)
|
|
||||||
#define HSH_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_HANDSHAKE, format , ## args)
|
|
||||||
#define INF_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_INFORMATION, format , ## args)
|
|
||||||
#define INI_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_INIT, format , ## args)
|
|
||||||
#define INT_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_INTR, format , ## args)
|
|
||||||
#define LNK_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_LINKED, format , ## args)
|
|
||||||
#define MAIN_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_MAIN, format , ## args)
|
|
||||||
#define NDAT_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_NO_DATAOUT, format , ## args)
|
|
||||||
#define NWR_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_NO_WRITE, format , ## args)
|
|
||||||
#define PIO_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_PIO, format , ## args)
|
|
||||||
#define PDMA_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_PSEUDO_DMA, format , ## args)
|
|
||||||
#define QU_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_QUEUES, format , ## args)
|
|
||||||
#define RSL_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_RESELECTION, format , ## args)
|
|
||||||
#define SEL_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_SELECTION, format , ## args)
|
|
||||||
#define USL_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_USLEEP, format , ## args)
|
|
||||||
#define LBS_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_LAST_BYTE_SENT, format , ## args)
|
|
||||||
#define RSS_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_RESTART_SELECT, format , ## args)
|
|
||||||
#define EXT_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_EXTENDED, format , ## args)
|
|
||||||
#define ABRT_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_ABORT, format , ## args)
|
|
||||||
#define TAG_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_TAGS, format , ## args)
|
|
||||||
#define MER_PRINTK(format, args...) \
|
|
||||||
dprint(NDEBUG_MERGING, format , ## args)
|
|
||||||
|
|
||||||
/* conditional macros for NCR5380_print_{,phase,status} */
|
|
||||||
|
|
||||||
#define NCR_PRINT(mask) \
|
|
||||||
((NDEBUG & (mask)) ? NCR5380_print(instance) : (void)0)
|
|
||||||
|
|
||||||
#define NCR_PRINT_PHASE(mask) \
|
|
||||||
((NDEBUG & (mask)) ? NCR5380_print_phase(instance) : (void)0)
|
|
||||||
|
|
||||||
#define NCR_PRINT_STATUS(mask) \
|
|
||||||
((NDEBUG & (mask)) ? NCR5380_print_status(instance) : (void)0)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ndef ASM */
|
#endif /* ndef ASM */
|
||||||
#endif /* ATARI_SCSI_H */
|
#endif /* ATARI_SCSI_H */
|
||||||
|
|
||||||
|
|
|
@ -83,9 +83,20 @@ static inline void queue_tail_inc(struct be_queue_info *q)
|
||||||
|
|
||||||
/*ISCSI */
|
/*ISCSI */
|
||||||
|
|
||||||
|
struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
|
||||||
|
bool enable;
|
||||||
|
u32 min_eqd; /* in usecs */
|
||||||
|
u32 max_eqd; /* in usecs */
|
||||||
|
u32 prev_eqd; /* in usecs */
|
||||||
|
u32 et_eqd; /* configured val when aic is off */
|
||||||
|
ulong jiffs;
|
||||||
|
u64 eq_prev; /* Used to calculate eqe */
|
||||||
|
};
|
||||||
|
|
||||||
struct be_eq_obj {
|
struct be_eq_obj {
|
||||||
bool todo_mcc_cq;
|
bool todo_mcc_cq;
|
||||||
bool todo_cq;
|
bool todo_cq;
|
||||||
|
u32 cq_count;
|
||||||
struct be_queue_info q;
|
struct be_queue_info q;
|
||||||
struct beiscsi_hba *phba;
|
struct beiscsi_hba *phba;
|
||||||
struct be_queue_info *cq;
|
struct be_queue_info *cq;
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct be_mcc_wrb {
|
||||||
#define BEISCSI_FW_MBX_TIMEOUT 100
|
#define BEISCSI_FW_MBX_TIMEOUT 100
|
||||||
|
|
||||||
/* MBOX Command VER */
|
/* MBOX Command VER */
|
||||||
|
#define MBX_CMD_VER1 0x01
|
||||||
#define MBX_CMD_VER2 0x02
|
#define MBX_CMD_VER2 0x02
|
||||||
|
|
||||||
struct be_mcc_compl {
|
struct be_mcc_compl {
|
||||||
|
@ -271,6 +272,12 @@ struct be_cmd_resp_eq_create {
|
||||||
u16 rsvd0; /* sword */
|
u16 rsvd0; /* sword */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct be_set_eqd {
|
||||||
|
u32 eq_id;
|
||||||
|
u32 phase;
|
||||||
|
u32 delay_multiplier;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct mgmt_chap_format {
|
struct mgmt_chap_format {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u8 intr_chap_name[256];
|
u8 intr_chap_name[256];
|
||||||
|
@ -622,7 +629,7 @@ struct be_cmd_req_modify_eq_delay {
|
||||||
u32 eq_id;
|
u32 eq_id;
|
||||||
u32 phase;
|
u32 phase;
|
||||||
u32 delay_multiplier;
|
u32 delay_multiplier;
|
||||||
} delay[8];
|
} delay[MAX_CPUS];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/******************** Get MAC ADDR *******************/
|
/******************** Get MAC ADDR *******************/
|
||||||
|
@ -708,6 +715,8 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
|
||||||
|
|
||||||
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
|
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
|
||||||
|
|
||||||
|
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
|
||||||
|
int num);
|
||||||
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
|
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
|
||||||
uint32_t tag, struct be_mcc_wrb **wrb,
|
uint32_t tag, struct be_mcc_wrb **wrb,
|
||||||
struct be_dma_mem *mbx_cmd_mem);
|
struct be_dma_mem *mbx_cmd_mem);
|
||||||
|
@ -1005,6 +1014,26 @@ struct tcp_connect_and_offload_in {
|
||||||
u8 rsvd0[3];
|
u8 rsvd0[3];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct tcp_connect_and_offload_in_v1 {
|
||||||
|
struct be_cmd_req_hdr hdr;
|
||||||
|
struct ip_addr_format ip_address;
|
||||||
|
u16 tcp_port;
|
||||||
|
u16 cid;
|
||||||
|
u16 cq_id;
|
||||||
|
u16 defq_id;
|
||||||
|
struct phys_addr dataout_template_pa;
|
||||||
|
u16 hdr_ring_id;
|
||||||
|
u16 data_ring_id;
|
||||||
|
u8 do_offload;
|
||||||
|
u8 ifd_state;
|
||||||
|
u8 rsvd0[2];
|
||||||
|
u16 tcp_window_size;
|
||||||
|
u8 tcp_window_scale_count;
|
||||||
|
u8 rsvd1;
|
||||||
|
u32 tcp_mss:24;
|
||||||
|
u8 rsvd2;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct tcp_connect_and_offload_out {
|
struct tcp_connect_and_offload_out {
|
||||||
struct be_cmd_resp_hdr hdr;
|
struct be_cmd_resp_hdr hdr;
|
||||||
u32 connection_handle;
|
u32 connection_handle;
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
|
||||||
struct beiscsi_hba *phba = beiscsi_ep->phba;
|
struct beiscsi_hba *phba = beiscsi_ep->phba;
|
||||||
struct tcp_connect_and_offload_out *ptcpcnct_out;
|
struct tcp_connect_and_offload_out *ptcpcnct_out;
|
||||||
struct be_dma_mem nonemb_cmd;
|
struct be_dma_mem nonemb_cmd;
|
||||||
unsigned int tag;
|
unsigned int tag, req_memsize;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
|
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
|
||||||
|
@ -1127,8 +1127,14 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
|
||||||
(beiscsi_ep->ep_cid)] = ep;
|
(beiscsi_ep->ep_cid)] = ep;
|
||||||
|
|
||||||
beiscsi_ep->cid_vld = 0;
|
beiscsi_ep->cid_vld = 0;
|
||||||
|
|
||||||
|
if (is_chip_be2_be3r(phba))
|
||||||
|
req_memsize = sizeof(struct tcp_connect_and_offload_in);
|
||||||
|
else
|
||||||
|
req_memsize = sizeof(struct tcp_connect_and_offload_in_v1);
|
||||||
|
|
||||||
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
|
nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
|
||||||
sizeof(struct tcp_connect_and_offload_in),
|
req_memsize,
|
||||||
&nonemb_cmd.dma);
|
&nonemb_cmd.dma);
|
||||||
if (nonemb_cmd.va == NULL) {
|
if (nonemb_cmd.va == NULL) {
|
||||||
|
|
||||||
|
@ -1139,7 +1145,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
|
||||||
beiscsi_free_ep(beiscsi_ep);
|
beiscsi_free_ep(beiscsi_ep);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
|
nonemb_cmd.size = req_memsize;
|
||||||
memset(nonemb_cmd.va, 0, nonemb_cmd.size);
|
memset(nonemb_cmd.va, 0, nonemb_cmd.size);
|
||||||
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
|
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
|
||||||
if (tag <= 0) {
|
if (tag <= 0) {
|
||||||
|
|
|
@ -599,15 +599,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
|
||||||
pci_set_drvdata(pcidev, phba);
|
pci_set_drvdata(pcidev, phba);
|
||||||
phba->interface_handle = 0xFFFFFFFF;
|
phba->interface_handle = 0xFFFFFFFF;
|
||||||
|
|
||||||
if (iscsi_host_add(shost, &phba->pcidev->dev))
|
|
||||||
goto free_devices;
|
|
||||||
|
|
||||||
return phba;
|
return phba;
|
||||||
|
|
||||||
free_devices:
|
|
||||||
pci_dev_put(phba->pcidev);
|
|
||||||
iscsi_host_free(phba->shost);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void beiscsi_unmap_pci_function(struct beiscsi_hba *phba)
|
static void beiscsi_unmap_pci_function(struct beiscsi_hba *phba)
|
||||||
|
@ -2279,6 +2271,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
|
||||||
|
|
||||||
pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
|
pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
|
||||||
ret = beiscsi_process_cq(pbe_eq);
|
ret = beiscsi_process_cq(pbe_eq);
|
||||||
|
pbe_eq->cq_count += ret;
|
||||||
if (ret < budget) {
|
if (ret < budget) {
|
||||||
phba = pbe_eq->phba;
|
phba = pbe_eq->phba;
|
||||||
blk_iopoll_complete(iop);
|
blk_iopoll_complete(iop);
|
||||||
|
@ -3692,7 +3685,7 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
|
||||||
struct hwi_controller *phwi_ctrlr;
|
struct hwi_controller *phwi_ctrlr;
|
||||||
struct hwi_context_memory *phwi_context;
|
struct hwi_context_memory *phwi_context;
|
||||||
struct hwi_async_pdu_context *pasync_ctx;
|
struct hwi_async_pdu_context *pasync_ctx;
|
||||||
int i, eq_num, ulp_num;
|
int i, eq_for_mcc, ulp_num;
|
||||||
|
|
||||||
phwi_ctrlr = phba->phwi_ctrlr;
|
phwi_ctrlr = phba->phwi_ctrlr;
|
||||||
phwi_context = phwi_ctrlr->phwi_ctxt;
|
phwi_context = phwi_ctrlr->phwi_ctxt;
|
||||||
|
@ -3729,16 +3722,17 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
|
||||||
if (q->created)
|
if (q->created)
|
||||||
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
|
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
be_mcc_queues_destroy(phba);
|
||||||
if (phba->msix_enabled)
|
if (phba->msix_enabled)
|
||||||
eq_num = 1;
|
eq_for_mcc = 1;
|
||||||
else
|
else
|
||||||
eq_num = 0;
|
eq_for_mcc = 0;
|
||||||
for (i = 0; i < (phba->num_cpus + eq_num); i++) {
|
for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
|
||||||
q = &phwi_context->be_eq[i].q;
|
q = &phwi_context->be_eq[i].q;
|
||||||
if (q->created)
|
if (q->created)
|
||||||
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
|
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
|
||||||
}
|
}
|
||||||
be_mcc_queues_destroy(phba);
|
|
||||||
be_cmd_fw_uninit(ctrl);
|
be_cmd_fw_uninit(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3833,9 +3827,9 @@ static int hwi_init_port(struct beiscsi_hba *phba)
|
||||||
|
|
||||||
phwi_ctrlr = phba->phwi_ctrlr;
|
phwi_ctrlr = phba->phwi_ctrlr;
|
||||||
phwi_context = phwi_ctrlr->phwi_ctxt;
|
phwi_context = phwi_ctrlr->phwi_ctxt;
|
||||||
phwi_context->max_eqd = 0;
|
phwi_context->max_eqd = 128;
|
||||||
phwi_context->min_eqd = 0;
|
phwi_context->min_eqd = 0;
|
||||||
phwi_context->cur_eqd = 64;
|
phwi_context->cur_eqd = 0;
|
||||||
be_cmd_fw_initialize(&phba->ctrl);
|
be_cmd_fw_initialize(&phba->ctrl);
|
||||||
|
|
||||||
status = beiscsi_create_eqs(phba, phwi_context);
|
status = beiscsi_create_eqs(phba, phwi_context);
|
||||||
|
@ -5290,6 +5284,57 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void be_eqd_update(struct beiscsi_hba *phba)
|
||||||
|
{
|
||||||
|
struct be_set_eqd set_eqd[MAX_CPUS];
|
||||||
|
struct be_aic_obj *aic;
|
||||||
|
struct be_eq_obj *pbe_eq;
|
||||||
|
struct hwi_controller *phwi_ctrlr;
|
||||||
|
struct hwi_context_memory *phwi_context;
|
||||||
|
int eqd, i, num = 0;
|
||||||
|
ulong now;
|
||||||
|
u32 pps, delta;
|
||||||
|
unsigned int tag;
|
||||||
|
|
||||||
|
phwi_ctrlr = phba->phwi_ctrlr;
|
||||||
|
phwi_context = phwi_ctrlr->phwi_ctxt;
|
||||||
|
|
||||||
|
for (i = 0; i <= phba->num_cpus; i++) {
|
||||||
|
aic = &phba->aic_obj[i];
|
||||||
|
pbe_eq = &phwi_context->be_eq[i];
|
||||||
|
now = jiffies;
|
||||||
|
if (!aic->jiffs || time_before(now, aic->jiffs) ||
|
||||||
|
pbe_eq->cq_count < aic->eq_prev) {
|
||||||
|
aic->jiffs = now;
|
||||||
|
aic->eq_prev = pbe_eq->cq_count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
delta = jiffies_to_msecs(now - aic->jiffs);
|
||||||
|
pps = (((u32)(pbe_eq->cq_count - aic->eq_prev) * 1000) / delta);
|
||||||
|
eqd = (pps / 1500) << 2;
|
||||||
|
|
||||||
|
if (eqd < 8)
|
||||||
|
eqd = 0;
|
||||||
|
eqd = min_t(u32, eqd, phwi_context->max_eqd);
|
||||||
|
eqd = max_t(u32, eqd, phwi_context->min_eqd);
|
||||||
|
|
||||||
|
aic->jiffs = now;
|
||||||
|
aic->eq_prev = pbe_eq->cq_count;
|
||||||
|
|
||||||
|
if (eqd != aic->prev_eqd) {
|
||||||
|
set_eqd[num].delay_multiplier = (eqd * 65)/100;
|
||||||
|
set_eqd[num].eq_id = pbe_eq->q.id;
|
||||||
|
aic->prev_eqd = eqd;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num) {
|
||||||
|
tag = be_cmd_modify_eq_delay(phba, set_eqd, num);
|
||||||
|
if (tag)
|
||||||
|
beiscsi_mccq_compl(phba, tag, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* beiscsi_hw_health_check()- Check adapter health
|
* beiscsi_hw_health_check()- Check adapter health
|
||||||
* @work: work item to check HW health
|
* @work: work item to check HW health
|
||||||
|
@ -5303,6 +5348,8 @@ beiscsi_hw_health_check(struct work_struct *work)
|
||||||
container_of(work, struct beiscsi_hba,
|
container_of(work, struct beiscsi_hba,
|
||||||
beiscsi_hw_check_task.work);
|
beiscsi_hw_check_task.work);
|
||||||
|
|
||||||
|
be_eqd_update(phba);
|
||||||
|
|
||||||
beiscsi_ue_detect(phba);
|
beiscsi_ue_detect(phba);
|
||||||
|
|
||||||
schedule_delayed_work(&phba->beiscsi_hw_check_task,
|
schedule_delayed_work(&phba->beiscsi_hw_check_task,
|
||||||
|
@ -5579,7 +5626,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
phba->ctrl.mcc_numtag[i + 1] = 0;
|
phba->ctrl.mcc_numtag[i + 1] = 0;
|
||||||
phba->ctrl.mcc_tag_available++;
|
phba->ctrl.mcc_tag_available++;
|
||||||
memset(&phba->ctrl.ptag_state[i].tag_mem_state, 0,
|
memset(&phba->ctrl.ptag_state[i].tag_mem_state, 0,
|
||||||
sizeof(struct beiscsi_mcc_tag_state));
|
sizeof(struct be_dma_mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
|
phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
|
||||||
|
@ -5621,6 +5668,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
|
||||||
}
|
}
|
||||||
hwi_enable_intr(phba);
|
hwi_enable_intr(phba);
|
||||||
|
|
||||||
|
if (iscsi_host_add(phba->shost, &phba->pcidev->dev))
|
||||||
|
goto free_blkenbld;
|
||||||
|
|
||||||
if (beiscsi_setup_boot_info(phba))
|
if (beiscsi_setup_boot_info(phba))
|
||||||
/*
|
/*
|
||||||
* log error but continue, because we may not be using
|
* log error but continue, because we may not be using
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include <scsi/scsi_transport_iscsi.h>
|
#include <scsi/scsi_transport_iscsi.h>
|
||||||
|
|
||||||
#define DRV_NAME "be2iscsi"
|
#define DRV_NAME "be2iscsi"
|
||||||
#define BUILD_STR "10.2.125.0"
|
#define BUILD_STR "10.2.273.0"
|
||||||
#define BE_NAME "Emulex OneConnect" \
|
#define BE_NAME "Emulex OneConnect" \
|
||||||
"Open-iSCSI Driver version" BUILD_STR
|
"Open-iSCSI Driver version" BUILD_STR
|
||||||
#define DRV_DESC BE_NAME " " "Driver"
|
#define DRV_DESC BE_NAME " " "Driver"
|
||||||
|
@ -71,8 +71,8 @@
|
||||||
|
|
||||||
#define BEISCSI_SGLIST_ELEMENTS 30
|
#define BEISCSI_SGLIST_ELEMENTS 30
|
||||||
|
|
||||||
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
|
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
|
||||||
#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */
|
#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */
|
||||||
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
|
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
|
||||||
|
|
||||||
#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
|
#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
|
||||||
|
@ -427,6 +427,7 @@ struct beiscsi_hba {
|
||||||
struct mgmt_session_info boot_sess;
|
struct mgmt_session_info boot_sess;
|
||||||
struct invalidate_command_table inv_tbl[128];
|
struct invalidate_command_table inv_tbl[128];
|
||||||
|
|
||||||
|
struct be_aic_obj aic_obj[MAX_CPUS];
|
||||||
unsigned int attr_log_enable;
|
unsigned int attr_log_enable;
|
||||||
int (*iotask_fn)(struct iscsi_task *,
|
int (*iotask_fn)(struct iscsi_task *,
|
||||||
struct scatterlist *sg,
|
struct scatterlist *sg,
|
||||||
|
|
|
@ -155,6 +155,43 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
|
||||||
|
struct be_set_eqd *set_eqd, int num)
|
||||||
|
{
|
||||||
|
struct be_ctrl_info *ctrl = &phba->ctrl;
|
||||||
|
struct be_mcc_wrb *wrb;
|
||||||
|
struct be_cmd_req_modify_eq_delay *req;
|
||||||
|
unsigned int tag = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
spin_lock(&ctrl->mbox_lock);
|
||||||
|
tag = alloc_mcc_tag(phba);
|
||||||
|
if (!tag) {
|
||||||
|
spin_unlock(&ctrl->mbox_lock);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrb = wrb_from_mccq(phba);
|
||||||
|
req = embedded_payload(wrb);
|
||||||
|
|
||||||
|
wrb->tag0 |= tag;
|
||||||
|
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
|
||||||
|
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||||
|
OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
|
||||||
|
|
||||||
|
req->num_eq = cpu_to_le32(num);
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
|
||||||
|
req->delay[i].phase = 0;
|
||||||
|
req->delay[i].delay_multiplier =
|
||||||
|
cpu_to_le32(set_eqd[i].delay_multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
be_mcc_notify(phba);
|
||||||
|
spin_unlock(&ctrl->mbox_lock);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mgmt_reopen_session()- Reopen a session based on reopen_type
|
* mgmt_reopen_session()- Reopen a session based on reopen_type
|
||||||
* @phba: Device priv structure instance
|
* @phba: Device priv structure instance
|
||||||
|
@ -447,8 +484,8 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
|
||||||
struct be_dma_mem *nonemb_cmd)
|
struct be_dma_mem *nonemb_cmd)
|
||||||
{
|
{
|
||||||
struct be_cmd_resp_hdr *resp;
|
struct be_cmd_resp_hdr *resp;
|
||||||
struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
|
struct be_mcc_wrb *wrb;
|
||||||
struct be_sge *mcc_sge = nonembedded_sgl(wrb);
|
struct be_sge *mcc_sge;
|
||||||
unsigned int tag = 0;
|
unsigned int tag = 0;
|
||||||
struct iscsi_bsg_request *bsg_req = job->request;
|
struct iscsi_bsg_request *bsg_req = job->request;
|
||||||
struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
|
struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
|
||||||
|
@ -465,7 +502,6 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
|
||||||
req->sector = sector;
|
req->sector = sector;
|
||||||
req->offset = offset;
|
req->offset = offset;
|
||||||
spin_lock(&ctrl->mbox_lock);
|
spin_lock(&ctrl->mbox_lock);
|
||||||
memset(wrb, 0, sizeof(*wrb));
|
|
||||||
|
|
||||||
switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
|
switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
|
||||||
case BEISCSI_WRITE_FLASH:
|
case BEISCSI_WRITE_FLASH:
|
||||||
|
@ -495,6 +531,8 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wrb = wrb_from_mccq(phba);
|
||||||
|
mcc_sge = nonembedded_sgl(wrb);
|
||||||
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
|
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
|
||||||
job->request_payload.sg_cnt);
|
job->request_payload.sg_cnt);
|
||||||
mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
|
mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
|
||||||
|
@ -525,7 +563,6 @@ int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
spin_lock(&ctrl->mbox_lock);
|
spin_lock(&ctrl->mbox_lock);
|
||||||
memset(wrb, 0, sizeof(*wrb));
|
|
||||||
|
|
||||||
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
|
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
|
||||||
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
|
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
|
||||||
|
@ -675,7 +712,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
|
||||||
struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
|
struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
|
||||||
struct be_ctrl_info *ctrl = &phba->ctrl;
|
struct be_ctrl_info *ctrl = &phba->ctrl;
|
||||||
struct be_mcc_wrb *wrb;
|
struct be_mcc_wrb *wrb;
|
||||||
struct tcp_connect_and_offload_in *req;
|
struct tcp_connect_and_offload_in_v1 *req;
|
||||||
unsigned short def_hdr_id;
|
unsigned short def_hdr_id;
|
||||||
unsigned short def_data_id;
|
unsigned short def_data_id;
|
||||||
struct phys_addr template_address = { 0, 0 };
|
struct phys_addr template_address = { 0, 0 };
|
||||||
|
@ -702,17 +739,16 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
wrb = wrb_from_mccq(phba);
|
wrb = wrb_from_mccq(phba);
|
||||||
memset(wrb, 0, sizeof(*wrb));
|
|
||||||
sge = nonembedded_sgl(wrb);
|
sge = nonembedded_sgl(wrb);
|
||||||
|
|
||||||
req = nonemb_cmd->va;
|
req = nonemb_cmd->va;
|
||||||
memset(req, 0, sizeof(*req));
|
memset(req, 0, sizeof(*req));
|
||||||
wrb->tag0 |= tag;
|
wrb->tag0 |= tag;
|
||||||
|
|
||||||
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
|
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
|
||||||
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
|
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
|
||||||
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
|
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
|
||||||
sizeof(*req));
|
nonemb_cmd->size);
|
||||||
if (dst_addr->sa_family == PF_INET) {
|
if (dst_addr->sa_family == PF_INET) {
|
||||||
__be32 s_addr = daddr_in->sin_addr.s_addr;
|
__be32 s_addr = daddr_in->sin_addr.s_addr;
|
||||||
req->ip_address.ip_type = BE2_IPV4;
|
req->ip_address.ip_type = BE2_IPV4;
|
||||||
|
@ -758,6 +794,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
|
||||||
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
|
sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
|
||||||
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
|
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
|
||||||
sge->len = cpu_to_le32(nonemb_cmd->size);
|
sge->len = cpu_to_le32(nonemb_cmd->size);
|
||||||
|
|
||||||
|
if (!is_chip_be2_be3r(phba)) {
|
||||||
|
req->hdr.version = MBX_CMD_VER1;
|
||||||
|
req->tcp_window_size = 0;
|
||||||
|
req->tcp_window_scale_count = 2;
|
||||||
|
}
|
||||||
|
|
||||||
be_mcc_notify(phba);
|
be_mcc_notify(phba);
|
||||||
spin_unlock(&ctrl->mbox_lock);
|
spin_unlock(&ctrl->mbox_lock);
|
||||||
return tag;
|
return tag;
|
||||||
|
@ -804,7 +847,7 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
|
||||||
int resp_buf_len)
|
int resp_buf_len)
|
||||||
{
|
{
|
||||||
struct be_ctrl_info *ctrl = &phba->ctrl;
|
struct be_ctrl_info *ctrl = &phba->ctrl;
|
||||||
struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
|
struct be_mcc_wrb *wrb;
|
||||||
struct be_sge *sge;
|
struct be_sge *sge;
|
||||||
unsigned int tag;
|
unsigned int tag;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
@ -816,7 +859,8 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto free_cmd;
|
goto free_cmd;
|
||||||
}
|
}
|
||||||
memset(wrb, 0, sizeof(*wrb));
|
|
||||||
|
wrb = wrb_from_mccq(phba);
|
||||||
wrb->tag0 |= tag;
|
wrb->tag0 |= tag;
|
||||||
sge = nonembedded_sgl(wrb);
|
sge = nonembedded_sgl(wrb);
|
||||||
|
|
||||||
|
|
|
@ -335,5 +335,7 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
|
||||||
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
|
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
|
||||||
struct wrb_handle *pwrb_handle);
|
struct wrb_handle *pwrb_handle);
|
||||||
void beiscsi_ue_detect(struct beiscsi_hba *phba);
|
void beiscsi_ue_detect(struct beiscsi_hba *phba);
|
||||||
|
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
|
||||||
|
struct be_set_eqd *, int num);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -507,7 +507,7 @@ bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
|
||||||
struct bfad_vport_s *vport;
|
struct bfad_vport_s *vport;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
|
vport = kzalloc(sizeof(struct bfad_vport_s), GFP_ATOMIC);
|
||||||
if (!vport) {
|
if (!vport) {
|
||||||
bfa_trc(bfad, 0);
|
bfa_trc(bfad, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1966,26 +1966,29 @@ static void bnx2fc_free_hash_table(struct bnx2fc_hba *hba)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int segment_count;
|
int segment_count;
|
||||||
int hash_table_size;
|
|
||||||
u32 *pbl;
|
u32 *pbl;
|
||||||
|
|
||||||
segment_count = hba->hash_tbl_segment_count;
|
if (hba->hash_tbl_segments) {
|
||||||
hash_table_size = BNX2FC_NUM_MAX_SESS * BNX2FC_MAX_ROWS_IN_HASH_TBL *
|
|
||||||
sizeof(struct fcoe_hash_table_entry);
|
|
||||||
|
|
||||||
pbl = hba->hash_tbl_pbl;
|
pbl = hba->hash_tbl_pbl;
|
||||||
for (i = 0; i < segment_count; ++i) {
|
if (pbl) {
|
||||||
dma_addr_t dma_address;
|
segment_count = hba->hash_tbl_segment_count;
|
||||||
|
for (i = 0; i < segment_count; ++i) {
|
||||||
|
dma_addr_t dma_address;
|
||||||
|
|
||||||
dma_address = le32_to_cpu(*pbl);
|
dma_address = le32_to_cpu(*pbl);
|
||||||
++pbl;
|
++pbl;
|
||||||
dma_address += ((u64)le32_to_cpu(*pbl)) << 32;
|
dma_address += ((u64)le32_to_cpu(*pbl)) << 32;
|
||||||
++pbl;
|
++pbl;
|
||||||
dma_free_coherent(&hba->pcidev->dev,
|
dma_free_coherent(&hba->pcidev->dev,
|
||||||
BNX2FC_HASH_TBL_CHUNK_SIZE,
|
BNX2FC_HASH_TBL_CHUNK_SIZE,
|
||||||
hba->hash_tbl_segments[i],
|
hba->hash_tbl_segments[i],
|
||||||
dma_address);
|
dma_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(hba->hash_tbl_segments);
|
||||||
|
hba->hash_tbl_segments = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hba->hash_tbl_pbl) {
|
if (hba->hash_tbl_pbl) {
|
||||||
|
@ -2023,7 +2026,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
|
||||||
dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL);
|
dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL);
|
||||||
if (!dma_segment_array) {
|
if (!dma_segment_array) {
|
||||||
printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
|
printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
|
||||||
return -ENOMEM;
|
goto cleanup_ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < segment_count; ++i) {
|
for (i = 0; i < segment_count; ++i) {
|
||||||
|
@ -2034,15 +2037,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!hba->hash_tbl_segments[i]) {
|
if (!hba->hash_tbl_segments[i]) {
|
||||||
printk(KERN_ERR PFX "hash segment alloc failed\n");
|
printk(KERN_ERR PFX "hash segment alloc failed\n");
|
||||||
while (--i >= 0) {
|
goto cleanup_dma;
|
||||||
dma_free_coherent(&hba->pcidev->dev,
|
|
||||||
BNX2FC_HASH_TBL_CHUNK_SIZE,
|
|
||||||
hba->hash_tbl_segments[i],
|
|
||||||
dma_segment_array[i]);
|
|
||||||
hba->hash_tbl_segments[i] = NULL;
|
|
||||||
}
|
|
||||||
kfree(dma_segment_array);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
memset(hba->hash_tbl_segments[i], 0,
|
memset(hba->hash_tbl_segments[i], 0,
|
||||||
BNX2FC_HASH_TBL_CHUNK_SIZE);
|
BNX2FC_HASH_TBL_CHUNK_SIZE);
|
||||||
|
@ -2054,8 +2049,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!hba->hash_tbl_pbl) {
|
if (!hba->hash_tbl_pbl) {
|
||||||
printk(KERN_ERR PFX "hash table pbl alloc failed\n");
|
printk(KERN_ERR PFX "hash table pbl alloc failed\n");
|
||||||
kfree(dma_segment_array);
|
goto cleanup_dma;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
memset(hba->hash_tbl_pbl, 0, PAGE_SIZE);
|
memset(hba->hash_tbl_pbl, 0, PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -2080,6 +2074,22 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
|
||||||
}
|
}
|
||||||
kfree(dma_segment_array);
|
kfree(dma_segment_array);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
cleanup_dma:
|
||||||
|
for (i = 0; i < segment_count; ++i) {
|
||||||
|
if (hba->hash_tbl_segments[i])
|
||||||
|
dma_free_coherent(&hba->pcidev->dev,
|
||||||
|
BNX2FC_HASH_TBL_CHUNK_SIZE,
|
||||||
|
hba->hash_tbl_segments[i],
|
||||||
|
dma_segment_array[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(dma_segment_array);
|
||||||
|
|
||||||
|
cleanup_ht:
|
||||||
|
kfree(hba->hash_tbl_segments);
|
||||||
|
hba->hash_tbl_segments = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#define PSEUDO_DMA
|
#define PSEUDO_DMA
|
||||||
#define DONT_USE_INTR
|
#define DONT_USE_INTR
|
||||||
#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
|
#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
|
||||||
#define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
|
|
||||||
NDEBUG_SELECTION+NDEBUG_ARBITRATION)
|
|
||||||
#define DMA_WORKS_RIGHT
|
#define DMA_WORKS_RIGHT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@ static int esas2r_probe(struct pci_dev *pcid,
|
||||||
esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev),
|
esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev),
|
||||||
"pci_enable_device() OK");
|
"pci_enable_device() OK");
|
||||||
esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev),
|
esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev),
|
||||||
"after pci_device_enable() enable_cnt: %d",
|
"after pci_enable_device() enable_cnt: %d",
|
||||||
pcid->enable_cnt.counter);
|
pcid->enable_cnt.counter);
|
||||||
|
|
||||||
host = scsi_host_alloc(&driver_template, host_alloc_size);
|
host = scsi_host_alloc(&driver_template, host_alloc_size);
|
||||||
|
|
|
@ -39,14 +39,15 @@
|
||||||
|
|
||||||
#define DRV_NAME "fnic"
|
#define DRV_NAME "fnic"
|
||||||
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
|
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
|
||||||
#define DRV_VERSION "1.5.0.45"
|
#define DRV_VERSION "1.6.0.10"
|
||||||
#define PFX DRV_NAME ": "
|
#define PFX DRV_NAME ": "
|
||||||
#define DFX DRV_NAME "%d: "
|
#define DFX DRV_NAME "%d: "
|
||||||
|
|
||||||
#define DESC_CLEAN_LOW_WATERMARK 8
|
#define DESC_CLEAN_LOW_WATERMARK 8
|
||||||
#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD 16 /* UCSM default throttle count */
|
#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD 16 /* UCSM default throttle count */
|
||||||
#define FNIC_MIN_IO_REQ 256 /* Min IO throttle count */
|
#define FNIC_MIN_IO_REQ 256 /* Min IO throttle count */
|
||||||
#define FNIC_MAX_IO_REQ 2048 /* scsi_cmnd tag map entries */
|
#define FNIC_MAX_IO_REQ 1024 /* scsi_cmnd tag map entries */
|
||||||
|
#define FNIC_DFLT_IO_REQ 256 /* Default scsi_cmnd tag map entries */
|
||||||
#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */
|
#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */
|
||||||
#define FNIC_DFLT_QUEUE_DEPTH 32
|
#define FNIC_DFLT_QUEUE_DEPTH 32
|
||||||
#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
|
#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */
|
||||||
|
|
|
@ -25,6 +25,21 @@ static struct dentry *fnic_trace_debugfs_file;
|
||||||
static struct dentry *fnic_trace_enable;
|
static struct dentry *fnic_trace_enable;
|
||||||
static struct dentry *fnic_stats_debugfs_root;
|
static struct dentry *fnic_stats_debugfs_root;
|
||||||
|
|
||||||
|
static struct dentry *fnic_fc_trace_debugfs_file;
|
||||||
|
static struct dentry *fnic_fc_rdata_trace_debugfs_file;
|
||||||
|
static struct dentry *fnic_fc_trace_enable;
|
||||||
|
static struct dentry *fnic_fc_trace_clear;
|
||||||
|
|
||||||
|
struct fc_trace_flag_type {
|
||||||
|
u8 fc_row_file;
|
||||||
|
u8 fc_normal_file;
|
||||||
|
u8 fnic_trace;
|
||||||
|
u8 fc_trace;
|
||||||
|
u8 fc_clear;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fc_trace_flag_type *fc_trc_flag;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_debugfs_init - Initialize debugfs for fnic debug logging
|
* fnic_debugfs_init - Initialize debugfs for fnic debug logging
|
||||||
*
|
*
|
||||||
|
@ -56,6 +71,18 @@ int fnic_debugfs_init(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate memory to structure */
|
||||||
|
fc_trc_flag = (struct fc_trace_flag_type *)
|
||||||
|
vmalloc(sizeof(struct fc_trace_flag_type));
|
||||||
|
|
||||||
|
if (fc_trc_flag) {
|
||||||
|
fc_trc_flag->fc_row_file = 0;
|
||||||
|
fc_trc_flag->fc_normal_file = 1;
|
||||||
|
fc_trc_flag->fnic_trace = 2;
|
||||||
|
fc_trc_flag->fc_trace = 3;
|
||||||
|
fc_trc_flag->fc_clear = 4;
|
||||||
|
}
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -74,15 +101,19 @@ void fnic_debugfs_terminate(void)
|
||||||
|
|
||||||
debugfs_remove(fnic_trace_debugfs_root);
|
debugfs_remove(fnic_trace_debugfs_root);
|
||||||
fnic_trace_debugfs_root = NULL;
|
fnic_trace_debugfs_root = NULL;
|
||||||
|
|
||||||
|
if (fc_trc_flag)
|
||||||
|
vfree(fc_trc_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_trace_ctrl_open - Open the trace_enable file
|
* fnic_trace_ctrl_open - Open the trace_enable file for fnic_trace
|
||||||
|
* Or Open fc_trace_enable file for fc_trace
|
||||||
* @inode: The inode pointer.
|
* @inode: The inode pointer.
|
||||||
* @file: The file pointer to attach the trace enable/disable flag.
|
* @file: The file pointer to attach the trace enable/disable flag.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This routine opens a debugsfs file trace_enable.
|
* This routine opens a debugsfs file trace_enable or fc_trace_enable.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* This function returns zero if successful.
|
* This function returns zero if successful.
|
||||||
|
@ -94,15 +125,19 @@ static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_trace_ctrl_read - Read a trace_enable debugfs file
|
* fnic_trace_ctrl_read -
|
||||||
|
* Read trace_enable ,fc_trace_enable
|
||||||
|
* or fc_trace_clear debugfs file
|
||||||
* @filp: The file pointer to read from.
|
* @filp: The file pointer to read from.
|
||||||
* @ubuf: The buffer to copy the data to.
|
* @ubuf: The buffer to copy the data to.
|
||||||
* @cnt: The number of bytes to read.
|
* @cnt: The number of bytes to read.
|
||||||
* @ppos: The position in the file to start reading from.
|
* @ppos: The position in the file to start reading from.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This routine reads value of variable fnic_tracing_enabled
|
* This routine reads value of variable fnic_tracing_enabled or
|
||||||
* and stores into local @buf. It will start reading file at @ppos and
|
* fnic_fc_tracing_enabled or fnic_fc_trace_cleared
|
||||||
|
* and stores into local @buf.
|
||||||
|
* It will start reading file at @ppos and
|
||||||
* copy up to @cnt of data to @ubuf from @buf.
|
* copy up to @cnt of data to @ubuf from @buf.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
@ -114,13 +149,25 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int len;
|
int len;
|
||||||
len = sprintf(buf, "%u\n", fnic_tracing_enabled);
|
u8 *trace_type;
|
||||||
|
len = 0;
|
||||||
|
trace_type = (u8 *)filp->private_data;
|
||||||
|
if (*trace_type == fc_trc_flag->fnic_trace)
|
||||||
|
len = sprintf(buf, "%u\n", fnic_tracing_enabled);
|
||||||
|
else if (*trace_type == fc_trc_flag->fc_trace)
|
||||||
|
len = sprintf(buf, "%u\n", fnic_fc_tracing_enabled);
|
||||||
|
else if (*trace_type == fc_trc_flag->fc_clear)
|
||||||
|
len = sprintf(buf, "%u\n", fnic_fc_trace_cleared);
|
||||||
|
else
|
||||||
|
pr_err("fnic: Cannot read to any debugfs file\n");
|
||||||
|
|
||||||
return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
|
return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_trace_ctrl_write - Write to trace_enable debugfs file
|
* fnic_trace_ctrl_write -
|
||||||
|
* Write to trace_enable, fc_trace_enable or
|
||||||
|
* fc_trace_clear debugfs file
|
||||||
* @filp: The file pointer to write from.
|
* @filp: The file pointer to write from.
|
||||||
* @ubuf: The buffer to copy the data from.
|
* @ubuf: The buffer to copy the data from.
|
||||||
* @cnt: The number of bytes to write.
|
* @cnt: The number of bytes to write.
|
||||||
|
@ -128,7 +175,8 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This routine writes data from user buffer @ubuf to buffer @buf and
|
* This routine writes data from user buffer @ubuf to buffer @buf and
|
||||||
* sets fnic_tracing_enabled value as per user input.
|
* sets fc_trace_enable ,tracing_enable or fnic_fc_trace_cleared
|
||||||
|
* value as per user input.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* This function returns the amount of data that was written.
|
* This function returns the amount of data that was written.
|
||||||
|
@ -140,6 +188,8 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
|
||||||
char buf[64];
|
char buf[64];
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int ret;
|
int ret;
|
||||||
|
u8 *trace_type;
|
||||||
|
trace_type = (u8 *)filp->private_data;
|
||||||
|
|
||||||
if (cnt >= sizeof(buf))
|
if (cnt >= sizeof(buf))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -153,12 +203,27 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fnic_tracing_enabled = val;
|
if (*trace_type == fc_trc_flag->fnic_trace)
|
||||||
|
fnic_tracing_enabled = val;
|
||||||
|
else if (*trace_type == fc_trc_flag->fc_trace)
|
||||||
|
fnic_fc_tracing_enabled = val;
|
||||||
|
else if (*trace_type == fc_trc_flag->fc_clear)
|
||||||
|
fnic_fc_trace_cleared = val;
|
||||||
|
else
|
||||||
|
pr_err("fnic: cannot write to any debufs file\n");
|
||||||
|
|
||||||
(*ppos)++;
|
(*ppos)++;
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations fnic_trace_ctrl_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = fnic_trace_ctrl_open,
|
||||||
|
.read = fnic_trace_ctrl_read,
|
||||||
|
.write = fnic_trace_ctrl_write,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_trace_debugfs_open - Open the fnic trace log
|
* fnic_trace_debugfs_open - Open the fnic trace log
|
||||||
* @inode: The inode pointer
|
* @inode: The inode pointer
|
||||||
|
@ -178,19 +243,36 @@ static int fnic_trace_debugfs_open(struct inode *inode,
|
||||||
struct file *file)
|
struct file *file)
|
||||||
{
|
{
|
||||||
fnic_dbgfs_t *fnic_dbg_prt;
|
fnic_dbgfs_t *fnic_dbg_prt;
|
||||||
|
u8 *rdata_ptr;
|
||||||
|
rdata_ptr = (u8 *)inode->i_private;
|
||||||
fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
|
fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
|
||||||
if (!fnic_dbg_prt)
|
if (!fnic_dbg_prt)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
fnic_dbg_prt->buffer = vmalloc((3*(trace_max_pages * PAGE_SIZE)));
|
if (*rdata_ptr == fc_trc_flag->fnic_trace) {
|
||||||
if (!fnic_dbg_prt->buffer) {
|
fnic_dbg_prt->buffer = vmalloc(3 *
|
||||||
kfree(fnic_dbg_prt);
|
(trace_max_pages * PAGE_SIZE));
|
||||||
return -ENOMEM;
|
if (!fnic_dbg_prt->buffer) {
|
||||||
|
kfree(fnic_dbg_prt);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memset((void *)fnic_dbg_prt->buffer, 0,
|
||||||
|
3 * (trace_max_pages * PAGE_SIZE));
|
||||||
|
fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
|
||||||
|
} else {
|
||||||
|
fnic_dbg_prt->buffer =
|
||||||
|
vmalloc(3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
|
||||||
|
if (!fnic_dbg_prt->buffer) {
|
||||||
|
kfree(fnic_dbg_prt);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memset((void *)fnic_dbg_prt->buffer, 0,
|
||||||
|
3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
|
||||||
|
fnic_dbg_prt->buffer_len =
|
||||||
|
fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr);
|
||||||
}
|
}
|
||||||
memset((void *)fnic_dbg_prt->buffer, 0,
|
|
||||||
(3*(trace_max_pages * PAGE_SIZE)));
|
|
||||||
fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
|
|
||||||
file->private_data = fnic_dbg_prt;
|
file->private_data = fnic_dbg_prt;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,13 +354,6 @@ static int fnic_trace_debugfs_release(struct inode *inode,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations fnic_trace_ctrl_fops = {
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.open = fnic_trace_ctrl_open,
|
|
||||||
.read = fnic_trace_ctrl_read,
|
|
||||||
.write = fnic_trace_ctrl_write,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct file_operations fnic_trace_debugfs_fops = {
|
static const struct file_operations fnic_trace_debugfs_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = fnic_trace_debugfs_open,
|
.open = fnic_trace_debugfs_open,
|
||||||
|
@ -306,9 +381,10 @@ int fnic_trace_debugfs_init(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
fnic_trace_enable = debugfs_create_file("tracing_enable",
|
fnic_trace_enable = debugfs_create_file("tracing_enable",
|
||||||
S_IFREG|S_IRUGO|S_IWUSR,
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
fnic_trace_debugfs_root,
|
fnic_trace_debugfs_root,
|
||||||
NULL, &fnic_trace_ctrl_fops);
|
&(fc_trc_flag->fnic_trace),
|
||||||
|
&fnic_trace_ctrl_fops);
|
||||||
|
|
||||||
if (!fnic_trace_enable) {
|
if (!fnic_trace_enable) {
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
|
@ -317,10 +393,10 @@ int fnic_trace_debugfs_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
fnic_trace_debugfs_file = debugfs_create_file("trace",
|
fnic_trace_debugfs_file = debugfs_create_file("trace",
|
||||||
S_IFREG|S_IRUGO|S_IWUSR,
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
fnic_trace_debugfs_root,
|
fnic_trace_debugfs_root,
|
||||||
NULL,
|
&(fc_trc_flag->fnic_trace),
|
||||||
&fnic_trace_debugfs_fops);
|
&fnic_trace_debugfs_fops);
|
||||||
|
|
||||||
if (!fnic_trace_debugfs_file) {
|
if (!fnic_trace_debugfs_file) {
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
|
@ -340,14 +416,104 @@ int fnic_trace_debugfs_init(void)
|
||||||
*/
|
*/
|
||||||
void fnic_trace_debugfs_terminate(void)
|
void fnic_trace_debugfs_terminate(void)
|
||||||
{
|
{
|
||||||
if (fnic_trace_debugfs_file) {
|
debugfs_remove(fnic_trace_debugfs_file);
|
||||||
debugfs_remove(fnic_trace_debugfs_file);
|
fnic_trace_debugfs_file = NULL;
|
||||||
fnic_trace_debugfs_file = NULL;
|
|
||||||
|
debugfs_remove(fnic_trace_enable);
|
||||||
|
fnic_trace_enable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fnic_fc_trace_debugfs_init -
|
||||||
|
* Initialize debugfs for fnic control frame trace logging
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* When Debugfs is configured this routine sets up the fnic_fc debugfs
|
||||||
|
* file system. If not already created, this routine will create the
|
||||||
|
* create file trace to log fnic fc trace buffer output into debugfs and
|
||||||
|
* it will also create file fc_trace_enable to control enable/disable of
|
||||||
|
* trace logging into trace buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fnic_fc_trace_debugfs_init(void)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
if (!fnic_trace_debugfs_root) {
|
||||||
|
pr_err("fnic:Debugfs root directory doesn't exist\n");
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
if (fnic_trace_enable) {
|
|
||||||
debugfs_remove(fnic_trace_enable);
|
fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
|
||||||
fnic_trace_enable = NULL;
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
|
fnic_trace_debugfs_root,
|
||||||
|
&(fc_trc_flag->fc_trace),
|
||||||
|
&fnic_trace_ctrl_fops);
|
||||||
|
|
||||||
|
if (!fnic_fc_trace_enable) {
|
||||||
|
pr_err("fnic: Failed create fc_trace_enable file\n");
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear",
|
||||||
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
|
fnic_trace_debugfs_root,
|
||||||
|
&(fc_trc_flag->fc_clear),
|
||||||
|
&fnic_trace_ctrl_fops);
|
||||||
|
|
||||||
|
if (!fnic_fc_trace_clear) {
|
||||||
|
pr_err("fnic: Failed to create fc_trace_enable file\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
fnic_fc_rdata_trace_debugfs_file =
|
||||||
|
debugfs_create_file("fc_trace_rdata",
|
||||||
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
|
fnic_trace_debugfs_root,
|
||||||
|
&(fc_trc_flag->fc_normal_file),
|
||||||
|
&fnic_trace_debugfs_fops);
|
||||||
|
|
||||||
|
if (!fnic_fc_rdata_trace_debugfs_file) {
|
||||||
|
pr_err("fnic: Failed create fc_rdata_trace file\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
fnic_fc_trace_debugfs_file =
|
||||||
|
debugfs_create_file("fc_trace",
|
||||||
|
S_IFREG|S_IRUGO|S_IWUSR,
|
||||||
|
fnic_trace_debugfs_root,
|
||||||
|
&(fc_trc_flag->fc_row_file),
|
||||||
|
&fnic_trace_debugfs_fops);
|
||||||
|
|
||||||
|
if (!fnic_fc_trace_debugfs_file) {
|
||||||
|
pr_err("fnic: Failed to create fc_trace file\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* When Debugfs is configured this routine removes debugfs file system
|
||||||
|
* elements that are specific to fnic_fc trace logging.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void fnic_fc_trace_debugfs_terminate(void)
|
||||||
|
{
|
||||||
|
debugfs_remove(fnic_fc_trace_debugfs_file);
|
||||||
|
fnic_fc_trace_debugfs_file = NULL;
|
||||||
|
|
||||||
|
debugfs_remove(fnic_fc_rdata_trace_debugfs_file);
|
||||||
|
fnic_fc_rdata_trace_debugfs_file = NULL;
|
||||||
|
|
||||||
|
debugfs_remove(fnic_fc_trace_enable);
|
||||||
|
fnic_fc_trace_enable = NULL;
|
||||||
|
|
||||||
|
debugfs_remove(fnic_fc_trace_clear);
|
||||||
|
fnic_fc_trace_clear = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work)
|
||||||
fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
|
fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
|
||||||
|
|
||||||
if (old_link_status == fnic->link_status) {
|
if (old_link_status == fnic->link_status) {
|
||||||
if (!fnic->link_status)
|
if (!fnic->link_status) {
|
||||||
/* DOWN -> DOWN */
|
/* DOWN -> DOWN */
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
else {
|
fnic_fc_trace_set_data(fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_LE, "Link Status: DOWN->DOWN",
|
||||||
|
strlen("Link Status: DOWN->DOWN"));
|
||||||
|
} else {
|
||||||
if (old_link_down_cnt != fnic->link_down_cnt) {
|
if (old_link_down_cnt != fnic->link_down_cnt) {
|
||||||
/* UP -> DOWN -> UP */
|
/* UP -> DOWN -> UP */
|
||||||
fnic->lport->host_stats.link_failure_count++;
|
fnic->lport->host_stats.link_failure_count++;
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
|
fnic_fc_trace_set_data(
|
||||||
|
fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_LE,
|
||||||
|
"Link Status:UP_DOWN_UP",
|
||||||
|
strlen("Link_Status:UP_DOWN_UP")
|
||||||
|
);
|
||||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
|
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
|
||||||
"link down\n");
|
"link down\n");
|
||||||
fcoe_ctlr_link_down(&fnic->ctlr);
|
fcoe_ctlr_link_down(&fnic->ctlr);
|
||||||
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
|
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
|
||||||
/* start FCoE VLAN discovery */
|
/* start FCoE VLAN discovery */
|
||||||
|
fnic_fc_trace_set_data(
|
||||||
|
fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_LE,
|
||||||
|
"Link Status: UP_DOWN_UP_VLAN",
|
||||||
|
strlen(
|
||||||
|
"Link Status: UP_DOWN_UP_VLAN")
|
||||||
|
);
|
||||||
fnic_fcoe_send_vlan_req(fnic);
|
fnic_fcoe_send_vlan_req(fnic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work)
|
||||||
} else
|
} else
|
||||||
/* UP -> UP */
|
/* UP -> UP */
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
|
fnic_fc_trace_set_data(
|
||||||
|
fnic->lport->host->host_no, FNIC_FC_LE,
|
||||||
|
"Link Status: UP_UP",
|
||||||
|
strlen("Link Status: UP_UP"));
|
||||||
}
|
}
|
||||||
} else if (fnic->link_status) {
|
} else if (fnic->link_status) {
|
||||||
/* DOWN -> UP */
|
/* DOWN -> UP */
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
|
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
|
||||||
/* start FCoE VLAN discovery */
|
/* start FCoE VLAN discovery */
|
||||||
|
fnic_fc_trace_set_data(
|
||||||
|
fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
|
||||||
|
strlen("Link Status: DOWN_UP_VLAN"));
|
||||||
fnic_fcoe_send_vlan_req(fnic);
|
fnic_fcoe_send_vlan_req(fnic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
|
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
|
||||||
|
fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
|
||||||
|
"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
|
||||||
fcoe_ctlr_link_up(&fnic->ctlr);
|
fcoe_ctlr_link_up(&fnic->ctlr);
|
||||||
} else {
|
} else {
|
||||||
/* UP -> DOWN */
|
/* UP -> DOWN */
|
||||||
fnic->lport->host_stats.link_failure_count++;
|
fnic->lport->host_stats.link_failure_count++;
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
|
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
|
||||||
|
fnic_fc_trace_set_data(
|
||||||
|
fnic->lport->host->host_no, FNIC_FC_LE,
|
||||||
|
"Link Status: UP_DOWN",
|
||||||
|
strlen("Link Status: UP_DOWN"));
|
||||||
fcoe_ctlr_link_down(&fnic->ctlr);
|
fcoe_ctlr_link_down(&fnic->ctlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,11 +297,6 @@ static inline int is_fnic_fip_flogi_reject(struct fcoe_ctlr *fip,
|
||||||
|
|
||||||
if (desc->fip_dtype == FIP_DT_FLOGI) {
|
if (desc->fip_dtype == FIP_DT_FLOGI) {
|
||||||
|
|
||||||
shost_printk(KERN_DEBUG, lport->host,
|
|
||||||
" FIP TYPE FLOGI: fab name:%llx "
|
|
||||||
"vfid:%d map:%x\n",
|
|
||||||
fip->sel_fcf->fabric_name, fip->sel_fcf->vfid,
|
|
||||||
fip->sel_fcf->fc_map);
|
|
||||||
if (dlen < sizeof(*els) + sizeof(*fh) + 1)
|
if (dlen < sizeof(*els) + sizeof(*fh) + 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -616,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
|
||||||
"using UCSM\n");
|
"using UCSM\n");
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_RECV|0x80, (char *)skb->data, skb->len)) != 0) {
|
||||||
|
printk(KERN_ERR "fnic ctlr frame trace error!!!");
|
||||||
|
}
|
||||||
skb_queue_tail(&fnic->fip_frame_queue, skb);
|
skb_queue_tail(&fnic->fip_frame_queue, skb);
|
||||||
queue_work(fnic_fip_queue, &fnic->fip_frame_work);
|
queue_work(fnic_fip_queue, &fnic->fip_frame_work);
|
||||||
return 1; /* let caller know packet was used */
|
return 1; /* let caller know packet was used */
|
||||||
|
@ -844,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
|
||||||
}
|
}
|
||||||
fr_dev(fp) = fnic->lport;
|
fr_dev(fp) = fnic->lport;
|
||||||
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
|
||||||
|
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_RECV,
|
||||||
|
(char *)skb->data, skb->len)) != 0) {
|
||||||
|
printk(KERN_ERR "fnic ctlr frame trace error!!!");
|
||||||
|
}
|
||||||
|
|
||||||
skb_queue_tail(&fnic->frame_queue, skb);
|
skb_queue_tail(&fnic->frame_queue, skb);
|
||||||
queue_work(fnic_event_queue, &fnic->frame_work);
|
queue_work(fnic_event_queue, &fnic->frame_work);
|
||||||
|
@ -951,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
|
||||||
vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
|
vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
|
||||||
vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
|
vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
|
||||||
vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
|
vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
|
||||||
|
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_SEND|0x80, (char *)eth_hdr, skb->len)) != 0) {
|
||||||
|
printk(KERN_ERR "fnic ctlr frame trace error!!!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
|
||||||
|
FNIC_FC_SEND|0x80, (char *)skb->data, skb->len)) != 0) {
|
||||||
|
printk(KERN_ERR "fnic ctlr frame trace error!!!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
|
pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
|
||||||
|
@ -1023,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
|
||||||
|
|
||||||
pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
|
pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
|
||||||
|
|
||||||
|
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
|
||||||
|
(char *)eth_hdr, tot_len)) != 0) {
|
||||||
|
printk(KERN_ERR "fnic ctlr frame trace error!!!");
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&fnic->wq_lock[0], flags);
|
spin_lock_irqsave(&fnic->wq_lock[0], flags);
|
||||||
|
|
||||||
if (!vnic_wq_desc_avail(wq)) {
|
if (!vnic_wq_desc_avail(wq)) {
|
||||||
|
|
|
@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
|
||||||
MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
|
MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
|
||||||
"for fnic trace buffer");
|
"for fnic trace buffer");
|
||||||
|
|
||||||
|
unsigned int fnic_fc_trace_max_pages = 64;
|
||||||
|
module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
|
||||||
|
MODULE_PARM_DESC(fnic_fc_trace_max_pages,
|
||||||
|
"Total allocated memory pages for fc trace buffer");
|
||||||
|
|
||||||
static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
|
static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
|
||||||
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
|
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
|
||||||
MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
|
MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
|
||||||
|
@ -111,7 +116,7 @@ static struct scsi_host_template fnic_host_template = {
|
||||||
.change_queue_type = fc_change_queue_type,
|
.change_queue_type = fc_change_queue_type,
|
||||||
.this_id = -1,
|
.this_id = -1,
|
||||||
.cmd_per_lun = 3,
|
.cmd_per_lun = 3,
|
||||||
.can_queue = FNIC_MAX_IO_REQ,
|
.can_queue = FNIC_DFLT_IO_REQ,
|
||||||
.use_clustering = ENABLE_CLUSTERING,
|
.use_clustering = ENABLE_CLUSTERING,
|
||||||
.sg_tablesize = FNIC_MAX_SG_DESC_CNT,
|
.sg_tablesize = FNIC_MAX_SG_DESC_CNT,
|
||||||
.max_sectors = 0xffff,
|
.max_sectors = 0xffff,
|
||||||
|
@ -773,6 +778,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
shost_printk(KERN_INFO, fnic->lport->host,
|
shost_printk(KERN_INFO, fnic->lport->host,
|
||||||
"firmware uses non-FIP mode\n");
|
"firmware uses non-FIP mode\n");
|
||||||
fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_NON_FIP);
|
fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_NON_FIP);
|
||||||
|
fnic->ctlr.state = FIP_ST_NON_FIP;
|
||||||
}
|
}
|
||||||
fnic->state = FNIC_IN_FC_MODE;
|
fnic->state = FNIC_IN_FC_MODE;
|
||||||
|
|
||||||
|
@ -1033,11 +1039,20 @@ static int __init fnic_init_module(void)
|
||||||
/* Allocate memory for trace buffer */
|
/* Allocate memory for trace buffer */
|
||||||
err = fnic_trace_buf_init();
|
err = fnic_trace_buf_init();
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
printk(KERN_ERR PFX "Trace buffer initialization Failed "
|
printk(KERN_ERR PFX
|
||||||
"Fnic Tracing utility is disabled\n");
|
"Trace buffer initialization Failed. "
|
||||||
|
"Fnic Tracing utility is disabled\n");
|
||||||
fnic_trace_free();
|
fnic_trace_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for fc trace buffer */
|
||||||
|
err = fnic_fc_trace_init();
|
||||||
|
if (err < 0) {
|
||||||
|
printk(KERN_ERR PFX "FC trace buffer initialization Failed "
|
||||||
|
"FC frame tracing utility is disabled\n");
|
||||||
|
fnic_fc_trace_free();
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a cache for allocation of default size sgls */
|
/* Create a cache for allocation of default size sgls */
|
||||||
len = sizeof(struct fnic_dflt_sgl_list);
|
len = sizeof(struct fnic_dflt_sgl_list);
|
||||||
fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
|
fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
|
||||||
|
@ -1118,6 +1133,7 @@ err_create_fnic_sgl_slab_max:
|
||||||
kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
|
kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
|
||||||
err_create_fnic_sgl_slab_dflt:
|
err_create_fnic_sgl_slab_dflt:
|
||||||
fnic_trace_free();
|
fnic_trace_free();
|
||||||
|
fnic_fc_trace_free();
|
||||||
fnic_debugfs_terminate();
|
fnic_debugfs_terminate();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1135,6 +1151,7 @@ static void __exit fnic_cleanup_module(void)
|
||||||
kmem_cache_destroy(fnic_io_req_cache);
|
kmem_cache_destroy(fnic_io_req_cache);
|
||||||
fc_release_transport(fnic_fc_transport);
|
fc_release_transport(fnic_fc_transport);
|
||||||
fnic_trace_free();
|
fnic_trace_free();
|
||||||
|
fnic_fc_trace_free();
|
||||||
fnic_debugfs_terminate();
|
fnic_debugfs_terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1312,8 +1312,9 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
|
||||||
|
|
||||||
cleanup_scsi_cmd:
|
cleanup_scsi_cmd:
|
||||||
sc->result = DID_TRANSPORT_DISRUPTED << 16;
|
sc->result = DID_TRANSPORT_DISRUPTED << 16;
|
||||||
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:"
|
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
|
||||||
" DID_TRANSPORT_DISRUPTED\n");
|
"%s: sc duration = %lu DID_TRANSPORT_DISRUPTED\n",
|
||||||
|
__func__, (jiffies - start_time));
|
||||||
|
|
||||||
if (atomic64_read(&fnic->io_cmpl_skip))
|
if (atomic64_read(&fnic->io_cmpl_skip))
|
||||||
atomic64_dec(&fnic->io_cmpl_skip);
|
atomic64_dec(&fnic->io_cmpl_skip);
|
||||||
|
@ -1733,6 +1734,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
|
||||||
struct fnic_stats *fnic_stats;
|
struct fnic_stats *fnic_stats;
|
||||||
struct abort_stats *abts_stats;
|
struct abort_stats *abts_stats;
|
||||||
struct terminate_stats *term_stats;
|
struct terminate_stats *term_stats;
|
||||||
|
enum fnic_ioreq_state old_ioreq_state;
|
||||||
int tag;
|
int tag;
|
||||||
DECLARE_COMPLETION_ONSTACK(tm_done);
|
DECLARE_COMPLETION_ONSTACK(tm_done);
|
||||||
|
|
||||||
|
@ -1793,6 +1795,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
|
||||||
* the completion wont be done till mid-layer, since abort
|
* the completion wont be done till mid-layer, since abort
|
||||||
* has already started.
|
* has already started.
|
||||||
*/
|
*/
|
||||||
|
old_ioreq_state = CMD_STATE(sc);
|
||||||
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
|
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
|
||||||
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
|
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
|
||||||
|
|
||||||
|
@ -1816,6 +1819,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
|
||||||
if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req,
|
if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req,
|
||||||
fc_lun.scsi_lun, io_req)) {
|
fc_lun.scsi_lun, io_req)) {
|
||||||
spin_lock_irqsave(io_lock, flags);
|
spin_lock_irqsave(io_lock, flags);
|
||||||
|
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
|
||||||
|
CMD_STATE(sc) = old_ioreq_state;
|
||||||
io_req = (struct fnic_io_req *)CMD_SP(sc);
|
io_req = (struct fnic_io_req *)CMD_SP(sc);
|
||||||
if (io_req)
|
if (io_req)
|
||||||
io_req->abts_done = NULL;
|
io_req->abts_done = NULL;
|
||||||
|
@ -1859,12 +1864,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
|
||||||
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) {
|
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) {
|
||||||
spin_unlock_irqrestore(io_lock, flags);
|
spin_unlock_irqrestore(io_lock, flags);
|
||||||
if (task_req == FCPIO_ITMF_ABT_TASK) {
|
if (task_req == FCPIO_ITMF_ABT_TASK) {
|
||||||
FNIC_SCSI_DBG(KERN_INFO,
|
|
||||||
fnic->lport->host, "Abort Driver Timeout\n");
|
|
||||||
atomic64_inc(&abts_stats->abort_drv_timeouts);
|
atomic64_inc(&abts_stats->abort_drv_timeouts);
|
||||||
} else {
|
} else {
|
||||||
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
|
|
||||||
"Terminate Driver Timeout\n");
|
|
||||||
atomic64_inc(&term_stats->terminate_drv_timeouts);
|
atomic64_inc(&term_stats->terminate_drv_timeouts);
|
||||||
}
|
}
|
||||||
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;
|
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/kallsyms.h>
|
#include <linux/kallsyms.h>
|
||||||
|
#include <linux/time.h>
|
||||||
#include "fnic_io.h"
|
#include "fnic_io.h"
|
||||||
#include "fnic.h"
|
#include "fnic.h"
|
||||||
|
|
||||||
|
@ -32,6 +33,16 @@ static DEFINE_SPINLOCK(fnic_trace_lock);
|
||||||
static fnic_trace_dbg_t fnic_trace_entries;
|
static fnic_trace_dbg_t fnic_trace_entries;
|
||||||
int fnic_tracing_enabled = 1;
|
int fnic_tracing_enabled = 1;
|
||||||
|
|
||||||
|
/* static char *fnic_fc_ctlr_trace_buf_p; */
|
||||||
|
|
||||||
|
static int fc_trace_max_entries;
|
||||||
|
static unsigned long fnic_fc_ctlr_trace_buf_p;
|
||||||
|
static fnic_trace_dbg_t fc_trace_entries;
|
||||||
|
int fnic_fc_tracing_enabled = 1;
|
||||||
|
int fnic_fc_trace_cleared = 1;
|
||||||
|
static DEFINE_SPINLOCK(fnic_fc_trace_lock);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fnic_trace_get_buf - Give buffer pointer to user to fill up trace information
|
* fnic_trace_get_buf - Give buffer pointer to user to fill up trace information
|
||||||
*
|
*
|
||||||
|
@ -428,10 +439,10 @@ int fnic_trace_buf_init(void)
|
||||||
}
|
}
|
||||||
err = fnic_trace_debugfs_init();
|
err = fnic_trace_debugfs_init();
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
printk(KERN_ERR PFX "Failed to initialize debugfs for tracing\n");
|
pr_err("fnic: Failed to initialize debugfs for tracing\n");
|
||||||
goto err_fnic_trace_debugfs_init;
|
goto err_fnic_trace_debugfs_init;
|
||||||
}
|
}
|
||||||
printk(KERN_INFO PFX "Successfully Initialized Trace Buffer\n");
|
pr_info("fnic: Successfully Initialized Trace Buffer\n");
|
||||||
return err;
|
return err;
|
||||||
err_fnic_trace_debugfs_init:
|
err_fnic_trace_debugfs_init:
|
||||||
fnic_trace_free();
|
fnic_trace_free();
|
||||||
|
@ -456,3 +467,314 @@ void fnic_trace_free(void)
|
||||||
}
|
}
|
||||||
printk(KERN_INFO PFX "Successfully Freed Trace Buffer\n");
|
printk(KERN_INFO PFX "Successfully Freed Trace Buffer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fnic_fc_ctlr_trace_buf_init -
|
||||||
|
* Initialize trace buffer to log fnic control frames
|
||||||
|
* Description:
|
||||||
|
* Initialize trace buffer data structure by allocating
|
||||||
|
* required memory for trace data as well as for Indexes.
|
||||||
|
* Frame size is 256 bytes and
|
||||||
|
* memory is allocated for 1024 entries of 256 bytes.
|
||||||
|
* Page_offset(Index) is set to the address of trace entry
|
||||||
|
* and page_offset is initialized by adding frame size
|
||||||
|
* to the previous page_offset entry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fnic_fc_trace_init(void)
|
||||||
|
{
|
||||||
|
unsigned long fc_trace_buf_head;
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fc_trace_max_entries = (fnic_fc_trace_max_pages * PAGE_SIZE)/
|
||||||
|
FC_TRC_SIZE_BYTES;
|
||||||
|
fnic_fc_ctlr_trace_buf_p = (unsigned long)vmalloc(
|
||||||
|
fnic_fc_trace_max_pages * PAGE_SIZE);
|
||||||
|
if (!fnic_fc_ctlr_trace_buf_p) {
|
||||||
|
pr_err("fnic: Failed to allocate memory for "
|
||||||
|
"FC Control Trace Buf\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_fnic_fc_ctlr_trace_buf_init;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((void *)fnic_fc_ctlr_trace_buf_p, 0,
|
||||||
|
fnic_fc_trace_max_pages * PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Allocate memory for page offset */
|
||||||
|
fc_trace_entries.page_offset = vmalloc(fc_trace_max_entries *
|
||||||
|
sizeof(unsigned long));
|
||||||
|
if (!fc_trace_entries.page_offset) {
|
||||||
|
pr_err("fnic:Failed to allocate memory for page_offset\n");
|
||||||
|
if (fnic_fc_ctlr_trace_buf_p) {
|
||||||
|
pr_err("fnic: Freeing FC Control Trace Buf\n");
|
||||||
|
vfree((void *)fnic_fc_ctlr_trace_buf_p);
|
||||||
|
fnic_fc_ctlr_trace_buf_p = 0;
|
||||||
|
}
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_fnic_fc_ctlr_trace_buf_init;
|
||||||
|
}
|
||||||
|
memset((void *)fc_trace_entries.page_offset, 0,
|
||||||
|
(fc_trace_max_entries * sizeof(unsigned long)));
|
||||||
|
|
||||||
|
fc_trace_entries.rd_idx = fc_trace_entries.wr_idx = 0;
|
||||||
|
fc_trace_buf_head = fnic_fc_ctlr_trace_buf_p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up fc_trace_entries.page_offset field with memory location
|
||||||
|
* for every trace entry
|
||||||
|
*/
|
||||||
|
for (i = 0; i < fc_trace_max_entries; i++) {
|
||||||
|
fc_trace_entries.page_offset[i] = fc_trace_buf_head;
|
||||||
|
fc_trace_buf_head += FC_TRC_SIZE_BYTES;
|
||||||
|
}
|
||||||
|
err = fnic_fc_trace_debugfs_init();
|
||||||
|
if (err < 0) {
|
||||||
|
pr_err("fnic: Failed to initialize FC_CTLR tracing.\n");
|
||||||
|
goto err_fnic_fc_ctlr_trace_debugfs_init;
|
||||||
|
}
|
||||||
|
pr_info("fnic: Successfully Initialized FC_CTLR Trace Buffer\n");
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err_fnic_fc_ctlr_trace_debugfs_init:
|
||||||
|
fnic_fc_trace_free();
|
||||||
|
err_fnic_fc_ctlr_trace_buf_init:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fnic_fc_ctlr_trace_free - Free memory of fnic_fc_ctlr trace data structures.
|
||||||
|
*/
|
||||||
|
void fnic_fc_trace_free(void)
|
||||||
|
{
|
||||||
|
fnic_fc_tracing_enabled = 0;
|
||||||
|
fnic_fc_trace_debugfs_terminate();
|
||||||
|
if (fc_trace_entries.page_offset) {
|
||||||
|
vfree((void *)fc_trace_entries.page_offset);
|
||||||
|
fc_trace_entries.page_offset = NULL;
|
||||||
|
}
|
||||||
|
if (fnic_fc_ctlr_trace_buf_p) {
|
||||||
|
vfree((void *)fnic_fc_ctlr_trace_buf_p);
|
||||||
|
fnic_fc_ctlr_trace_buf_p = 0;
|
||||||
|
}
|
||||||
|
pr_info("fnic:Successfully FC_CTLR Freed Trace Buffer\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fnic_fc_ctlr_set_trace_data:
|
||||||
|
* Maintain rd & wr idx accordingly and set data
|
||||||
|
* Passed parameters:
|
||||||
|
* host_no: host number accociated with fnic
|
||||||
|
* frame_type: send_frame, rece_frame or link event
|
||||||
|
* fc_frame: pointer to fc_frame
|
||||||
|
* frame_len: Length of the fc_frame
|
||||||
|
* Description:
|
||||||
|
* This routine will get next available wr_idx and
|
||||||
|
* copy all passed trace data to the buffer pointed by wr_idx
|
||||||
|
* and increment wr_idx. It will also make sure that we dont
|
||||||
|
* overwrite the entry which we are reading and also
|
||||||
|
* wrap around if we reach the maximum entries.
|
||||||
|
* Returned Value:
|
||||||
|
* It will return 0 for success or -1 for failure
|
||||||
|
*/
|
||||||
|
int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
|
||||||
|
char *frame, u32 fc_trc_frame_len)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct fc_trace_hdr *fc_buf;
|
||||||
|
unsigned long eth_fcoe_hdr_len;
|
||||||
|
char *fc_trace;
|
||||||
|
|
||||||
|
if (fnic_fc_tracing_enabled == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fnic_fc_trace_lock, flags);
|
||||||
|
|
||||||
|
if (fnic_fc_trace_cleared == 1) {
|
||||||
|
fc_trace_entries.rd_idx = fc_trace_entries.wr_idx = 0;
|
||||||
|
pr_info("fnic: Reseting the read idx\n");
|
||||||
|
memset((void *)fnic_fc_ctlr_trace_buf_p, 0,
|
||||||
|
fnic_fc_trace_max_pages * PAGE_SIZE);
|
||||||
|
fnic_fc_trace_cleared = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc_buf = (struct fc_trace_hdr *)
|
||||||
|
fc_trace_entries.page_offset[fc_trace_entries.wr_idx];
|
||||||
|
|
||||||
|
fc_trace_entries.wr_idx++;
|
||||||
|
|
||||||
|
if (fc_trace_entries.wr_idx >= fc_trace_max_entries)
|
||||||
|
fc_trace_entries.wr_idx = 0;
|
||||||
|
|
||||||
|
if (fc_trace_entries.wr_idx == fc_trace_entries.rd_idx) {
|
||||||
|
fc_trace_entries.rd_idx++;
|
||||||
|
if (fc_trace_entries.rd_idx >= fc_trace_max_entries)
|
||||||
|
fc_trace_entries.rd_idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fc_buf->time_stamp = CURRENT_TIME;
|
||||||
|
fc_buf->host_no = host_no;
|
||||||
|
fc_buf->frame_type = frame_type;
|
||||||
|
|
||||||
|
fc_trace = (char *)FC_TRACE_ADDRESS(fc_buf);
|
||||||
|
|
||||||
|
/* During the receive path, we do not have eth hdr as well as fcoe hdr
|
||||||
|
* at trace entry point so we will stuff 0xff just to make it generic.
|
||||||
|
*/
|
||||||
|
if (frame_type == FNIC_FC_RECV) {
|
||||||
|
eth_fcoe_hdr_len = sizeof(struct ethhdr) +
|
||||||
|
sizeof(struct fcoe_hdr);
|
||||||
|
fc_trc_frame_len = fc_trc_frame_len + eth_fcoe_hdr_len;
|
||||||
|
memset((char *)fc_trace, 0xff, eth_fcoe_hdr_len);
|
||||||
|
/* Copy the rest of data frame */
|
||||||
|
memcpy((char *)(fc_trace + eth_fcoe_hdr_len), (void *)frame,
|
||||||
|
min_t(u8, fc_trc_frame_len,
|
||||||
|
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)));
|
||||||
|
} else {
|
||||||
|
memcpy((char *)fc_trace, (void *)frame,
|
||||||
|
min_t(u8, fc_trc_frame_len,
|
||||||
|
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the actual received length */
|
||||||
|
fc_buf->frame_len = fc_trc_frame_len;
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fnic_fc_ctlr_get_trace_data: Copy trace buffer to a memory file
|
||||||
|
* Passed parameter:
|
||||||
|
* @fnic_dbgfs_t: pointer to debugfs trace buffer
|
||||||
|
* rdata_flag: 1 => Unformated file
|
||||||
|
* 0 => formated file
|
||||||
|
* Description:
|
||||||
|
* This routine will copy the trace data to memory file with
|
||||||
|
* proper formatting and also copy to another memory
|
||||||
|
* file without formatting for further procesing.
|
||||||
|
* Retrun Value:
|
||||||
|
* Number of bytes that were dumped into fnic_dbgfs_t
|
||||||
|
*/
|
||||||
|
|
||||||
|
int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag)
|
||||||
|
{
|
||||||
|
int rd_idx, wr_idx;
|
||||||
|
unsigned long flags;
|
||||||
|
int len = 0, j;
|
||||||
|
struct fc_trace_hdr *tdata;
|
||||||
|
char *fc_trace;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fnic_fc_trace_lock, flags);
|
||||||
|
if (fc_trace_entries.wr_idx == fc_trace_entries.rd_idx) {
|
||||||
|
spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
|
||||||
|
pr_info("fnic: Buffer is empty\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rd_idx = fc_trace_entries.rd_idx;
|
||||||
|
wr_idx = fc_trace_entries.wr_idx;
|
||||||
|
if (rdata_flag == 0) {
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
|
||||||
|
"Time Stamp (UTC)\t\t"
|
||||||
|
"Host No: F Type: len: FCoE_FRAME:\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rd_idx != wr_idx) {
|
||||||
|
tdata = (struct fc_trace_hdr *)
|
||||||
|
fc_trace_entries.page_offset[rd_idx];
|
||||||
|
if (!tdata) {
|
||||||
|
pr_info("fnic: Rd data is NULL\n");
|
||||||
|
spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rdata_flag == 0) {
|
||||||
|
copy_and_format_trace_data(tdata,
|
||||||
|
fnic_dbgfs_prt, &len, rdata_flag);
|
||||||
|
} else {
|
||||||
|
fc_trace = (char *)tdata;
|
||||||
|
for (j = 0; j < FC_TRC_SIZE_BYTES; j++) {
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
(fnic_fc_trace_max_pages * PAGE_SIZE * 3)
|
||||||
|
- len, "%02x", fc_trace[j] & 0xff);
|
||||||
|
} /* for loop */
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
rd_idx++;
|
||||||
|
if (rd_idx > (fc_trace_max_entries - 1))
|
||||||
|
rd_idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* copy_and_format_trace_data: Copy formatted data to char * buffer
|
||||||
|
* Passed Parameter:
|
||||||
|
* @fc_trace_hdr_t: pointer to trace data
|
||||||
|
* @fnic_dbgfs_t: pointer to debugfs trace buffer
|
||||||
|
* @orig_len: pointer to len
|
||||||
|
* rdata_flag: 0 => Formated file, 1 => Unformated file
|
||||||
|
* Description:
|
||||||
|
* This routine will format and copy the passed trace data
|
||||||
|
* for formated file or unformated file accordingly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
|
||||||
|
fnic_dbgfs_t *fnic_dbgfs_prt, int *orig_len,
|
||||||
|
u8 rdata_flag)
|
||||||
|
{
|
||||||
|
struct tm tm;
|
||||||
|
int j, i = 1, len;
|
||||||
|
char *fc_trace, *fmt;
|
||||||
|
int ethhdr_len = sizeof(struct ethhdr) - 1;
|
||||||
|
int fcoehdr_len = sizeof(struct fcoe_hdr);
|
||||||
|
int fchdr_len = sizeof(struct fc_frame_header);
|
||||||
|
int max_size = fnic_fc_trace_max_pages * PAGE_SIZE * 3;
|
||||||
|
|
||||||
|
tdata->frame_type = tdata->frame_type & 0x7F;
|
||||||
|
|
||||||
|
len = *orig_len;
|
||||||
|
|
||||||
|
time_to_tm(tdata->time_stamp.tv_sec, 0, &tm);
|
||||||
|
|
||||||
|
fmt = "%02d:%02d:%04ld %02d:%02d:%02d.%09lu ns%8x %c%8x\t";
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
(fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
|
||||||
|
fmt,
|
||||||
|
tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900,
|
||||||
|
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||||
|
tdata->time_stamp.tv_nsec, tdata->host_no,
|
||||||
|
tdata->frame_type, tdata->frame_len);
|
||||||
|
|
||||||
|
fc_trace = (char *)FC_TRACE_ADDRESS(tdata);
|
||||||
|
|
||||||
|
for (j = 0; j < min_t(u8, tdata->frame_len,
|
||||||
|
(u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)); j++) {
|
||||||
|
if (tdata->frame_type == FNIC_FC_LE) {
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
max_size - len, "%c", fc_trace[j]);
|
||||||
|
} else {
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
max_size - len, "%02x", fc_trace[j] & 0xff);
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
max_size - len, " ");
|
||||||
|
if (j == ethhdr_len ||
|
||||||
|
j == ethhdr_len + fcoehdr_len ||
|
||||||
|
j == ethhdr_len + fcoehdr_len + fchdr_len ||
|
||||||
|
(i > 3 && j%fchdr_len == 0)) {
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer
|
||||||
|
+ len, (fnic_fc_trace_max_pages
|
||||||
|
* PAGE_SIZE * 3) - len,
|
||||||
|
"\n\t\t\t\t\t\t\t\t");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} /* end of else*/
|
||||||
|
} /* End of for loop*/
|
||||||
|
len += snprintf(fnic_dbgfs_prt->buffer + len,
|
||||||
|
max_size - len, "\n");
|
||||||
|
*orig_len = len;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,17 @@
|
||||||
#define __FNIC_TRACE_H__
|
#define __FNIC_TRACE_H__
|
||||||
|
|
||||||
#define FNIC_ENTRY_SIZE_BYTES 64
|
#define FNIC_ENTRY_SIZE_BYTES 64
|
||||||
|
#define FC_TRC_SIZE_BYTES 256
|
||||||
|
#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type
|
||||||
|
* of frame 1 => Eth frame, 0=> FC frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FNIC_FC_RECV 0x52 /* Character R */
|
||||||
|
#define FNIC_FC_SEND 0x54 /* Character T */
|
||||||
|
#define FNIC_FC_LE 0x4C /* Character L */
|
||||||
|
|
||||||
extern ssize_t simple_read_from_buffer(void __user *to,
|
extern ssize_t simple_read_from_buffer(void __user *to,
|
||||||
size_t count,
|
size_t count,
|
||||||
|
@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages;
|
||||||
extern int fnic_tracing_enabled;
|
extern int fnic_tracing_enabled;
|
||||||
extern unsigned int trace_max_pages;
|
extern unsigned int trace_max_pages;
|
||||||
|
|
||||||
|
extern unsigned int fnic_fc_trace_max_pages;
|
||||||
|
extern int fnic_fc_tracing_enabled;
|
||||||
|
extern int fnic_fc_trace_cleared;
|
||||||
|
|
||||||
typedef struct fnic_trace_dbg {
|
typedef struct fnic_trace_dbg {
|
||||||
int wr_idx;
|
int wr_idx;
|
||||||
int rd_idx;
|
int rd_idx;
|
||||||
|
@ -56,6 +71,16 @@ struct fnic_trace_data {
|
||||||
|
|
||||||
typedef struct fnic_trace_data fnic_trace_data_t;
|
typedef struct fnic_trace_data fnic_trace_data_t;
|
||||||
|
|
||||||
|
struct fc_trace_hdr {
|
||||||
|
struct timespec time_stamp;
|
||||||
|
u32 host_no;
|
||||||
|
u8 frame_type;
|
||||||
|
u8 frame_len;
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
#define FC_TRACE_ADDRESS(a) \
|
||||||
|
((unsigned long)(a) + sizeof(struct fc_trace_hdr))
|
||||||
|
|
||||||
#define FNIC_TRACE_ENTRY_SIZE \
|
#define FNIC_TRACE_ENTRY_SIZE \
|
||||||
(FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
|
(FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
|
||||||
|
|
||||||
|
@ -88,4 +113,17 @@ int fnic_debugfs_init(void);
|
||||||
void fnic_debugfs_terminate(void);
|
void fnic_debugfs_terminate(void);
|
||||||
int fnic_trace_debugfs_init(void);
|
int fnic_trace_debugfs_init(void);
|
||||||
void fnic_trace_debugfs_terminate(void);
|
void fnic_trace_debugfs_terminate(void);
|
||||||
|
|
||||||
|
/* Fnic FC CTLR Trace releated function */
|
||||||
|
int fnic_fc_trace_init(void);
|
||||||
|
void fnic_fc_trace_free(void);
|
||||||
|
int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
|
||||||
|
char *frame, u32 fc_frame_len);
|
||||||
|
int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag);
|
||||||
|
void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
|
||||||
|
fnic_dbgfs_t *fnic_dbgfs_prt,
|
||||||
|
int *len, u8 rdata_flag);
|
||||||
|
int fnic_fc_trace_debugfs_init(void);
|
||||||
|
void fnic_fc_trace_debugfs_terminate(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,10 +78,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: generic_NCR5380.c,v $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* settings for DTC3181E card with only Mustek scanner attached */
|
/* settings for DTC3181E card with only Mustek scanner attached */
|
||||||
#define USLEEP
|
#define USLEEP
|
||||||
#define USLEEP_POLL 1
|
#define USLEEP_POLL 1
|
||||||
|
|
|
@ -25,10 +25,6 @@
|
||||||
* 1+ (800) 334-5454
|
* 1+ (800) 334-5454
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: generic_NCR5380.h,v $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GENERIC_NCR5380_H
|
#ifndef GENERIC_NCR5380_H
|
||||||
#define GENERIC_NCR5380_H
|
#define GENERIC_NCR5380_H
|
||||||
|
|
||||||
|
@ -58,8 +54,6 @@ static const char* generic_NCR5380_info(struct Scsi_Host *);
|
||||||
#define CAN_QUEUE 16
|
#define CAN_QUEUE 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HOSTS_C
|
|
||||||
|
|
||||||
#define __STRVAL(x) #x
|
#define __STRVAL(x) #x
|
||||||
#define STRVAL(x) __STRVAL(x)
|
#define STRVAL(x) __STRVAL(x)
|
||||||
|
|
||||||
|
@ -131,7 +125,6 @@ static const char* generic_NCR5380_info(struct Scsi_Host *);
|
||||||
#define BOARD_NCR53C400A 2
|
#define BOARD_NCR53C400A 2
|
||||||
#define BOARD_DTC3181E 3
|
#define BOARD_DTC3181E 3
|
||||||
|
|
||||||
#endif /* else def HOSTS_C */
|
|
||||||
#endif /* ndef ASM */
|
#endif /* ndef ASM */
|
||||||
#endif /* GENERIC_NCR5380_H */
|
#endif /* GENERIC_NCR5380_H */
|
||||||
|
|
||||||
|
|
|
@ -115,9 +115,15 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C3},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C3},
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C4},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C4},
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C5},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C5},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C6},
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C7},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C7},
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C8},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C8},
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C9},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21C9},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21CA},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21CB},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21CC},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21CD},
|
||||||
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSI, 0x103C, 0x21CE},
|
||||||
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x0076},
|
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x0076},
|
||||||
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x0087},
|
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x0087},
|
||||||
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x007D},
|
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x007D},
|
||||||
|
@ -165,9 +171,15 @@ static struct board_type products[] = {
|
||||||
{0x21C3103C, "Smart Array", &SA5_access},
|
{0x21C3103C, "Smart Array", &SA5_access},
|
||||||
{0x21C4103C, "Smart Array", &SA5_access},
|
{0x21C4103C, "Smart Array", &SA5_access},
|
||||||
{0x21C5103C, "Smart Array", &SA5_access},
|
{0x21C5103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21C6103C, "Smart Array", &SA5_access},
|
||||||
{0x21C7103C, "Smart Array", &SA5_access},
|
{0x21C7103C, "Smart Array", &SA5_access},
|
||||||
{0x21C8103C, "Smart Array", &SA5_access},
|
{0x21C8103C, "Smart Array", &SA5_access},
|
||||||
{0x21C9103C, "Smart Array", &SA5_access},
|
{0x21C9103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21CA103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21CB103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21CC103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21CD103C, "Smart Array", &SA5_access},
|
||||||
|
{0x21CE103C, "Smart Array", &SA5_access},
|
||||||
{0x00761590, "HP Storage P1224 Array Controller", &SA5_access},
|
{0x00761590, "HP Storage P1224 Array Controller", &SA5_access},
|
||||||
{0x00871590, "HP Storage P1224e Array Controller", &SA5_access},
|
{0x00871590, "HP Storage P1224e Array Controller", &SA5_access},
|
||||||
{0x007D1590, "HP Storage P1228 Array Controller", &SA5_access},
|
{0x007D1590, "HP Storage P1228 Array Controller", &SA5_access},
|
||||||
|
@ -2836,6 +2848,8 @@ static int hpsa_get_pdisk_of_ioaccel2(struct ctlr_info *h,
|
||||||
|
|
||||||
/* Get the list of physical devices */
|
/* Get the list of physical devices */
|
||||||
physicals = kzalloc(reportsize, GFP_KERNEL);
|
physicals = kzalloc(reportsize, GFP_KERNEL);
|
||||||
|
if (physicals == NULL)
|
||||||
|
return 0;
|
||||||
if (hpsa_scsi_do_report_phys_luns(h, (struct ReportLUNdata *) physicals,
|
if (hpsa_scsi_do_report_phys_luns(h, (struct ReportLUNdata *) physicals,
|
||||||
reportsize, extended)) {
|
reportsize, extended)) {
|
||||||
dev_err(&h->pdev->dev,
|
dev_err(&h->pdev->dev,
|
||||||
|
@ -2963,19 +2977,24 @@ u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i,
|
||||||
static int hpsa_hba_mode_enabled(struct ctlr_info *h)
|
static int hpsa_hba_mode_enabled(struct ctlr_info *h)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
int hba_mode_enabled;
|
||||||
struct bmic_controller_parameters *ctlr_params;
|
struct bmic_controller_parameters *ctlr_params;
|
||||||
ctlr_params = kzalloc(sizeof(struct bmic_controller_parameters),
|
ctlr_params = kzalloc(sizeof(struct bmic_controller_parameters),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
||||||
if (!ctlr_params)
|
if (!ctlr_params)
|
||||||
return 0;
|
return -ENOMEM;
|
||||||
rc = hpsa_bmic_ctrl_mode_sense(h, RAID_CTLR_LUNID, 0, ctlr_params,
|
rc = hpsa_bmic_ctrl_mode_sense(h, RAID_CTLR_LUNID, 0, ctlr_params,
|
||||||
sizeof(struct bmic_controller_parameters));
|
sizeof(struct bmic_controller_parameters));
|
||||||
if (rc != 0) {
|
if (rc) {
|
||||||
kfree(ctlr_params);
|
kfree(ctlr_params);
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
return ctlr_params->nvram_flags & (1 << 3) ? 1 : 0;
|
|
||||||
|
hba_mode_enabled =
|
||||||
|
((ctlr_params->nvram_flags & HBA_MODE_ENABLED_FLAG) != 0);
|
||||||
|
kfree(ctlr_params);
|
||||||
|
return hba_mode_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
|
@ -3001,7 +3020,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24;
|
int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24;
|
||||||
int i, n_ext_target_devs, ndevs_to_allocate;
|
int i, n_ext_target_devs, ndevs_to_allocate;
|
||||||
int raid_ctlr_position;
|
int raid_ctlr_position;
|
||||||
u8 rescan_hba_mode;
|
int rescan_hba_mode;
|
||||||
DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
|
DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
|
||||||
|
|
||||||
currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
|
currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
|
||||||
|
@ -3016,6 +3035,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
|
||||||
memset(lunzerobits, 0, sizeof(lunzerobits));
|
memset(lunzerobits, 0, sizeof(lunzerobits));
|
||||||
|
|
||||||
rescan_hba_mode = hpsa_hba_mode_enabled(h);
|
rescan_hba_mode = hpsa_hba_mode_enabled(h);
|
||||||
|
if (rescan_hba_mode < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (!h->hba_mode_enabled && rescan_hba_mode)
|
if (!h->hba_mode_enabled && rescan_hba_mode)
|
||||||
dev_warn(&h->pdev->dev, "HBA mode enabled\n");
|
dev_warn(&h->pdev->dev, "HBA mode enabled\n");
|
||||||
|
|
|
@ -90,6 +90,7 @@ struct bmic_controller_parameters {
|
||||||
u8 automatic_drive_slamming;
|
u8 automatic_drive_slamming;
|
||||||
u8 reserved1;
|
u8 reserved1;
|
||||||
u8 nvram_flags;
|
u8 nvram_flags;
|
||||||
|
#define HBA_MODE_ENABLED_FLAG (1 << 3)
|
||||||
u8 cache_nvram_flags;
|
u8 cache_nvram_flags;
|
||||||
u8 drive_config_flags;
|
u8 drive_config_flags;
|
||||||
u16 reserved2;
|
u16 reserved2;
|
||||||
|
|
|
@ -1442,9 +1442,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
|
||||||
conn->task = NULL;
|
conn->task = NULL;
|
||||||
}
|
}
|
||||||
/* regular RX path uses back_lock */
|
/* regular RX path uses back_lock */
|
||||||
spin_lock_bh(&conn->session->back_lock);
|
spin_lock(&conn->session->back_lock);
|
||||||
__iscsi_put_task(task);
|
__iscsi_put_task(task);
|
||||||
spin_unlock_bh(&conn->session->back_lock);
|
spin_unlock(&conn->session->back_lock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,16 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
q->hba_index = idx;
|
q->hba_index = idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* insert barrier for instruction interlock : data from the hardware
|
||||||
|
* must have the valid bit checked before it can be copied and acted
|
||||||
|
* upon. Given what was seen in lpfc_sli4_cq_get() of speculative
|
||||||
|
* instructions allowing action on content before valid bit checked,
|
||||||
|
* add barrier here as well. May not be needed as "content" is a
|
||||||
|
* single 32-bit entity here (vs multi word structure for cq's).
|
||||||
|
*/
|
||||||
|
mb();
|
||||||
return eqe;
|
return eqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +380,17 @@ lpfc_sli4_cq_get(struct lpfc_queue *q)
|
||||||
|
|
||||||
cqe = q->qe[q->hba_index].cqe;
|
cqe = q->qe[q->hba_index].cqe;
|
||||||
q->hba_index = idx;
|
q->hba_index = idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* insert barrier for instruction interlock : data from the hardware
|
||||||
|
* must have the valid bit checked before it can be copied and acted
|
||||||
|
* upon. Speculative instructions were allowing a bcopy at the start
|
||||||
|
* of lpfc_sli4_fp_handle_wcqe(), which is called immediately
|
||||||
|
* after our return, to copy data before the valid bit check above
|
||||||
|
* was done. As such, some of the copied data was stale. The barrier
|
||||||
|
* ensures the check is before any data is copied.
|
||||||
|
*/
|
||||||
|
mb();
|
||||||
return cqe;
|
return cqe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,6 @@
|
||||||
* 1+ (800) 334-5454
|
* 1+ (800) 334-5454
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: mac_NCR5380.c,v $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
@ -58,12 +54,6 @@
|
||||||
|
|
||||||
#include "NCR5380.h"
|
#include "NCR5380.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define NDEBUG (NDEBUG_INTR | NDEBUG_PSEUDO_DMA | NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_RESELECTION)
|
|
||||||
#else
|
|
||||||
#define NDEBUG (NDEBUG_ABORT)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RESET_BOOT
|
#define RESET_BOOT
|
||||||
#define DRIVER_SETUP
|
#define DRIVER_SETUP
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
* 1+ (800) 334-5454
|
* 1+ (800) 334-5454
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* $Log: cumana_NCR5380.h,v $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MAC_NCR5380_H
|
#ifndef MAC_NCR5380_H
|
||||||
#define MAC_NCR5380_H
|
#define MAC_NCR5380_H
|
||||||
|
|
||||||
|
@ -51,8 +47,6 @@
|
||||||
|
|
||||||
#include <scsi/scsicam.h>
|
#include <scsi/scsicam.h>
|
||||||
|
|
||||||
#ifndef HOSTS_C
|
|
||||||
|
|
||||||
#define NCR5380_implementation_fields \
|
#define NCR5380_implementation_fields \
|
||||||
int port, ctrl
|
int port, ctrl
|
||||||
|
|
||||||
|
@ -75,10 +69,6 @@
|
||||||
#define NCR5380_show_info macscsi_show_info
|
#define NCR5380_show_info macscsi_show_info
|
||||||
#define NCR5380_write_info macscsi_write_info
|
#define NCR5380_write_info macscsi_write_info
|
||||||
|
|
||||||
#define BOARD_NORMAL 0
|
|
||||||
#define BOARD_NCR53C400 1
|
|
||||||
|
|
||||||
#endif /* ndef HOSTS_C */
|
|
||||||
#endif /* ndef ASM */
|
#endif /* ndef ASM */
|
||||||
#endif /* MAC_NCR5380_H */
|
#endif /* MAC_NCR5380_H */
|
||||||
|
|
||||||
|
|
|
@ -3061,7 +3061,8 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
||||||
u32 cur_state;
|
u32 cur_state;
|
||||||
u32 abs_state, curr_abs_state;
|
u32 abs_state, curr_abs_state;
|
||||||
|
|
||||||
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
|
abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
|
||||||
|
fw_state = abs_state & MFI_STATE_MASK;
|
||||||
|
|
||||||
if (fw_state != MFI_STATE_READY)
|
if (fw_state != MFI_STATE_READY)
|
||||||
printk(KERN_INFO "megasas: Waiting for FW to come to ready"
|
printk(KERN_INFO "megasas: Waiting for FW to come to ready"
|
||||||
|
@ -3069,9 +3070,6 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
||||||
|
|
||||||
while (fw_state != MFI_STATE_READY) {
|
while (fw_state != MFI_STATE_READY) {
|
||||||
|
|
||||||
abs_state =
|
|
||||||
instance->instancet->read_fw_status_reg(instance->reg_set);
|
|
||||||
|
|
||||||
switch (fw_state) {
|
switch (fw_state) {
|
||||||
|
|
||||||
case MFI_STATE_FAULT:
|
case MFI_STATE_FAULT:
|
||||||
|
@ -3223,10 +3221,8 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
||||||
* The cur_state should not last for more than max_wait secs
|
* The cur_state should not last for more than max_wait secs
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < (max_wait * 1000); i++) {
|
for (i = 0; i < (max_wait * 1000); i++) {
|
||||||
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
|
curr_abs_state = instance->instancet->
|
||||||
MFI_STATE_MASK ;
|
read_fw_status_reg(instance->reg_set);
|
||||||
curr_abs_state =
|
|
||||||
instance->instancet->read_fw_status_reg(instance->reg_set);
|
|
||||||
|
|
||||||
if (abs_state == curr_abs_state) {
|
if (abs_state == curr_abs_state) {
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
@ -3242,6 +3238,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
|
||||||
"in %d secs\n", fw_state, max_wait);
|
"in %d secs\n", fw_state, max_wait);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abs_state = curr_abs_state;
|
||||||
|
fw_state = curr_abs_state & MFI_STATE_MASK;
|
||||||
}
|
}
|
||||||
printk(KERN_INFO "megasas: FW now in Ready state\n");
|
printk(KERN_INFO "megasas: FW now in Ready state\n");
|
||||||
|
|
||||||
|
|
|
@ -1739,14 +1739,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
|
||||||
list_for_each_entry_safe(chain_req, next,
|
list_for_each_entry_safe(chain_req, next,
|
||||||
&ioc->scsi_lookup[i].chain_list, tracker_list) {
|
&ioc->scsi_lookup[i].chain_list, tracker_list) {
|
||||||
list_del_init(&chain_req->tracker_list);
|
list_del_init(&chain_req->tracker_list);
|
||||||
list_add_tail(&chain_req->tracker_list,
|
list_add(&chain_req->tracker_list,
|
||||||
&ioc->free_chain_list);
|
&ioc->free_chain_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ioc->scsi_lookup[i].cb_idx = 0xFF;
|
ioc->scsi_lookup[i].cb_idx = 0xFF;
|
||||||
ioc->scsi_lookup[i].scmd = NULL;
|
ioc->scsi_lookup[i].scmd = NULL;
|
||||||
ioc->scsi_lookup[i].direct_io = 0;
|
ioc->scsi_lookup[i].direct_io = 0;
|
||||||
list_add_tail(&ioc->scsi_lookup[i].tracker_list,
|
list_add(&ioc->scsi_lookup[i].tracker_list,
|
||||||
&ioc->free_list);
|
&ioc->free_list);
|
||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
|
|
||||||
|
@ -1764,13 +1764,13 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
|
||||||
/* hi-priority */
|
/* hi-priority */
|
||||||
i = smid - ioc->hi_priority_smid;
|
i = smid - ioc->hi_priority_smid;
|
||||||
ioc->hpr_lookup[i].cb_idx = 0xFF;
|
ioc->hpr_lookup[i].cb_idx = 0xFF;
|
||||||
list_add_tail(&ioc->hpr_lookup[i].tracker_list,
|
list_add(&ioc->hpr_lookup[i].tracker_list,
|
||||||
&ioc->hpr_free_list);
|
&ioc->hpr_free_list);
|
||||||
} else if (smid <= ioc->hba_queue_depth) {
|
} else if (smid <= ioc->hba_queue_depth) {
|
||||||
/* internal queue */
|
/* internal queue */
|
||||||
i = smid - ioc->internal_smid;
|
i = smid - ioc->internal_smid;
|
||||||
ioc->internal_lookup[i].cb_idx = 0xFF;
|
ioc->internal_lookup[i].cb_idx = 0xFF;
|
||||||
list_add_tail(&ioc->internal_lookup[i].tracker_list,
|
list_add(&ioc->internal_lookup[i].tracker_list,
|
||||||
&ioc->internal_free_list);
|
&ioc->internal_free_list);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
|
|
|
@ -1065,7 +1065,7 @@ void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
|
||||||
u32 reply);
|
u32 reply);
|
||||||
int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
|
int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
|
||||||
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
||||||
ulong timeout, unsigned long serial_number, enum mutex_type m_type);
|
ulong timeout, enum mutex_type m_type);
|
||||||
void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
|
void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
|
void mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
|
void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
|
||||||
|
|
|
@ -987,7 +987,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg,
|
||||||
mpt2sas_scsih_issue_tm(ioc,
|
mpt2sas_scsih_issue_tm(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
||||||
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
|
||||||
0, TM_MUTEX_ON);
|
TM_MUTEX_ON);
|
||||||
ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
|
ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
|
||||||
} else
|
} else
|
||||||
mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
|
|
|
@ -2368,7 +2368,6 @@ mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
||||||
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
||||||
* @smid_task: smid assigned to the task
|
* @smid_task: smid assigned to the task
|
||||||
* @timeout: timeout in seconds
|
* @timeout: timeout in seconds
|
||||||
* @serial_number: the serial_number from scmd
|
|
||||||
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
|
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
|
||||||
* Context: user
|
* Context: user
|
||||||
*
|
*
|
||||||
|
@ -2381,7 +2380,7 @@ mpt2sas_scsih_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle)
|
||||||
int
|
int
|
||||||
mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel,
|
mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
|
uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
|
||||||
unsigned long serial_number, enum mutex_type m_type)
|
enum mutex_type m_type)
|
||||||
{
|
{
|
||||||
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
||||||
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
||||||
|
@ -2634,8 +2633,7 @@ _scsih_abort(struct scsi_cmnd *scmd)
|
||||||
handle = sas_device_priv_data->sas_target->handle;
|
handle = sas_device_priv_data->sas_target->handle;
|
||||||
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
|
||||||
scmd->serial_number, TM_MUTEX_ON);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
||||||
|
@ -2696,8 +2694,7 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
|
||||||
|
|
||||||
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, 0,
|
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
|
||||||
TM_MUTEX_ON);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
||||||
|
@ -2757,7 +2754,7 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
|
||||||
|
|
||||||
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
30, 0, TM_MUTEX_ON);
|
30, TM_MUTEX_ON);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
||||||
|
@ -3953,9 +3950,9 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
||||||
* SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
|
* SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
_scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
||||||
{
|
{
|
||||||
struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
|
||||||
struct MPT2SAS_DEVICE *sas_device_priv_data;
|
struct MPT2SAS_DEVICE *sas_device_priv_data;
|
||||||
struct MPT2SAS_TARGET *sas_target_priv_data;
|
struct MPT2SAS_TARGET *sas_target_priv_data;
|
||||||
struct _raid_device *raid_device;
|
struct _raid_device *raid_device;
|
||||||
|
@ -3963,7 +3960,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
u32 mpi_control;
|
u32 mpi_control;
|
||||||
u16 smid;
|
u16 smid;
|
||||||
|
|
||||||
scmd->scsi_done = done;
|
|
||||||
sas_device_priv_data = scmd->device->hostdata;
|
sas_device_priv_data = scmd->device->hostdata;
|
||||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
||||||
scmd->result = DID_NO_CONNECT << 16;
|
scmd->result = DID_NO_CONNECT << 16;
|
||||||
|
@ -4039,7 +4035,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
MPT_TARGET_FLAGS_RAID_COMPONENT)
|
MPT_TARGET_FLAGS_RAID_COMPONENT)
|
||||||
mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
|
mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
|
||||||
else
|
else
|
||||||
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
||||||
mpi_request->DevHandle =
|
mpi_request->DevHandle =
|
||||||
cpu_to_le16(sas_device_priv_data->sas_target->handle);
|
cpu_to_le16(sas_device_priv_data->sas_target->handle);
|
||||||
mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
|
mpi_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
|
||||||
|
@ -4083,8 +4079,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEF_SCSI_QCMD(_scsih_qcmd)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
|
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
|
||||||
* @sense_buffer: sense data returned by target
|
* @sense_buffer: sense data returned by target
|
||||||
|
@ -5880,7 +5874,7 @@ broadcast_aen_retry:
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
r = mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
r = mpt2sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, 0,
|
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30,
|
||||||
TM_MUTEX_OFF);
|
TM_MUTEX_OFF);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
|
@ -5922,7 +5916,7 @@ broadcast_aen_retry:
|
||||||
|
|
||||||
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
||||||
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
||||||
scmd->serial_number, TM_MUTEX_OFF);
|
TM_MUTEX_OFF);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
"mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
||||||
|
|
|
@ -993,7 +993,7 @@ void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
|
||||||
|
|
||||||
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
uint channel, uint id, uint lun, u8 type, u16 smid_task,
|
||||||
ulong timeout, unsigned long serial_number, enum mutex_type m_type);
|
ulong timeout, enum mutex_type m_type);
|
||||||
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);
|
||||||
|
|
|
@ -980,7 +980,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
||||||
mpt3sas_scsih_issue_tm(ioc,
|
mpt3sas_scsih_issue_tm(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
|
||||||
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30,
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30,
|
||||||
0, TM_MUTEX_ON);
|
TM_MUTEX_ON);
|
||||||
} else
|
} else
|
||||||
mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
|
||||||
FORCE_BIG_HAMMER);
|
FORCE_BIG_HAMMER);
|
||||||
|
|
|
@ -2029,7 +2029,6 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
||||||
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
* @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in mpi2_init.h)
|
||||||
* @smid_task: smid assigned to the task
|
* @smid_task: smid assigned to the task
|
||||||
* @timeout: timeout in seconds
|
* @timeout: timeout in seconds
|
||||||
* @serial_number: the serial_number from scmd
|
|
||||||
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
|
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
|
||||||
* Context: user
|
* Context: user
|
||||||
*
|
*
|
||||||
|
@ -2042,7 +2041,7 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
||||||
int
|
int
|
||||||
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
|
||||||
uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
|
uint id, uint lun, u8 type, u16 smid_task, ulong timeout,
|
||||||
unsigned long serial_number, enum mutex_type m_type)
|
enum mutex_type m_type)
|
||||||
{
|
{
|
||||||
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
||||||
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
||||||
|
@ -2293,8 +2292,7 @@ _scsih_abort(struct scsi_cmnd *scmd)
|
||||||
handle = sas_device_priv_data->sas_target->handle;
|
handle = sas_device_priv_data->sas_target->handle;
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
|
||||||
scmd->serial_number, TM_MUTEX_ON);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
||||||
|
@ -2353,8 +2351,7 @@ _scsih_dev_reset(struct scsi_cmnd *scmd)
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, scmd->device->lun,
|
scmd->device->id, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, 0,
|
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
|
||||||
TM_MUTEX_ON);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
|
||||||
|
@ -2414,7 +2411,7 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
|
||||||
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
30, 0, TM_MUTEX_ON);
|
30, TM_MUTEX_ON);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
|
||||||
|
@ -3518,7 +3515,7 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _scsih_qcmd_lck - main scsi request entry point
|
* _scsih_qcmd - main scsi request entry point
|
||||||
* @scmd: pointer to scsi command object
|
* @scmd: pointer to scsi command object
|
||||||
* @done: function pointer to be invoked on completion
|
* @done: function pointer to be invoked on completion
|
||||||
*
|
*
|
||||||
|
@ -3529,9 +3526,9 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
|
||||||
* SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
|
* SCSI_MLQUEUE_HOST_BUSY if the entire host queue is full
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
_scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
|
||||||
{
|
{
|
||||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
|
||||||
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
||||||
struct MPT3SAS_TARGET *sas_target_priv_data;
|
struct MPT3SAS_TARGET *sas_target_priv_data;
|
||||||
Mpi2SCSIIORequest_t *mpi_request;
|
Mpi2SCSIIORequest_t *mpi_request;
|
||||||
|
@ -3544,7 +3541,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
scsi_print_command(scmd);
|
scsi_print_command(scmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scmd->scsi_done = done;
|
|
||||||
sas_device_priv_data = scmd->device->hostdata;
|
sas_device_priv_data = scmd->device->hostdata;
|
||||||
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
|
||||||
scmd->result = DID_NO_CONNECT << 16;
|
scmd->result = DID_NO_CONNECT << 16;
|
||||||
|
@ -3659,8 +3655,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
out:
|
out:
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
}
|
}
|
||||||
static DEF_SCSI_QCMD(_scsih_qcmd)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
|
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
|
||||||
|
@ -5425,7 +5419,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, 0, 0, lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30, 0,
|
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, smid, 30,
|
||||||
TM_MUTEX_OFF);
|
TM_MUTEX_OFF);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
|
@ -5467,7 +5461,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
|
||||||
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
|
||||||
scmd->serial_number, TM_MUTEX_OFF);
|
TM_MUTEX_OFF);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
||||||
|
|
|
@ -728,6 +728,15 @@ static struct pci_device_id mvs_pci_table[] = {
|
||||||
.class_mask = 0,
|
.class_mask = 0,
|
||||||
.driver_data = chip_9485,
|
.driver_data = chip_9485,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.vendor = PCI_VENDOR_ID_MARVELL_EXT,
|
||||||
|
.device = 0x9485,
|
||||||
|
.subvendor = PCI_ANY_ID,
|
||||||
|
.subdevice = 0x9485,
|
||||||
|
.class = 0,
|
||||||
|
.class_mask = 0,
|
||||||
|
.driver_data = chip_9485,
|
||||||
|
},
|
||||||
{ PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */
|
{ PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */
|
||||||
{ PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
|
{ PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
|
||||||
{ PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
|
{ PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
|
||||||
|
|
|
@ -129,8 +129,6 @@ static int pas16_bus_reset(Scsi_Cmnd *);
|
||||||
#define CAN_QUEUE 32
|
#define CAN_QUEUE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HOSTS_C
|
|
||||||
|
|
||||||
#define NCR5380_implementation_fields \
|
#define NCR5380_implementation_fields \
|
||||||
volatile unsigned short io_port
|
volatile unsigned short io_port
|
||||||
|
|
||||||
|
@ -171,6 +169,5 @@ static int pas16_bus_reset(Scsi_Cmnd *);
|
||||||
|
|
||||||
#define PAS16_IRQS 0xd4a8
|
#define PAS16_IRQS 0xd4a8
|
||||||
|
|
||||||
#endif /* else def HOSTS_C */
|
|
||||||
#endif /* ndef ASM */
|
#endif /* ndef ASM */
|
||||||
#endif /* PAS16_H */
|
#endif /* PAS16_H */
|
||||||
|
|
|
@ -395,6 +395,8 @@ static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
|
||||||
payload.offset = 0;
|
payload.offset = 0;
|
||||||
payload.length = 4096;
|
payload.length = 4096;
|
||||||
payload.func_specific = kzalloc(4096, GFP_KERNEL);
|
payload.func_specific = kzalloc(4096, GFP_KERNEL);
|
||||||
|
if (!payload.func_specific)
|
||||||
|
return -ENOMEM;
|
||||||
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
|
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
|
||||||
wait_for_completion(&completion);
|
wait_for_completion(&completion);
|
||||||
virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
|
virt_addr = pm8001_ha->memoryMap.region[NVMD].virt_ptr;
|
||||||
|
@ -402,6 +404,7 @@ static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
|
||||||
bios_index++)
|
bios_index++)
|
||||||
str += sprintf(str, "%c",
|
str += sprintf(str, "%c",
|
||||||
*((u8 *)((u8 *)virt_addr+bios_index)));
|
*((u8 *)((u8 *)virt_addr+bios_index)));
|
||||||
|
kfree(payload.func_specific);
|
||||||
return str - buf;
|
return str - buf;
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(bios_version, S_IRUGO, pm8001_ctl_bios_version_show, NULL);
|
static DEVICE_ATTR(bios_version, S_IRUGO, pm8001_ctl_bios_version_show, NULL);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -664,7 +664,7 @@ do_read:
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data,
|
rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data,
|
||||||
addr, offset, SFP_BLOCK_SIZE, 0);
|
addr, offset, SFP_BLOCK_SIZE, BIT_1);
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
ql_log(ql_log_warn, vha, 0x706d,
|
ql_log(ql_log_warn, vha, 0x706d,
|
||||||
"Unable to read SFP data (%x/%x/%x).\n", rval,
|
"Unable to read SFP data (%x/%x/%x).\n", rval,
|
||||||
|
@ -1495,7 +1495,7 @@ qla2x00_fw_dump_size_show(struct device *dev, struct device_attribute *attr,
|
||||||
|
|
||||||
if (!ha->fw_dumped)
|
if (!ha->fw_dumped)
|
||||||
size = 0;
|
size = 0;
|
||||||
else if (IS_QLA82XX(ha))
|
else if (IS_P3P_TYPE(ha))
|
||||||
size = ha->md_template_size + ha->md_dump_size;
|
size = ha->md_template_size + ha->md_dump_size;
|
||||||
else
|
else
|
||||||
size = ha->fw_dump_len;
|
size = ha->fw_dump_len;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2012 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -2054,9 +2054,49 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
|
||||||
bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
|
bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ql_log(ql_log_warn, vha, 0x708c,
|
ql_dbg(ql_dbg_user, vha, 0x708c,
|
||||||
"Unknown serdes cmd %x.\n", sr.cmd);
|
"Unknown serdes cmd %x.\n", sr.cmd);
|
||||||
rval = -EDOM;
|
rval = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
|
||||||
|
rval ? EXT_STATUS_MAILBOX : 0;
|
||||||
|
|
||||||
|
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
|
||||||
|
bsg_job->reply->result = DID_OK << 16;
|
||||||
|
bsg_job->job_done(bsg_job);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla8044_serdes_op(struct fc_bsg_job *bsg_job)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *host = bsg_job->shost;
|
||||||
|
scsi_qla_host_t *vha = shost_priv(host);
|
||||||
|
int rval = 0;
|
||||||
|
struct qla_serdes_reg_ex sr;
|
||||||
|
|
||||||
|
memset(&sr, 0, sizeof(sr));
|
||||||
|
|
||||||
|
sg_copy_to_buffer(bsg_job->request_payload.sg_list,
|
||||||
|
bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
|
||||||
|
|
||||||
|
switch (sr.cmd) {
|
||||||
|
case INT_SC_SERDES_WRITE_REG:
|
||||||
|
rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
|
||||||
|
bsg_job->reply->reply_payload_rcv_len = 0;
|
||||||
|
break;
|
||||||
|
case INT_SC_SERDES_READ_REG:
|
||||||
|
rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
|
||||||
|
sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
|
||||||
|
bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
|
||||||
|
bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ql_dbg(ql_dbg_user, vha, 0x70cf,
|
||||||
|
"Unknown serdes cmd %x.\n", sr.cmd);
|
||||||
|
rval = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2121,6 +2161,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
|
||||||
case QL_VND_SERDES_OP:
|
case QL_VND_SERDES_OP:
|
||||||
return qla26xx_serdes_op(bsg_job);
|
return qla26xx_serdes_op(bsg_job);
|
||||||
|
|
||||||
|
case QL_VND_SERDES_OP_EX:
|
||||||
|
return qla8044_serdes_op(bsg_job);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#define QL_VND_READ_I2C 0x11
|
#define QL_VND_READ_I2C 0x11
|
||||||
#define QL_VND_FX00_MGMT_CMD 0x12
|
#define QL_VND_FX00_MGMT_CMD 0x12
|
||||||
#define QL_VND_SERDES_OP 0x13
|
#define QL_VND_SERDES_OP 0x13
|
||||||
|
#define QL_VND_SERDES_OP_EX 0x14
|
||||||
|
|
||||||
/* BSG Vendor specific subcode returns */
|
/* BSG Vendor specific subcode returns */
|
||||||
#define EXT_STATUS_OK 0
|
#define EXT_STATUS_OK 0
|
||||||
|
@ -225,4 +226,10 @@ struct qla_serdes_reg {
|
||||||
uint16_t val;
|
uint16_t val;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct qla_serdes_reg_ex {
|
||||||
|
uint16_t cmd;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t val;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
* | | | 0x0144,0x0146 |
|
* | | | 0x0144,0x0146 |
|
||||||
* | | | 0x015b-0x0160 |
|
* | | | 0x015b-0x0160 |
|
||||||
* | | | 0x016e-0x0170 |
|
* | | | 0x016e-0x0170 |
|
||||||
* | Mailbox commands | 0x1187 | 0x1018-0x1019 |
|
* | Mailbox commands | 0x118d | 0x1018-0x1019 |
|
||||||
* | | | 0x10ca |
|
* | | | 0x10ca |
|
||||||
* | | | 0x1115-0x1116 |
|
* | | | 0x1115-0x1116 |
|
||||||
* | | | 0x111a-0x111b |
|
* | | | 0x111a-0x111b |
|
||||||
|
@ -45,12 +45,16 @@
|
||||||
* | | | 0x70ad-0x70ae |
|
* | | | 0x70ad-0x70ae |
|
||||||
* | | | 0x70d7-0x70db |
|
* | | | 0x70d7-0x70db |
|
||||||
* | | | 0x70de-0x70df |
|
* | | | 0x70de-0x70df |
|
||||||
* | Task Management | 0x803d | 0x8025-0x8026 |
|
* | Task Management | 0x803d | 0x8000,0x800b |
|
||||||
* | | | 0x800b,0x8039 |
|
* | | | 0x8019 |
|
||||||
|
* | | | 0x8025,0x8026 |
|
||||||
|
* | | | 0x8031,0x8032 |
|
||||||
|
* | | | 0x8039,0x803c |
|
||||||
* | AER/EEH | 0x9011 | |
|
* | AER/EEH | 0x9011 | |
|
||||||
* | Virtual Port | 0xa007 | |
|
* | Virtual Port | 0xa007 | |
|
||||||
* | ISP82XX Specific | 0xb14c | 0xb002,0xb024 |
|
* | ISP82XX Specific | 0xb157 | 0xb002,0xb024 |
|
||||||
* | | | 0xb09e,0xb0ae |
|
* | | | 0xb09e,0xb0ae |
|
||||||
|
* | | | 0xb0c3,0xb0c6 |
|
||||||
* | | | 0xb0e0-0xb0ef |
|
* | | | 0xb0e0-0xb0ef |
|
||||||
* | | | 0xb085,0xb0dc |
|
* | | | 0xb085,0xb0dc |
|
||||||
* | | | 0xb107,0xb108 |
|
* | | | 0xb107,0xb108 |
|
||||||
|
@ -60,12 +64,12 @@
|
||||||
* | | | 0xb13c-0xb140 |
|
* | | | 0xb13c-0xb140 |
|
||||||
* | | | 0xb149 |
|
* | | | 0xb149 |
|
||||||
* | MultiQ | 0xc00c | |
|
* | MultiQ | 0xc00c | |
|
||||||
* | Misc | 0xd2ff | 0xd017-0xd019 |
|
* | Misc | 0xd212 | 0xd017-0xd019 |
|
||||||
* | | | 0xd020 |
|
* | | | 0xd020 |
|
||||||
* | | | 0xd02e-0xd0ff |
|
* | | | 0xd030-0xd0ff |
|
||||||
* | | | 0xd101-0xd1fe |
|
* | | | 0xd101-0xd1fe |
|
||||||
* | | | 0xd212-0xd2fe |
|
* | | | 0xd213-0xd2fe |
|
||||||
* | Target Mode | 0xe070 | 0xe021 |
|
* | Target Mode | 0xe078 | |
|
||||||
* | Target Mode Management | 0xf072 | 0xf002-0xf003 |
|
* | Target Mode Management | 0xf072 | 0xf002-0xf003 |
|
||||||
* | | | 0xf046-0xf049 |
|
* | | | 0xf046-0xf049 |
|
||||||
* | Target Mode Task Management | 0x1000b | |
|
* | Target Mode Task Management | 0x1000b | |
|
||||||
|
@ -277,9 +281,15 @@ qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram,
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
return rval;
|
return rval;
|
||||||
|
|
||||||
|
set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
|
||||||
|
|
||||||
/* External Memory. */
|
/* External Memory. */
|
||||||
return qla24xx_dump_ram(ha, 0x100000, *nxt,
|
rval = qla24xx_dump_ram(ha, 0x100000, *nxt,
|
||||||
ha->fw_memory_size - 0x100000 + 1, nxt);
|
ha->fw_memory_size - 0x100000 + 1, nxt);
|
||||||
|
if (rval == QLA_SUCCESS)
|
||||||
|
set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags);
|
||||||
|
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t *
|
static uint32_t *
|
||||||
|
@ -296,23 +306,15 @@ qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
|
qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
int rval = QLA_SUCCESS;
|
|
||||||
uint32_t cnt;
|
|
||||||
|
|
||||||
WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE);
|
WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE);
|
||||||
for (cnt = 30000;
|
|
||||||
((RD_REG_DWORD(®->host_status) & HSRX_RISC_PAUSED) == 0) &&
|
|
||||||
rval == QLA_SUCCESS; cnt--) {
|
|
||||||
if (cnt)
|
|
||||||
udelay(100);
|
|
||||||
else
|
|
||||||
rval = QLA_FUNCTION_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
/* 100 usec delay is sufficient enough for hardware to pause RISC */
|
||||||
|
udelay(100);
|
||||||
|
if (RD_REG_DWORD(®->host_status) & HSRX_RISC_PAUSED)
|
||||||
|
set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -320,10 +322,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
int rval = QLA_SUCCESS;
|
int rval = QLA_SUCCESS;
|
||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
uint16_t mb0, wd;
|
uint16_t wd;
|
||||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||||
|
|
||||||
/* Reset RISC. */
|
/*
|
||||||
|
* Reset RISC. The delay is dependent on system architecture.
|
||||||
|
* Driver can proceed with the reset sequence after waiting
|
||||||
|
* for a timeout period.
|
||||||
|
*/
|
||||||
WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
|
WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
|
||||||
for (cnt = 0; cnt < 30000; cnt++) {
|
for (cnt = 0; cnt < 30000; cnt++) {
|
||||||
if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
|
if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
|
||||||
|
@ -331,19 +337,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
|
||||||
|
|
||||||
udelay(10);
|
udelay(10);
|
||||||
}
|
}
|
||||||
|
if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE))
|
||||||
|
set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
|
||||||
|
|
||||||
WRT_REG_DWORD(®->ctrl_status,
|
WRT_REG_DWORD(®->ctrl_status,
|
||||||
CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
|
CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
|
||||||
pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
|
pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
|
||||||
|
|
||||||
udelay(100);
|
udelay(100);
|
||||||
/* Wait for firmware to complete NVRAM accesses. */
|
|
||||||
mb0 = (uint32_t) RD_REG_WORD(®->mailbox0);
|
|
||||||
for (cnt = 10000 ; cnt && mb0; cnt--) {
|
|
||||||
udelay(5);
|
|
||||||
mb0 = (uint32_t) RD_REG_WORD(®->mailbox0);
|
|
||||||
barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for soft-reset to complete. */
|
/* Wait for soft-reset to complete. */
|
||||||
for (cnt = 0; cnt < 30000; cnt++) {
|
for (cnt = 0; cnt < 30000; cnt++) {
|
||||||
|
@ -353,16 +354,21 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
|
||||||
|
|
||||||
udelay(10);
|
udelay(10);
|
||||||
}
|
}
|
||||||
|
if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET))
|
||||||
|
set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
|
||||||
|
|
||||||
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET);
|
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET);
|
||||||
RD_REG_DWORD(®->hccr); /* PCI Posting. */
|
RD_REG_DWORD(®->hccr); /* PCI Posting. */
|
||||||
|
|
||||||
for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 &&
|
for (cnt = 10000; RD_REG_WORD(®->mailbox0) != 0 &&
|
||||||
rval == QLA_SUCCESS; cnt--) {
|
rval == QLA_SUCCESS; cnt--) {
|
||||||
if (cnt)
|
if (cnt)
|
||||||
udelay(100);
|
udelay(10);
|
||||||
else
|
else
|
||||||
rval = QLA_FUNCTION_TIMEOUT;
|
rval = QLA_FUNCTION_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
if (rval == QLA_SUCCESS)
|
||||||
|
set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -659,12 +665,13 @@ qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
|
||||||
|
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
ql_log(ql_log_warn, vha, 0xd000,
|
ql_log(ql_log_warn, vha, 0xd000,
|
||||||
"Failed to dump firmware (%x).\n", rval);
|
"Failed to dump firmware (%x), dump status flags (0x%lx).\n",
|
||||||
|
rval, ha->fw_dump_cap_flags);
|
||||||
ha->fw_dumped = 0;
|
ha->fw_dumped = 0;
|
||||||
} else {
|
} else {
|
||||||
ql_log(ql_log_info, vha, 0xd001,
|
ql_log(ql_log_info, vha, 0xd001,
|
||||||
"Firmware dump saved to temp buffer (%ld/%p).\n",
|
"Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
|
||||||
vha->host_no, ha->fw_dump);
|
vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
|
||||||
ha->fw_dumped = 1;
|
ha->fw_dumped = 1;
|
||||||
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
|
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
|
||||||
}
|
}
|
||||||
|
@ -1053,6 +1060,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
risc_address = ext_mem_cnt = 0;
|
risc_address = ext_mem_cnt = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
|
|
||||||
if (!hardware_locked)
|
if (!hardware_locked)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
@ -1075,10 +1083,11 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
||||||
|
|
||||||
/* Pause RISC. */
|
/*
|
||||||
rval = qla24xx_pause_risc(reg);
|
* Pause RISC. No need to track timeout, as resetting the chip
|
||||||
if (rval != QLA_SUCCESS)
|
* is the right approach incase of pause timeout
|
||||||
goto qla24xx_fw_dump_failed_0;
|
*/
|
||||||
|
qla24xx_pause_risc(reg, ha);
|
||||||
|
|
||||||
/* Host interface registers. */
|
/* Host interface registers. */
|
||||||
dmp_reg = ®->flash_addr;
|
dmp_reg = ®->flash_addr;
|
||||||
|
@ -1302,6 +1311,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
risc_address = ext_mem_cnt = 0;
|
risc_address = ext_mem_cnt = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
|
|
||||||
if (!hardware_locked)
|
if (!hardware_locked)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
@ -1325,10 +1335,11 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
||||||
|
|
||||||
/* Pause RISC. */
|
/*
|
||||||
rval = qla24xx_pause_risc(reg);
|
* Pause RISC. No need to track timeout, as resetting the chip
|
||||||
if (rval != QLA_SUCCESS)
|
* is the right approach incase of pause timeout
|
||||||
goto qla25xx_fw_dump_failed_0;
|
*/
|
||||||
|
qla24xx_pause_risc(reg, ha);
|
||||||
|
|
||||||
/* Host/Risc registers. */
|
/* Host/Risc registers. */
|
||||||
iter_reg = fw->host_risc_reg;
|
iter_reg = fw->host_risc_reg;
|
||||||
|
@ -1619,6 +1630,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
risc_address = ext_mem_cnt = 0;
|
risc_address = ext_mem_cnt = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
|
|
||||||
if (!hardware_locked)
|
if (!hardware_locked)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
@ -1641,10 +1653,11 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
||||||
|
|
||||||
/* Pause RISC. */
|
/*
|
||||||
rval = qla24xx_pause_risc(reg);
|
* Pause RISC. No need to track timeout, as resetting the chip
|
||||||
if (rval != QLA_SUCCESS)
|
* is the right approach incase of pause timeout
|
||||||
goto qla81xx_fw_dump_failed_0;
|
*/
|
||||||
|
qla24xx_pause_risc(reg, ha);
|
||||||
|
|
||||||
/* Host/Risc registers. */
|
/* Host/Risc registers. */
|
||||||
iter_reg = fw->host_risc_reg;
|
iter_reg = fw->host_risc_reg;
|
||||||
|
@ -1938,6 +1951,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
risc_address = ext_mem_cnt = 0;
|
risc_address = ext_mem_cnt = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
|
|
||||||
if (!hardware_locked)
|
if (!hardware_locked)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
@ -1959,10 +1973,11 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
|
|
||||||
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
fw->host_status = htonl(RD_REG_DWORD(®->host_status));
|
||||||
|
|
||||||
/* Pause RISC. */
|
/*
|
||||||
rval = qla24xx_pause_risc(reg);
|
* Pause RISC. No need to track timeout, as resetting the chip
|
||||||
if (rval != QLA_SUCCESS)
|
* is the right approach incase of pause timeout
|
||||||
goto qla83xx_fw_dump_failed_0;
|
*/
|
||||||
|
qla24xx_pause_risc(reg, ha);
|
||||||
|
|
||||||
WRT_REG_DWORD(®->iobase_addr, 0x6000);
|
WRT_REG_DWORD(®->iobase_addr, 0x6000);
|
||||||
dmp_reg = ®->iobase_window;
|
dmp_reg = ®->iobase_window;
|
||||||
|
@ -2385,9 +2400,11 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||||
nxt += sizeof(fw->code_ram);
|
nxt += sizeof(fw->code_ram);
|
||||||
nxt += (ha->fw_memory_size - 0x100000 + 1);
|
nxt += (ha->fw_memory_size - 0x100000 + 1);
|
||||||
goto copy_queue;
|
goto copy_queue;
|
||||||
} else
|
} else {
|
||||||
|
set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
|
||||||
ql_log(ql_log_warn, vha, 0xd010,
|
ql_log(ql_log_warn, vha, 0xd010,
|
||||||
"bigger hammer success?\n");
|
"bigger hammer success?\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
|
rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -353,5 +353,6 @@ extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
|
||||||
uint32_t, void **);
|
uint32_t, void **);
|
||||||
extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
|
extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
|
||||||
uint32_t, void **);
|
uint32_t, void **);
|
||||||
extern int qla24xx_pause_risc(struct device_reg_24xx __iomem *);
|
extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *,
|
||||||
|
struct qla_hw_data *);
|
||||||
extern int qla24xx_soft_reset(struct qla_hw_data *);
|
extern int qla24xx_soft_reset(struct qla_hw_data *);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -965,6 +965,13 @@ struct mbx_cmd_32 {
|
||||||
*/
|
*/
|
||||||
#define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */
|
#define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ISP8044 mailbox commands
|
||||||
|
*/
|
||||||
|
#define MBC_SET_GET_ETH_SERDES_REG 0x150
|
||||||
|
#define HCS_WRITE_SERDES 0x3
|
||||||
|
#define HCS_READ_SERDES 0x4
|
||||||
|
|
||||||
/* Firmware return data sizes */
|
/* Firmware return data sizes */
|
||||||
#define FCAL_MAP_SIZE 128
|
#define FCAL_MAP_SIZE 128
|
||||||
|
|
||||||
|
@ -1622,10 +1629,20 @@ typedef struct {
|
||||||
#define PO_MODE_DIF_PASS 2
|
#define PO_MODE_DIF_PASS 2
|
||||||
#define PO_MODE_DIF_REPLACE 3
|
#define PO_MODE_DIF_REPLACE 3
|
||||||
#define PO_MODE_DIF_TCP_CKSUM 6
|
#define PO_MODE_DIF_TCP_CKSUM 6
|
||||||
#define PO_ENABLE_DIF_BUNDLING BIT_8
|
|
||||||
#define PO_ENABLE_INCR_GUARD_SEED BIT_3
|
#define PO_ENABLE_INCR_GUARD_SEED BIT_3
|
||||||
#define PO_DISABLE_INCR_REF_TAG BIT_5
|
|
||||||
#define PO_DISABLE_GUARD_CHECK BIT_4
|
#define PO_DISABLE_GUARD_CHECK BIT_4
|
||||||
|
#define PO_DISABLE_INCR_REF_TAG BIT_5
|
||||||
|
#define PO_DIS_HEADER_MODE BIT_7
|
||||||
|
#define PO_ENABLE_DIF_BUNDLING BIT_8
|
||||||
|
#define PO_DIS_FRAME_MODE BIT_9
|
||||||
|
#define PO_DIS_VALD_APP_ESC BIT_10 /* Dis validation for escape tag/ffffh */
|
||||||
|
#define PO_DIS_VALD_APP_REF_ESC BIT_11
|
||||||
|
|
||||||
|
#define PO_DIS_APP_TAG_REPL BIT_12 /* disable REG Tag replacement */
|
||||||
|
#define PO_DIS_REF_TAG_REPL BIT_13
|
||||||
|
#define PO_DIS_APP_TAG_VALD BIT_14 /* disable REF Tag validation */
|
||||||
|
#define PO_DIS_REF_TAG_VALD BIT_15
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISP queue - 64-Bit addressing, continuation crc entry structure definition.
|
* ISP queue - 64-Bit addressing, continuation crc entry structure definition.
|
||||||
*/
|
*/
|
||||||
|
@ -1748,6 +1765,8 @@ typedef struct {
|
||||||
#define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */
|
#define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */
|
||||||
#define CS_PORT_BUSY 0x2B /* Port Busy */
|
#define CS_PORT_BUSY 0x2B /* Port Busy */
|
||||||
#define CS_COMPLETE_CHKCOND 0x30 /* Error? */
|
#define CS_COMPLETE_CHKCOND 0x30 /* Error? */
|
||||||
|
#define CS_IOCB_ERROR 0x31 /* Generic error for IOCB request
|
||||||
|
failure */
|
||||||
#define CS_BAD_PAYLOAD 0x80 /* Driver defined */
|
#define CS_BAD_PAYLOAD 0x80 /* Driver defined */
|
||||||
#define CS_UNKNOWN 0x81 /* Driver defined */
|
#define CS_UNKNOWN 0x81 /* Driver defined */
|
||||||
#define CS_RETRY 0x82 /* Driver defined */
|
#define CS_RETRY 0x82 /* Driver defined */
|
||||||
|
@ -2676,6 +2695,7 @@ struct rsp_que {
|
||||||
uint32_t __iomem *rsp_q_out;
|
uint32_t __iomem *rsp_q_out;
|
||||||
uint16_t ring_index;
|
uint16_t ring_index;
|
||||||
uint16_t out_ptr;
|
uint16_t out_ptr;
|
||||||
|
uint16_t *in_ptr; /* queue shadow in index */
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint16_t options;
|
uint16_t options;
|
||||||
uint16_t rid;
|
uint16_t rid;
|
||||||
|
@ -2702,6 +2722,7 @@ struct req_que {
|
||||||
uint32_t __iomem *req_q_out;
|
uint32_t __iomem *req_q_out;
|
||||||
uint16_t ring_index;
|
uint16_t ring_index;
|
||||||
uint16_t in_ptr;
|
uint16_t in_ptr;
|
||||||
|
uint16_t *out_ptr; /* queue shadow out index */
|
||||||
uint16_t cnt;
|
uint16_t cnt;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint16_t options;
|
uint16_t options;
|
||||||
|
@ -2907,6 +2928,8 @@ struct qla_hw_data {
|
||||||
#define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031
|
#define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031
|
||||||
#define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031
|
#define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031
|
||||||
#define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071
|
#define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071
|
||||||
|
#define PCI_DEVICE_ID_QLOGIC_ISP2271 0x2271
|
||||||
|
|
||||||
uint32_t device_type;
|
uint32_t device_type;
|
||||||
#define DT_ISP2100 BIT_0
|
#define DT_ISP2100 BIT_0
|
||||||
#define DT_ISP2200 BIT_1
|
#define DT_ISP2200 BIT_1
|
||||||
|
@ -2928,7 +2951,8 @@ struct qla_hw_data {
|
||||||
#define DT_ISPFX00 BIT_17
|
#define DT_ISPFX00 BIT_17
|
||||||
#define DT_ISP8044 BIT_18
|
#define DT_ISP8044 BIT_18
|
||||||
#define DT_ISP2071 BIT_19
|
#define DT_ISP2071 BIT_19
|
||||||
#define DT_ISP_LAST (DT_ISP2071 << 1)
|
#define DT_ISP2271 BIT_20
|
||||||
|
#define DT_ISP_LAST (DT_ISP2271 << 1)
|
||||||
|
|
||||||
#define DT_T10_PI BIT_25
|
#define DT_T10_PI BIT_25
|
||||||
#define DT_IIDMA BIT_26
|
#define DT_IIDMA BIT_26
|
||||||
|
@ -2959,6 +2983,7 @@ struct qla_hw_data {
|
||||||
#define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031)
|
#define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031)
|
||||||
#define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00)
|
#define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00)
|
||||||
#define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071)
|
#define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071)
|
||||||
|
#define IS_QLA2271(ha) (DT_MASK(ha) & DT_ISP2271)
|
||||||
|
|
||||||
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
||||||
IS_QLA6312(ha) || IS_QLA6322(ha))
|
IS_QLA6312(ha) || IS_QLA6322(ha))
|
||||||
|
@ -2967,7 +2992,7 @@ struct qla_hw_data {
|
||||||
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
|
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
|
||||||
#define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha))
|
#define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha))
|
||||||
#define IS_QLA84XX(ha) (IS_QLA8432(ha))
|
#define IS_QLA84XX(ha) (IS_QLA8432(ha))
|
||||||
#define IS_QLA27XX(ha) (IS_QLA2071(ha))
|
#define IS_QLA27XX(ha) (IS_QLA2071(ha) || IS_QLA2271(ha))
|
||||||
#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
|
#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
|
||||||
IS_QLA84XX(ha))
|
IS_QLA84XX(ha))
|
||||||
#define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \
|
#define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \
|
||||||
|
@ -3006,6 +3031,7 @@ struct qla_hw_data {
|
||||||
(((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22))
|
(((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22))
|
||||||
#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha))
|
#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha))
|
||||||
#define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length)
|
#define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length)
|
||||||
|
#define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha))
|
||||||
|
|
||||||
/* HBA serial number */
|
/* HBA serial number */
|
||||||
uint8_t serial0;
|
uint8_t serial0;
|
||||||
|
@ -3136,7 +3162,15 @@ struct qla_hw_data {
|
||||||
struct qla2xxx_fw_dump *fw_dump;
|
struct qla2xxx_fw_dump *fw_dump;
|
||||||
uint32_t fw_dump_len;
|
uint32_t fw_dump_len;
|
||||||
int fw_dumped;
|
int fw_dumped;
|
||||||
|
unsigned long fw_dump_cap_flags;
|
||||||
|
#define RISC_PAUSE_CMPL 0
|
||||||
|
#define DMA_SHUTDOWN_CMPL 1
|
||||||
|
#define ISP_RESET_CMPL 2
|
||||||
|
#define RISC_RDY_AFT_RESET 3
|
||||||
|
#define RISC_SRAM_DUMP_CMPL 4
|
||||||
|
#define RISC_EXT_MEM_DUMP_CMPL 5
|
||||||
int fw_dump_reading;
|
int fw_dump_reading;
|
||||||
|
int prev_minidump_failed;
|
||||||
dma_addr_t eft_dma;
|
dma_addr_t eft_dma;
|
||||||
void *eft;
|
void *eft;
|
||||||
/* Current size of mctp dump is 0x086064 bytes */
|
/* Current size of mctp dump is 0x086064 bytes */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -371,7 +371,10 @@ struct init_cb_24xx {
|
||||||
* BIT 14 = Data Rate bit 1
|
* BIT 14 = Data Rate bit 1
|
||||||
* BIT 15 = Data Rate bit 2
|
* BIT 15 = Data Rate bit 2
|
||||||
* BIT 16 = Enable 75 ohm Termination Select
|
* BIT 16 = Enable 75 ohm Termination Select
|
||||||
* BIT 17-31 = Reserved
|
* BIT 17-28 = Reserved
|
||||||
|
* BIT 29 = Enable response queue 0 in index shadowing
|
||||||
|
* BIT 30 = Enable request queue 0 out index shadowing
|
||||||
|
* BIT 31 = Reserved
|
||||||
*/
|
*/
|
||||||
uint32_t firmware_options_3;
|
uint32_t firmware_options_3;
|
||||||
uint16_t qos;
|
uint16_t qos;
|
||||||
|
@ -1134,13 +1137,6 @@ struct device_reg_24xx {
|
||||||
#define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */
|
#define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */
|
||||||
#define MAX_MULTI_ID_FABRIC 256 /* ... */
|
#define MAX_MULTI_ID_FABRIC 256 /* ... */
|
||||||
|
|
||||||
#define for_each_mapped_vp_idx(_ha, _idx) \
|
|
||||||
for (_idx = find_next_bit((_ha)->vp_idx_map, \
|
|
||||||
(_ha)->max_npiv_vports + 1, 1); \
|
|
||||||
_idx <= (_ha)->max_npiv_vports; \
|
|
||||||
_idx = find_next_bit((_ha)->vp_idx_map, \
|
|
||||||
(_ha)->max_npiv_vports + 1, _idx + 1)) \
|
|
||||||
|
|
||||||
struct mid_conf_entry_24xx {
|
struct mid_conf_entry_24xx {
|
||||||
uint16_t reserved_1;
|
uint16_t reserved_1;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -220,6 +220,13 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *);
|
||||||
|
|
||||||
extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
|
extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *);
|
||||||
extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
|
extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
|
||||||
|
extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
|
||||||
|
uint32_t *, uint16_t, struct qla_tgt_cmd *);
|
||||||
|
extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *,
|
||||||
|
uint32_t *, uint16_t, struct qla_tgt_cmd *);
|
||||||
|
extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
|
||||||
|
uint32_t *, uint16_t, struct qla_tgt_cmd *);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global Function Prototypes in qla_mbx.c source file.
|
* Global Function Prototypes in qla_mbx.c source file.
|
||||||
|
@ -346,6 +353,11 @@ qla2x00_write_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t);
|
||||||
extern int
|
extern int
|
||||||
qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *);
|
qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
qla8044_write_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t);
|
||||||
|
extern int
|
||||||
|
qla8044_read_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t *);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
|
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -1476,6 +1476,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
|
||||||
}
|
}
|
||||||
|
|
||||||
ha->fw_dumped = 0;
|
ha->fw_dumped = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
|
dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
|
||||||
req_q_size = rsp_q_size = 0;
|
req_q_size = rsp_q_size = 0;
|
||||||
|
|
||||||
|
@ -2061,6 +2062,10 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
|
||||||
icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma));
|
icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma));
|
||||||
icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma));
|
icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma));
|
||||||
|
|
||||||
|
if (IS_SHADOW_REG_CAPABLE(ha))
|
||||||
|
icb->firmware_options_2 |=
|
||||||
|
__constant_cpu_to_le32(BIT_30|BIT_29);
|
||||||
|
|
||||||
if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
|
if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
|
||||||
icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS);
|
icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS);
|
||||||
icb->rid = __constant_cpu_to_le16(rid);
|
icb->rid = __constant_cpu_to_le16(rid);
|
||||||
|
@ -2138,6 +2143,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
||||||
req = ha->req_q_map[que];
|
req = ha->req_q_map[que];
|
||||||
if (!req)
|
if (!req)
|
||||||
continue;
|
continue;
|
||||||
|
req->out_ptr = (void *)(req->ring + req->length);
|
||||||
|
*req->out_ptr = 0;
|
||||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
|
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
|
||||||
req->outstanding_cmds[cnt] = NULL;
|
req->outstanding_cmds[cnt] = NULL;
|
||||||
|
|
||||||
|
@ -2153,6 +2160,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
||||||
rsp = ha->rsp_q_map[que];
|
rsp = ha->rsp_q_map[que];
|
||||||
if (!rsp)
|
if (!rsp)
|
||||||
continue;
|
continue;
|
||||||
|
rsp->in_ptr = (void *)(rsp->ring + rsp->length);
|
||||||
|
*rsp->in_ptr = 0;
|
||||||
/* Initialize response queue entries */
|
/* Initialize response queue entries */
|
||||||
if (IS_QLAFX00(ha))
|
if (IS_QLAFX00(ha))
|
||||||
qlafx00_init_response_q_entries(rsp);
|
qlafx00_init_response_q_entries(rsp);
|
||||||
|
@ -3406,7 +3415,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
|
||||||
fcport->d_id.b.domain,
|
fcport->d_id.b.domain,
|
||||||
fcport->d_id.b.area,
|
fcport->d_id.b.area,
|
||||||
fcport->d_id.b.al_pa);
|
fcport->d_id.b.al_pa);
|
||||||
fcport->loop_id = FC_NO_LOOP_ID;
|
qla2x00_clear_loop_id(fcport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4727,7 +4736,6 @@ static int
|
||||||
qla2x00_restart_isp(scsi_qla_host_t *vha)
|
qla2x00_restart_isp(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
uint32_t wait_time;
|
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
struct req_que *req = ha->req_q_map[0];
|
struct req_que *req = ha->req_q_map[0];
|
||||||
struct rsp_que *rsp = ha->rsp_q_map[0];
|
struct rsp_que *rsp = ha->rsp_q_map[0];
|
||||||
|
@ -4744,14 +4752,12 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
||||||
if (!status && !(status = qla2x00_init_rings(vha))) {
|
if (!status && !(status = qla2x00_init_rings(vha))) {
|
||||||
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
|
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
|
||||||
ha->flags.chip_reset_done = 1;
|
ha->flags.chip_reset_done = 1;
|
||||||
|
|
||||||
/* Initialize the queues in use */
|
/* Initialize the queues in use */
|
||||||
qla25xx_init_queues(ha);
|
qla25xx_init_queues(ha);
|
||||||
|
|
||||||
status = qla2x00_fw_ready(vha);
|
status = qla2x00_fw_ready(vha);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x8031,
|
|
||||||
"Start configure loop status = %d.\n", status);
|
|
||||||
|
|
||||||
/* Issue a marker after FW becomes ready. */
|
/* Issue a marker after FW becomes ready. */
|
||||||
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
|
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
|
||||||
|
|
||||||
|
@ -4766,24 +4772,12 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
|
||||||
qlt_24xx_process_atio_queue(vha);
|
qlt_24xx_process_atio_queue(vha);
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
/* Wait at most MAX_TARGET RSCNs for a stable link. */
|
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||||
wait_time = 256;
|
|
||||||
do {
|
|
||||||
clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
|
||||||
qla2x00_configure_loop(vha);
|
|
||||||
wait_time--;
|
|
||||||
} while (!atomic_read(&vha->loop_down_timer) &&
|
|
||||||
!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
|
|
||||||
&& wait_time && (test_bit(LOOP_RESYNC_NEEDED,
|
|
||||||
&vha->dpc_flags)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if no cable then assume it's good */
|
/* if no cable then assume it's good */
|
||||||
if ((vha->device_flags & DFLG_NO_CABLE))
|
if ((vha->device_flags & DFLG_NO_CABLE))
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x8032,
|
|
||||||
"Configure loop done, status = 0x%x.\n", status);
|
|
||||||
}
|
}
|
||||||
return (status);
|
return (status);
|
||||||
}
|
}
|
||||||
|
@ -6130,7 +6124,6 @@ int
|
||||||
qla82xx_restart_isp(scsi_qla_host_t *vha)
|
qla82xx_restart_isp(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
int status, rval;
|
int status, rval;
|
||||||
uint32_t wait_time;
|
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
struct req_que *req = ha->req_q_map[0];
|
struct req_que *req = ha->req_q_map[0];
|
||||||
struct rsp_que *rsp = ha->rsp_q_map[0];
|
struct rsp_que *rsp = ha->rsp_q_map[0];
|
||||||
|
@ -6144,31 +6137,15 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
status = qla2x00_fw_ready(vha);
|
status = qla2x00_fw_ready(vha);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
ql_log(ql_log_info, vha, 0x803c,
|
|
||||||
"Start configure loop, status =%d.\n", status);
|
|
||||||
|
|
||||||
/* Issue a marker after FW becomes ready. */
|
/* Issue a marker after FW becomes ready. */
|
||||||
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
|
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
|
||||||
|
|
||||||
vha->flags.online = 1;
|
vha->flags.online = 1;
|
||||||
/* Wait at most MAX_TARGET RSCNs for a stable link. */
|
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
||||||
wait_time = 256;
|
|
||||||
do {
|
|
||||||
clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
|
|
||||||
qla2x00_configure_loop(vha);
|
|
||||||
wait_time--;
|
|
||||||
} while (!atomic_read(&vha->loop_down_timer) &&
|
|
||||||
!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) &&
|
|
||||||
wait_time &&
|
|
||||||
(test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if no cable then assume it's good */
|
/* if no cable then assume it's good */
|
||||||
if ((vha->device_flags & DFLG_NO_CABLE))
|
if ((vha->device_flags & DFLG_NO_CABLE))
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
ql_log(ql_log_info, vha, 0x8000,
|
|
||||||
"Configure loop done, status = 0x%x.\n", status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
@ -6182,8 +6159,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
|
||||||
vha->marker_needed = 1;
|
vha->marker_needed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vha->flags.online = 1;
|
|
||||||
|
|
||||||
ha->isp_ops->enable_intrs(ha);
|
ha->isp_ops->enable_intrs(ha);
|
||||||
|
|
||||||
ha->isp_abort_cnt = 0;
|
ha->isp_abort_cnt = 0;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "qla_target.h"
|
||||||
/**
|
/**
|
||||||
* qla24xx_calc_iocbs() - Determine number of Command Type 3 and
|
* qla24xx_calc_iocbs() - Determine number of Command Type 3 and
|
||||||
* Continuation Type 1 IOCBs to allocate.
|
* Continuation Type 1 IOCBs to allocate.
|
||||||
|
@ -128,12 +129,20 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
|
qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp,
|
||||||
|
struct qla_tgt_cmd *tc)
|
||||||
{
|
{
|
||||||
struct dsd_dma *dsd_ptr, *tdsd_ptr;
|
struct dsd_dma *dsd_ptr, *tdsd_ptr;
|
||||||
struct crc_context *ctx;
|
struct crc_context *ctx;
|
||||||
|
|
||||||
ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
|
if (sp)
|
||||||
|
ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
|
||||||
|
else if (tc)
|
||||||
|
ctx = (struct crc_context *)tc->ctx;
|
||||||
|
else {
|
||||||
|
BUG();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* clean up allocated prev pool */
|
/* clean up allocated prev pool */
|
||||||
list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
|
list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -936,9 +936,9 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
|
qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
|
||||||
uint32_t *dsd, uint16_t tot_dsds)
|
uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
|
||||||
{
|
{
|
||||||
void *next_dsd;
|
void *next_dsd;
|
||||||
uint8_t avail_dsds = 0;
|
uint8_t avail_dsds = 0;
|
||||||
|
@ -948,21 +948,35 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
|
||||||
uint32_t *cur_dsd = dsd;
|
uint32_t *cur_dsd = dsd;
|
||||||
uint16_t used_dsds = tot_dsds;
|
uint16_t used_dsds = tot_dsds;
|
||||||
|
|
||||||
uint32_t prot_int;
|
uint32_t prot_int; /* protection interval */
|
||||||
uint32_t partial;
|
uint32_t partial;
|
||||||
struct qla2_sgx sgx;
|
struct qla2_sgx sgx;
|
||||||
dma_addr_t sle_dma;
|
dma_addr_t sle_dma;
|
||||||
uint32_t sle_dma_len, tot_prot_dma_len = 0;
|
uint32_t sle_dma_len, tot_prot_dma_len = 0;
|
||||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
struct scsi_cmnd *cmd;
|
||||||
|
struct scsi_qla_host *vha;
|
||||||
prot_int = cmd->device->sector_size;
|
|
||||||
|
|
||||||
memset(&sgx, 0, sizeof(struct qla2_sgx));
|
memset(&sgx, 0, sizeof(struct qla2_sgx));
|
||||||
sgx.tot_bytes = scsi_bufflen(cmd);
|
if (sp) {
|
||||||
sgx.cur_sg = scsi_sglist(cmd);
|
vha = sp->fcport->vha;
|
||||||
sgx.sp = sp;
|
cmd = GET_CMD_SP(sp);
|
||||||
|
prot_int = cmd->device->sector_size;
|
||||||
|
|
||||||
sg_prot = scsi_prot_sglist(cmd);
|
sgx.tot_bytes = scsi_bufflen(cmd);
|
||||||
|
sgx.cur_sg = scsi_sglist(cmd);
|
||||||
|
sgx.sp = sp;
|
||||||
|
|
||||||
|
sg_prot = scsi_prot_sglist(cmd);
|
||||||
|
} else if (tc) {
|
||||||
|
vha = tc->vha;
|
||||||
|
prot_int = tc->blk_sz;
|
||||||
|
sgx.tot_bytes = tc->bufflen;
|
||||||
|
sgx.cur_sg = tc->sg;
|
||||||
|
sg_prot = tc->prot_sg;
|
||||||
|
} else {
|
||||||
|
BUG();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
|
while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
|
||||||
|
|
||||||
|
@ -995,10 +1009,18 @@ alloc_and_fill:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&dsd_ptr->list,
|
if (sp) {
|
||||||
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&((struct crc_context *)
|
||||||
|
sp->u.scmd.ctx)->dsd_list);
|
||||||
|
|
||||||
|
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||||
|
} else {
|
||||||
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&(tc->ctx->dsd_list));
|
||||||
|
tc->ctx_dsd_alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
|
||||||
|
|
||||||
/* add new list to cmd iocb or last list */
|
/* add new list to cmd iocb or last list */
|
||||||
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||||
|
@ -1033,21 +1055,35 @@ alloc_and_fill:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
|
qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
|
||||||
uint16_t tot_dsds)
|
uint16_t tot_dsds, struct qla_tgt_cmd *tc)
|
||||||
{
|
{
|
||||||
void *next_dsd;
|
void *next_dsd;
|
||||||
uint8_t avail_dsds = 0;
|
uint8_t avail_dsds = 0;
|
||||||
uint32_t dsd_list_len;
|
uint32_t dsd_list_len;
|
||||||
struct dsd_dma *dsd_ptr;
|
struct dsd_dma *dsd_ptr;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg, *sgl;
|
||||||
uint32_t *cur_dsd = dsd;
|
uint32_t *cur_dsd = dsd;
|
||||||
int i;
|
int i;
|
||||||
uint16_t used_dsds = tot_dsds;
|
uint16_t used_dsds = tot_dsds;
|
||||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
struct scsi_cmnd *cmd;
|
||||||
|
struct scsi_qla_host *vha;
|
||||||
|
|
||||||
scsi_for_each_sg(cmd, sg, tot_dsds, i) {
|
if (sp) {
|
||||||
|
cmd = GET_CMD_SP(sp);
|
||||||
|
sgl = scsi_sglist(cmd);
|
||||||
|
vha = sp->fcport->vha;
|
||||||
|
} else if (tc) {
|
||||||
|
sgl = tc->sg;
|
||||||
|
vha = tc->vha;
|
||||||
|
} else {
|
||||||
|
BUG();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||||
dma_addr_t sle_dma;
|
dma_addr_t sle_dma;
|
||||||
|
|
||||||
/* Allocate additional continuation packets? */
|
/* Allocate additional continuation packets? */
|
||||||
|
@ -1076,10 +1112,17 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&dsd_ptr->list,
|
if (sp) {
|
||||||
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&((struct crc_context *)
|
||||||
|
sp->u.scmd.ctx)->dsd_list);
|
||||||
|
|
||||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||||
|
} else {
|
||||||
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&(tc->ctx->dsd_list));
|
||||||
|
tc->ctx_dsd_alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* add new list to cmd iocb or last list */
|
/* add new list to cmd iocb or last list */
|
||||||
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||||
|
@ -1102,23 +1145,37 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
||||||
uint32_t *dsd,
|
uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
|
||||||
uint16_t tot_dsds)
|
|
||||||
{
|
{
|
||||||
void *next_dsd;
|
void *next_dsd;
|
||||||
uint8_t avail_dsds = 0;
|
uint8_t avail_dsds = 0;
|
||||||
uint32_t dsd_list_len;
|
uint32_t dsd_list_len;
|
||||||
struct dsd_dma *dsd_ptr;
|
struct dsd_dma *dsd_ptr;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg, *sgl;
|
||||||
int i;
|
int i;
|
||||||
struct scsi_cmnd *cmd;
|
struct scsi_cmnd *cmd;
|
||||||
uint32_t *cur_dsd = dsd;
|
uint32_t *cur_dsd = dsd;
|
||||||
uint16_t used_dsds = tot_dsds;
|
uint16_t used_dsds = tot_dsds;
|
||||||
|
struct scsi_qla_host *vha;
|
||||||
|
|
||||||
cmd = GET_CMD_SP(sp);
|
if (sp) {
|
||||||
scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
|
cmd = GET_CMD_SP(sp);
|
||||||
|
sgl = scsi_prot_sglist(cmd);
|
||||||
|
vha = sp->fcport->vha;
|
||||||
|
} else if (tc) {
|
||||||
|
vha = tc->vha;
|
||||||
|
sgl = tc->prot_sg;
|
||||||
|
} else {
|
||||||
|
BUG();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xe021,
|
||||||
|
"%s: enter\n", __func__);
|
||||||
|
|
||||||
|
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||||
dma_addr_t sle_dma;
|
dma_addr_t sle_dma;
|
||||||
|
|
||||||
/* Allocate additional continuation packets? */
|
/* Allocate additional continuation packets? */
|
||||||
|
@ -1147,10 +1204,17 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&dsd_ptr->list,
|
if (sp) {
|
||||||
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&((struct crc_context *)
|
||||||
|
sp->u.scmd.ctx)->dsd_list);
|
||||||
|
|
||||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||||
|
} else {
|
||||||
|
list_add_tail(&dsd_ptr->list,
|
||||||
|
&(tc->ctx->dsd_list));
|
||||||
|
tc->ctx_dsd_alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* add new list to cmd iocb or last list */
|
/* add new list to cmd iocb or last list */
|
||||||
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||||
|
@ -1386,10 +1450,10 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
|
||||||
|
|
||||||
if (!bundling && tot_prot_dsds) {
|
if (!bundling && tot_prot_dsds) {
|
||||||
if (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
|
if (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
|
||||||
cur_dsd, tot_dsds))
|
cur_dsd, tot_dsds, NULL))
|
||||||
goto crc_queuing_error;
|
goto crc_queuing_error;
|
||||||
} else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
|
} else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd,
|
||||||
(tot_dsds - tot_prot_dsds)))
|
(tot_dsds - tot_prot_dsds), NULL))
|
||||||
goto crc_queuing_error;
|
goto crc_queuing_error;
|
||||||
|
|
||||||
if (bundling && tot_prot_dsds) {
|
if (bundling && tot_prot_dsds) {
|
||||||
|
@ -1398,7 +1462,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
|
||||||
__constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
|
__constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE);
|
||||||
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
|
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
|
||||||
if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd,
|
if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd,
|
||||||
tot_prot_dsds))
|
tot_prot_dsds, NULL))
|
||||||
goto crc_queuing_error;
|
goto crc_queuing_error;
|
||||||
}
|
}
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
|
@ -1478,8 +1542,8 @@ qla24xx_start_scsi(srb_t *sp)
|
||||||
tot_dsds = nseg;
|
tot_dsds = nseg;
|
||||||
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
|
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
|
||||||
if (req->cnt < (req_cnt + 2)) {
|
if (req->cnt < (req_cnt + 2)) {
|
||||||
cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
|
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
|
||||||
|
RD_REG_DWORD_RELAXED(req->req_q_out);
|
||||||
if (req->ring_index < cnt)
|
if (req->ring_index < cnt)
|
||||||
req->cnt = cnt - req->ring_index;
|
req->cnt = cnt - req->ring_index;
|
||||||
else
|
else
|
||||||
|
@ -1697,8 +1761,8 @@ qla24xx_dif_start_scsi(srb_t *sp)
|
||||||
tot_prot_dsds = nseg;
|
tot_prot_dsds = nseg;
|
||||||
tot_dsds += nseg;
|
tot_dsds += nseg;
|
||||||
if (req->cnt < (req_cnt + 2)) {
|
if (req->cnt < (req_cnt + 2)) {
|
||||||
cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
|
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
|
||||||
|
RD_REG_DWORD_RELAXED(req->req_q_out);
|
||||||
if (req->ring_index < cnt)
|
if (req->ring_index < cnt)
|
||||||
req->cnt = cnt - req->ring_index;
|
req->cnt = cnt - req->ring_index;
|
||||||
else
|
else
|
||||||
|
@ -2825,8 +2889,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
|
||||||
|
|
||||||
/* Check for room on request queue. */
|
/* Check for room on request queue. */
|
||||||
if (req->cnt < req_cnt + 2) {
|
if (req->cnt < req_cnt + 2) {
|
||||||
cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
|
cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
|
||||||
|
RD_REG_DWORD_RELAXED(req->req_q_out);
|
||||||
if (req->ring_index < cnt)
|
if (req->ring_index < cnt)
|
||||||
req->cnt = cnt - req->ring_index;
|
req->cnt = cnt - req->ring_index;
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -2009,11 +2009,13 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
||||||
ql_dbg(ql_dbg_io, vha, 0x3017,
|
ql_dbg(ql_dbg_io, vha, 0x3017,
|
||||||
"Invalid status handle (0x%x).\n", sts->handle);
|
"Invalid status handle (0x%x).\n", sts->handle);
|
||||||
|
|
||||||
if (IS_P3P_TYPE(ha))
|
if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
|
||||||
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
|
if (IS_P3P_TYPE(ha))
|
||||||
else
|
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
|
||||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
else
|
||||||
qla2xxx_wake_dpc(vha);
|
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||||
|
qla2xxx_wake_dpc(vha);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2472,12 +2474,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
|
||||||
if (pkt->entry_status != 0) {
|
if (pkt->entry_status != 0) {
|
||||||
qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt);
|
qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt);
|
||||||
|
|
||||||
(void)qlt_24xx_process_response_error(vha, pkt);
|
if (qlt_24xx_process_response_error(vha, pkt))
|
||||||
|
goto process_err;
|
||||||
|
|
||||||
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
|
((response_t *)pkt)->signature = RESPONSE_PROCESSED;
|
||||||
wmb();
|
wmb();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
process_err:
|
||||||
|
|
||||||
switch (pkt->entry_type) {
|
switch (pkt->entry_type) {
|
||||||
case STATUS_TYPE:
|
case STATUS_TYPE:
|
||||||
|
@ -2494,10 +2498,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
|
||||||
qla24xx_logio_entry(vha, rsp->req,
|
qla24xx_logio_entry(vha, rsp->req,
|
||||||
(struct logio_entry_24xx *)pkt);
|
(struct logio_entry_24xx *)pkt);
|
||||||
break;
|
break;
|
||||||
case CT_IOCB_TYPE:
|
case CT_IOCB_TYPE:
|
||||||
qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
|
qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
|
||||||
break;
|
break;
|
||||||
case ELS_IOCB_TYPE:
|
case ELS_IOCB_TYPE:
|
||||||
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
|
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
|
||||||
break;
|
break;
|
||||||
case ABTS_RECV_24XX:
|
case ABTS_RECV_24XX:
|
||||||
|
@ -2506,6 +2510,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
|
||||||
case ABTS_RESP_24XX:
|
case ABTS_RESP_24XX:
|
||||||
case CTIO_TYPE7:
|
case CTIO_TYPE7:
|
||||||
case NOTIFY_ACK_TYPE:
|
case NOTIFY_ACK_TYPE:
|
||||||
|
case CTIO_CRC2:
|
||||||
qlt_response_pkt_all_vps(vha, (response_t *)pkt);
|
qlt_response_pkt_all_vps(vha, (response_t *)pkt);
|
||||||
break;
|
break;
|
||||||
case MARKER_TYPE:
|
case MARKER_TYPE:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -1319,7 +1319,7 @@ qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
|
||||||
|
|
||||||
left = 0;
|
left = 0;
|
||||||
|
|
||||||
list = kzalloc(dma_size, GFP_KERNEL);
|
list = kmemdup(pmap, dma_size, GFP_KERNEL);
|
||||||
if (!list) {
|
if (!list) {
|
||||||
ql_log(ql_log_warn, vha, 0x1140,
|
ql_log(ql_log_warn, vha, 0x1140,
|
||||||
"%s(%ld): failed to allocate node names list "
|
"%s(%ld): failed to allocate node names list "
|
||||||
|
@ -1328,7 +1328,6 @@ qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(list, pmap, dma_size);
|
|
||||||
restart:
|
restart:
|
||||||
dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
|
dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
|
||||||
}
|
}
|
||||||
|
@ -2644,7 +2643,10 @@ qla24xx_abort_command(srb_t *sp)
|
||||||
ql_dbg(ql_dbg_mbx, vha, 0x1090,
|
ql_dbg(ql_dbg_mbx, vha, 0x1090,
|
||||||
"Failed to complete IOCB -- completion status (%x).\n",
|
"Failed to complete IOCB -- completion status (%x).\n",
|
||||||
le16_to_cpu(abt->nport_handle));
|
le16_to_cpu(abt->nport_handle));
|
||||||
rval = QLA_FUNCTION_FAILED;
|
if (abt->nport_handle == CS_IOCB_ERROR)
|
||||||
|
rval = QLA_FUNCTION_PARAMETER_ERROR;
|
||||||
|
else
|
||||||
|
rval = QLA_FUNCTION_FAILED;
|
||||||
} else {
|
} else {
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
|
||||||
"Done %s.\n", __func__);
|
"Done %s.\n", __func__);
|
||||||
|
@ -2879,6 +2881,78 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
mbx_cmd_t mc;
|
||||||
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
|
if (!IS_QLA8044(vha->hw))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186,
|
||||||
|
"Entered %s.\n", __func__);
|
||||||
|
|
||||||
|
mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
|
||||||
|
mcp->mb[1] = HCS_WRITE_SERDES;
|
||||||
|
mcp->mb[3] = LSW(addr);
|
||||||
|
mcp->mb[4] = MSW(addr);
|
||||||
|
mcp->mb[5] = LSW(data);
|
||||||
|
mcp->mb[6] = MSW(data);
|
||||||
|
mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
|
||||||
|
mcp->in_mb = MBX_0;
|
||||||
|
mcp->tov = MBX_TOV_SECONDS;
|
||||||
|
mcp->flags = 0;
|
||||||
|
rval = qla2x00_mailbox_command(vha, mcp);
|
||||||
|
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
ql_dbg(ql_dbg_mbx, vha, 0x1187,
|
||||||
|
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
|
||||||
|
"Done %s.\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
mbx_cmd_t mc;
|
||||||
|
mbx_cmd_t *mcp = &mc;
|
||||||
|
|
||||||
|
if (!IS_QLA8044(vha->hw))
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
|
||||||
|
"Entered %s.\n", __func__);
|
||||||
|
|
||||||
|
mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
|
||||||
|
mcp->mb[1] = HCS_READ_SERDES;
|
||||||
|
mcp->mb[3] = LSW(addr);
|
||||||
|
mcp->mb[4] = MSW(addr);
|
||||||
|
mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
|
||||||
|
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||||
|
mcp->tov = MBX_TOV_SECONDS;
|
||||||
|
mcp->flags = 0;
|
||||||
|
rval = qla2x00_mailbox_command(vha, mcp);
|
||||||
|
|
||||||
|
*data = mcp->mb[2] << 16 | mcp->mb[1];
|
||||||
|
|
||||||
|
if (rval != QLA_SUCCESS) {
|
||||||
|
ql_dbg(ql_dbg_mbx, vha, 0x118a,
|
||||||
|
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
|
||||||
|
"Done %s.\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla2x00_set_serdes_params() -
|
* qla2x00_set_serdes_params() -
|
||||||
* @ha: HA context
|
* @ha: HA context
|
||||||
|
@ -3660,6 +3734,9 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
|
||||||
"Entered %s.\n", __func__);
|
"Entered %s.\n", __func__);
|
||||||
|
|
||||||
|
if (IS_SHADOW_REG_CAPABLE(ha))
|
||||||
|
req->options |= BIT_13;
|
||||||
|
|
||||||
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
|
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
|
||||||
mcp->mb[1] = req->options;
|
mcp->mb[1] = req->options;
|
||||||
mcp->mb[2] = MSW(LSD(req->dma));
|
mcp->mb[2] = MSW(LSD(req->dma));
|
||||||
|
@ -3679,7 +3756,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
|
||||||
/* que in ptr index */
|
/* que in ptr index */
|
||||||
mcp->mb[8] = 0;
|
mcp->mb[8] = 0;
|
||||||
/* que out ptr index */
|
/* que out ptr index */
|
||||||
mcp->mb[9] = 0;
|
mcp->mb[9] = *req->out_ptr = 0;
|
||||||
mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
|
mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
|
||||||
MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||||
mcp->in_mb = MBX_0;
|
mcp->in_mb = MBX_0;
|
||||||
|
@ -3688,7 +3765,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
|
||||||
|
|
||||||
if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
|
if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
|
||||||
mcp->in_mb |= MBX_1;
|
mcp->in_mb |= MBX_1;
|
||||||
if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) {
|
if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
|
||||||
mcp->out_mb |= MBX_15;
|
mcp->out_mb |= MBX_15;
|
||||||
/* debug q create issue in SR-IOV */
|
/* debug q create issue in SR-IOV */
|
||||||
mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
|
mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
|
||||||
|
@ -3697,7 +3774,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
if (!(req->options & BIT_0)) {
|
if (!(req->options & BIT_0)) {
|
||||||
WRT_REG_DWORD(req->req_q_in, 0);
|
WRT_REG_DWORD(req->req_q_in, 0);
|
||||||
if (!IS_QLA83XX(ha) || !IS_QLA27XX(ha))
|
if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
|
||||||
WRT_REG_DWORD(req->req_q_out, 0);
|
WRT_REG_DWORD(req->req_q_out, 0);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
@ -3726,6 +3803,9 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
|
||||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
|
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
|
||||||
"Entered %s.\n", __func__);
|
"Entered %s.\n", __func__);
|
||||||
|
|
||||||
|
if (IS_SHADOW_REG_CAPABLE(ha))
|
||||||
|
rsp->options |= BIT_13;
|
||||||
|
|
||||||
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
|
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
|
||||||
mcp->mb[1] = rsp->options;
|
mcp->mb[1] = rsp->options;
|
||||||
mcp->mb[2] = MSW(LSD(rsp->dma));
|
mcp->mb[2] = MSW(LSD(rsp->dma));
|
||||||
|
@ -3740,7 +3820,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
|
||||||
|
|
||||||
mcp->mb[4] = rsp->id;
|
mcp->mb[4] = rsp->id;
|
||||||
/* que in ptr index */
|
/* que in ptr index */
|
||||||
mcp->mb[8] = 0;
|
mcp->mb[8] = *rsp->in_ptr = 0;
|
||||||
/* que out ptr index */
|
/* que out ptr index */
|
||||||
mcp->mb[9] = 0;
|
mcp->mb[9] = 0;
|
||||||
mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
|
mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -527,21 +527,63 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
int i, core;
|
int i, core;
|
||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
|
uint32_t reg_val;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x80004, 0);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x82004, 0);
|
||||||
|
|
||||||
|
/* stop the XOR DMA engines */
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x60920, 0x02);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x60924, 0x02);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0xf0920, 0x02);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0xf0924, 0x02);
|
||||||
|
|
||||||
|
/* stop the IDMA engines */
|
||||||
|
reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60840);
|
||||||
|
reg_val &= ~(1<<12);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x60840, reg_val);
|
||||||
|
|
||||||
|
reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60844);
|
||||||
|
reg_val &= ~(1<<12);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x60844, reg_val);
|
||||||
|
|
||||||
|
reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60848);
|
||||||
|
reg_val &= ~(1<<12);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x60848, reg_val);
|
||||||
|
|
||||||
|
reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x6084C);
|
||||||
|
reg_val &= ~(1<<12);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x6084C, reg_val);
|
||||||
|
|
||||||
|
for (i = 0; i < 100000; i++) {
|
||||||
|
if ((QLAFX00_GET_HBA_SOC_REG(ha, 0xd0000) & 0x10000000) == 0 &&
|
||||||
|
(QLAFX00_GET_HBA_SOC_REG(ha, 0x10600) & 0x1) == 0)
|
||||||
|
break;
|
||||||
|
udelay(100);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set all 4 cores in reset */
|
/* Set all 4 cores in reset */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha,
|
QLAFX00_SET_HBA_SOC_REG(ha,
|
||||||
(SOC_SW_RST_CONTROL_REG_CORE0 + 8*i), (0xF01));
|
(SOC_SW_RST_CONTROL_REG_CORE0 + 8*i), (0xF01));
|
||||||
}
|
|
||||||
|
|
||||||
/* Set all 4 core Clock gating control */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha,
|
QLAFX00_SET_HBA_SOC_REG(ha,
|
||||||
(SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101));
|
(SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset all units in Fabric */
|
/* Reset all units in Fabric */
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x11F0101));
|
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x011f0101));
|
||||||
|
|
||||||
|
/* */
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x10610, 1);
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha, 0x10600, 0);
|
||||||
|
|
||||||
|
/* Set all 4 core Memory Power Down Registers */
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
QLAFX00_SET_HBA_SOC_REG(ha,
|
||||||
|
(SOC_PWR_MANAGEMENT_PWR_DOWN_REG + 4*i), (0x0));
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset all interrupt control registers */
|
/* Reset all interrupt control registers */
|
||||||
for (i = 0; i < 115; i++) {
|
for (i = 0; i < 115; i++) {
|
||||||
|
@ -564,20 +606,19 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONTROL_REG, (0x2));
|
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONTROL_REG, (0x2));
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONFIG_REG, (0x3));
|
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONFIG_REG, (0x3));
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
||||||
|
|
||||||
/* Kick in Fabric units */
|
/* Kick in Fabric units */
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0));
|
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0));
|
||||||
|
|
||||||
/* Kick in Core0 to start boot process */
|
/* Kick in Core0 to start boot process */
|
||||||
QLAFX00_SET_HBA_SOC_REG(ha, SOC_SW_RST_CONTROL_REG_CORE0, (0xF00));
|
QLAFX00_SET_HBA_SOC_REG(ha, SOC_SW_RST_CONTROL_REG_CORE0, (0xF00));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
/* Wait 10secs for soft-reset to complete. */
|
/* Wait 10secs for soft-reset to complete. */
|
||||||
for (cnt = 10; cnt; cnt--) {
|
for (cnt = 10; cnt; cnt--) {
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -597,7 +638,6 @@ qlafx00_soft_reset(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
ha->isp_ops->disable_intrs(ha);
|
ha->isp_ops->disable_intrs(ha);
|
||||||
qlafx00_soc_cpu_reset(vha);
|
qlafx00_soc_cpu_reset(vha);
|
||||||
ha->isp_ops->enable_intrs(ha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2675,7 +2715,7 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
|
||||||
uint16_t lreq_q_out = 0;
|
uint16_t lreq_q_out = 0;
|
||||||
|
|
||||||
lreq_q_in = RD_REG_DWORD(rsp->rsp_q_in);
|
lreq_q_in = RD_REG_DWORD(rsp->rsp_q_in);
|
||||||
lreq_q_out = RD_REG_DWORD(rsp->rsp_q_out);
|
lreq_q_out = rsp->ring_index;
|
||||||
|
|
||||||
while (lreq_q_in != lreq_q_out) {
|
while (lreq_q_in != lreq_q_out) {
|
||||||
lptr = rsp->ring_ptr;
|
lptr = rsp->ring_ptr;
|
||||||
|
@ -3426,7 +3466,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
|
||||||
sp->fcport->vha, 0x3047,
|
sp->fcport->vha, 0x3047,
|
||||||
(uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00));
|
(uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00));
|
||||||
|
|
||||||
memcpy((void *)pfxiocb, &fx_iocb,
|
memcpy_toio((void __iomem *)pfxiocb, &fx_iocb,
|
||||||
sizeof(struct fxdisc_entry_fx00));
|
sizeof(struct fxdisc_entry_fx00));
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -351,6 +351,7 @@ struct config_info_data {
|
||||||
#define SOC_FABRIC_RST_CONTROL_REG 0x0020840
|
#define SOC_FABRIC_RST_CONTROL_REG 0x0020840
|
||||||
#define SOC_FABRIC_CONTROL_REG 0x0020200
|
#define SOC_FABRIC_CONTROL_REG 0x0020200
|
||||||
#define SOC_FABRIC_CONFIG_REG 0x0020204
|
#define SOC_FABRIC_CONFIG_REG 0x0020204
|
||||||
|
#define SOC_PWR_MANAGEMENT_PWR_DOWN_REG 0x001820C
|
||||||
|
|
||||||
#define SOC_INTERRUPT_SOURCE_I_CONTROL_REG 0x0020B00
|
#define SOC_INTERRUPT_SOURCE_I_CONTROL_REG 0x0020B00
|
||||||
#define SOC_CORE_TIMER_REG 0x0021850
|
#define SOC_CORE_TIMER_REG 0x0021850
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -848,6 +848,7 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
int done = 0, timeout = 0;
|
int done = 0, timeout = 0;
|
||||||
uint32_t lock_owner = 0;
|
uint32_t lock_owner = 0;
|
||||||
|
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
/* acquire semaphore2 from PCI HW block */
|
/* acquire semaphore2 from PCI HW block */
|
||||||
|
@ -856,17 +857,21 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
|
||||||
break;
|
break;
|
||||||
if (timeout >= qla82xx_rom_lock_timeout) {
|
if (timeout >= qla82xx_rom_lock_timeout) {
|
||||||
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
|
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
|
||||||
|
ql_log(ql_log_warn, vha, 0xb157,
|
||||||
|
"%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d",
|
||||||
|
__func__, ha->portnum, lock_owner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
timeout++;
|
timeout++;
|
||||||
}
|
}
|
||||||
qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
|
qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ha->portnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qla82xx_rom_unlock(struct qla_hw_data *ha)
|
qla82xx_rom_unlock(struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
|
qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, 0xffffffff);
|
||||||
qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
|
qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,6 +955,7 @@ static int
|
||||||
qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
|
qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
|
||||||
{
|
{
|
||||||
int ret, loops = 0;
|
int ret, loops = 0;
|
||||||
|
uint32_t lock_owner = 0;
|
||||||
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
||||||
|
|
||||||
while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
|
while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
|
||||||
|
@ -958,8 +964,10 @@ qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
|
||||||
loops++;
|
loops++;
|
||||||
}
|
}
|
||||||
if (loops >= 50000) {
|
if (loops >= 50000) {
|
||||||
|
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
|
||||||
ql_log(ql_log_fatal, vha, 0x00b9,
|
ql_log(ql_log_fatal, vha, 0x00b9,
|
||||||
"Failed to acquire SEM2 lock.\n");
|
"Failed to acquire SEM2 lock, Lock Owner %u.\n",
|
||||||
|
lock_owner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = qla82xx_do_rom_fast_read(ha, addr, valp);
|
ret = qla82xx_do_rom_fast_read(ha, addr, valp);
|
||||||
|
@ -1057,6 +1065,7 @@ static int
|
||||||
ql82xx_rom_lock_d(struct qla_hw_data *ha)
|
ql82xx_rom_lock_d(struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
|
uint32_t lock_owner = 0;
|
||||||
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
||||||
|
|
||||||
while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
|
while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
|
||||||
|
@ -1065,8 +1074,9 @@ ql82xx_rom_lock_d(struct qla_hw_data *ha)
|
||||||
loops++;
|
loops++;
|
||||||
}
|
}
|
||||||
if (loops >= 50000) {
|
if (loops >= 50000) {
|
||||||
|
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
|
||||||
ql_log(ql_log_warn, vha, 0xb010,
|
ql_log(ql_log_warn, vha, 0xb010,
|
||||||
"ROM lock failed.\n");
|
"ROM lock failed, Lock Owner %u.\n", lock_owner);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2811,12 +2821,14 @@ static void
|
||||||
qla82xx_rom_lock_recovery(struct qla_hw_data *ha)
|
qla82xx_rom_lock_recovery(struct qla_hw_data *ha)
|
||||||
{
|
{
|
||||||
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
|
||||||
|
uint32_t lock_owner = 0;
|
||||||
|
|
||||||
if (qla82xx_rom_lock(ha))
|
if (qla82xx_rom_lock(ha)) {
|
||||||
|
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
|
||||||
/* Someone else is holding the lock. */
|
/* Someone else is holding the lock. */
|
||||||
ql_log(ql_log_info, vha, 0xb022,
|
ql_log(ql_log_info, vha, 0xb022,
|
||||||
"Resetting rom_lock.\n");
|
"Resetting rom_lock, Lock Owner %u.\n", lock_owner);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Either we got the lock, or someone
|
* Either we got the lock, or someone
|
||||||
* else died while holding it.
|
* else died while holding it.
|
||||||
|
@ -2840,47 +2852,30 @@ static int
|
||||||
qla82xx_device_bootstrap(scsi_qla_host_t *vha)
|
qla82xx_device_bootstrap(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
int rval = QLA_SUCCESS;
|
int rval = QLA_SUCCESS;
|
||||||
int i, timeout;
|
int i;
|
||||||
uint32_t old_count, count;
|
uint32_t old_count, count;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
int need_reset = 0, peg_stuck = 1;
|
int need_reset = 0;
|
||||||
|
|
||||||
need_reset = qla82xx_need_reset(ha);
|
need_reset = qla82xx_need_reset(ha);
|
||||||
|
|
||||||
old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
timeout = msleep_interruptible(200);
|
|
||||||
if (timeout) {
|
|
||||||
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
|
||||||
QLA8XXX_DEV_FAILED);
|
|
||||||
return QLA_FUNCTION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
|
||||||
if (count != old_count)
|
|
||||||
peg_stuck = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
/* We are trying to perform a recovery here. */
|
/* We are trying to perform a recovery here. */
|
||||||
if (peg_stuck)
|
if (ha->flags.isp82xx_fw_hung)
|
||||||
qla82xx_rom_lock_recovery(ha);
|
qla82xx_rom_lock_recovery(ha);
|
||||||
goto dev_initialize;
|
|
||||||
} else {
|
} else {
|
||||||
/* Start of day for this ha context. */
|
old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
||||||
if (peg_stuck) {
|
for (i = 0; i < 10; i++) {
|
||||||
/* Either we are the first or recovery in progress. */
|
msleep(200);
|
||||||
qla82xx_rom_lock_recovery(ha);
|
count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
||||||
goto dev_initialize;
|
if (count != old_count) {
|
||||||
} else
|
rval = QLA_SUCCESS;
|
||||||
/* Firmware already running. */
|
goto dev_ready;
|
||||||
goto dev_ready;
|
}
|
||||||
|
}
|
||||||
|
qla82xx_rom_lock_recovery(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
|
||||||
|
|
||||||
dev_initialize:
|
|
||||||
/* set to DEV_INITIALIZING */
|
/* set to DEV_INITIALIZING */
|
||||||
ql_log(ql_log_info, vha, 0x009e,
|
ql_log(ql_log_info, vha, 0x009e,
|
||||||
"HW State: INITIALIZING.\n");
|
"HW State: INITIALIZING.\n");
|
||||||
|
@ -3142,18 +3137,18 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
|
||||||
|
|
||||||
if (ql2xmdenable) {
|
if (ql2xmdenable) {
|
||||||
if (!ha->fw_dumped) {
|
if (!ha->fw_dumped) {
|
||||||
if (fw_major_version != ha->fw_major_version ||
|
if ((fw_major_version != ha->fw_major_version ||
|
||||||
fw_minor_version != ha->fw_minor_version ||
|
fw_minor_version != ha->fw_minor_version ||
|
||||||
fw_subminor_version != ha->fw_subminor_version) {
|
fw_subminor_version != ha->fw_subminor_version) ||
|
||||||
|
(ha->prev_minidump_failed)) {
|
||||||
ql_dbg(ql_dbg_p3p, vha, 0xb02d,
|
ql_dbg(ql_dbg_p3p, vha, 0xb02d,
|
||||||
"Firmware version differs "
|
"Firmware version differs Previous version: %d:%d:%d - New version: %d:%d:%d, prev_minidump_failed: %d.\n",
|
||||||
"Previous version: %d:%d:%d - "
|
|
||||||
"New version: %d:%d:%d\n",
|
|
||||||
fw_major_version, fw_minor_version,
|
fw_major_version, fw_minor_version,
|
||||||
fw_subminor_version,
|
fw_subminor_version,
|
||||||
ha->fw_major_version,
|
ha->fw_major_version,
|
||||||
ha->fw_minor_version,
|
ha->fw_minor_version,
|
||||||
ha->fw_subminor_version);
|
ha->fw_subminor_version,
|
||||||
|
ha->prev_minidump_failed);
|
||||||
/* Release MiniDump resources */
|
/* Release MiniDump resources */
|
||||||
qla82xx_md_free(vha);
|
qla82xx_md_free(vha);
|
||||||
/* ALlocate MiniDump resources */
|
/* ALlocate MiniDump resources */
|
||||||
|
@ -3682,8 +3677,10 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
|
||||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||||
sp = req->outstanding_cmds[cnt];
|
sp = req->outstanding_cmds[cnt];
|
||||||
if (sp) {
|
if (sp) {
|
||||||
if (!sp->u.scmd.ctx ||
|
if ((!sp->u.scmd.ctx ||
|
||||||
(sp->flags & SRB_FCP_CMND_DMA_VALID)) {
|
(sp->flags &
|
||||||
|
SRB_FCP_CMND_DMA_VALID)) &&
|
||||||
|
!ha->flags.isp82xx_fw_hung) {
|
||||||
spin_unlock_irqrestore(
|
spin_unlock_irqrestore(
|
||||||
&ha->hardware_lock, flags);
|
&ha->hardware_lock, flags);
|
||||||
if (ha->isp_ops->abort_command(sp)) {
|
if (ha->isp_ops->abort_command(sp)) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -333,9 +333,6 @@
|
||||||
#define QLA82XX_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004)
|
#define QLA82XX_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004)
|
||||||
#define QLA82XX_ROMUSB_GLB_CAS_RST (ROMUSB_GLB + 0x0038)
|
#define QLA82XX_ROMUSB_GLB_CAS_RST (ROMUSB_GLB + 0x0038)
|
||||||
|
|
||||||
/* Lock IDs for ROM lock */
|
|
||||||
#define ROM_LOCK_DRIVER 0x0d417340
|
|
||||||
|
|
||||||
#define QLA82XX_PCI_CRB_WINDOWSIZE 0x00100000 /* all are 1MB windows */
|
#define QLA82XX_PCI_CRB_WINDOWSIZE 0x00100000 /* all are 1MB windows */
|
||||||
#define QLA82XX_PCI_CRB_WINDOW(A) \
|
#define QLA82XX_PCI_CRB_WINDOW(A) \
|
||||||
(QLA82XX_PCI_CRBSPACE + (A)*QLA82XX_PCI_CRB_WINDOWSIZE)
|
(QLA82XX_PCI_CRBSPACE + (A)*QLA82XX_PCI_CRB_WINDOWSIZE)
|
||||||
|
@ -1186,6 +1183,7 @@ static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC,
|
||||||
#define CRB_NIU_XG_PAUSE_CTL_P1 0x8
|
#define CRB_NIU_XG_PAUSE_CTL_P1 0x8
|
||||||
|
|
||||||
#define qla82xx_get_temp_val(x) ((x) >> 16)
|
#define qla82xx_get_temp_val(x) ((x) >> 16)
|
||||||
|
#define qla82xx_get_temp_val1(x) ((x) && 0x0000FFFF)
|
||||||
#define qla82xx_get_temp_state(x) ((x) & 0xffff)
|
#define qla82xx_get_temp_state(x) ((x) & 0xffff)
|
||||||
#define qla82xx_encode_temp(val, state) (((val) << 16) | (state))
|
#define qla82xx_encode_temp(val, state) (((val) << 16) | (state))
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include "qla_def.h"
|
#include "qla_def.h"
|
||||||
#include "qla_gbl.h"
|
#include "qla_gbl.h"
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#define TIMEOUT_100_MS 100
|
||||||
|
|
||||||
/* 8044 Flash Read/Write functions */
|
/* 8044 Flash Read/Write functions */
|
||||||
uint32_t
|
uint32_t
|
||||||
qla8044_rd_reg(struct qla_hw_data *ha, ulong addr)
|
qla8044_rd_reg(struct qla_hw_data *ha, ulong addr)
|
||||||
|
@ -117,6 +120,95 @@ qla8044_read_write_crb_reg(struct scsi_qla_host *vha,
|
||||||
qla8044_wr_reg_indirect(vha, waddr, value);
|
qla8044_wr_reg_indirect(vha, waddr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla8044_poll_wait_for_ready(struct scsi_qla_host *vha, uint32_t addr1,
|
||||||
|
uint32_t mask)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
/* jiffies after 100ms */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
|
||||||
|
do {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
if (time_after_eq(jiffies, timeout)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb151,
|
||||||
|
"Error in processing rdmdio entry\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
qla8044_ipmdio_rd_reg(struct scsi_qla_host *vha,
|
||||||
|
uint32_t addr1, uint32_t addr3, uint32_t mask, uint32_t addr)
|
||||||
|
{
|
||||||
|
uint32_t temp;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = qla8044_poll_wait_for_ready(vha, addr1, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
temp = (0x40000000 | addr);
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1, temp);
|
||||||
|
|
||||||
|
ret = qla8044_poll_wait_for_ready(vha, addr1, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
qla8044_rd_reg_indirect(vha, addr3, &ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla8044_poll_wait_ipmdio_bus_idle(struct scsi_qla_host *vha,
|
||||||
|
uint32_t addr1, uint32_t addr2, uint32_t addr3, uint32_t mask)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
/* jiffies after 100 msecs */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
|
||||||
|
do {
|
||||||
|
temp = qla8044_ipmdio_rd_reg(vha, addr1, addr3, mask, addr2);
|
||||||
|
if ((temp & 0x1) != 1)
|
||||||
|
break;
|
||||||
|
if (time_after_eq(jiffies, timeout)) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb152,
|
||||||
|
"Error in processing mdiobus idle\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla8044_ipmdio_wr_reg(struct scsi_qla_host *vha, uint32_t addr1,
|
||||||
|
uint32_t addr3, uint32_t mask, uint32_t addr, uint32_t value)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = qla8044_poll_wait_for_ready(vha, addr1, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
qla8044_wr_reg_indirect(vha, addr3, value);
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1, addr);
|
||||||
|
|
||||||
|
ret = qla8044_poll_wait_for_ready(vha, addr1, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask,
|
* qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask,
|
||||||
* Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
|
* Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
|
||||||
|
@ -356,8 +448,8 @@ qla8044_flash_lock(scsi_qla_host_t *vha)
|
||||||
lock_owner = qla8044_rd_reg(ha,
|
lock_owner = qla8044_rd_reg(ha,
|
||||||
QLA8044_FLASH_LOCK_ID);
|
QLA8044_FLASH_LOCK_ID);
|
||||||
ql_log(ql_log_warn, vha, 0xb113,
|
ql_log(ql_log_warn, vha, 0xb113,
|
||||||
"%s: flash lock by %d failed, held by %d\n",
|
"%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d",
|
||||||
__func__, ha->portnum, lock_owner);
|
__func__, ha->portnum, lock_owner);
|
||||||
ret_val = QLA_FUNCTION_FAILED;
|
ret_val = QLA_FUNCTION_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1541,7 +1633,7 @@ static void
|
||||||
qla8044_need_reset_handler(struct scsi_qla_host *vha)
|
qla8044_need_reset_handler(struct scsi_qla_host *vha)
|
||||||
{
|
{
|
||||||
uint32_t dev_state = 0, drv_state, drv_active;
|
uint32_t dev_state = 0, drv_state, drv_active;
|
||||||
unsigned long reset_timeout, dev_init_timeout;
|
unsigned long reset_timeout;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
|
||||||
ql_log(ql_log_fatal, vha, 0xb0c2,
|
ql_log(ql_log_fatal, vha, 0xb0c2,
|
||||||
|
@ -1555,84 +1647,78 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
|
||||||
qla8044_idc_lock(ha);
|
qla8044_idc_lock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_state = qla8044_rd_direct(vha,
|
||||||
|
QLA8044_CRB_DEV_STATE_INDEX);
|
||||||
drv_state = qla8044_rd_direct(vha,
|
drv_state = qla8044_rd_direct(vha,
|
||||||
QLA8044_CRB_DRV_STATE_INDEX);
|
QLA8044_CRB_DRV_STATE_INDEX);
|
||||||
drv_active = qla8044_rd_direct(vha,
|
drv_active = qla8044_rd_direct(vha,
|
||||||
QLA8044_CRB_DRV_ACTIVE_INDEX);
|
QLA8044_CRB_DRV_ACTIVE_INDEX);
|
||||||
|
|
||||||
ql_log(ql_log_info, vha, 0xb0c5,
|
ql_log(ql_log_info, vha, 0xb0c5,
|
||||||
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
|
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x dev_state = 0x%x\n",
|
||||||
__func__, vha->host_no, drv_state, drv_active);
|
__func__, vha->host_no, drv_state, drv_active, dev_state);
|
||||||
|
|
||||||
if (!ha->flags.nic_core_reset_owner) {
|
qla8044_set_rst_ready(vha);
|
||||||
ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
|
|
||||||
"%s(%ld): reset acknowledged\n",
|
|
||||||
__func__, vha->host_no);
|
|
||||||
qla8044_set_rst_ready(vha);
|
|
||||||
|
|
||||||
/* Non-reset owners ACK Reset and wait for device INIT state
|
/* wait for 10 seconds for reset ack from all functions */
|
||||||
* as part of Reset Recovery by Reset Owner
|
reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
|
||||||
*/
|
|
||||||
dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (time_after_eq(jiffies, dev_init_timeout)) {
|
if (time_after_eq(jiffies, reset_timeout)) {
|
||||||
ql_log(ql_log_info, vha, 0xb0c4,
|
ql_log(ql_log_info, vha, 0xb0c4,
|
||||||
"%s: Non Reset owner: Reset Ack Timeout!\n",
|
"%s: Function %d: Reset Ack Timeout!, drv_state: 0x%08x, drv_active: 0x%08x\n",
|
||||||
__func__);
|
__func__, ha->portnum, drv_state, drv_active);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qla8044_idc_unlock(ha);
|
qla8044_idc_unlock(ha);
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
qla8044_idc_lock(ha);
|
qla8044_idc_lock(ha);
|
||||||
|
|
||||||
dev_state = qla8044_rd_direct(vha,
|
dev_state = qla8044_rd_direct(vha,
|
||||||
QLA8044_CRB_DEV_STATE_INDEX);
|
QLA8044_CRB_DEV_STATE_INDEX);
|
||||||
} while (((drv_state & drv_active) != drv_active) &&
|
drv_state = qla8044_rd_direct(vha,
|
||||||
(dev_state == QLA8XXX_DEV_NEED_RESET));
|
QLA8044_CRB_DRV_STATE_INDEX);
|
||||||
|
drv_active = qla8044_rd_direct(vha,
|
||||||
|
QLA8044_CRB_DRV_ACTIVE_INDEX);
|
||||||
|
} while (((drv_state & drv_active) != drv_active) &&
|
||||||
|
(dev_state == QLA8XXX_DEV_NEED_RESET));
|
||||||
|
|
||||||
|
/* Remove IDC participation of functions not acknowledging */
|
||||||
|
if (drv_state != drv_active) {
|
||||||
|
ql_log(ql_log_info, vha, 0xb0c7,
|
||||||
|
"%s(%ld): Function %d turning off drv_active of non-acking function 0x%x\n",
|
||||||
|
__func__, vha->host_no, ha->portnum,
|
||||||
|
(drv_active ^ drv_state));
|
||||||
|
drv_active = drv_active & drv_state;
|
||||||
|
qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
|
||||||
|
drv_active);
|
||||||
} else {
|
} else {
|
||||||
qla8044_set_rst_ready(vha);
|
|
||||||
|
|
||||||
/* wait for 10 seconds for reset ack from all functions */
|
|
||||||
reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
|
|
||||||
|
|
||||||
while ((drv_state & drv_active) != drv_active) {
|
|
||||||
if (time_after_eq(jiffies, reset_timeout)) {
|
|
||||||
ql_log(ql_log_info, vha, 0xb0c6,
|
|
||||||
"%s: RESET TIMEOUT!"
|
|
||||||
"drv_state: 0x%08x, drv_active: 0x%08x\n",
|
|
||||||
QLA2XXX_DRIVER_NAME, drv_state, drv_active);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
qla8044_idc_unlock(ha);
|
|
||||||
msleep(1000);
|
|
||||||
qla8044_idc_lock(ha);
|
|
||||||
|
|
||||||
drv_state = qla8044_rd_direct(vha,
|
|
||||||
QLA8044_CRB_DRV_STATE_INDEX);
|
|
||||||
drv_active = qla8044_rd_direct(vha,
|
|
||||||
QLA8044_CRB_DRV_ACTIVE_INDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drv_state != drv_active) {
|
|
||||||
ql_log(ql_log_info, vha, 0xb0c7,
|
|
||||||
"%s(%ld): Reset_owner turning off drv_active "
|
|
||||||
"of non-acking function 0x%x\n", __func__,
|
|
||||||
vha->host_no, (drv_active ^ drv_state));
|
|
||||||
drv_active = drv_active & drv_state;
|
|
||||||
qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
|
|
||||||
drv_active);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear RESET OWNER, will be set at next reset
|
* Reset owner should execute reset recovery,
|
||||||
* by next RST_OWNER
|
* if all functions acknowledged
|
||||||
*/
|
*/
|
||||||
ha->flags.nic_core_reset_owner = 0;
|
if ((ha->flags.nic_core_reset_owner) &&
|
||||||
|
(dev_state == QLA8XXX_DEV_NEED_RESET)) {
|
||||||
|
ha->flags.nic_core_reset_owner = 0;
|
||||||
|
qla8044_device_bootstrap(vha);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Start Reset Recovery */
|
/* Exit if non active function */
|
||||||
|
if (!(drv_active & (1 << ha->portnum))) {
|
||||||
|
ha->flags.nic_core_reset_owner = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute Reset Recovery if Reset Owner or Function 7
|
||||||
|
* is the only active function
|
||||||
|
*/
|
||||||
|
if (ha->flags.nic_core_reset_owner ||
|
||||||
|
((drv_state & drv_active) == QLA8044_FUN7_ACTIVE_INDEX)) {
|
||||||
|
ha->flags.nic_core_reset_owner = 0;
|
||||||
qla8044_device_bootstrap(vha);
|
qla8044_device_bootstrap(vha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1655,6 +1741,19 @@ qla8044_set_drv_active(struct scsi_qla_host *vha)
|
||||||
qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
|
qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla8044_check_drv_active(struct scsi_qla_host *vha)
|
||||||
|
{
|
||||||
|
uint32_t drv_active;
|
||||||
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
|
||||||
|
drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
|
||||||
|
if (drv_active & (1 << ha->portnum))
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
else
|
||||||
|
return QLA_TEST_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
|
qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
|
||||||
{
|
{
|
||||||
|
@ -1837,14 +1936,16 @@ qla8044_device_state_handler(struct scsi_qla_host *vha)
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (time_after_eq(jiffies, dev_init_timeout)) {
|
if (time_after_eq(jiffies, dev_init_timeout)) {
|
||||||
ql_log(ql_log_warn, vha, 0xb0cf,
|
if (qla8044_check_drv_active(vha) == QLA_SUCCESS) {
|
||||||
"%s: Device Init Failed 0x%x = %s\n",
|
ql_log(ql_log_warn, vha, 0xb0cf,
|
||||||
QLA2XXX_DRIVER_NAME, dev_state,
|
"%s: Device Init Failed 0x%x = %s\n",
|
||||||
dev_state < MAX_STATES ?
|
QLA2XXX_DRIVER_NAME, dev_state,
|
||||||
qdev_state(dev_state) : "Unknown");
|
dev_state < MAX_STATES ?
|
||||||
|
qdev_state(dev_state) : "Unknown");
|
||||||
qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
|
qla8044_wr_direct(vha,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8044_CRB_DEV_STATE_INDEX,
|
||||||
|
QLA8XXX_DEV_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
|
dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
|
||||||
|
@ -2017,6 +2118,13 @@ qla8044_watchdog(struct scsi_qla_host *vha)
|
||||||
test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) {
|
test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) {
|
||||||
dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
|
dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
|
||||||
|
|
||||||
|
if (qla8044_check_fw_alive(vha)) {
|
||||||
|
ha->flags.isp82xx_fw_hung = 1;
|
||||||
|
ql_log(ql_log_warn, vha, 0xb10a,
|
||||||
|
"Firmware hung.\n");
|
||||||
|
qla82xx_clear_pending_mbx(vha);
|
||||||
|
}
|
||||||
|
|
||||||
if (qla8044_check_temp(vha)) {
|
if (qla8044_check_temp(vha)) {
|
||||||
set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
|
set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
|
||||||
ha->flags.isp82xx_fw_hung = 1;
|
ha->flags.isp82xx_fw_hung = 1;
|
||||||
|
@ -2037,7 +2145,7 @@ qla8044_watchdog(struct scsi_qla_host *vha)
|
||||||
qla2xxx_wake_dpc(vha);
|
qla2xxx_wake_dpc(vha);
|
||||||
} else {
|
} else {
|
||||||
/* Check firmware health */
|
/* Check firmware health */
|
||||||
if (qla8044_check_fw_alive(vha)) {
|
if (ha->flags.isp82xx_fw_hung) {
|
||||||
halt_status = qla8044_rd_direct(vha,
|
halt_status = qla8044_rd_direct(vha,
|
||||||
QLA8044_PEG_HALT_STATUS1_INDEX);
|
QLA8044_PEG_HALT_STATUS1_INDEX);
|
||||||
if (halt_status &
|
if (halt_status &
|
||||||
|
@ -2073,12 +2181,8 @@ qla8044_watchdog(struct scsi_qla_host *vha)
|
||||||
__func__);
|
__func__);
|
||||||
set_bit(ISP_ABORT_NEEDED,
|
set_bit(ISP_ABORT_NEEDED,
|
||||||
&vha->dpc_flags);
|
&vha->dpc_flags);
|
||||||
qla82xx_clear_pending_mbx(vha);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ha->flags.isp82xx_fw_hung = 1;
|
|
||||||
ql_log(ql_log_warn, vha, 0xb10a,
|
|
||||||
"Firmware hung.\n");
|
|
||||||
qla2xxx_wake_dpc(vha);
|
qla2xxx_wake_dpc(vha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2286,8 +2390,6 @@ qla8044_minidump_process_rdmem(struct scsi_qla_host *vha,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j >= MAX_CTL_CHECK) {
|
if (j >= MAX_CTL_CHECK) {
|
||||||
printk_ratelimited(KERN_ERR
|
|
||||||
"%s: failed to read through agent\n", __func__);
|
|
||||||
write_unlock_irqrestore(&ha->hw_lock, flags);
|
write_unlock_irqrestore(&ha->hw_lock, flags);
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2882,6 +2984,231 @@ error_exit:
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
qla8044_minidump_process_rddfe(struct scsi_qla_host *vha,
|
||||||
|
struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
int loop_cnt;
|
||||||
|
uint32_t addr1, addr2, value, data, temp, wrVal;
|
||||||
|
uint8_t stride, stride2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll, mask, data_size, modify_mask;
|
||||||
|
uint32_t wait_count = 0;
|
||||||
|
|
||||||
|
uint32_t *data_ptr = *d_ptr;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rddfe *rddfe;
|
||||||
|
rddfe = (struct qla8044_minidump_entry_rddfe *) entry_hdr;
|
||||||
|
|
||||||
|
addr1 = rddfe->addr_1;
|
||||||
|
value = rddfe->value;
|
||||||
|
stride = rddfe->stride;
|
||||||
|
stride2 = rddfe->stride2;
|
||||||
|
count = rddfe->count;
|
||||||
|
|
||||||
|
poll = rddfe->poll;
|
||||||
|
mask = rddfe->mask;
|
||||||
|
modify_mask = rddfe->modify_mask;
|
||||||
|
data_size = rddfe->data_size;
|
||||||
|
|
||||||
|
addr2 = addr1 + stride;
|
||||||
|
|
||||||
|
for (loop_cnt = 0x0; loop_cnt < count; loop_cnt++) {
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1, (0x40000000 | value));
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb153,
|
||||||
|
"%s: TIMEOUT\n", __func__);
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr2, &temp);
|
||||||
|
temp = temp & modify_mask;
|
||||||
|
temp = (temp | ((loop_cnt << 16) | loop_cnt));
|
||||||
|
wrVal = ((temp << 16) | temp);
|
||||||
|
|
||||||
|
qla8044_wr_reg_indirect(vha, addr2, wrVal);
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1, value);
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb154,
|
||||||
|
"%s: TIMEOUT\n", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1,
|
||||||
|
((0x40000000 | value) + stride2));
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb155,
|
||||||
|
"%s: TIMEOUT\n", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
qla8044_rd_reg_indirect(vha, addr2, &data);
|
||||||
|
|
||||||
|
*data_ptr++ = wrVal;
|
||||||
|
*data_ptr++ = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*d_ptr = data_ptr;
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
qla8044_minidump_process_rdmdio(struct scsi_qla_host *vha,
|
||||||
|
struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t addr1, addr2, value1, value2, data, selVal;
|
||||||
|
uint8_t stride1, stride2;
|
||||||
|
uint32_t addr3, addr4, addr5, addr6, addr7;
|
||||||
|
uint16_t count, loop_cnt;
|
||||||
|
uint32_t poll, mask;
|
||||||
|
uint32_t *data_ptr = *d_ptr;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rdmdio *rdmdio;
|
||||||
|
|
||||||
|
rdmdio = (struct qla8044_minidump_entry_rdmdio *) entry_hdr;
|
||||||
|
|
||||||
|
addr1 = rdmdio->addr_1;
|
||||||
|
addr2 = rdmdio->addr_2;
|
||||||
|
value1 = rdmdio->value_1;
|
||||||
|
stride1 = rdmdio->stride_1;
|
||||||
|
stride2 = rdmdio->stride_2;
|
||||||
|
count = rdmdio->count;
|
||||||
|
|
||||||
|
poll = rdmdio->poll;
|
||||||
|
mask = rdmdio->mask;
|
||||||
|
value2 = rdmdio->value_2;
|
||||||
|
|
||||||
|
addr3 = addr1 + stride1;
|
||||||
|
|
||||||
|
for (loop_cnt = 0; loop_cnt < count; loop_cnt++) {
|
||||||
|
ret = qla8044_poll_wait_ipmdio_bus_idle(vha, addr1, addr2,
|
||||||
|
addr3, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
addr4 = addr2 - stride1;
|
||||||
|
ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask, addr4,
|
||||||
|
value2);
|
||||||
|
if (ret == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
addr5 = addr2 - (2 * stride1);
|
||||||
|
ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask, addr5,
|
||||||
|
value1);
|
||||||
|
if (ret == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
addr6 = addr2 - (3 * stride1);
|
||||||
|
ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask,
|
||||||
|
addr6, 0x2);
|
||||||
|
if (ret == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
ret = qla8044_poll_wait_ipmdio_bus_idle(vha, addr1, addr2,
|
||||||
|
addr3, mask);
|
||||||
|
if (ret == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
addr7 = addr2 - (4 * stride1);
|
||||||
|
data = qla8044_ipmdio_rd_reg(vha, addr1, addr3,
|
||||||
|
mask, addr7);
|
||||||
|
if (data == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
selVal = (value2 << 18) | (value1 << 2) | 2;
|
||||||
|
|
||||||
|
stride2 = rdmdio->stride_2;
|
||||||
|
*data_ptr++ = selVal;
|
||||||
|
*data_ptr++ = data;
|
||||||
|
|
||||||
|
value1 = value1 + stride2;
|
||||||
|
*d_ptr = data_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t qla8044_minidump_process_pollwr(struct scsi_qla_host *vha,
|
||||||
|
struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
uint32_t addr1, addr2, value1, value2, poll, mask, r_value;
|
||||||
|
uint32_t wait_count = 0;
|
||||||
|
struct qla8044_minidump_entry_pollwr *pollwr_hdr;
|
||||||
|
|
||||||
|
pollwr_hdr = (struct qla8044_minidump_entry_pollwr *)entry_hdr;
|
||||||
|
addr1 = pollwr_hdr->addr_1;
|
||||||
|
addr2 = pollwr_hdr->addr_2;
|
||||||
|
value1 = pollwr_hdr->value_1;
|
||||||
|
value2 = pollwr_hdr->value_2;
|
||||||
|
|
||||||
|
poll = pollwr_hdr->poll;
|
||||||
|
mask = pollwr_hdr->mask;
|
||||||
|
|
||||||
|
while (wait_count < poll) {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &r_value);
|
||||||
|
|
||||||
|
if ((r_value & poll) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xb156, "%s: TIMEOUT\n", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
qla8044_wr_reg_indirect(vha, addr2, value2);
|
||||||
|
qla8044_wr_reg_indirect(vha, addr1, value1);
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
qla8044_rd_reg_indirect(vha, addr1, &r_value);
|
||||||
|
|
||||||
|
if ((r_value & poll) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* qla8044_collect_md_data - Retrieve firmware minidump data.
|
* qla8044_collect_md_data - Retrieve firmware minidump data.
|
||||||
|
@ -3089,6 +3416,24 @@ qla8044_collect_md_data(struct scsi_qla_host *vha)
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
||||||
break;
|
break;
|
||||||
|
case QLA8044_RDDFE:
|
||||||
|
rval = qla8044_minidump_process_rddfe(vha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
||||||
|
break;
|
||||||
|
case QLA8044_RDMDIO:
|
||||||
|
rval = qla8044_minidump_process_rdmdio(vha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
||||||
|
break;
|
||||||
|
case QLA8044_POLLWR:
|
||||||
|
rval = qla8044_minidump_process_pollwr(vha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
||||||
|
break;
|
||||||
case QLA82XX_RDNOP:
|
case QLA82XX_RDNOP:
|
||||||
default:
|
default:
|
||||||
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
qla8044_mark_entry_skipped(vha, entry_hdr, i);
|
||||||
|
@ -3110,6 +3455,7 @@ skip_nxt_entry:
|
||||||
"Dump data mismatch: Data collected: "
|
"Dump data mismatch: Data collected: "
|
||||||
"[0x%x], total_data_size:[0x%x]\n",
|
"[0x%x], total_data_size:[0x%x]\n",
|
||||||
data_collected, ha->md_dump_size);
|
data_collected, ha->md_dump_size);
|
||||||
|
rval = QLA_FUNCTION_FAILED;
|
||||||
goto md_failed;
|
goto md_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3134,10 +3480,12 @@ qla8044_get_minidump(struct scsi_qla_host *vha)
|
||||||
|
|
||||||
if (!qla8044_collect_md_data(vha)) {
|
if (!qla8044_collect_md_data(vha)) {
|
||||||
ha->fw_dumped = 1;
|
ha->fw_dumped = 1;
|
||||||
|
ha->prev_minidump_failed = 0;
|
||||||
} else {
|
} else {
|
||||||
ql_log(ql_log_fatal, vha, 0xb0db,
|
ql_log(ql_log_fatal, vha, 0xb0db,
|
||||||
"%s: Unable to collect minidump\n",
|
"%s: Unable to collect minidump\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
ha->prev_minidump_failed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -133,6 +133,7 @@
|
||||||
#define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
|
#define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
|
||||||
#define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
|
#define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
|
||||||
#define QLA8044_LINK_SPEED_FACTOR 10
|
#define QLA8044_LINK_SPEED_FACTOR 10
|
||||||
|
#define QLA8044_FUN7_ACTIVE_INDEX 0x80
|
||||||
|
|
||||||
/* FLASH API Defines */
|
/* FLASH API Defines */
|
||||||
#define QLA8044_FLASH_MAX_WAIT_USEC 100
|
#define QLA8044_FLASH_MAX_WAIT_USEC 100
|
||||||
|
@ -431,6 +432,50 @@ struct qla8044_minidump_entry_pollrd {
|
||||||
uint32_t rsvd_1;
|
uint32_t rsvd_1;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rddfe {
|
||||||
|
struct qla8044_minidump_entry_hdr h;
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t value;
|
||||||
|
uint8_t stride;
|
||||||
|
uint8_t stride2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t modify_mask;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint32_t rsvd;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rdmdio {
|
||||||
|
struct qla8044_minidump_entry_hdr h;
|
||||||
|
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t addr_2;
|
||||||
|
uint32_t value_1;
|
||||||
|
uint8_t stride_1;
|
||||||
|
uint8_t stride_2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t value_2;
|
||||||
|
uint32_t data_size;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_pollwr {
|
||||||
|
struct qla8044_minidump_entry_hdr h;
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t addr_2;
|
||||||
|
uint32_t value_1;
|
||||||
|
uint32_t value_2;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint32_t rsvd;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* RDMUX2 Entry */
|
/* RDMUX2 Entry */
|
||||||
struct qla8044_minidump_entry_rdmux2 {
|
struct qla8044_minidump_entry_rdmux2 {
|
||||||
struct qla8044_minidump_entry_hdr h;
|
struct qla8044_minidump_entry_hdr h;
|
||||||
|
@ -516,6 +561,9 @@ static const uint32_t qla8044_reg_tbl[] = {
|
||||||
#define QLA8044_DBG_RSVD_ARRAY_LEN 8
|
#define QLA8044_DBG_RSVD_ARRAY_LEN 8
|
||||||
#define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN 16
|
#define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN 16
|
||||||
#define QLA8044_SS_PCI_INDEX 0
|
#define QLA8044_SS_PCI_INDEX 0
|
||||||
|
#define QLA8044_RDDFE 38
|
||||||
|
#define QLA8044_RDMDIO 39
|
||||||
|
#define QLA8044_POLLWR 40
|
||||||
|
|
||||||
struct qla8044_minidump_template_hdr {
|
struct qla8044_minidump_template_hdr {
|
||||||
uint32_t entry_type;
|
uint32_t entry_type;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -616,7 +616,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
|
||||||
|
|
||||||
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
|
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
|
||||||
/* List assured to be having elements */
|
/* List assured to be having elements */
|
||||||
qla2x00_clean_dsd_pool(ha, sp);
|
qla2x00_clean_dsd_pool(ha, sp, NULL);
|
||||||
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
|
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +781,7 @@ static int
|
||||||
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
|
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
|
||||||
{
|
{
|
||||||
#define ABORT_POLLING_PERIOD 1000
|
#define ABORT_POLLING_PERIOD 1000
|
||||||
#define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD))
|
#define ABORT_WAIT_ITER ((2 * 1000) / (ABORT_POLLING_PERIOD))
|
||||||
unsigned long wait_iter = ABORT_WAIT_ITER;
|
unsigned long wait_iter = ABORT_WAIT_ITER;
|
||||||
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
@ -844,11 +844,8 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qla2x00_wait_for_reset_ready
|
* qla2x00_wait_for_hba_ready
|
||||||
* Wait till the HBA is online after going through
|
* Wait till the HBA is ready before doing driver unload
|
||||||
* <= MAX_RETRIES_OF_ISP_ABORT or
|
|
||||||
* finally HBA is disabled ie marked offline or flash
|
|
||||||
* operations are in progress.
|
|
||||||
*
|
*
|
||||||
* Input:
|
* Input:
|
||||||
* ha - pointer to host adapter structure
|
* ha - pointer to host adapter structure
|
||||||
|
@ -857,35 +854,15 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
|
||||||
* Does context switching-Release SPIN_LOCK
|
* Does context switching-Release SPIN_LOCK
|
||||||
* (if any) before calling this routine.
|
* (if any) before calling this routine.
|
||||||
*
|
*
|
||||||
* Return:
|
|
||||||
* Success (Adapter is online/no flash ops) : 0
|
|
||||||
* Failed (Adapter is offline/disabled/flash ops in progress) : 1
|
|
||||||
*/
|
*/
|
||||||
static int
|
static void
|
||||||
qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
|
qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
|
||||||
{
|
{
|
||||||
int return_status;
|
|
||||||
unsigned long wait_online;
|
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
|
||||||
|
|
||||||
wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
|
while ((!(vha->flags.online) || ha->dpc_active ||
|
||||||
while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
|
ha->flags.mbox_busy))
|
||||||
test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
|
|
||||||
test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
|
|
||||||
ha->optrom_state != QLA_SWAITING ||
|
|
||||||
ha->dpc_active) && time_before(jiffies, wait_online))
|
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
|
|
||||||
if (base_vha->flags.online && ha->optrom_state == QLA_SWAITING)
|
|
||||||
return_status = QLA_SUCCESS;
|
|
||||||
else
|
|
||||||
return_status = QLA_FUNCTION_FAILED;
|
|
||||||
|
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x8019,
|
|
||||||
"%s return status=%d.\n", __func__, return_status);
|
|
||||||
|
|
||||||
return return_status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -945,7 +922,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int id, lun;
|
unsigned int id, lun;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int wait = 0;
|
int rval, wait = 0;
|
||||||
struct qla_hw_data *ha = vha->hw;
|
struct qla_hw_data *ha = vha->hw;
|
||||||
|
|
||||||
if (!CMD_SP(cmd))
|
if (!CMD_SP(cmd))
|
||||||
|
@ -974,10 +951,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
||||||
sp_get(sp);
|
sp_get(sp);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
if (ha->isp_ops->abort_command(sp)) {
|
rval = ha->isp_ops->abort_command(sp);
|
||||||
ret = FAILED;
|
if (rval) {
|
||||||
|
if (rval == QLA_FUNCTION_PARAMETER_ERROR) {
|
||||||
|
/*
|
||||||
|
* Decrement the ref_count since we can't find the
|
||||||
|
* command
|
||||||
|
*/
|
||||||
|
atomic_dec(&sp->ref_count);
|
||||||
|
ret = SUCCESS;
|
||||||
|
} else
|
||||||
|
ret = FAILED;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x8003,
|
ql_dbg(ql_dbg_taskm, vha, 0x8003,
|
||||||
"Abort command mbx failed cmd=%p.\n", cmd);
|
"Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval);
|
||||||
} else {
|
} else {
|
||||||
ql_dbg(ql_dbg_taskm, vha, 0x8004,
|
ql_dbg(ql_dbg_taskm, vha, 0x8004,
|
||||||
"Abort command mbx success cmd=%p.\n", cmd);
|
"Abort command mbx success cmd=%p.\n", cmd);
|
||||||
|
@ -985,6 +972,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
|
/*
|
||||||
|
* Clear the slot in the oustanding_cmds array if we can't find the
|
||||||
|
* command to reclaim the resources.
|
||||||
|
*/
|
||||||
|
if (rval == QLA_FUNCTION_PARAMETER_ERROR)
|
||||||
|
vha->req->outstanding_cmds[sp->handle] = NULL;
|
||||||
sp->done(ha, sp, 0);
|
sp->done(ha, sp, 0);
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
@ -1236,7 +1229,11 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
|
||||||
ql_log(ql_log_info, vha, 0x8018,
|
ql_log(ql_log_info, vha, 0x8018,
|
||||||
"ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
|
"ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
|
||||||
|
|
||||||
if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS)
|
/*
|
||||||
|
* No point in issuing another reset if one is active. Also do not
|
||||||
|
* attempt a reset if we are updating flash.
|
||||||
|
*/
|
||||||
|
if (qla2x00_reset_active(vha) || ha->optrom_state != QLA_SWAITING)
|
||||||
goto eh_host_reset_lock;
|
goto eh_host_reset_lock;
|
||||||
|
|
||||||
if (vha != base_vha) {
|
if (vha != base_vha) {
|
||||||
|
@ -2270,6 +2267,13 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
|
||||||
ha->device_type |= DT_IIDMA;
|
ha->device_type |= DT_IIDMA;
|
||||||
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
|
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
|
||||||
break;
|
break;
|
||||||
|
case PCI_DEVICE_ID_QLOGIC_ISP2271:
|
||||||
|
ha->device_type |= DT_ISP2271;
|
||||||
|
ha->device_type |= DT_ZIO_SUPPORTED;
|
||||||
|
ha->device_type |= DT_FWI2;
|
||||||
|
ha->device_type |= DT_IIDMA;
|
||||||
|
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_QLA82XX(ha))
|
if (IS_QLA82XX(ha))
|
||||||
|
@ -2346,7 +2350,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
|
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
|
||||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
|
pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
|
||||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 ||
|
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 ||
|
||||||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071) {
|
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 ||
|
||||||
|
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271) {
|
||||||
bars = pci_select_bars(pdev, IORESOURCE_MEM);
|
bars = pci_select_bars(pdev, IORESOURCE_MEM);
|
||||||
mem_only = 1;
|
mem_only = 1;
|
||||||
ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
|
ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
|
||||||
|
@ -2877,6 +2882,7 @@ skip_dpc:
|
||||||
|
|
||||||
base_vha->flags.init_done = 1;
|
base_vha->flags.init_done = 1;
|
||||||
base_vha->flags.online = 1;
|
base_vha->flags.online = 1;
|
||||||
|
ha->prev_minidump_failed = 0;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_init, base_vha, 0x00f2,
|
ql_dbg(ql_dbg_init, base_vha, 0x00f2,
|
||||||
"Init done and hba is online.\n");
|
"Init done and hba is online.\n");
|
||||||
|
@ -3136,6 +3142,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
|
||||||
base_vha = pci_get_drvdata(pdev);
|
base_vha = pci_get_drvdata(pdev);
|
||||||
ha = base_vha->hw;
|
ha = base_vha->hw;
|
||||||
|
|
||||||
|
qla2x00_wait_for_hba_ready(base_vha);
|
||||||
|
|
||||||
set_bit(UNLOADING, &base_vha->dpc_flags);
|
set_bit(UNLOADING, &base_vha->dpc_flags);
|
||||||
|
|
||||||
if (IS_QLAFX00(ha))
|
if (IS_QLAFX00(ha))
|
||||||
|
@ -3645,6 +3653,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
|
||||||
ha->eft = NULL;
|
ha->eft = NULL;
|
||||||
ha->eft_dma = 0;
|
ha->eft_dma = 0;
|
||||||
ha->fw_dumped = 0;
|
ha->fw_dumped = 0;
|
||||||
|
ha->fw_dump_cap_flags = 0;
|
||||||
ha->fw_dump_reading = 0;
|
ha->fw_dump_reading = 0;
|
||||||
ha->fw_dump = NULL;
|
ha->fw_dump = NULL;
|
||||||
ha->fw_dump_len = 0;
|
ha->fw_dump_len = 0;
|
||||||
|
@ -4913,12 +4922,13 @@ qla2x00_do_dpc(void *data)
|
||||||
if (qlafx00_reset_initialize(base_vha)) {
|
if (qlafx00_reset_initialize(base_vha)) {
|
||||||
/* Failed. Abort isp later. */
|
/* Failed. Abort isp later. */
|
||||||
if (!test_bit(UNLOADING,
|
if (!test_bit(UNLOADING,
|
||||||
&base_vha->dpc_flags))
|
&base_vha->dpc_flags)) {
|
||||||
set_bit(ISP_UNRECOVERABLE,
|
set_bit(ISP_UNRECOVERABLE,
|
||||||
&base_vha->dpc_flags);
|
&base_vha->dpc_flags);
|
||||||
ql_dbg(ql_dbg_dpc, base_vha,
|
ql_dbg(ql_dbg_dpc, base_vha,
|
||||||
0x4021,
|
0x4021,
|
||||||
"Reset Recovery Failed\n");
|
"Reset Recovery Failed\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5077,8 +5087,10 @@ intr_on_check:
|
||||||
ha->isp_ops->enable_intrs(ha);
|
ha->isp_ops->enable_intrs(ha);
|
||||||
|
|
||||||
if (test_and_clear_bit(BEACON_BLINK_NEEDED,
|
if (test_and_clear_bit(BEACON_BLINK_NEEDED,
|
||||||
&base_vha->dpc_flags))
|
&base_vha->dpc_flags)) {
|
||||||
ha->isp_ops->beacon_blink(base_vha);
|
if (ha->beacon_blink_led == 1)
|
||||||
|
ha->isp_ops->beacon_blink(base_vha);
|
||||||
|
}
|
||||||
|
|
||||||
if (!IS_QLAFX00(ha))
|
if (!IS_QLAFX00(ha))
|
||||||
qla2x00_do_dpc_all_vps(base_vha);
|
qla2x00_do_dpc_all_vps(base_vha);
|
||||||
|
@ -5325,7 +5337,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
|
||||||
#define FW_ISP82XX 7
|
#define FW_ISP82XX 7
|
||||||
#define FW_ISP2031 8
|
#define FW_ISP2031 8
|
||||||
#define FW_ISP8031 9
|
#define FW_ISP8031 9
|
||||||
#define FW_ISP2071 10
|
#define FW_ISP27XX 10
|
||||||
|
|
||||||
#define FW_FILE_ISP21XX "ql2100_fw.bin"
|
#define FW_FILE_ISP21XX "ql2100_fw.bin"
|
||||||
#define FW_FILE_ISP22XX "ql2200_fw.bin"
|
#define FW_FILE_ISP22XX "ql2200_fw.bin"
|
||||||
|
@ -5337,7 +5349,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
|
||||||
#define FW_FILE_ISP82XX "ql8200_fw.bin"
|
#define FW_FILE_ISP82XX "ql8200_fw.bin"
|
||||||
#define FW_FILE_ISP2031 "ql2600_fw.bin"
|
#define FW_FILE_ISP2031 "ql2600_fw.bin"
|
||||||
#define FW_FILE_ISP8031 "ql8300_fw.bin"
|
#define FW_FILE_ISP8031 "ql8300_fw.bin"
|
||||||
#define FW_FILE_ISP2071 "ql2700_fw.bin"
|
#define FW_FILE_ISP27XX "ql2700_fw.bin"
|
||||||
|
|
||||||
|
|
||||||
static DEFINE_MUTEX(qla_fw_lock);
|
static DEFINE_MUTEX(qla_fw_lock);
|
||||||
|
@ -5353,7 +5365,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
|
||||||
{ .name = FW_FILE_ISP82XX, },
|
{ .name = FW_FILE_ISP82XX, },
|
||||||
{ .name = FW_FILE_ISP2031, },
|
{ .name = FW_FILE_ISP2031, },
|
||||||
{ .name = FW_FILE_ISP8031, },
|
{ .name = FW_FILE_ISP8031, },
|
||||||
{ .name = FW_FILE_ISP2071, },
|
{ .name = FW_FILE_ISP27XX, },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fw_blob *
|
struct fw_blob *
|
||||||
|
@ -5382,8 +5394,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha)
|
||||||
blob = &qla_fw_blobs[FW_ISP2031];
|
blob = &qla_fw_blobs[FW_ISP2031];
|
||||||
} else if (IS_QLA8031(ha)) {
|
} else if (IS_QLA8031(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP8031];
|
blob = &qla_fw_blobs[FW_ISP8031];
|
||||||
} else if (IS_QLA2071(ha)) {
|
} else if (IS_QLA27XX(ha)) {
|
||||||
blob = &qla_fw_blobs[FW_ISP2071];
|
blob = &qla_fw_blobs[FW_ISP27XX];
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -5714,6 +5726,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -1727,11 +1727,8 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha)
|
||||||
if (IS_QLA2031(ha)) {
|
if (IS_QLA2031(ha)) {
|
||||||
led_select_value = qla83xx_select_led_port(ha);
|
led_select_value = qla83xx_select_led_port(ha);
|
||||||
|
|
||||||
qla83xx_wr_reg(vha, led_select_value, 0x40002000);
|
qla83xx_wr_reg(vha, led_select_value, 0x40000230);
|
||||||
qla83xx_wr_reg(vha, led_select_value + 4, 0x40002000);
|
qla83xx_wr_reg(vha, led_select_value + 4, 0x40000230);
|
||||||
msleep(1000);
|
|
||||||
qla83xx_wr_reg(vha, led_select_value, 0x40004000);
|
|
||||||
qla83xx_wr_reg(vha, led_select_value + 4, 0x40004000);
|
|
||||||
} else if (IS_QLA8031(ha)) {
|
} else if (IS_QLA8031(ha)) {
|
||||||
led_select_value = qla83xx_select_led_port(ha);
|
led_select_value = qla83xx_select_led_port(ha);
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,11 @@ struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha,
|
||||||
void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
|
void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
|
||||||
struct atio_from_isp *atio)
|
struct atio_from_isp *atio)
|
||||||
{
|
{
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xe072,
|
||||||
|
"%s: qla_target(%d): type %x ox_id %04x\n",
|
||||||
|
__func__, vha->vp_idx, atio->u.raw.entry_type,
|
||||||
|
be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id));
|
||||||
|
|
||||||
switch (atio->u.raw.entry_type) {
|
switch (atio->u.raw.entry_type) {
|
||||||
case ATIO_TYPE7:
|
case ATIO_TYPE7:
|
||||||
{
|
{
|
||||||
|
@ -236,6 +241,10 @@ void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
|
||||||
void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
|
void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt)
|
||||||
{
|
{
|
||||||
switch (pkt->entry_type) {
|
switch (pkt->entry_type) {
|
||||||
|
case CTIO_CRC2:
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xe073,
|
||||||
|
"qla_target(%d):%s: CRC2 Response pkt\n",
|
||||||
|
vha->vp_idx, __func__);
|
||||||
case CTIO_TYPE7:
|
case CTIO_TYPE7:
|
||||||
{
|
{
|
||||||
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
|
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
|
||||||
|
@ -1350,13 +1359,42 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm)
|
||||||
|
|
||||||
prm->cmd->sg_mapped = 1;
|
prm->cmd->sg_mapped = 1;
|
||||||
|
|
||||||
/*
|
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) {
|
||||||
* If greater than four sg entries then we need to allocate
|
/*
|
||||||
* the continuation entries
|
* If greater than four sg entries then we need to allocate
|
||||||
*/
|
* the continuation entries
|
||||||
if (prm->seg_cnt > prm->tgt->datasegs_per_cmd)
|
*/
|
||||||
prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt -
|
if (prm->seg_cnt > prm->tgt->datasegs_per_cmd)
|
||||||
prm->tgt->datasegs_per_cmd, prm->tgt->datasegs_per_cont);
|
prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt -
|
||||||
|
prm->tgt->datasegs_per_cmd,
|
||||||
|
prm->tgt->datasegs_per_cont);
|
||||||
|
} else {
|
||||||
|
/* DIF */
|
||||||
|
if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
|
||||||
|
(cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) {
|
||||||
|
prm->seg_cnt = DIV_ROUND_UP(cmd->bufflen, cmd->blk_sz);
|
||||||
|
prm->tot_dsds = prm->seg_cnt;
|
||||||
|
} else
|
||||||
|
prm->tot_dsds = prm->seg_cnt;
|
||||||
|
|
||||||
|
if (cmd->prot_sg_cnt) {
|
||||||
|
prm->prot_sg = cmd->prot_sg;
|
||||||
|
prm->prot_seg_cnt = pci_map_sg(prm->tgt->ha->pdev,
|
||||||
|
cmd->prot_sg, cmd->prot_sg_cnt,
|
||||||
|
cmd->dma_data_direction);
|
||||||
|
if (unlikely(prm->prot_seg_cnt == 0))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) ||
|
||||||
|
(cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) {
|
||||||
|
/* Dif Bundling not support here */
|
||||||
|
prm->prot_seg_cnt = DIV_ROUND_UP(cmd->bufflen,
|
||||||
|
cmd->blk_sz);
|
||||||
|
prm->tot_dsds += prm->prot_seg_cnt;
|
||||||
|
} else
|
||||||
|
prm->tot_dsds += prm->prot_seg_cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n",
|
ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n",
|
||||||
prm->seg_cnt, prm->req_cnt);
|
prm->seg_cnt, prm->req_cnt);
|
||||||
|
@ -1377,6 +1415,16 @@ static inline void qlt_unmap_sg(struct scsi_qla_host *vha,
|
||||||
BUG_ON(!cmd->sg_mapped);
|
BUG_ON(!cmd->sg_mapped);
|
||||||
pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
|
pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
|
||||||
cmd->sg_mapped = 0;
|
cmd->sg_mapped = 0;
|
||||||
|
|
||||||
|
if (cmd->prot_sg_cnt)
|
||||||
|
pci_unmap_sg(ha->pdev, cmd->prot_sg, cmd->prot_sg_cnt,
|
||||||
|
cmd->dma_data_direction);
|
||||||
|
|
||||||
|
if (cmd->ctx_dsd_alloced)
|
||||||
|
qla2x00_clean_dsd_pool(ha, NULL, cmd);
|
||||||
|
|
||||||
|
if (cmd->ctx)
|
||||||
|
dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
|
static int qlt_check_reserve_free_req(struct scsi_qla_host *vha,
|
||||||
|
@ -1665,8 +1713,9 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
|
||||||
return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
|
return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u\n",
|
ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u ox_id %04x\n",
|
||||||
vha->vp_idx, cmd->tag);
|
vha->vp_idx, cmd->tag,
|
||||||
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
||||||
|
|
||||||
prm->cmd = cmd;
|
prm->cmd = cmd;
|
||||||
prm->tgt = tgt;
|
prm->tgt = tgt;
|
||||||
|
@ -1902,6 +1951,323 @@ skip_explict_conf:
|
||||||
/* Sense with len > 24, is it possible ??? */
|
/* Sense with len > 24, is it possible ??? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* diff */
|
||||||
|
static inline int
|
||||||
|
qlt_hba_err_chk_enabled(struct se_cmd *se_cmd)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Uncomment when corresponding SCSI changes are done.
|
||||||
|
*
|
||||||
|
if (!sp->cmd->prot_chk)
|
||||||
|
return 0;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
switch (se_cmd->prot_op) {
|
||||||
|
case TARGET_PROT_DOUT_INSERT:
|
||||||
|
case TARGET_PROT_DIN_STRIP:
|
||||||
|
if (ql2xenablehba_err_chk >= 1)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TARGET_PROT_DOUT_PASS:
|
||||||
|
case TARGET_PROT_DIN_PASS:
|
||||||
|
if (ql2xenablehba_err_chk >= 2)
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case TARGET_PROT_DIN_INSERT:
|
||||||
|
case TARGET_PROT_DOUT_STRIP:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx)
|
||||||
|
{
|
||||||
|
uint32_t lba = 0xffffffff & se_cmd->t_task_lba;
|
||||||
|
|
||||||
|
/* wait til Mode Sense/Select cmd, modepage Ah, subpage 2
|
||||||
|
* have been immplemented by TCM, before AppTag is avail.
|
||||||
|
* Look for modesense_handlers[]
|
||||||
|
*/
|
||||||
|
ctx->app_tag = __constant_cpu_to_le16(0);
|
||||||
|
ctx->app_tag_mask[0] = 0x0;
|
||||||
|
ctx->app_tag_mask[1] = 0x0;
|
||||||
|
|
||||||
|
switch (se_cmd->prot_type) {
|
||||||
|
case TARGET_DIF_TYPE0_PROT:
|
||||||
|
/*
|
||||||
|
* No check for ql2xenablehba_err_chk, as it would be an
|
||||||
|
* I/O error if hba tag generation is not done.
|
||||||
|
*/
|
||||||
|
ctx->ref_tag = cpu_to_le32(lba);
|
||||||
|
|
||||||
|
if (!qlt_hba_err_chk_enabled(se_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* enable ALL bytes of the ref tag */
|
||||||
|
ctx->ref_tag_mask[0] = 0xff;
|
||||||
|
ctx->ref_tag_mask[1] = 0xff;
|
||||||
|
ctx->ref_tag_mask[2] = 0xff;
|
||||||
|
ctx->ref_tag_mask[3] = 0xff;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and
|
||||||
|
* 16 bit app tag.
|
||||||
|
*/
|
||||||
|
case TARGET_DIF_TYPE1_PROT:
|
||||||
|
ctx->ref_tag = cpu_to_le32(lba);
|
||||||
|
|
||||||
|
if (!qlt_hba_err_chk_enabled(se_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* enable ALL bytes of the ref tag */
|
||||||
|
ctx->ref_tag_mask[0] = 0xff;
|
||||||
|
ctx->ref_tag_mask[1] = 0xff;
|
||||||
|
ctx->ref_tag_mask[2] = 0xff;
|
||||||
|
ctx->ref_tag_mask[3] = 0xff;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to
|
||||||
|
* match LBA in CDB + N
|
||||||
|
*/
|
||||||
|
case TARGET_DIF_TYPE2_PROT:
|
||||||
|
ctx->ref_tag = cpu_to_le32(lba);
|
||||||
|
|
||||||
|
if (!qlt_hba_err_chk_enabled(se_cmd))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* enable ALL bytes of the ref tag */
|
||||||
|
ctx->ref_tag_mask[0] = 0xff;
|
||||||
|
ctx->ref_tag_mask[1] = 0xff;
|
||||||
|
ctx->ref_tag_mask[2] = 0xff;
|
||||||
|
ctx->ref_tag_mask[3] = 0xff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* For Type 3 protection: 16 bit GUARD only */
|
||||||
|
case TARGET_DIF_TYPE3_PROT:
|
||||||
|
ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] =
|
||||||
|
ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha)
|
||||||
|
{
|
||||||
|
uint32_t *cur_dsd;
|
||||||
|
int sgc;
|
||||||
|
uint32_t transfer_length = 0;
|
||||||
|
uint32_t data_bytes;
|
||||||
|
uint32_t dif_bytes;
|
||||||
|
uint8_t bundling = 1;
|
||||||
|
uint8_t *clr_ptr;
|
||||||
|
struct crc_context *crc_ctx_pkt = NULL;
|
||||||
|
struct qla_hw_data *ha;
|
||||||
|
struct ctio_crc2_to_fw *pkt;
|
||||||
|
dma_addr_t crc_ctx_dma;
|
||||||
|
uint16_t fw_prot_opts = 0;
|
||||||
|
struct qla_tgt_cmd *cmd = prm->cmd;
|
||||||
|
struct se_cmd *se_cmd = &cmd->se_cmd;
|
||||||
|
uint32_t h;
|
||||||
|
struct atio_from_isp *atio = &prm->cmd->atio;
|
||||||
|
|
||||||
|
sgc = 0;
|
||||||
|
ha = vha->hw;
|
||||||
|
|
||||||
|
pkt = (struct ctio_crc2_to_fw *)vha->req->ring_ptr;
|
||||||
|
prm->pkt = pkt;
|
||||||
|
memset(pkt, 0, sizeof(*pkt));
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xe071,
|
||||||
|
"qla_target(%d):%s: se_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n",
|
||||||
|
vha->vp_idx, __func__, se_cmd, se_cmd->prot_op,
|
||||||
|
prm->prot_sg, prm->prot_seg_cnt, se_cmd->t_task_lba);
|
||||||
|
|
||||||
|
if ((se_cmd->prot_op == TARGET_PROT_DIN_INSERT) ||
|
||||||
|
(se_cmd->prot_op == TARGET_PROT_DOUT_STRIP))
|
||||||
|
bundling = 0;
|
||||||
|
|
||||||
|
/* Compute dif len and adjust data len to incude protection */
|
||||||
|
data_bytes = cmd->bufflen;
|
||||||
|
dif_bytes = (data_bytes / cmd->blk_sz) * 8;
|
||||||
|
|
||||||
|
switch (se_cmd->prot_op) {
|
||||||
|
case TARGET_PROT_DIN_INSERT:
|
||||||
|
case TARGET_PROT_DOUT_STRIP:
|
||||||
|
transfer_length = data_bytes;
|
||||||
|
data_bytes += dif_bytes;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TARGET_PROT_DIN_STRIP:
|
||||||
|
case TARGET_PROT_DOUT_INSERT:
|
||||||
|
case TARGET_PROT_DIN_PASS:
|
||||||
|
case TARGET_PROT_DOUT_PASS:
|
||||||
|
transfer_length = data_bytes + dif_bytes;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qlt_hba_err_chk_enabled(se_cmd))
|
||||||
|
fw_prot_opts |= 0x10; /* Disable Guard tag checking */
|
||||||
|
/* HBA error checking enabled */
|
||||||
|
else if (IS_PI_UNINIT_CAPABLE(ha)) {
|
||||||
|
if ((se_cmd->prot_type == TARGET_DIF_TYPE1_PROT) ||
|
||||||
|
(se_cmd->prot_type == TARGET_DIF_TYPE2_PROT))
|
||||||
|
fw_prot_opts |= PO_DIS_VALD_APP_ESC;
|
||||||
|
else if (se_cmd->prot_type == TARGET_DIF_TYPE3_PROT)
|
||||||
|
fw_prot_opts |= PO_DIS_VALD_APP_REF_ESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (se_cmd->prot_op) {
|
||||||
|
case TARGET_PROT_DIN_INSERT:
|
||||||
|
case TARGET_PROT_DOUT_INSERT:
|
||||||
|
fw_prot_opts |= PO_MODE_DIF_INSERT;
|
||||||
|
break;
|
||||||
|
case TARGET_PROT_DIN_STRIP:
|
||||||
|
case TARGET_PROT_DOUT_STRIP:
|
||||||
|
fw_prot_opts |= PO_MODE_DIF_REMOVE;
|
||||||
|
break;
|
||||||
|
case TARGET_PROT_DIN_PASS:
|
||||||
|
case TARGET_PROT_DOUT_PASS:
|
||||||
|
fw_prot_opts |= PO_MODE_DIF_PASS;
|
||||||
|
/* FUTURE: does tcm require T10CRC<->IPCKSUM conversion? */
|
||||||
|
break;
|
||||||
|
default:/* Normal Request */
|
||||||
|
fw_prot_opts |= PO_MODE_DIF_PASS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ---- PKT ---- */
|
||||||
|
/* Update entry type to indicate Command Type CRC_2 IOCB */
|
||||||
|
pkt->entry_type = CTIO_CRC2;
|
||||||
|
pkt->entry_count = 1;
|
||||||
|
pkt->vp_index = vha->vp_idx;
|
||||||
|
|
||||||
|
h = qlt_make_handle(vha);
|
||||||
|
if (unlikely(h == QLA_TGT_NULL_HANDLE)) {
|
||||||
|
/*
|
||||||
|
* CTIO type 7 from the firmware doesn't provide a way to
|
||||||
|
* know the initiator's LOOP ID, hence we can't find
|
||||||
|
* the session and, so, the command.
|
||||||
|
*/
|
||||||
|
return -EAGAIN;
|
||||||
|
} else
|
||||||
|
ha->tgt.cmds[h-1] = prm->cmd;
|
||||||
|
|
||||||
|
|
||||||
|
pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK;
|
||||||
|
pkt->nport_handle = prm->cmd->loop_id;
|
||||||
|
pkt->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT);
|
||||||
|
pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2];
|
||||||
|
pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1];
|
||||||
|
pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0];
|
||||||
|
pkt->exchange_addr = atio->u.isp24.exchange_addr;
|
||||||
|
pkt->ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id);
|
||||||
|
pkt->flags |= (atio->u.isp24.attr << 9);
|
||||||
|
pkt->relative_offset = cpu_to_le32(prm->cmd->offset);
|
||||||
|
|
||||||
|
/* Set transfer direction */
|
||||||
|
if (cmd->dma_data_direction == DMA_TO_DEVICE)
|
||||||
|
pkt->flags = __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN);
|
||||||
|
else if (cmd->dma_data_direction == DMA_FROM_DEVICE)
|
||||||
|
pkt->flags = __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT);
|
||||||
|
|
||||||
|
|
||||||
|
pkt->dseg_count = prm->tot_dsds;
|
||||||
|
/* Fibre channel byte count */
|
||||||
|
pkt->transfer_length = cpu_to_le32(transfer_length);
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- CRC context -------- */
|
||||||
|
|
||||||
|
/* Allocate CRC context from global pool */
|
||||||
|
crc_ctx_pkt = cmd->ctx =
|
||||||
|
dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
|
||||||
|
|
||||||
|
if (!crc_ctx_pkt)
|
||||||
|
goto crc_queuing_error;
|
||||||
|
|
||||||
|
/* Zero out CTX area. */
|
||||||
|
clr_ptr = (uint8_t *)crc_ctx_pkt;
|
||||||
|
memset(clr_ptr, 0, sizeof(*crc_ctx_pkt));
|
||||||
|
|
||||||
|
crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma;
|
||||||
|
INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list);
|
||||||
|
|
||||||
|
/* Set handle */
|
||||||
|
crc_ctx_pkt->handle = pkt->handle;
|
||||||
|
|
||||||
|
qlt_set_t10dif_tags(se_cmd, crc_ctx_pkt);
|
||||||
|
|
||||||
|
pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma));
|
||||||
|
pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma));
|
||||||
|
pkt->crc_context_len = CRC_CONTEXT_LEN_FW;
|
||||||
|
|
||||||
|
|
||||||
|
if (!bundling) {
|
||||||
|
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Configure Bundling if we need to fetch interlaving
|
||||||
|
* protection PCI accesses
|
||||||
|
*/
|
||||||
|
fw_prot_opts |= PO_ENABLE_DIF_BUNDLING;
|
||||||
|
crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes);
|
||||||
|
crc_ctx_pkt->u.bundling.dseg_count =
|
||||||
|
cpu_to_le16(prm->tot_dsds - prm->prot_seg_cnt);
|
||||||
|
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.data_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the common fields of CRC pkt */
|
||||||
|
crc_ctx_pkt->blk_size = cpu_to_le16(cmd->blk_sz);
|
||||||
|
crc_ctx_pkt->prot_opts = cpu_to_le16(fw_prot_opts);
|
||||||
|
crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes);
|
||||||
|
crc_ctx_pkt->guard_seed = __constant_cpu_to_le16(0);
|
||||||
|
|
||||||
|
|
||||||
|
/* Walks data segments */
|
||||||
|
pkt->flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DSD_PTR);
|
||||||
|
|
||||||
|
if (!bundling && prm->prot_seg_cnt) {
|
||||||
|
if (qla24xx_walk_and_build_sglist_no_difb(ha, NULL, cur_dsd,
|
||||||
|
prm->tot_dsds, cmd))
|
||||||
|
goto crc_queuing_error;
|
||||||
|
} else if (qla24xx_walk_and_build_sglist(ha, NULL, cur_dsd,
|
||||||
|
(prm->tot_dsds - prm->prot_seg_cnt), cmd))
|
||||||
|
goto crc_queuing_error;
|
||||||
|
|
||||||
|
if (bundling && prm->prot_seg_cnt) {
|
||||||
|
/* Walks dif segments */
|
||||||
|
pkt->add_flags |=
|
||||||
|
__constant_cpu_to_le16(CTIO_CRC2_AF_DIF_DSD_ENA);
|
||||||
|
|
||||||
|
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
|
||||||
|
if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd,
|
||||||
|
prm->prot_seg_cnt, cmd))
|
||||||
|
goto crc_queuing_error;
|
||||||
|
}
|
||||||
|
return QLA_SUCCESS;
|
||||||
|
|
||||||
|
crc_queuing_error:
|
||||||
|
/* Cleanup will be performed by the caller */
|
||||||
|
|
||||||
|
return QLA_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and *
|
* Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and *
|
||||||
* QLA_TGT_XMIT_STATUS for >= 24xx silicon
|
* QLA_TGT_XMIT_STATUS for >= 24xx silicon
|
||||||
|
@ -1921,9 +2287,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||||
qlt_check_srr_debug(cmd, &xmit_type);
|
qlt_check_srr_debug(cmd, &xmit_type);
|
||||||
|
|
||||||
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
|
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
|
||||||
"is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, "
|
"is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n",
|
||||||
"cmd->dma_data_direction=%d\n", (xmit_type & QLA_TGT_XMIT_STATUS) ?
|
(xmit_type & QLA_TGT_XMIT_STATUS) ?
|
||||||
1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction);
|
1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction,
|
||||||
|
&cmd->se_cmd);
|
||||||
|
|
||||||
res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
|
res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
|
||||||
&full_req_cnt);
|
&full_req_cnt);
|
||||||
|
@ -1941,7 +2308,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||||
if (unlikely(res))
|
if (unlikely(res))
|
||||||
goto out_unmap_unlock;
|
goto out_unmap_unlock;
|
||||||
|
|
||||||
res = qlt_24xx_build_ctio_pkt(&prm, vha);
|
if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA))
|
||||||
|
res = qlt_build_ctio_crc2_pkt(&prm, vha);
|
||||||
|
else
|
||||||
|
res = qlt_24xx_build_ctio_pkt(&prm, vha);
|
||||||
if (unlikely(res != 0))
|
if (unlikely(res != 0))
|
||||||
goto out_unmap_unlock;
|
goto out_unmap_unlock;
|
||||||
|
|
||||||
|
@ -1953,7 +2323,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||||
__constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN |
|
__constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN |
|
||||||
CTIO7_FLAGS_STATUS_MODE_0);
|
CTIO7_FLAGS_STATUS_MODE_0);
|
||||||
|
|
||||||
qlt_load_data_segments(&prm, vha);
|
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
|
||||||
|
qlt_load_data_segments(&prm, vha);
|
||||||
|
|
||||||
if (prm.add_status_pkt == 0) {
|
if (prm.add_status_pkt == 0) {
|
||||||
if (xmit_type & QLA_TGT_XMIT_STATUS) {
|
if (xmit_type & QLA_TGT_XMIT_STATUS) {
|
||||||
|
@ -1983,8 +2354,14 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe019,
|
ql_dbg(ql_dbg_tgt, vha, 0xe019,
|
||||||
"Building additional status packet\n");
|
"Building additional status packet\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* T10Dif: ctio_crc2_to_fw overlay ontop of
|
||||||
|
* ctio7_to_24xx
|
||||||
|
*/
|
||||||
memcpy(ctio, pkt, sizeof(*ctio));
|
memcpy(ctio, pkt, sizeof(*ctio));
|
||||||
|
/* reset back to CTIO7 */
|
||||||
ctio->entry_count = 1;
|
ctio->entry_count = 1;
|
||||||
|
ctio->entry_type = CTIO_TYPE7;
|
||||||
ctio->dseg_count = 0;
|
ctio->dseg_count = 0;
|
||||||
ctio->u.status1.flags &= ~__constant_cpu_to_le16(
|
ctio->u.status1.flags &= ~__constant_cpu_to_le16(
|
||||||
CTIO7_FLAGS_DATA_IN);
|
CTIO7_FLAGS_DATA_IN);
|
||||||
|
@ -1993,6 +2370,11 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
|
||||||
pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK;
|
pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK;
|
||||||
pkt->u.status0.flags |= __constant_cpu_to_le16(
|
pkt->u.status0.flags |= __constant_cpu_to_le16(
|
||||||
CTIO7_FLAGS_DONT_RET_CTIO);
|
CTIO7_FLAGS_DONT_RET_CTIO);
|
||||||
|
|
||||||
|
/* qlt_24xx_init_ctio_to_isp will correct
|
||||||
|
* all neccessary fields that's part of CTIO7.
|
||||||
|
* There should be no residual of CTIO-CRC2 data.
|
||||||
|
*/
|
||||||
qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio,
|
qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio,
|
||||||
&prm);
|
&prm);
|
||||||
pr_debug("Status CTIO7: %p\n", ctio);
|
pr_debug("Status CTIO7: %p\n", ctio);
|
||||||
|
@ -2041,8 +2423,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
|
||||||
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
|
if (qlt_issue_marker(vha, 0) != QLA_SUCCESS)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe01b, "CTIO_start: vha(%d)",
|
ql_dbg(ql_dbg_tgt, vha, 0xe01b,
|
||||||
(int)vha->vp_idx);
|
"%s: CTIO_start: vha(%d) se_cmd %p ox_id %04x\n",
|
||||||
|
__func__, (int)vha->vp_idx, &cmd->se_cmd,
|
||||||
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
||||||
|
|
||||||
/* Calculate number of entries and segments required */
|
/* Calculate number of entries and segments required */
|
||||||
if (qlt_pci_map_calc_cnt(&prm) != 0)
|
if (qlt_pci_map_calc_cnt(&prm) != 0)
|
||||||
|
@ -2054,14 +2438,19 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
|
||||||
res = qlt_check_reserve_free_req(vha, prm.req_cnt);
|
res = qlt_check_reserve_free_req(vha, prm.req_cnt);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
goto out_unlock_free_unmap;
|
goto out_unlock_free_unmap;
|
||||||
|
if (cmd->se_cmd.prot_op)
|
||||||
|
res = qlt_build_ctio_crc2_pkt(&prm, vha);
|
||||||
|
else
|
||||||
|
res = qlt_24xx_build_ctio_pkt(&prm, vha);
|
||||||
|
|
||||||
res = qlt_24xx_build_ctio_pkt(&prm, vha);
|
|
||||||
if (unlikely(res != 0))
|
if (unlikely(res != 0))
|
||||||
goto out_unlock_free_unmap;
|
goto out_unlock_free_unmap;
|
||||||
pkt = (struct ctio7_to_24xx *)prm.pkt;
|
pkt = (struct ctio7_to_24xx *)prm.pkt;
|
||||||
pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT |
|
pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT |
|
||||||
CTIO7_FLAGS_STATUS_MODE_0);
|
CTIO7_FLAGS_STATUS_MODE_0);
|
||||||
qlt_load_data_segments(&prm, vha);
|
|
||||||
|
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL)
|
||||||
|
qlt_load_data_segments(&prm, vha);
|
||||||
|
|
||||||
cmd->state = QLA_TGT_STATE_NEED_DATA;
|
cmd->state = QLA_TGT_STATE_NEED_DATA;
|
||||||
|
|
||||||
|
@ -2079,6 +2468,143 @@ out_unlock_free_unmap:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(qlt_rdy_to_xfer);
|
EXPORT_SYMBOL(qlt_rdy_to_xfer);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks the guard or meta-data for the type of error
|
||||||
|
* detected by the HBA.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd,
|
||||||
|
struct ctio_crc_from_fw *sts)
|
||||||
|
{
|
||||||
|
uint8_t *ap = &sts->actual_dif[0];
|
||||||
|
uint8_t *ep = &sts->expected_dif[0];
|
||||||
|
uint32_t e_ref_tag, a_ref_tag;
|
||||||
|
uint16_t e_app_tag, a_app_tag;
|
||||||
|
uint16_t e_guard, a_guard;
|
||||||
|
uint64_t lba = cmd->se_cmd.t_task_lba;
|
||||||
|
|
||||||
|
a_guard = be16_to_cpu(*(uint16_t *)(ap + 0));
|
||||||
|
a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2));
|
||||||
|
a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4));
|
||||||
|
|
||||||
|
e_guard = be16_to_cpu(*(uint16_t *)(ep + 0));
|
||||||
|
e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2));
|
||||||
|
e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4));
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xe075,
|
||||||
|
"iocb(s) %p Returned STATUS.\n", sts);
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xf075,
|
||||||
|
"dif check TGT cdb 0x%x lba 0x%llu: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x]\n",
|
||||||
|
cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
|
||||||
|
a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore sector if:
|
||||||
|
* For type 3: ref & app tag is all 'f's
|
||||||
|
* For type 0,1,2: app tag is all 'f's
|
||||||
|
*/
|
||||||
|
if ((a_app_tag == 0xffff) &&
|
||||||
|
((cmd->se_cmd.prot_type != TARGET_DIF_TYPE3_PROT) ||
|
||||||
|
(a_ref_tag == 0xffffffff))) {
|
||||||
|
uint32_t blocks_done;
|
||||||
|
|
||||||
|
/* 2TB boundary case covered automatically with this */
|
||||||
|
blocks_done = e_ref_tag - (uint32_t)lba + 1;
|
||||||
|
cmd->se_cmd.bad_sector = e_ref_tag;
|
||||||
|
cmd->se_cmd.pi_err = 0;
|
||||||
|
ql_dbg(ql_dbg_tgt, vha, 0xf074,
|
||||||
|
"need to return scsi good\n");
|
||||||
|
|
||||||
|
/* Update protection tag */
|
||||||
|
if (cmd->prot_sg_cnt) {
|
||||||
|
uint32_t i, j = 0, k = 0, num_ent;
|
||||||
|
struct scatterlist *sg, *sgl;
|
||||||
|
|
||||||
|
|
||||||
|
sgl = cmd->prot_sg;
|
||||||
|
|
||||||
|
/* Patch the corresponding protection tags */
|
||||||
|
for_each_sg(sgl, sg, cmd->prot_sg_cnt, i) {
|
||||||
|
num_ent = sg_dma_len(sg) / 8;
|
||||||
|
if (k + num_ent < blocks_done) {
|
||||||
|
k += num_ent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
j = blocks_done - k - 1;
|
||||||
|
k = blocks_done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k != blocks_done) {
|
||||||
|
ql_log(ql_log_warn, vha, 0xf076,
|
||||||
|
"unexpected tag values tag:lba=%u:%llu)\n",
|
||||||
|
e_ref_tag, (unsigned long long)lba);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct sd_dif_tuple *spt;
|
||||||
|
/* TODO:
|
||||||
|
* This section came from initiator. Is it valid here?
|
||||||
|
* should ulp be override with actual val???
|
||||||
|
*/
|
||||||
|
spt = page_address(sg_page(sg)) + sg->offset;
|
||||||
|
spt += j;
|
||||||
|
|
||||||
|
spt->app_tag = 0xffff;
|
||||||
|
if (cmd->se_cmd.prot_type == SCSI_PROT_DIF_TYPE3)
|
||||||
|
spt->ref_tag = 0xffffffff;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check guard */
|
||||||
|
if (e_guard != a_guard) {
|
||||||
|
cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED;
|
||||||
|
cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba;
|
||||||
|
|
||||||
|
ql_log(ql_log_warn, vha, 0xe076,
|
||||||
|
"Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
|
||||||
|
cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
|
||||||
|
a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
|
||||||
|
a_guard, e_guard, cmd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check ref tag */
|
||||||
|
if (e_ref_tag != a_ref_tag) {
|
||||||
|
cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED;
|
||||||
|
cmd->se_cmd.bad_sector = e_ref_tag;
|
||||||
|
|
||||||
|
ql_log(ql_log_warn, vha, 0xe077,
|
||||||
|
"Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
|
||||||
|
cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
|
||||||
|
a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
|
||||||
|
a_guard, e_guard, cmd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check appl tag */
|
||||||
|
if (e_app_tag != a_app_tag) {
|
||||||
|
cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED;
|
||||||
|
cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba;
|
||||||
|
|
||||||
|
ql_log(ql_log_warn, vha, 0xe078,
|
||||||
|
"App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n",
|
||||||
|
cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba,
|
||||||
|
a_ref_tag, e_ref_tag, a_app_tag, e_app_tag,
|
||||||
|
a_guard, e_guard, cmd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If hardware_lock held on entry, might drop it, then reaquire */
|
/* If hardware_lock held on entry, might drop it, then reaquire */
|
||||||
/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
|
/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
|
||||||
static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
|
static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
|
||||||
|
@ -2155,18 +2681,36 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
|
||||||
rc = __qlt_send_term_exchange(vha, cmd, atio);
|
rc = __qlt_send_term_exchange(vha, cmd, atio);
|
||||||
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
||||||
done:
|
done:
|
||||||
if (rc == 1) {
|
/*
|
||||||
|
* Terminate exchange will tell fw to release any active CTIO
|
||||||
|
* that's in FW posession and cleanup the exchange.
|
||||||
|
*
|
||||||
|
* "cmd->state == QLA_TGT_STATE_ABORTED" means CTIO is still
|
||||||
|
* down at FW. Free the cmd later when CTIO comes back later
|
||||||
|
* w/aborted(0x2) status.
|
||||||
|
*
|
||||||
|
* "cmd->state != QLA_TGT_STATE_ABORTED" means CTIO is already
|
||||||
|
* back w/some err. Free the cmd now.
|
||||||
|
*/
|
||||||
|
if ((rc == 1) && (cmd->state != QLA_TGT_STATE_ABORTED)) {
|
||||||
if (!ha_locked && !in_interrupt())
|
if (!ha_locked && !in_interrupt())
|
||||||
msleep(250); /* just in case */
|
msleep(250); /* just in case */
|
||||||
|
|
||||||
|
if (cmd->sg_mapped)
|
||||||
|
qlt_unmap_sg(vha, cmd);
|
||||||
vha->hw->tgt.tgt_ops->free_cmd(cmd);
|
vha->hw->tgt.tgt_ops->free_cmd(cmd);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qlt_free_cmd(struct qla_tgt_cmd *cmd)
|
void qlt_free_cmd(struct qla_tgt_cmd *cmd)
|
||||||
{
|
{
|
||||||
BUG_ON(cmd->sg_mapped);
|
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe074,
|
||||||
|
"%s: se_cmd[%p] ox_id %04x\n",
|
||||||
|
__func__, &cmd->se_cmd,
|
||||||
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
||||||
|
|
||||||
|
BUG_ON(cmd->sg_mapped);
|
||||||
if (unlikely(cmd->free_sg))
|
if (unlikely(cmd->free_sg))
|
||||||
kfree(cmd->sg);
|
kfree(cmd->sg);
|
||||||
kmem_cache_free(qla_tgt_cmd_cachep, cmd);
|
kmem_cache_free(qla_tgt_cmd_cachep, cmd);
|
||||||
|
@ -2374,6 +2918,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
|
||||||
case CTIO_LIP_RESET:
|
case CTIO_LIP_RESET:
|
||||||
case CTIO_TARGET_RESET:
|
case CTIO_TARGET_RESET:
|
||||||
case CTIO_ABORTED:
|
case CTIO_ABORTED:
|
||||||
|
/* driver request abort via Terminate exchange */
|
||||||
case CTIO_TIMEOUT:
|
case CTIO_TIMEOUT:
|
||||||
case CTIO_INVALID_RX_ID:
|
case CTIO_INVALID_RX_ID:
|
||||||
/* They are OK */
|
/* They are OK */
|
||||||
|
@ -2404,18 +2949,58 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case CTIO_DIF_ERROR: {
|
||||||
|
struct ctio_crc_from_fw *crc =
|
||||||
|
(struct ctio_crc_from_fw *)ctio;
|
||||||
|
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073,
|
||||||
|
"qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n",
|
||||||
|
vha->vp_idx, status, cmd->state, se_cmd,
|
||||||
|
*((u64 *)&crc->actual_dif[0]),
|
||||||
|
*((u64 *)&crc->expected_dif[0]));
|
||||||
|
|
||||||
|
if (qlt_handle_dif_error(vha, cmd, ctio)) {
|
||||||
|
if (cmd->state == QLA_TGT_STATE_NEED_DATA) {
|
||||||
|
/* scsi Write/xfer rdy complete */
|
||||||
|
goto skip_term;
|
||||||
|
} else {
|
||||||
|
/* scsi read/xmit respond complete
|
||||||
|
* call handle dif to send scsi status
|
||||||
|
* rather than terminate exchange.
|
||||||
|
*/
|
||||||
|
cmd->state = QLA_TGT_STATE_PROCESSED;
|
||||||
|
ha->tgt.tgt_ops->handle_dif_err(cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Need to generate a SCSI good completion.
|
||||||
|
* because FW did not send scsi status.
|
||||||
|
*/
|
||||||
|
status = 0;
|
||||||
|
goto skip_term;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
|
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
|
||||||
"qla_target(%d): CTIO with error status "
|
"qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n",
|
||||||
"0x%x received (state %x, se_cmd %p\n",
|
|
||||||
vha->vp_idx, status, cmd->state, se_cmd);
|
vha->vp_idx, status, cmd->state, se_cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->state != QLA_TGT_STATE_NEED_DATA)
|
|
||||||
|
/* "cmd->state == QLA_TGT_STATE_ABORTED" means
|
||||||
|
* cmd is already aborted/terminated, we don't
|
||||||
|
* need to terminate again. The exchange is already
|
||||||
|
* cleaned up/freed at FW level. Just cleanup at driver
|
||||||
|
* level.
|
||||||
|
*/
|
||||||
|
if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
|
||||||
|
(cmd->state != QLA_TGT_STATE_ABORTED)) {
|
||||||
if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
|
if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
skip_term:
|
||||||
|
|
||||||
if (cmd->state == QLA_TGT_STATE_PROCESSED) {
|
if (cmd->state == QLA_TGT_STATE_PROCESSED) {
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd);
|
ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd);
|
||||||
|
@ -2444,7 +3029,8 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
|
||||||
"not return a CTIO complete\n", vha->vp_idx, cmd->state);
|
"not return a CTIO complete\n", vha->vp_idx, cmd->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(status != CTIO_SUCCESS)) {
|
if (unlikely(status != CTIO_SUCCESS) &&
|
||||||
|
(cmd->state != QLA_TGT_STATE_ABORTED)) {
|
||||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n");
|
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n");
|
||||||
dump_stack();
|
dump_stack();
|
||||||
}
|
}
|
||||||
|
@ -2563,8 +3149,9 @@ static void qlt_do_work(struct work_struct *work)
|
||||||
atio->u.isp24.fcp_cmnd.add_cdb_len]));
|
atio->u.isp24.fcp_cmnd.add_cdb_len]));
|
||||||
|
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe022,
|
ql_dbg(ql_dbg_tgt, vha, 0xe022,
|
||||||
"qla_target: START qla command: %p lun: 0x%04x (tag %d)\n",
|
"qla_target: START qla cmd: %p se_cmd %p lun: 0x%04x (tag %d) len(%d) ox_id %x\n",
|
||||||
cmd, cmd->unpacked_lun, cmd->tag);
|
cmd, &cmd->se_cmd, cmd->unpacked_lun, cmd->tag, data_length,
|
||||||
|
cmd->atio.u.isp24.fcp_hdr.ox_id);
|
||||||
|
|
||||||
ret = vha->hw->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length,
|
ret = vha->hw->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length,
|
||||||
fcp_task_attr, data_dir, bidi);
|
fcp_task_attr, data_dir, bidi);
|
||||||
|
@ -3527,11 +4114,11 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
|
||||||
switch (atio->u.raw.entry_type) {
|
switch (atio->u.raw.entry_type) {
|
||||||
case ATIO_TYPE7:
|
case ATIO_TYPE7:
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe02d,
|
ql_dbg(ql_dbg_tgt, vha, 0xe02d,
|
||||||
"ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, "
|
"ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, cdb %x, add_cdb_len %x, data_length %04x, s_id %02x%02x%02x\n",
|
||||||
"add_cdb_len %d, data_length %04x, s_id %x:%x:%x\n",
|
|
||||||
vha->vp_idx, atio->u.isp24.fcp_cmnd.lun,
|
vha->vp_idx, atio->u.isp24.fcp_cmnd.lun,
|
||||||
atio->u.isp24.fcp_cmnd.rddata,
|
atio->u.isp24.fcp_cmnd.rddata,
|
||||||
atio->u.isp24.fcp_cmnd.wrdata,
|
atio->u.isp24.fcp_cmnd.wrdata,
|
||||||
|
atio->u.isp24.fcp_cmnd.cdb[0],
|
||||||
atio->u.isp24.fcp_cmnd.add_cdb_len,
|
atio->u.isp24.fcp_cmnd.add_cdb_len,
|
||||||
be32_to_cpu(get_unaligned((uint32_t *)
|
be32_to_cpu(get_unaligned((uint32_t *)
|
||||||
&atio->u.isp24.fcp_cmnd.add_cdb[
|
&atio->u.isp24.fcp_cmnd.add_cdb[
|
||||||
|
@ -3629,11 +4216,13 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
|
||||||
tgt->irq_cmd_count++;
|
tgt->irq_cmd_count++;
|
||||||
|
|
||||||
switch (pkt->entry_type) {
|
switch (pkt->entry_type) {
|
||||||
|
case CTIO_CRC2:
|
||||||
case CTIO_TYPE7:
|
case CTIO_TYPE7:
|
||||||
{
|
{
|
||||||
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
|
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe030, "CTIO_TYPE7: instance %d\n",
|
ql_dbg(ql_dbg_tgt, vha, 0xe030,
|
||||||
vha->vp_idx);
|
"CTIO[0x%x] 12/CTIO7 7A/CRC2: instance %d\n",
|
||||||
|
entry->entry_type, vha->vp_idx);
|
||||||
qlt_do_ctio_completion(vha, entry->handle,
|
qlt_do_ctio_completion(vha, entry->handle,
|
||||||
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
|
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
|
||||||
entry);
|
entry);
|
||||||
|
@ -4768,6 +5357,7 @@ qlt_24xx_process_response_error(struct scsi_qla_host *vha,
|
||||||
case ABTS_RESP_24XX:
|
case ABTS_RESP_24XX:
|
||||||
case CTIO_TYPE7:
|
case CTIO_TYPE7:
|
||||||
case NOTIFY_ACK_TYPE:
|
case NOTIFY_ACK_TYPE:
|
||||||
|
case CTIO_CRC2:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -293,6 +293,7 @@ struct ctio_to_2xxx {
|
||||||
#define CTIO_ABORTED 0x02
|
#define CTIO_ABORTED 0x02
|
||||||
#define CTIO_INVALID_RX_ID 0x08
|
#define CTIO_INVALID_RX_ID 0x08
|
||||||
#define CTIO_TIMEOUT 0x0B
|
#define CTIO_TIMEOUT 0x0B
|
||||||
|
#define CTIO_DIF_ERROR 0x0C /* DIF error detected */
|
||||||
#define CTIO_LIP_RESET 0x0E
|
#define CTIO_LIP_RESET 0x0E
|
||||||
#define CTIO_TARGET_RESET 0x17
|
#define CTIO_TARGET_RESET 0x17
|
||||||
#define CTIO_PORT_UNAVAILABLE 0x28
|
#define CTIO_PORT_UNAVAILABLE 0x28
|
||||||
|
@ -498,11 +499,12 @@ struct ctio7_from_24xx {
|
||||||
#define CTIO7_FLAGS_DONT_RET_CTIO BIT_8
|
#define CTIO7_FLAGS_DONT_RET_CTIO BIT_8
|
||||||
#define CTIO7_FLAGS_STATUS_MODE_0 0
|
#define CTIO7_FLAGS_STATUS_MODE_0 0
|
||||||
#define CTIO7_FLAGS_STATUS_MODE_1 BIT_6
|
#define CTIO7_FLAGS_STATUS_MODE_1 BIT_6
|
||||||
|
#define CTIO7_FLAGS_STATUS_MODE_2 BIT_7
|
||||||
#define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5
|
#define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5
|
||||||
#define CTIO7_FLAGS_CONFIRM_SATISF BIT_4
|
#define CTIO7_FLAGS_CONFIRM_SATISF BIT_4
|
||||||
#define CTIO7_FLAGS_DSD_PTR BIT_2
|
#define CTIO7_FLAGS_DSD_PTR BIT_2
|
||||||
#define CTIO7_FLAGS_DATA_IN BIT_1
|
#define CTIO7_FLAGS_DATA_IN BIT_1 /* data to initiator */
|
||||||
#define CTIO7_FLAGS_DATA_OUT BIT_0
|
#define CTIO7_FLAGS_DATA_OUT BIT_0 /* data from initiator */
|
||||||
|
|
||||||
#define ELS_PLOGI 0x3
|
#define ELS_PLOGI 0x3
|
||||||
#define ELS_FLOGI 0x4
|
#define ELS_FLOGI 0x4
|
||||||
|
@ -513,6 +515,68 @@ struct ctio7_from_24xx {
|
||||||
#define ELS_PDISC 0x50
|
#define ELS_PDISC 0x50
|
||||||
#define ELS_ADISC 0x52
|
#define ELS_ADISC 0x52
|
||||||
|
|
||||||
|
/*
|
||||||
|
*CTIO Type CRC_2 IOCB
|
||||||
|
*/
|
||||||
|
struct ctio_crc2_to_fw {
|
||||||
|
uint8_t entry_type; /* Entry type. */
|
||||||
|
#define CTIO_CRC2 0x7A
|
||||||
|
uint8_t entry_count; /* Entry count. */
|
||||||
|
uint8_t sys_define; /* System defined. */
|
||||||
|
uint8_t entry_status; /* Entry Status. */
|
||||||
|
|
||||||
|
uint32_t handle; /* System handle. */
|
||||||
|
uint16_t nport_handle; /* N_PORT handle. */
|
||||||
|
uint16_t timeout; /* Command timeout. */
|
||||||
|
|
||||||
|
uint16_t dseg_count; /* Data segment count. */
|
||||||
|
uint8_t vp_index;
|
||||||
|
uint8_t add_flags; /* additional flags */
|
||||||
|
#define CTIO_CRC2_AF_DIF_DSD_ENA BIT_3
|
||||||
|
|
||||||
|
uint8_t initiator_id[3]; /* initiator ID */
|
||||||
|
uint8_t reserved1;
|
||||||
|
uint32_t exchange_addr; /* rcv exchange address */
|
||||||
|
uint16_t reserved2;
|
||||||
|
uint16_t flags; /* refer to CTIO7 flags values */
|
||||||
|
uint32_t residual;
|
||||||
|
uint16_t ox_id;
|
||||||
|
uint16_t scsi_status;
|
||||||
|
uint32_t relative_offset;
|
||||||
|
uint32_t reserved5;
|
||||||
|
uint32_t transfer_length; /* total fc transfer length */
|
||||||
|
uint32_t reserved6;
|
||||||
|
uint32_t crc_context_address[2];/* Data segment address. */
|
||||||
|
uint16_t crc_context_len; /* Data segment length. */
|
||||||
|
uint16_t reserved_1; /* MUST be set to 0. */
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/* CTIO Type CRC_x Status IOCB */
|
||||||
|
struct ctio_crc_from_fw {
|
||||||
|
uint8_t entry_type; /* Entry type. */
|
||||||
|
uint8_t entry_count; /* Entry count. */
|
||||||
|
uint8_t sys_define; /* System defined. */
|
||||||
|
uint8_t entry_status; /* Entry Status. */
|
||||||
|
|
||||||
|
uint32_t handle; /* System handle. */
|
||||||
|
uint16_t status;
|
||||||
|
uint16_t timeout; /* Command timeout. */
|
||||||
|
uint16_t dseg_count; /* Data segment count. */
|
||||||
|
uint32_t reserved1;
|
||||||
|
uint16_t state_flags;
|
||||||
|
#define CTIO_CRC_SF_DIF_CHOPPED BIT_4
|
||||||
|
|
||||||
|
uint32_t exchange_address; /* rcv exchange address */
|
||||||
|
uint16_t reserved2;
|
||||||
|
uint16_t flags;
|
||||||
|
uint32_t resid_xfer_length;
|
||||||
|
uint16_t ox_id;
|
||||||
|
uint8_t reserved3[12];
|
||||||
|
uint16_t runt_guard; /* reported runt blk guard */
|
||||||
|
uint8_t actual_dif[8];
|
||||||
|
uint8_t expected_dif[8];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISP queue - ABTS received/response entries structure definition for 24xx.
|
* ISP queue - ABTS received/response entries structure definition for 24xx.
|
||||||
*/
|
*/
|
||||||
|
@ -641,6 +705,7 @@ struct qla_tgt_func_tmpl {
|
||||||
int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
|
int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
|
||||||
unsigned char *, uint32_t, int, int, int);
|
unsigned char *, uint32_t, int, int, int);
|
||||||
void (*handle_data)(struct qla_tgt_cmd *);
|
void (*handle_data)(struct qla_tgt_cmd *);
|
||||||
|
void (*handle_dif_err)(struct qla_tgt_cmd *);
|
||||||
int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t,
|
int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t,
|
||||||
uint32_t);
|
uint32_t);
|
||||||
void (*free_cmd)(struct qla_tgt_cmd *);
|
void (*free_cmd)(struct qla_tgt_cmd *);
|
||||||
|
@ -829,9 +894,9 @@ struct qla_tgt_sess {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qla_tgt_cmd {
|
struct qla_tgt_cmd {
|
||||||
|
struct se_cmd se_cmd;
|
||||||
struct qla_tgt_sess *sess;
|
struct qla_tgt_sess *sess;
|
||||||
int state;
|
int state;
|
||||||
struct se_cmd se_cmd;
|
|
||||||
struct work_struct free_work;
|
struct work_struct free_work;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
/* Sense buffer that will be mapped into outgoing status */
|
/* Sense buffer that will be mapped into outgoing status */
|
||||||
|
@ -843,6 +908,7 @@ struct qla_tgt_cmd {
|
||||||
unsigned int free_sg:1;
|
unsigned int free_sg:1;
|
||||||
unsigned int aborted:1; /* Needed in case of SRR */
|
unsigned int aborted:1; /* Needed in case of SRR */
|
||||||
unsigned int write_data_transferred:1;
|
unsigned int write_data_transferred:1;
|
||||||
|
unsigned int ctx_dsd_alloced:1;
|
||||||
|
|
||||||
struct scatterlist *sg; /* cmd data buffer SG vector */
|
struct scatterlist *sg; /* cmd data buffer SG vector */
|
||||||
int sg_cnt; /* SG segments count */
|
int sg_cnt; /* SG segments count */
|
||||||
|
@ -857,6 +923,12 @@ struct qla_tgt_cmd {
|
||||||
struct scsi_qla_host *vha;
|
struct scsi_qla_host *vha;
|
||||||
|
|
||||||
struct atio_from_isp atio;
|
struct atio_from_isp atio;
|
||||||
|
/* t10dif */
|
||||||
|
struct scatterlist *prot_sg;
|
||||||
|
uint32_t prot_sg_cnt;
|
||||||
|
uint32_t blk_sz;
|
||||||
|
struct crc_context *ctx;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qla_tgt_sess_work_param {
|
struct qla_tgt_sess_work_param {
|
||||||
|
@ -901,6 +973,10 @@ struct qla_tgt_prm {
|
||||||
int sense_buffer_len;
|
int sense_buffer_len;
|
||||||
int residual;
|
int residual;
|
||||||
int add_status_pkt;
|
int add_status_pkt;
|
||||||
|
/* dif */
|
||||||
|
struct scatterlist *prot_sg;
|
||||||
|
uint16_t prot_seg_cnt;
|
||||||
|
uint16_t tot_dsds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qla_tgt_srr_imm {
|
struct qla_tgt_srr_imm {
|
||||||
|
@ -976,6 +1052,8 @@ extern void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *,
|
||||||
extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
|
extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
|
||||||
extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
|
extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
|
||||||
extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
|
extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
|
||||||
|
extern int qlt_rdy_to_xfer_dif(struct qla_tgt_cmd *);
|
||||||
|
extern int qlt_xmit_response_dif(struct qla_tgt_cmd *, int, uint8_t);
|
||||||
extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
|
extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
|
||||||
extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
|
extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
|
||||||
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
|
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -201,7 +201,6 @@ qla27xx_read_reg(__iomem struct device_reg_24xx *reg,
|
||||||
ql_dbg(ql_dbg_misc, NULL, 0xd014,
|
ql_dbg(ql_dbg_misc, NULL, 0xd014,
|
||||||
"%s: @%x\n", __func__, offset);
|
"%s: @%x\n", __func__, offset);
|
||||||
}
|
}
|
||||||
qla27xx_insert32(offset, buf, len);
|
|
||||||
qla27xx_read32(window, buf, len);
|
qla27xx_read32(window, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +219,7 @@ qla27xx_write_reg(__iomem struct device_reg_24xx *reg,
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
qla27xx_read_window(__iomem struct device_reg_24xx *reg,
|
qla27xx_read_window(__iomem struct device_reg_24xx *reg,
|
||||||
uint32_t base, uint offset, uint count, uint width, void *buf,
|
uint32_t addr, uint offset, uint count, uint width, void *buf,
|
||||||
ulong *len)
|
ulong *len)
|
||||||
{
|
{
|
||||||
void *window = (void *)reg + offset;
|
void *window = (void *)reg + offset;
|
||||||
|
@ -229,14 +228,14 @@ qla27xx_read_window(__iomem struct device_reg_24xx *reg,
|
||||||
if (buf) {
|
if (buf) {
|
||||||
ql_dbg(ql_dbg_misc, NULL, 0xd016,
|
ql_dbg(ql_dbg_misc, NULL, 0xd016,
|
||||||
"%s: base=%x offset=%x count=%x width=%x\n",
|
"%s: base=%x offset=%x count=%x width=%x\n",
|
||||||
__func__, base, offset, count, width);
|
__func__, addr, offset, count, width);
|
||||||
}
|
}
|
||||||
qla27xx_write_reg(reg, IOBASE_ADDR, base, buf);
|
qla27xx_write_reg(reg, IOBASE_ADDR, addr, buf);
|
||||||
while (count--) {
|
while (count--) {
|
||||||
qla27xx_insert32(base, buf, len);
|
qla27xx_insert32(addr, buf, len);
|
||||||
readn(window, buf, len);
|
readn(window, buf, len);
|
||||||
window += width;
|
window += width;
|
||||||
base += width;
|
addr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +335,8 @@ qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
|
||||||
|
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd204,
|
ql_dbg(ql_dbg_misc, vha, 0xd204,
|
||||||
"%s: rdpci [%lx]\n", __func__, *len);
|
"%s: rdpci [%lx]\n", __func__, *len);
|
||||||
qla27xx_read_reg(reg, ent->t260.pci_addr, buf, len);
|
qla27xx_insert32(ent->t260.pci_offset, buf, len);
|
||||||
|
qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
|
||||||
|
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd205,
|
ql_dbg(ql_dbg_misc, vha, 0xd205,
|
||||||
"%s: wrpci [%lx]\n", __func__, *len);
|
"%s: wrpci [%lx]\n", __func__, *len);
|
||||||
qla27xx_write_reg(reg, ent->t261.pci_addr, ent->t261.write_data, buf);
|
qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -392,9 +392,9 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end < start) {
|
if (end < start || end == 0) {
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd023,
|
ql_dbg(ql_dbg_misc, vha, 0xd023,
|
||||||
"%s: bad range (start=%x end=%x)\n", __func__,
|
"%s: unusable range (start=%x end=%x)\n", __func__,
|
||||||
ent->t262.end_addr, ent->t262.start_addr);
|
ent->t262.end_addr, ent->t262.start_addr);
|
||||||
qla27xx_skip_entry(ent, buf);
|
qla27xx_skip_entry(ent, buf);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -452,17 +452,15 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd025,
|
ql_dbg(ql_dbg_misc, vha, 0xd025,
|
||||||
"%s: unsupported atio queue\n", __func__);
|
"%s: unsupported atio queue\n", __func__);
|
||||||
qla27xx_skip_entry(ent, buf);
|
qla27xx_skip_entry(ent, buf);
|
||||||
goto done;
|
|
||||||
} else {
|
} else {
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd026,
|
ql_dbg(ql_dbg_misc, vha, 0xd026,
|
||||||
"%s: unknown queue %u\n", __func__, ent->t263.queue_type);
|
"%s: unknown queue %u\n", __func__, ent->t263.queue_type);
|
||||||
qla27xx_skip_entry(ent, buf);
|
qla27xx_skip_entry(ent, buf);
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf)
|
if (buf)
|
||||||
ent->t263.num_queues = count;
|
ent->t263.num_queues = count;
|
||||||
done:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +501,7 @@ qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd209,
|
ql_dbg(ql_dbg_misc, vha, 0xd209,
|
||||||
"%s: pause risc [%lx]\n", __func__, *len);
|
"%s: pause risc [%lx]\n", __func__, *len);
|
||||||
if (buf)
|
if (buf)
|
||||||
qla24xx_pause_risc(reg);
|
qla24xx_pause_risc(reg, vha->hw);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -590,7 +588,6 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
|
||||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||||
{
|
{
|
||||||
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
||||||
void *window = (void *)reg + 0xc4;
|
|
||||||
ulong dwords = ent->t270.count;
|
ulong dwords = ent->t270.count;
|
||||||
ulong addr = ent->t270.addr;
|
ulong addr = ent->t270.addr;
|
||||||
|
|
||||||
|
@ -599,10 +596,9 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
|
||||||
qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
|
qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
|
||||||
while (dwords--) {
|
while (dwords--) {
|
||||||
qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf);
|
qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf);
|
||||||
qla27xx_read_reg(reg, 0xc4, buf, len);
|
|
||||||
qla27xx_insert32(addr, buf, len);
|
qla27xx_insert32(addr, buf, len);
|
||||||
qla27xx_read32(window, buf, len);
|
qla27xx_read_reg(reg, 0xc4, buf, len);
|
||||||
addr++;
|
addr += sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -614,12 +610,12 @@ qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
|
||||||
{
|
{
|
||||||
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
||||||
ulong addr = ent->t271.addr;
|
ulong addr = ent->t271.addr;
|
||||||
|
ulong data = ent->t271.data;
|
||||||
|
|
||||||
ql_dbg(ql_dbg_misc, vha, 0xd20f,
|
ql_dbg(ql_dbg_misc, vha, 0xd20f,
|
||||||
"%s: wrremreg [%lx]\n", __func__, *len);
|
"%s: wrremreg [%lx]\n", __func__, *len);
|
||||||
qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
|
qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
|
||||||
qla27xx_read_reg(reg, 0xc4, buf, len);
|
qla27xx_write_reg(reg, 0xc4, data, buf);
|
||||||
qla27xx_insert32(addr, buf, len);
|
|
||||||
qla27xx_write_reg(reg, 0xc0, addr, buf);
|
qla27xx_write_reg(reg, 0xc0, addr, buf);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -662,12 +658,62 @@ qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
|
||||||
"%s: failed pcicfg read at %lx\n", __func__, addr);
|
"%s: failed pcicfg read at %lx\n", __func__, addr);
|
||||||
qla27xx_insert32(addr, buf, len);
|
qla27xx_insert32(addr, buf, len);
|
||||||
qla27xx_insert32(value, buf, len);
|
qla27xx_insert32(value, buf, len);
|
||||||
addr += 4;
|
addr += sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
|
||||||
|
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||||
|
{
|
||||||
|
uint count = 0;
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
ql_dbg(ql_dbg_misc, vha, 0xd212,
|
||||||
|
"%s: getqsh(%x) [%lx]\n", __func__, ent->t274.queue_type, *len);
|
||||||
|
if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
|
||||||
|
for (i = 0; i < vha->hw->max_req_queues; i++) {
|
||||||
|
struct req_que *req = vha->hw->req_q_map[i];
|
||||||
|
if (req || !buf) {
|
||||||
|
qla27xx_insert16(i, buf, len);
|
||||||
|
qla27xx_insert16(1, buf, len);
|
||||||
|
qla27xx_insert32(req && req->out_ptr ?
|
||||||
|
*req->out_ptr : 0, buf, len);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
|
||||||
|
for (i = 0; i < vha->hw->max_rsp_queues; i++) {
|
||||||
|
struct rsp_que *rsp = vha->hw->rsp_q_map[i];
|
||||||
|
if (rsp || !buf) {
|
||||||
|
qla27xx_insert16(i, buf, len);
|
||||||
|
qla27xx_insert16(1, buf, len);
|
||||||
|
qla27xx_insert32(rsp && rsp->in_ptr ?
|
||||||
|
*rsp->in_ptr : 0, buf, len);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ent->t274.queue_type == T274_QUEUE_TYPE_ATIO_SHAD) {
|
||||||
|
ql_dbg(ql_dbg_misc, vha, 0xd02e,
|
||||||
|
"%s: unsupported atio queue\n", __func__);
|
||||||
|
qla27xx_skip_entry(ent, buf);
|
||||||
|
} else {
|
||||||
|
ql_dbg(ql_dbg_misc, vha, 0xd02f,
|
||||||
|
"%s: unknown queue %u\n", __func__, ent->t274.queue_type);
|
||||||
|
qla27xx_skip_entry(ent, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
ent->t274.num_queues = count;
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
qla27xx_skip_entry(ent, buf);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
|
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
|
||||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||||
|
@ -709,6 +755,7 @@ static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = {
|
||||||
{ ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } ,
|
{ ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } ,
|
||||||
{ ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } ,
|
{ ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } ,
|
||||||
{ ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } ,
|
{ ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } ,
|
||||||
|
{ ENTRY_TYPE_GET_SHADOW , qla27xx_fwdt_entry_t274 } ,
|
||||||
{ -1 , qla27xx_fwdt_entry_other }
|
{ -1 , qla27xx_fwdt_entry_other }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +52,7 @@ struct __packed qla27xx_fwdt_template {
|
||||||
#define ENTRY_TYPE_WRREMREG 271
|
#define ENTRY_TYPE_WRREMREG 271
|
||||||
#define ENTRY_TYPE_RDREMRAM 272
|
#define ENTRY_TYPE_RDREMRAM 272
|
||||||
#define ENTRY_TYPE_PCICFG 273
|
#define ENTRY_TYPE_PCICFG 273
|
||||||
|
#define ENTRY_TYPE_GET_SHADOW 274
|
||||||
|
|
||||||
#define CAPTURE_FLAG_PHYS_ONLY BIT_0
|
#define CAPTURE_FLAG_PHYS_ONLY BIT_0
|
||||||
#define CAPTURE_FLAG_PHYS_VIRT BIT_1
|
#define CAPTURE_FLAG_PHYS_VIRT BIT_1
|
||||||
|
@ -109,12 +110,12 @@ struct __packed qla27xx_fwdt_entry {
|
||||||
} t259;
|
} t259;
|
||||||
|
|
||||||
struct __packed {
|
struct __packed {
|
||||||
uint8_t pci_addr;
|
uint8_t pci_offset;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
} t260;
|
} t260;
|
||||||
|
|
||||||
struct __packed {
|
struct __packed {
|
||||||
uint8_t pci_addr;
|
uint8_t pci_offset;
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
uint32_t write_data;
|
uint32_t write_data;
|
||||||
} t261;
|
} t261;
|
||||||
|
@ -186,6 +187,12 @@ struct __packed qla27xx_fwdt_entry {
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
} t273;
|
} t273;
|
||||||
|
|
||||||
|
struct __packed {
|
||||||
|
uint32_t num_queues;
|
||||||
|
uint8_t queue_type;
|
||||||
|
uint8_t reserved[3];
|
||||||
|
} t274;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,4 +209,8 @@ struct __packed qla27xx_fwdt_entry {
|
||||||
#define T268_BUF_TYPE_EXCH_BUFOFF 2
|
#define T268_BUF_TYPE_EXCH_BUFOFF 2
|
||||||
#define T268_BUF_TYPE_EXTD_LOGIN 3
|
#define T268_BUF_TYPE_EXTD_LOGIN 3
|
||||||
|
|
||||||
|
#define T274_QUEUE_TYPE_REQ_SHAD 1
|
||||||
|
#define T274_QUEUE_TYPE_RSP_SHAD 2
|
||||||
|
#define T274_QUEUE_TYPE_ATIO_SHAD 3
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* QLogic Fibre Channel HBA Driver
|
* QLogic Fibre Channel HBA Driver
|
||||||
* Copyright (c) 2003-2013 QLogic Corporation
|
* Copyright (c) 2003-2014 QLogic Corporation
|
||||||
*
|
*
|
||||||
* See LICENSE.qla2xxx for copyright and licensing details.
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Driver version
|
* Driver version
|
||||||
*/
|
*/
|
||||||
#define QLA2XXX_VERSION "8.07.00.02-k"
|
#define QLA2XXX_VERSION "8.07.00.08-k"
|
||||||
|
|
||||||
#define QLA_DRIVER_MAJOR_VER 8
|
#define QLA_DRIVER_MAJOR_VER 8
|
||||||
#define QLA_DRIVER_MINOR_VER 7
|
#define QLA_DRIVER_MINOR_VER 7
|
||||||
|
|
|
@ -472,6 +472,11 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
|
||||||
cmd->sg_cnt = se_cmd->t_data_nents;
|
cmd->sg_cnt = se_cmd->t_data_nents;
|
||||||
cmd->sg = se_cmd->t_data_sg;
|
cmd->sg = se_cmd->t_data_sg;
|
||||||
|
|
||||||
|
cmd->prot_sg_cnt = se_cmd->t_prot_nents;
|
||||||
|
cmd->prot_sg = se_cmd->t_prot_sg;
|
||||||
|
cmd->blk_sz = se_cmd->se_dev->dev_attrib.block_size;
|
||||||
|
se_cmd->pi_err = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup
|
* qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup
|
||||||
* the SGL mappings into PCIe memory for incoming FCP WRITE data.
|
* the SGL mappings into PCIe memory for incoming FCP WRITE data.
|
||||||
|
@ -567,8 +572,13 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
transport_generic_request_failure(&cmd->se_cmd,
|
if (cmd->se_cmd.pi_err)
|
||||||
TCM_CHECK_CONDITION_ABORT_CMD);
|
transport_generic_request_failure(&cmd->se_cmd,
|
||||||
|
cmd->se_cmd.pi_err);
|
||||||
|
else
|
||||||
|
transport_generic_request_failure(&cmd->se_cmd,
|
||||||
|
TCM_CHECK_CONDITION_ABORT_CMD);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,6 +594,27 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
|
||||||
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
|
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tcm_qla2xxx_handle_dif_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
|
||||||
|
|
||||||
|
/* take an extra kref to prevent cmd free too early.
|
||||||
|
* need to wait for SCSI status/check condition to
|
||||||
|
* finish responding generate by transport_generic_request_failure.
|
||||||
|
*/
|
||||||
|
kref_get(&cmd->se_cmd.cmd_kref);
|
||||||
|
transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called from qla_target.c:qlt_do_ctio_completion()
|
||||||
|
*/
|
||||||
|
static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd)
|
||||||
|
{
|
||||||
|
INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work);
|
||||||
|
queue_work(tcm_qla2xxx_free_wq, &cmd->work);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called from qla_target.c:qlt_issue_task_mgmt()
|
* Called from qla_target.c:qlt_issue_task_mgmt()
|
||||||
*/
|
*/
|
||||||
|
@ -610,6 +641,11 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
|
||||||
cmd->sg = se_cmd->t_data_sg;
|
cmd->sg = se_cmd->t_data_sg;
|
||||||
cmd->offset = 0;
|
cmd->offset = 0;
|
||||||
|
|
||||||
|
cmd->prot_sg_cnt = se_cmd->t_prot_nents;
|
||||||
|
cmd->prot_sg = se_cmd->t_prot_sg;
|
||||||
|
cmd->blk_sz = se_cmd->se_dev->dev_attrib.block_size;
|
||||||
|
se_cmd->pi_err = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now queue completed DATA_IN the qla2xxx LLD and response ring
|
* Now queue completed DATA_IN the qla2xxx LLD and response ring
|
||||||
*/
|
*/
|
||||||
|
@ -1600,6 +1636,7 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
|
||||||
static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
|
static struct qla_tgt_func_tmpl tcm_qla2xxx_template = {
|
||||||
.handle_cmd = tcm_qla2xxx_handle_cmd,
|
.handle_cmd = tcm_qla2xxx_handle_cmd,
|
||||||
.handle_data = tcm_qla2xxx_handle_data,
|
.handle_data = tcm_qla2xxx_handle_data,
|
||||||
|
.handle_dif_err = tcm_qla2xxx_handle_dif_err,
|
||||||
.handle_tmr = tcm_qla2xxx_handle_tmr,
|
.handle_tmr = tcm_qla2xxx_handle_tmr,
|
||||||
.free_cmd = tcm_qla2xxx_free_cmd,
|
.free_cmd = tcm_qla2xxx_free_cmd,
|
||||||
.free_mcmd = tcm_qla2xxx_free_mcmd,
|
.free_mcmd = tcm_qla2xxx_free_mcmd,
|
||||||
|
|
|
@ -249,110 +249,6 @@ void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha)
|
||||||
qla4_83xx_flash_unlock(ha);
|
qla4_83xx_flash_unlock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* qla4_83xx_ms_mem_write_128b - Writes data to MS/off-chip memory
|
|
||||||
* @ha: Pointer to adapter structure
|
|
||||||
* @addr: Flash address to write to
|
|
||||||
* @data: Data to be written
|
|
||||||
* @count: word_count to be written
|
|
||||||
*
|
|
||||||
* Return: On success return QLA_SUCCESS
|
|
||||||
* On error return QLA_ERROR
|
|
||||||
**/
|
|
||||||
int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
|
|
||||||
uint32_t *data, uint32_t count)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
uint32_t agt_ctrl;
|
|
||||||
unsigned long flags;
|
|
||||||
int ret_val = QLA_SUCCESS;
|
|
||||||
|
|
||||||
/* Only 128-bit aligned access */
|
|
||||||
if (addr & 0xF) {
|
|
||||||
ret_val = QLA_ERROR;
|
|
||||||
goto exit_ms_mem_write;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_lock_irqsave(&ha->hw_lock, flags);
|
|
||||||
|
|
||||||
/* Write address */
|
|
||||||
ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
|
|
||||||
if (ret_val == QLA_ERROR) {
|
|
||||||
ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
|
|
||||||
__func__);
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++, addr += 16) {
|
|
||||||
if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
|
|
||||||
QLA8XXX_ADDR_QDR_NET_MAX)) ||
|
|
||||||
(QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
|
|
||||||
QLA8XXX_ADDR_DDR_NET_MAX)))) {
|
|
||||||
ret_val = QLA_ERROR;
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
|
|
||||||
addr);
|
|
||||||
/* Write data */
|
|
||||||
ret_val |= qla4_83xx_wr_reg_indirect(ha,
|
|
||||||
MD_MIU_TEST_AGT_WRDATA_LO,
|
|
||||||
*data++);
|
|
||||||
ret_val |= qla4_83xx_wr_reg_indirect(ha,
|
|
||||||
MD_MIU_TEST_AGT_WRDATA_HI,
|
|
||||||
*data++);
|
|
||||||
ret_val |= qla4_83xx_wr_reg_indirect(ha,
|
|
||||||
MD_MIU_TEST_AGT_WRDATA_ULO,
|
|
||||||
*data++);
|
|
||||||
ret_val |= qla4_83xx_wr_reg_indirect(ha,
|
|
||||||
MD_MIU_TEST_AGT_WRDATA_UHI,
|
|
||||||
*data++);
|
|
||||||
if (ret_val == QLA_ERROR) {
|
|
||||||
ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
|
|
||||||
__func__);
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check write status */
|
|
||||||
ret_val = qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
|
|
||||||
MIU_TA_CTL_WRITE_ENABLE);
|
|
||||||
ret_val |= qla4_83xx_wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
|
|
||||||
MIU_TA_CTL_WRITE_START);
|
|
||||||
if (ret_val == QLA_ERROR) {
|
|
||||||
ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
|
|
||||||
__func__);
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < MAX_CTL_CHECK; j++) {
|
|
||||||
ret_val = qla4_83xx_rd_reg_indirect(ha,
|
|
||||||
MD_MIU_TEST_AGT_CTRL,
|
|
||||||
&agt_ctrl);
|
|
||||||
if (ret_val == QLA_ERROR) {
|
|
||||||
ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
|
|
||||||
__func__);
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Status check failed */
|
|
||||||
if (j >= MAX_CTL_CHECK) {
|
|
||||||
printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
|
|
||||||
__func__);
|
|
||||||
ret_val = QLA_ERROR;
|
|
||||||
goto exit_ms_mem_write_unlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_ms_mem_write_unlock:
|
|
||||||
write_unlock_irqrestore(&ha->hw_lock, flags);
|
|
||||||
|
|
||||||
exit_ms_mem_write:
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INTENT_TO_RECOVER 0x01
|
#define INTENT_TO_RECOVER 0x01
|
||||||
#define PROCEED_TO_RECOVER 0x02
|
#define PROCEED_TO_RECOVER 0x02
|
||||||
|
|
||||||
|
@ -760,7 +656,7 @@ static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
|
||||||
__func__));
|
__func__));
|
||||||
|
|
||||||
/* 128 bit/16 byte write to MS memory */
|
/* 128 bit/16 byte write to MS memory */
|
||||||
ret_val = qla4_83xx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
|
ret_val = qla4_8xxx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
|
||||||
count);
|
count);
|
||||||
if (ret_val == QLA_ERROR) {
|
if (ret_val == QLA_ERROR) {
|
||||||
ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
|
ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
|
||||||
|
|
|
@ -254,6 +254,50 @@ struct qla83xx_minidump_entry_pollrd {
|
||||||
uint32_t rsvd_1;
|
uint32_t rsvd_1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rddfe {
|
||||||
|
struct qla8xxx_minidump_entry_hdr h;
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t value;
|
||||||
|
uint8_t stride;
|
||||||
|
uint8_t stride2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t modify_mask;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint32_t rsvd;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_rdmdio {
|
||||||
|
struct qla8xxx_minidump_entry_hdr h;
|
||||||
|
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t addr_2;
|
||||||
|
uint32_t value_1;
|
||||||
|
uint8_t stride_1;
|
||||||
|
uint8_t stride_2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t value_2;
|
||||||
|
uint32_t data_size;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct qla8044_minidump_entry_pollwr {
|
||||||
|
struct qla8xxx_minidump_entry_hdr h;
|
||||||
|
uint32_t addr_1;
|
||||||
|
uint32_t addr_2;
|
||||||
|
uint32_t value_1;
|
||||||
|
uint32_t value_2;
|
||||||
|
uint32_t poll;
|
||||||
|
uint32_t mask;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint32_t rsvd;
|
||||||
|
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* RDMUX2 Entry */
|
/* RDMUX2 Entry */
|
||||||
struct qla83xx_minidump_entry_rdmux2 {
|
struct qla83xx_minidump_entry_rdmux2 {
|
||||||
struct qla8xxx_minidump_entry_hdr h;
|
struct qla8xxx_minidump_entry_hdr h;
|
||||||
|
|
|
@ -601,6 +601,7 @@ struct scsi_qla_host {
|
||||||
#define DPC_HA_NEED_QUIESCENT 22 /* 0x00400000 ISP-82xx only*/
|
#define DPC_HA_NEED_QUIESCENT 22 /* 0x00400000 ISP-82xx only*/
|
||||||
#define DPC_POST_IDC_ACK 23 /* 0x00800000 */
|
#define DPC_POST_IDC_ACK 23 /* 0x00800000 */
|
||||||
#define DPC_RESTORE_ACB 24 /* 0x01000000 */
|
#define DPC_RESTORE_ACB 24 /* 0x01000000 */
|
||||||
|
#define DPC_SYSFS_DDB_EXPORT 25 /* 0x02000000 */
|
||||||
|
|
||||||
struct Scsi_Host *host; /* pointer to host data */
|
struct Scsi_Host *host; /* pointer to host data */
|
||||||
uint32_t tot_ddbs;
|
uint32_t tot_ddbs;
|
||||||
|
|
|
@ -1415,6 +1415,9 @@ struct ql_iscsi_stats {
|
||||||
#define QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN 16
|
#define QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN 16
|
||||||
#define QLA83XX_SS_OCM_WNDREG_INDEX 3
|
#define QLA83XX_SS_OCM_WNDREG_INDEX 3
|
||||||
#define QLA83XX_SS_PCI_INDEX 0
|
#define QLA83XX_SS_PCI_INDEX 0
|
||||||
|
#define QLA8022_TEMPLATE_CAP_OFFSET 172
|
||||||
|
#define QLA83XX_TEMPLATE_CAP_OFFSET 268
|
||||||
|
#define QLA80XX_TEMPLATE_RESERVED_BITS 16
|
||||||
|
|
||||||
struct qla4_8xxx_minidump_template_hdr {
|
struct qla4_8xxx_minidump_template_hdr {
|
||||||
uint32_t entry_type;
|
uint32_t entry_type;
|
||||||
|
@ -1434,6 +1437,7 @@ struct qla4_8xxx_minidump_template_hdr {
|
||||||
uint32_t saved_state_array[QLA8XXX_DBG_STATE_ARRAY_LEN];
|
uint32_t saved_state_array[QLA8XXX_DBG_STATE_ARRAY_LEN];
|
||||||
uint32_t capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN];
|
uint32_t capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN];
|
||||||
uint32_t ocm_window_reg[QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN];
|
uint32_t ocm_window_reg[QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN];
|
||||||
|
uint32_t capabilities[QLA80XX_TEMPLATE_RESERVED_BITS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _QLA4X_FW_H */
|
#endif /* _QLA4X_FW_H */
|
||||||
|
|
|
@ -274,13 +274,14 @@ int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
|
||||||
int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
|
int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
|
||||||
uint32_t acb_type, uint32_t len);
|
uint32_t acb_type, uint32_t len);
|
||||||
int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
|
int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config);
|
||||||
int qla4_83xx_ms_mem_write_128b(struct scsi_qla_host *ha,
|
int qla4_8xxx_ms_mem_write_128b(struct scsi_qla_host *ha,
|
||||||
uint64_t addr, uint32_t *data, uint32_t count);
|
uint64_t addr, uint32_t *data, uint32_t count);
|
||||||
uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
|
uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state);
|
||||||
int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config);
|
int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config);
|
||||||
int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config);
|
int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config);
|
||||||
int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha);
|
int qla4_8xxx_check_init_adapter_retry(struct scsi_qla_host *ha);
|
||||||
int qla4_83xx_is_detached(struct scsi_qla_host *ha);
|
int qla4_83xx_is_detached(struct scsi_qla_host *ha);
|
||||||
|
int qla4xxx_sysfs_ddb_export(struct scsi_qla_host *ha);
|
||||||
|
|
||||||
extern int ql4xextended_error_logging;
|
extern int ql4xextended_error_logging;
|
||||||
extern int ql4xdontresethba;
|
extern int ql4xdontresethba;
|
||||||
|
|
|
@ -282,6 +282,25 @@ qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha)
|
||||||
return ipv4_wait|ipv6_wait;
|
return ipv4_wait|ipv6_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qla4_80xx_is_minidump_dma_capable(struct scsi_qla_host *ha,
|
||||||
|
struct qla4_8xxx_minidump_template_hdr *md_hdr)
|
||||||
|
{
|
||||||
|
int offset = (is_qla8022(ha)) ? QLA8022_TEMPLATE_CAP_OFFSET :
|
||||||
|
QLA83XX_TEMPLATE_CAP_OFFSET;
|
||||||
|
int rval = 1;
|
||||||
|
uint32_t *cap_offset;
|
||||||
|
|
||||||
|
cap_offset = (uint32_t *)((char *)md_hdr + offset);
|
||||||
|
|
||||||
|
if (!(le32_to_cpu(*cap_offset) & BIT_0)) {
|
||||||
|
ql4_printk(KERN_INFO, ha, "PEX DMA Not supported %d\n",
|
||||||
|
*cap_offset);
|
||||||
|
rval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla4xxx_alloc_fw_dump - Allocate memory for minidump data.
|
* qla4xxx_alloc_fw_dump - Allocate memory for minidump data.
|
||||||
* @ha: pointer to host adapter structure.
|
* @ha: pointer to host adapter structure.
|
||||||
|
@ -294,6 +313,7 @@ void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha)
|
||||||
void *md_tmp;
|
void *md_tmp;
|
||||||
dma_addr_t md_tmp_dma;
|
dma_addr_t md_tmp_dma;
|
||||||
struct qla4_8xxx_minidump_template_hdr *md_hdr;
|
struct qla4_8xxx_minidump_template_hdr *md_hdr;
|
||||||
|
int dma_capable;
|
||||||
|
|
||||||
if (ha->fw_dump) {
|
if (ha->fw_dump) {
|
||||||
ql4_printk(KERN_WARNING, ha,
|
ql4_printk(KERN_WARNING, ha,
|
||||||
|
@ -326,13 +346,19 @@ void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha)
|
||||||
|
|
||||||
md_hdr = (struct qla4_8xxx_minidump_template_hdr *)md_tmp;
|
md_hdr = (struct qla4_8xxx_minidump_template_hdr *)md_tmp;
|
||||||
|
|
||||||
|
dma_capable = qla4_80xx_is_minidump_dma_capable(ha, md_hdr);
|
||||||
|
|
||||||
capture_debug_level = md_hdr->capture_debug_level;
|
capture_debug_level = md_hdr->capture_debug_level;
|
||||||
|
|
||||||
/* Get capture mask based on module loadtime setting. */
|
/* Get capture mask based on module loadtime setting. */
|
||||||
if (ql4xmdcapmask >= 0x3 && ql4xmdcapmask <= 0x7F)
|
if ((ql4xmdcapmask >= 0x3 && ql4xmdcapmask <= 0x7F) ||
|
||||||
|
(ql4xmdcapmask == 0xFF && dma_capable)) {
|
||||||
ha->fw_dump_capture_mask = ql4xmdcapmask;
|
ha->fw_dump_capture_mask = ql4xmdcapmask;
|
||||||
else
|
} else {
|
||||||
|
if (ql4xmdcapmask == 0xFF)
|
||||||
|
ql4_printk(KERN_INFO, ha, "Falling back to default capture mask, as PEX DMA is not supported\n");
|
||||||
ha->fw_dump_capture_mask = capture_debug_level;
|
ha->fw_dump_capture_mask = capture_debug_level;
|
||||||
|
}
|
||||||
|
|
||||||
md_hdr->driver_capture_mask = ha->fw_dump_capture_mask;
|
md_hdr->driver_capture_mask = ha->fw_dump_capture_mask;
|
||||||
|
|
||||||
|
@ -864,6 +890,8 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha)
|
||||||
if (status == QLA_SUCCESS) {
|
if (status == QLA_SUCCESS) {
|
||||||
if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
|
if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
|
||||||
qla4xxx_get_crash_record(ha);
|
qla4xxx_get_crash_record(ha);
|
||||||
|
|
||||||
|
qla4xxx_init_rings(ha);
|
||||||
} else {
|
} else {
|
||||||
DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n",
|
DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n",
|
||||||
ha->host_no, __func__));
|
ha->host_no, __func__));
|
||||||
|
|
|
@ -1526,7 +1526,7 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
|
||||||
|
|
||||||
int qla4xxx_request_irqs(struct scsi_qla_host *ha)
|
int qla4xxx_request_irqs(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
int rval = QLA_ERROR;
|
int rval = QLA_ERROR;
|
||||||
|
|
||||||
if (is_qla40XX(ha))
|
if (is_qla40XX(ha))
|
||||||
|
@ -1580,15 +1580,13 @@ try_msi:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
try_intx:
|
||||||
* Prevent interrupts from falling back to INTx mode in cases where
|
|
||||||
* interrupts cannot get acquired through MSI-X or MSI mode.
|
|
||||||
*/
|
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
ql4_printk(KERN_WARNING, ha, "IRQ not attached -- %d.\n", ret);
|
ql4_printk(KERN_WARNING, ha, "%s: ISP82xx Legacy interrupt not supported\n",
|
||||||
|
__func__);
|
||||||
goto irq_not_attached;
|
goto irq_not_attached;
|
||||||
}
|
}
|
||||||
try_intx:
|
|
||||||
/* Trying INTx */
|
/* Trying INTx */
|
||||||
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
|
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
|
||||||
IRQF_SHARED, DRIVER_NAME, ha);
|
IRQF_SHARED, DRIVER_NAME, ha);
|
||||||
|
|
|
@ -2381,7 +2381,7 @@ int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config)
|
||||||
ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",
|
ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",
|
||||||
__func__);
|
__func__);
|
||||||
rval = QLA_ERROR;
|
rval = QLA_ERROR;
|
||||||
goto exit_config_acb;
|
goto exit_free_acb;
|
||||||
}
|
}
|
||||||
memcpy(ha->saved_acb, acb, acb_len);
|
memcpy(ha->saved_acb, acb, acb_len);
|
||||||
break;
|
break;
|
||||||
|
@ -2395,8 +2395,6 @@ int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(acb, ha->saved_acb, acb_len);
|
memcpy(acb, ha->saved_acb, acb_len);
|
||||||
kfree(ha->saved_acb);
|
|
||||||
ha->saved_acb = NULL;
|
|
||||||
|
|
||||||
rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);
|
rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
|
@ -2412,6 +2410,10 @@ exit_free_acb:
|
||||||
dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), acb,
|
dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), acb,
|
||||||
acb_dma);
|
acb_dma);
|
||||||
exit_config_acb:
|
exit_config_acb:
|
||||||
|
if ((acb_config == ACB_CONFIG_SET) && ha->saved_acb) {
|
||||||
|
kfree(ha->saved_acb);
|
||||||
|
ha->saved_acb = NULL;
|
||||||
|
}
|
||||||
DEBUG2(ql4_printk(KERN_INFO, ha,
|
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||||
"%s %s\n", __func__,
|
"%s %s\n", __func__,
|
||||||
rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));
|
rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <asm-generic/io-64-nonatomic-lo-hi.h>
|
#include <asm-generic/io-64-nonatomic-lo-hi.h>
|
||||||
|
|
||||||
|
#define TIMEOUT_100_MS 100
|
||||||
#define MASK(n) DMA_BIT_MASK(n)
|
#define MASK(n) DMA_BIT_MASK(n)
|
||||||
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
|
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
|
||||||
#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
|
#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
|
||||||
|
@ -1176,6 +1177,112 @@ qla4_82xx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qla4_8xxx_ms_mem_write_128b - Writes data to MS/off-chip memory
|
||||||
|
* @ha: Pointer to adapter structure
|
||||||
|
* @addr: Flash address to write to
|
||||||
|
* @data: Data to be written
|
||||||
|
* @count: word_count to be written
|
||||||
|
*
|
||||||
|
* Return: On success return QLA_SUCCESS
|
||||||
|
* On error return QLA_ERROR
|
||||||
|
**/
|
||||||
|
int qla4_8xxx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
|
||||||
|
uint32_t *data, uint32_t count)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
uint32_t agt_ctrl;
|
||||||
|
unsigned long flags;
|
||||||
|
int ret_val = QLA_SUCCESS;
|
||||||
|
|
||||||
|
/* Only 128-bit aligned access */
|
||||||
|
if (addr & 0xF) {
|
||||||
|
ret_val = QLA_ERROR;
|
||||||
|
goto exit_ms_mem_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_lock_irqsave(&ha->hw_lock, flags);
|
||||||
|
|
||||||
|
/* Write address */
|
||||||
|
ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
|
||||||
|
if (ret_val == QLA_ERROR) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
|
||||||
|
__func__);
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++, addr += 16) {
|
||||||
|
if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
|
||||||
|
QLA8XXX_ADDR_QDR_NET_MAX)) ||
|
||||||
|
(QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
|
||||||
|
QLA8XXX_ADDR_DDR_NET_MAX)))) {
|
||||||
|
ret_val = QLA_ERROR;
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_val = ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_ADDR_LO,
|
||||||
|
addr);
|
||||||
|
/* Write data */
|
||||||
|
ret_val |= ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_WRDATA_LO,
|
||||||
|
*data++);
|
||||||
|
ret_val |= ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_WRDATA_HI,
|
||||||
|
*data++);
|
||||||
|
ret_val |= ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_WRDATA_ULO,
|
||||||
|
*data++);
|
||||||
|
ret_val |= ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_WRDATA_UHI,
|
||||||
|
*data++);
|
||||||
|
if (ret_val == QLA_ERROR) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
|
||||||
|
__func__);
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check write status */
|
||||||
|
ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
|
||||||
|
MIU_TA_CTL_WRITE_ENABLE);
|
||||||
|
ret_val |= ha->isp_ops->wr_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_CTRL,
|
||||||
|
MIU_TA_CTL_WRITE_START);
|
||||||
|
if (ret_val == QLA_ERROR) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
|
||||||
|
__func__);
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < MAX_CTL_CHECK; j++) {
|
||||||
|
ret_val = ha->isp_ops->rd_reg_indirect(ha,
|
||||||
|
MD_MIU_TEST_AGT_CTRL,
|
||||||
|
&agt_ctrl);
|
||||||
|
if (ret_val == QLA_ERROR) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
|
||||||
|
__func__);
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status check failed */
|
||||||
|
if (j >= MAX_CTL_CHECK) {
|
||||||
|
printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
|
||||||
|
__func__);
|
||||||
|
ret_val = QLA_ERROR;
|
||||||
|
goto exit_ms_mem_write_unlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_ms_mem_write_unlock:
|
||||||
|
write_unlock_irqrestore(&ha->hw_lock, flags);
|
||||||
|
|
||||||
|
exit_ms_mem_write:
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qla4_82xx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
|
qla4_82xx_load_from_flash(struct scsi_qla_host *ha, uint32_t image_start)
|
||||||
{
|
{
|
||||||
|
@ -1714,6 +1821,101 @@ void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
|
||||||
qla4_82xx_rom_unlock(ha);
|
qla4_82xx_rom_unlock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t ql4_84xx_poll_wait_for_ready(struct scsi_qla_host *ha,
|
||||||
|
uint32_t addr1, uint32_t mask)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
uint32_t rval = QLA_SUCCESS;
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
|
||||||
|
do {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (time_after_eq(jiffies, timeout)) {
|
||||||
|
ql4_printk(KERN_INFO, ha, "Error in processing rdmdio entry\n");
|
||||||
|
return QLA_ERROR;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ql4_84xx_ipmdio_rd_reg(struct scsi_qla_host *ha, uint32_t addr1,
|
||||||
|
uint32_t addr3, uint32_t mask, uint32_t addr,
|
||||||
|
uint32_t *data_ptr)
|
||||||
|
{
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
uint32_t temp;
|
||||||
|
uint32_t data;
|
||||||
|
|
||||||
|
rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_ipmdio_rd_reg;
|
||||||
|
|
||||||
|
temp = (0x40000000 | addr);
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1, temp);
|
||||||
|
|
||||||
|
rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_ipmdio_rd_reg;
|
||||||
|
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr3, &data);
|
||||||
|
*data_ptr = data;
|
||||||
|
|
||||||
|
exit_ipmdio_rd_reg:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t ql4_84xx_poll_wait_ipmdio_bus_idle(struct scsi_qla_host *ha,
|
||||||
|
uint32_t addr1,
|
||||||
|
uint32_t addr2,
|
||||||
|
uint32_t addr3,
|
||||||
|
uint32_t mask)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
uint32_t temp;
|
||||||
|
uint32_t rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
|
||||||
|
do {
|
||||||
|
ql4_84xx_ipmdio_rd_reg(ha, addr1, addr3, mask, addr2, &temp);
|
||||||
|
if ((temp & 0x1) != 1)
|
||||||
|
break;
|
||||||
|
if (time_after_eq(jiffies, timeout)) {
|
||||||
|
ql4_printk(KERN_INFO, ha, "Error in processing mdiobus idle\n");
|
||||||
|
return QLA_ERROR;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ql4_84xx_ipmdio_wr_reg(struct scsi_qla_host *ha,
|
||||||
|
uint32_t addr1, uint32_t addr3,
|
||||||
|
uint32_t mask, uint32_t addr,
|
||||||
|
uint32_t value)
|
||||||
|
{
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_ipmdio_wr_reg;
|
||||||
|
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr3, value);
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1, addr);
|
||||||
|
|
||||||
|
rval = ql4_84xx_poll_wait_for_ready(ha, addr1, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_ipmdio_wr_reg;
|
||||||
|
|
||||||
|
exit_ipmdio_wr_reg:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
|
static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
|
||||||
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
uint32_t **d_ptr)
|
uint32_t **d_ptr)
|
||||||
|
@ -1822,7 +2024,7 @@ error_exit:
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qla4_83xx_minidump_pex_dma_read(struct scsi_qla_host *ha,
|
static int qla4_8xxx_minidump_pex_dma_read(struct scsi_qla_host *ha,
|
||||||
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
uint32_t **d_ptr)
|
uint32_t **d_ptr)
|
||||||
{
|
{
|
||||||
|
@ -1899,11 +2101,11 @@ static int qla4_83xx_minidump_pex_dma_read(struct scsi_qla_host *ha,
|
||||||
dma_desc.cmd.read_data_size = size;
|
dma_desc.cmd.read_data_size = size;
|
||||||
|
|
||||||
/* Prepare: Write pex-dma descriptor to MS memory. */
|
/* Prepare: Write pex-dma descriptor to MS memory. */
|
||||||
rval = qla4_83xx_ms_mem_write_128b(ha,
|
rval = qla4_8xxx_ms_mem_write_128b(ha,
|
||||||
(uint64_t)m_hdr->desc_card_addr,
|
(uint64_t)m_hdr->desc_card_addr,
|
||||||
(uint32_t *)&dma_desc,
|
(uint32_t *)&dma_desc,
|
||||||
(sizeof(struct qla4_83xx_pex_dma_descriptor)/16));
|
(sizeof(struct qla4_83xx_pex_dma_descriptor)/16));
|
||||||
if (rval == -1) {
|
if (rval != QLA_SUCCESS) {
|
||||||
ql4_printk(KERN_INFO, ha,
|
ql4_printk(KERN_INFO, ha,
|
||||||
"%s: Error writing rdmem-dma-init to MS !!!\n",
|
"%s: Error writing rdmem-dma-init to MS !!!\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -2359,17 +2561,10 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
|
||||||
uint32_t *data_ptr = *d_ptr;
|
uint32_t *data_ptr = *d_ptr;
|
||||||
int rval = QLA_SUCCESS;
|
int rval = QLA_SUCCESS;
|
||||||
|
|
||||||
if (is_qla8032(ha) || is_qla8042(ha)) {
|
rval = qla4_8xxx_minidump_pex_dma_read(ha, entry_hdr, &data_ptr);
|
||||||
rval = qla4_83xx_minidump_pex_dma_read(ha, entry_hdr,
|
if (rval != QLA_SUCCESS)
|
||||||
&data_ptr);
|
|
||||||
if (rval != QLA_SUCCESS) {
|
|
||||||
rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
|
|
||||||
&data_ptr);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
|
rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
|
||||||
&data_ptr);
|
&data_ptr);
|
||||||
}
|
|
||||||
*d_ptr = data_ptr;
|
*d_ptr = data_ptr;
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -2440,6 +2635,227 @@ exit_process_pollrd:
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t qla4_84xx_minidump_process_rddfe(struct scsi_qla_host *ha,
|
||||||
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
|
uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
int loop_cnt;
|
||||||
|
uint32_t addr1, addr2, value, data, temp, wrval;
|
||||||
|
uint8_t stride, stride2;
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t poll, mask, data_size, modify_mask;
|
||||||
|
uint32_t wait_count = 0;
|
||||||
|
uint32_t *data_ptr = *d_ptr;
|
||||||
|
struct qla8044_minidump_entry_rddfe *rddfe;
|
||||||
|
uint32_t rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
rddfe = (struct qla8044_minidump_entry_rddfe *)entry_hdr;
|
||||||
|
addr1 = le32_to_cpu(rddfe->addr_1);
|
||||||
|
value = le32_to_cpu(rddfe->value);
|
||||||
|
stride = le32_to_cpu(rddfe->stride);
|
||||||
|
stride2 = le32_to_cpu(rddfe->stride2);
|
||||||
|
count = le32_to_cpu(rddfe->count);
|
||||||
|
|
||||||
|
poll = le32_to_cpu(rddfe->poll);
|
||||||
|
mask = le32_to_cpu(rddfe->mask);
|
||||||
|
modify_mask = le32_to_cpu(rddfe->modify_mask);
|
||||||
|
data_size = le32_to_cpu(rddfe->data_size);
|
||||||
|
|
||||||
|
addr2 = addr1 + stride;
|
||||||
|
|
||||||
|
for (loop_cnt = 0x0; loop_cnt < count; loop_cnt++) {
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1, (0x40000000 | value));
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n", __func__);
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
goto exit_process_rddfe;
|
||||||
|
} else {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr2, &temp);
|
||||||
|
temp = temp & modify_mask;
|
||||||
|
temp = (temp | ((loop_cnt << 16) | loop_cnt));
|
||||||
|
wrval = ((temp << 16) | temp);
|
||||||
|
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr2, wrval);
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1, value);
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
|
||||||
|
__func__);
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
goto exit_process_rddfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1,
|
||||||
|
((0x40000000 | value) +
|
||||||
|
stride2));
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &temp);
|
||||||
|
if ((temp & mask) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n",
|
||||||
|
__func__);
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
goto exit_process_rddfe;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr2, &data);
|
||||||
|
|
||||||
|
*data_ptr++ = cpu_to_le32(wrval);
|
||||||
|
*data_ptr++ = cpu_to_le32(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*d_ptr = data_ptr;
|
||||||
|
exit_process_rddfe:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t qla4_84xx_minidump_process_rdmdio(struct scsi_qla_host *ha,
|
||||||
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
|
uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
uint32_t addr1, addr2, value1, value2, data, selval;
|
||||||
|
uint8_t stride1, stride2;
|
||||||
|
uint32_t addr3, addr4, addr5, addr6, addr7;
|
||||||
|
uint16_t count, loop_cnt;
|
||||||
|
uint32_t poll, mask;
|
||||||
|
uint32_t *data_ptr = *d_ptr;
|
||||||
|
struct qla8044_minidump_entry_rdmdio *rdmdio;
|
||||||
|
|
||||||
|
rdmdio = (struct qla8044_minidump_entry_rdmdio *)entry_hdr;
|
||||||
|
addr1 = le32_to_cpu(rdmdio->addr_1);
|
||||||
|
addr2 = le32_to_cpu(rdmdio->addr_2);
|
||||||
|
value1 = le32_to_cpu(rdmdio->value_1);
|
||||||
|
stride1 = le32_to_cpu(rdmdio->stride_1);
|
||||||
|
stride2 = le32_to_cpu(rdmdio->stride_2);
|
||||||
|
count = le32_to_cpu(rdmdio->count);
|
||||||
|
|
||||||
|
poll = le32_to_cpu(rdmdio->poll);
|
||||||
|
mask = le32_to_cpu(rdmdio->mask);
|
||||||
|
value2 = le32_to_cpu(rdmdio->value_2);
|
||||||
|
|
||||||
|
addr3 = addr1 + stride1;
|
||||||
|
|
||||||
|
for (loop_cnt = 0; loop_cnt < count; loop_cnt++) {
|
||||||
|
rval = ql4_84xx_poll_wait_ipmdio_bus_idle(ha, addr1, addr2,
|
||||||
|
addr3, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
addr4 = addr2 - stride1;
|
||||||
|
rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask, addr4,
|
||||||
|
value2);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
addr5 = addr2 - (2 * stride1);
|
||||||
|
rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask, addr5,
|
||||||
|
value1);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
addr6 = addr2 - (3 * stride1);
|
||||||
|
rval = ql4_84xx_ipmdio_wr_reg(ha, addr1, addr3, mask,
|
||||||
|
addr6, 0x2);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
rval = ql4_84xx_poll_wait_ipmdio_bus_idle(ha, addr1, addr2,
|
||||||
|
addr3, mask);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
addr7 = addr2 - (4 * stride1);
|
||||||
|
rval = ql4_84xx_ipmdio_rd_reg(ha, addr1, addr3,
|
||||||
|
mask, addr7, &data);
|
||||||
|
if (rval)
|
||||||
|
goto exit_process_rdmdio;
|
||||||
|
|
||||||
|
selval = (value2 << 18) | (value1 << 2) | 2;
|
||||||
|
|
||||||
|
stride2 = le32_to_cpu(rdmdio->stride_2);
|
||||||
|
*data_ptr++ = cpu_to_le32(selval);
|
||||||
|
*data_ptr++ = cpu_to_le32(data);
|
||||||
|
|
||||||
|
value1 = value1 + stride2;
|
||||||
|
*d_ptr = data_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_process_rdmdio:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t qla4_84xx_minidump_process_pollwr(struct scsi_qla_host *ha,
|
||||||
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
|
uint32_t **d_ptr)
|
||||||
|
{
|
||||||
|
uint32_t addr1, addr2, value1, value2, poll, mask, r_value;
|
||||||
|
struct qla8044_minidump_entry_pollwr *pollwr_hdr;
|
||||||
|
uint32_t wait_count = 0;
|
||||||
|
uint32_t rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
pollwr_hdr = (struct qla8044_minidump_entry_pollwr *)entry_hdr;
|
||||||
|
addr1 = le32_to_cpu(pollwr_hdr->addr_1);
|
||||||
|
addr2 = le32_to_cpu(pollwr_hdr->addr_2);
|
||||||
|
value1 = le32_to_cpu(pollwr_hdr->value_1);
|
||||||
|
value2 = le32_to_cpu(pollwr_hdr->value_2);
|
||||||
|
|
||||||
|
poll = le32_to_cpu(pollwr_hdr->poll);
|
||||||
|
mask = le32_to_cpu(pollwr_hdr->mask);
|
||||||
|
|
||||||
|
while (wait_count < poll) {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &r_value);
|
||||||
|
|
||||||
|
if ((r_value & poll) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_count == poll) {
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: TIMEOUT\n", __func__);
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
goto exit_process_pollwr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr2, value2);
|
||||||
|
ha->isp_ops->wr_reg_indirect(ha, addr1, value1);
|
||||||
|
|
||||||
|
wait_count = 0;
|
||||||
|
while (wait_count < poll) {
|
||||||
|
ha->isp_ops->rd_reg_indirect(ha, addr1, &r_value);
|
||||||
|
|
||||||
|
if ((r_value & poll) != 0)
|
||||||
|
break;
|
||||||
|
wait_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_process_pollwr:
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
static void qla83xx_minidump_process_rdmux2(struct scsi_qla_host *ha,
|
static void qla83xx_minidump_process_rdmux2(struct scsi_qla_host *ha,
|
||||||
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
struct qla8xxx_minidump_entry_hdr *entry_hdr,
|
||||||
uint32_t **d_ptr)
|
uint32_t **d_ptr)
|
||||||
|
@ -2753,6 +3169,24 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
|
||||||
if (rval != QLA_SUCCESS)
|
if (rval != QLA_SUCCESS)
|
||||||
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
||||||
break;
|
break;
|
||||||
|
case QLA8044_RDDFE:
|
||||||
|
rval = qla4_84xx_minidump_process_rddfe(ha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
||||||
|
break;
|
||||||
|
case QLA8044_RDMDIO:
|
||||||
|
rval = qla4_84xx_minidump_process_rdmdio(ha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
||||||
|
break;
|
||||||
|
case QLA8044_POLLWR:
|
||||||
|
rval = qla4_84xx_minidump_process_pollwr(ha, entry_hdr,
|
||||||
|
&data_ptr);
|
||||||
|
if (rval != QLA_SUCCESS)
|
||||||
|
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
||||||
|
break;
|
||||||
case QLA8XXX_RDNOP:
|
case QLA8XXX_RDNOP:
|
||||||
default:
|
default:
|
||||||
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
|
||||||
|
|
|
@ -858,6 +858,9 @@ struct crb_addr_pair {
|
||||||
#define QLA83XX_POLLRD 35
|
#define QLA83XX_POLLRD 35
|
||||||
#define QLA83XX_RDMUX2 36
|
#define QLA83XX_RDMUX2 36
|
||||||
#define QLA83XX_POLLRDMWR 37
|
#define QLA83XX_POLLRDMWR 37
|
||||||
|
#define QLA8044_RDDFE 38
|
||||||
|
#define QLA8044_RDMDIO 39
|
||||||
|
#define QLA8044_POLLWR 40
|
||||||
#define QLA8XXX_RDROM 71
|
#define QLA8XXX_RDROM 71
|
||||||
#define QLA8XXX_RDMEM 72
|
#define QLA8XXX_RDMEM 72
|
||||||
#define QLA8XXX_CNTRL 98
|
#define QLA8XXX_CNTRL 98
|
||||||
|
|
|
@ -83,12 +83,12 @@ MODULE_PARM_DESC(ql4xsess_recovery_tmo,
|
||||||
" Target Session Recovery Timeout.\n"
|
" Target Session Recovery Timeout.\n"
|
||||||
"\t\t Default: 120 sec.");
|
"\t\t Default: 120 sec.");
|
||||||
|
|
||||||
int ql4xmdcapmask = 0x1F;
|
int ql4xmdcapmask = 0;
|
||||||
module_param(ql4xmdcapmask, int, S_IRUGO);
|
module_param(ql4xmdcapmask, int, S_IRUGO);
|
||||||
MODULE_PARM_DESC(ql4xmdcapmask,
|
MODULE_PARM_DESC(ql4xmdcapmask,
|
||||||
" Set the Minidump driver capture mask level.\n"
|
" Set the Minidump driver capture mask level.\n"
|
||||||
"\t\t Default is 0x1F.\n"
|
"\t\t Default is 0 (firmware default capture mask)\n"
|
||||||
"\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F");
|
"\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF");
|
||||||
|
|
||||||
int ql4xenablemd = 1;
|
int ql4xenablemd = 1;
|
||||||
module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR);
|
module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR);
|
||||||
|
@ -1742,6 +1742,9 @@ static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep,
|
||||||
struct sockaddr *dst_addr;
|
struct sockaddr *dst_addr;
|
||||||
struct scsi_qla_host *ha;
|
struct scsi_qla_host *ha;
|
||||||
|
|
||||||
|
if (!qla_ep)
|
||||||
|
return -ENOTCONN;
|
||||||
|
|
||||||
ha = to_qla_host(qla_ep->host);
|
ha = to_qla_host(qla_ep->host);
|
||||||
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,
|
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,
|
||||||
ha->host_no));
|
ha->host_no));
|
||||||
|
@ -1749,9 +1752,6 @@ static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep,
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case ISCSI_PARAM_CONN_PORT:
|
case ISCSI_PARAM_CONN_PORT:
|
||||||
case ISCSI_PARAM_CONN_ADDRESS:
|
case ISCSI_PARAM_CONN_ADDRESS:
|
||||||
if (!qla_ep)
|
|
||||||
return -ENOTCONN;
|
|
||||||
|
|
||||||
dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
|
dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
|
||||||
if (!dst_addr)
|
if (!dst_addr)
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
|
@ -2879,7 +2879,6 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||||
struct iscsi_conn *conn;
|
struct iscsi_conn *conn;
|
||||||
struct qla_conn *qla_conn;
|
struct qla_conn *qla_conn;
|
||||||
struct sockaddr *dst_addr;
|
struct sockaddr *dst_addr;
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
conn = cls_conn->dd_data;
|
conn = cls_conn->dd_data;
|
||||||
qla_conn = conn->dd_data;
|
qla_conn = conn->dd_data;
|
||||||
|
@ -2893,9 +2892,6 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
|
||||||
default:
|
default:
|
||||||
return iscsi_conn_get_param(cls_conn, param, buf);
|
return iscsi_conn_get_param(cls_conn, param, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index)
|
int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index)
|
||||||
|
@ -3569,14 +3565,13 @@ static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,
|
||||||
if (test_bit(OPT_IPV6_DEVICE, &options)) {
|
if (test_bit(OPT_IPV6_DEVICE, &options)) {
|
||||||
conn->ipv6_traffic_class = fw_ddb_entry->ipv4_tos;
|
conn->ipv6_traffic_class = fw_ddb_entry->ipv4_tos;
|
||||||
|
|
||||||
conn->link_local_ipv6_addr = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);
|
conn->link_local_ipv6_addr = kmemdup(
|
||||||
|
fw_ddb_entry->link_local_ipv6_addr,
|
||||||
|
IPv6_ADDR_LEN, GFP_KERNEL);
|
||||||
if (!conn->link_local_ipv6_addr) {
|
if (!conn->link_local_ipv6_addr) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto exit_copy;
|
goto exit_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(conn->link_local_ipv6_addr,
|
|
||||||
fw_ddb_entry->link_local_ipv6_addr, IPv6_ADDR_LEN);
|
|
||||||
} else {
|
} else {
|
||||||
conn->ipv4_tos = fw_ddb_entry->ipv4_tos;
|
conn->ipv4_tos = fw_ddb_entry->ipv4_tos;
|
||||||
}
|
}
|
||||||
|
@ -4565,6 +4560,7 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
|
||||||
test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) ||
|
test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) ||
|
||||||
test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) ||
|
test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) ||
|
||||||
test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||
|
test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||
|
||||||
|
test_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags) ||
|
||||||
test_bit(DPC_AEN, &ha->dpc_flags)) {
|
test_bit(DPC_AEN, &ha->dpc_flags)) {
|
||||||
DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
|
DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
|
||||||
" - dpc flags = 0x%lx\n",
|
" - dpc flags = 0x%lx\n",
|
||||||
|
@ -4862,9 +4858,6 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
|
||||||
ha->host_no, __func__));
|
ha->host_no, __func__));
|
||||||
status = ha->isp_ops->reset_firmware(ha);
|
status = ha->isp_ops->reset_firmware(ha);
|
||||||
if (status == QLA_SUCCESS) {
|
if (status == QLA_SUCCESS) {
|
||||||
if (!test_bit(AF_FW_RECOVERY, &ha->flags))
|
|
||||||
qla4xxx_cmd_wait(ha);
|
|
||||||
|
|
||||||
ha->isp_ops->disable_intrs(ha);
|
ha->isp_ops->disable_intrs(ha);
|
||||||
qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
|
qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
|
||||||
qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
|
qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
|
||||||
|
@ -5432,6 +5425,11 @@ dpc_post_reset_ha:
|
||||||
qla4xxx_relogin_all_devices(ha);
|
qla4xxx_relogin_all_devices(ha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (test_and_clear_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags)) {
|
||||||
|
if (qla4xxx_sysfs_ddb_export(ha))
|
||||||
|
ql4_printk(KERN_ERR, ha, "%s: Error exporting ddb to sysfs\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8409,7 +8407,7 @@ exit_ddb_del:
|
||||||
*
|
*
|
||||||
* Export the firmware DDB for all send targets and normal targets to sysfs.
|
* Export the firmware DDB for all send targets and normal targets to sysfs.
|
||||||
**/
|
**/
|
||||||
static int qla4xxx_sysfs_ddb_export(struct scsi_qla_host *ha)
|
int qla4xxx_sysfs_ddb_export(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
struct dev_db_entry *fw_ddb_entry = NULL;
|
struct dev_db_entry *fw_ddb_entry = NULL;
|
||||||
dma_addr_t fw_ddb_entry_dma;
|
dma_addr_t fw_ddb_entry_dma;
|
||||||
|
@ -8847,11 +8845,8 @@ skip_retry_init:
|
||||||
ql4_printk(KERN_ERR, ha,
|
ql4_printk(KERN_ERR, ha,
|
||||||
"%s: No iSCSI boot target configured\n", __func__);
|
"%s: No iSCSI boot target configured\n", __func__);
|
||||||
|
|
||||||
if (qla4xxx_sysfs_ddb_export(ha))
|
set_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags);
|
||||||
ql4_printk(KERN_ERR, ha,
|
/* Perform the build ddb list and login to each */
|
||||||
"%s: Error exporting ddb to sysfs\n", __func__);
|
|
||||||
|
|
||||||
/* Perform the build ddb list and login to each */
|
|
||||||
qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
|
qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
|
||||||
iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
|
iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
|
||||||
qla4xxx_wait_login_resp_boot_tgt(ha);
|
qla4xxx_wait_login_resp_boot_tgt(ha);
|
||||||
|
|
|
@ -5,4 +5,4 @@
|
||||||
* See LICENSE.qla4xxx for copyright and licensing details.
|
* See LICENSE.qla4xxx for copyright and licensing details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define QLA4XXX_DRIVER_VERSION "5.04.00-k4"
|
#define QLA4XXX_DRIVER_VERSION "5.04.00-k6"
|
||||||
|
|
|
@ -130,6 +130,7 @@ static const char * scsi_debug_version_date = "20100324";
|
||||||
#define SCSI_DEBUG_OPT_DIF_ERR 32
|
#define SCSI_DEBUG_OPT_DIF_ERR 32
|
||||||
#define SCSI_DEBUG_OPT_DIX_ERR 64
|
#define SCSI_DEBUG_OPT_DIX_ERR 64
|
||||||
#define SCSI_DEBUG_OPT_MAC_TIMEOUT 128
|
#define SCSI_DEBUG_OPT_MAC_TIMEOUT 128
|
||||||
|
#define SCSI_DEBUG_OPT_SHORT_TRANSFER 256
|
||||||
/* When "every_nth" > 0 then modulo "every_nth" commands:
|
/* When "every_nth" > 0 then modulo "every_nth" commands:
|
||||||
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
|
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
|
||||||
* - a RECOVERED_ERROR is simulated on successful read and write
|
* - a RECOVERED_ERROR is simulated on successful read and write
|
||||||
|
@ -3583,6 +3584,7 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
|
||||||
int inj_transport = 0;
|
int inj_transport = 0;
|
||||||
int inj_dif = 0;
|
int inj_dif = 0;
|
||||||
int inj_dix = 0;
|
int inj_dix = 0;
|
||||||
|
int inj_short = 0;
|
||||||
int delay_override = 0;
|
int delay_override = 0;
|
||||||
int unmap = 0;
|
int unmap = 0;
|
||||||
|
|
||||||
|
@ -3628,6 +3630,8 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
|
||||||
inj_dif = 1; /* to reads and writes below */
|
inj_dif = 1; /* to reads and writes below */
|
||||||
else if (SCSI_DEBUG_OPT_DIX_ERR & scsi_debug_opts)
|
else if (SCSI_DEBUG_OPT_DIX_ERR & scsi_debug_opts)
|
||||||
inj_dix = 1; /* to reads and writes below */
|
inj_dix = 1; /* to reads and writes below */
|
||||||
|
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & scsi_debug_opts)
|
||||||
|
inj_short = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (devip->wlun) {
|
if (devip->wlun) {
|
||||||
|
@ -3744,6 +3748,10 @@ read:
|
||||||
if (scsi_debug_fake_rw)
|
if (scsi_debug_fake_rw)
|
||||||
break;
|
break;
|
||||||
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
|
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
|
||||||
|
|
||||||
|
if (inj_short)
|
||||||
|
num /= 2;
|
||||||
|
|
||||||
errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
|
errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
|
||||||
if (inj_recovered && (0 == errsts)) {
|
if (inj_recovered && (0 == errsts)) {
|
||||||
mk_sense_buffer(devip, RECOVERED_ERROR,
|
mk_sense_buffer(devip, RECOVERED_ERROR,
|
||||||
|
|
|
@ -1029,6 +1029,7 @@ retry:
|
||||||
rtn = NEEDS_RETRY;
|
rtn = NEEDS_RETRY;
|
||||||
} else {
|
} else {
|
||||||
timeleft = wait_for_completion_timeout(&done, timeout);
|
timeleft = wait_for_completion_timeout(&done, timeout);
|
||||||
|
rtn = SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
shost->eh_action = NULL;
|
shost->eh_action = NULL;
|
||||||
|
@ -2306,6 +2307,12 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
scmd = scsi_get_command(dev, GFP_KERNEL);
|
scmd = scsi_get_command(dev, GFP_KERNEL);
|
||||||
|
if (!scmd) {
|
||||||
|
rtn = FAILED;
|
||||||
|
put_device(&dev->sdev_gendev);
|
||||||
|
goto out_put_autopm_host;
|
||||||
|
}
|
||||||
|
|
||||||
blk_rq_init(NULL, &req);
|
blk_rq_init(NULL, &req);
|
||||||
scmd->request = &req;
|
scmd->request = &req;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue