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:
Linus Torvalds 2014-06-09 18:54:06 -07:00
commit 1c54fc1efe
117 changed files with 4636 additions and 2710 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2003-2013 QLogic Corporation
Copyright (c) 2003-2014 QLogic Corporation
QLogic Linux FC-FCoE Driver
This program includes a device driver for Linux 3.x.

View File

@ -4390,7 +4390,7 @@ S: Supported
F: drivers/crypto/nx/
IBM Power 842 compression accelerator
M: Robert Jennings <rcj@linux.vnet.ibm.com>
M: Nathan Fontenot <nfont@linux.vnet.ibm.com>
S: Supported
F: drivers/crypto/nx/nx-842.c
F: include/linux/nx842.h
@ -4406,12 +4406,18 @@ L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/ibm/ibmveth.*
IBM Power Virtual SCSI/FC Device Drivers
M: Robert Jennings <rcj@linux.vnet.ibm.com>
IBM Power Virtual SCSI Device Drivers
M: Nathan Fontenot <nfont@linux.vnet.ibm.com>
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/ibmvscsi/
X: drivers/scsi/ibmvscsi/ibmvstgt.c
F: drivers/scsi/ibmvscsi/ibmvscsi*
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
P: Jack Hammer
@ -6028,6 +6034,28 @@ M: Petr Vandrovec <petr@vandrovec.name>
S: Odd Fixes
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)
M: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
L: linux-scsi@vger.kernel.org

View File

@ -1037,7 +1037,7 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
goto out;
/* signature to know if this mf is freed */
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
ioc->mfcnt--;
#endif

View File

@ -2432,9 +2432,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
int rc, cim_rev;
ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
MPT_FRAME_HDR *mf = NULL;
MPIHeader_t *mpi_hdr;
unsigned long timeleft;
int retval;
u32 msgcontext;
/* 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;
mpi_hdr = (MPIHeader_t *) mf;
msgcontext = IstwiRWRequest->MsgContext;
memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
IstwiRWRequest->MsgContext = msgcontext;
IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
IstwiRWRequest->NumAddressBytes = 0x01;
IstwiRWRequest->DataLength = cpu_to_le16(0x04);

View File

@ -649,7 +649,7 @@ mptfc_slave_alloc(struct scsi_device *sdev)
}
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 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) {
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
return 0;
}
err = fc_remote_port_chkready(rport);
if (unlikely(err)) {
SCpnt->result = err;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
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);
if (unlikely(!ri)) {
SCpnt->result = DID_IMM_RETRY << 16;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
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
* @ioc: Pointer to MPT_ADAPTER structure

View File

@ -1896,7 +1896,7 @@ mptsas_slave_alloc(struct scsi_device *sdev)
}
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_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) {
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
return 0;
}
hd = shost_priv(SCpnt->device->host);
hd = shost_priv(shost);
ioc = hd->ioc;
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)
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
* if the device under question is currently in the

View File

@ -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.
* @SCpnt: Pointer to scsi_cmnd structure
* @done: Pointer SCSI mid-layer IO completion function
*
* (linux scsi_host_template.queuecommand routine)
* 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)
*/
int
mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
mptscsih_qcmd(struct scsi_cmnd *SCpnt)
{
MPT_SCSI_HOST *hd;
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);
ioc = hd->ioc;
SCpnt->scsi_done = done;
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
ioc->name, SCpnt, done));
dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
ioc->name, SCpnt));
if (ioc->taskmgmt_quiesce_io)
return SCSI_MLQUEUE_HOST_BUSY;

View File

@ -113,7 +113,7 @@ extern int mptscsih_resume(struct pci_dev *pdev);
#endif
extern int mptscsih_show_info(struct seq_file *, struct Scsi_Host *);
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,
u8 id, int lun, int ctx2abort, ulong timeout);
extern void mptscsih_slave_destroy(struct scsi_device *device);

View File

@ -780,33 +780,31 @@ static int mptspi_slave_configure(struct scsi_device *sdev)
}
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;
MPT_ADAPTER *ioc = hd->ioc;
if (!vdevice || !vdevice->vtarget) {
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
return 0;
}
if (SCpnt->device->channel == 1 &&
mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) {
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
SCpnt->scsi_done(SCpnt);
return 0;
}
if (spi_dv_pending(scsi_target(SCpnt->device)))
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)
{
struct scsi_target *starget = scsi_target(sdev);

View File

@ -27,8 +27,6 @@
*/
/*
* $Log: NCR5380.c,v $
* Revision 1.10 1998/9/2 Alan Cox
* (alan@lxorguk.ukuu.org.uk)
* Fixed up the timer lockups reported so far. Things still suck. Looking
@ -89,13 +87,6 @@
#include <scsi/scsi_dbg.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)
#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); }
@ -1005,7 +996,7 @@ static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)
LIST(cmd, tmp);
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. */
/* Kick off command processing */
@ -1040,7 +1031,7 @@ static void NCR5380_main(struct work_struct *work)
/* Lock held here */
done = 1;
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
* 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)
{
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. */
if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) {
if (prev) {
@ -1066,7 +1057,7 @@ static void NCR5380_main(struct work_struct *work)
* On failure, we must add the command back to the
* 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
@ -1095,7 +1086,7 @@ static void NCR5380_main(struct work_struct *work)
tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = tmp;
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 */
} /* if target/lun is not busy */
@ -1125,9 +1116,9 @@ static void NCR5380_main(struct work_struct *work)
#endif
&& (!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);
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;
} else
break;
@ -1159,8 +1150,8 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
unsigned char basr;
unsigned long flags;
dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n",
instance->irq));
dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n",
instance->irq);
do {
done = 1;
@ -1173,14 +1164,14 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
NCR5380_dprint(NDEBUG_INTR, instance);
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
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);
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
} 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);
} 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);
} else {
#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);
}
#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);
#endif
}
@ -1304,7 +1295,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
hostdata->restart_select = 0;
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
@ -1333,7 +1324,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
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
@ -1347,7 +1338,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
/* 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)) {
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;
}
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_write(MODE_REG, MR_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;
}
/*
@ -1370,7 +1361,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
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
@ -1422,7 +1413,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag)
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
@ -1487,7 +1478,7 @@ part2:
collect_stats(hostdata, cmd);
cmd->scsi_done(cmd);
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);
return 0;
}
@ -1520,7 +1511,7 @@ part2:
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);
len = 1;
@ -1530,7 +1521,7 @@ part2:
data = tmp;
phase = PHASE_MSGOUT;
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 */
hostdata->connected = cmd;
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);
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
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
@ -1620,11 +1611,11 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
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 */
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);
break;
}
@ -1660,7 +1651,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
/* FIXME - if this fails bus reset ?? */
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 :
@ -1681,7 +1672,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
}
} 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;
*data = d;
@ -1828,7 +1819,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
c -= 2;
}
#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);
#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);
#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.
@ -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(INITIATOR_COMMAND_REG, ICR_BASE);
@ -1948,7 +1939,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
#ifdef READ_OVERRUNS
if (*phase == p && (p & SR_IO) && residue == 0) {
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 += 1;
*count -= 1;
@ -1957,13 +1948,13 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
printk("No overrun??\n");
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);
*count -= toPIO - cnt;
}
#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;
#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);
#else
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))) {
/*
* 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));
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) {
hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
if (NCR5380_read(TARGET_COMMAND_REG) & TCR_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 {
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));
dprintk(NDEBUG_C400_PWRITE, ("Got LASTBYTE\n"));
dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n");
}
}
#endif
@ -2045,9 +2036,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
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) {
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);
} else {
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.this_residual = cmd->SCp.buffer->length;
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
@ -2219,7 +2210,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
case LINKED_FLG_CMD_COMPLETE:
/* Accept message by clearing ACK */
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
* 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 */
cmd->next_link->tag = cmd->tag;
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);
cmd->scsi_done(cmd);
cmd = hostdata->connected;
@ -2247,7 +2238,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
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);
/*
@ -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)) {
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);
cmd->host_scribble = (unsigned char *)
hostdata->issue_queue;
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
#endif /* def AUTOSENSE */
{
@ -2327,7 +2318,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
hostdata->disconnected_queue;
hostdata->connected = NULL;
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,
* arbitration can resume.
@ -2373,14 +2364,14 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
extended_msg[0] = EXTENDED_MESSAGE;
/* Accept first byte by clearing ACK */
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;
data = extended_msg + 1;
phase = PHASE_MSGIN;
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)) {
/* Accept third byte by clearing ACK */
@ -2390,7 +2381,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
phase = PHASE_MSGIN;
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]) {
case EXTENDED_SDTR:
@ -2456,7 +2447,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {
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;
}
break;
@ -2468,7 +2459,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
break;
default:
printk("scsi%d : unknown phase\n", instance->host_no);
NCR5380_dprint(NDEBUG_ALL, instance);
NCR5380_dprint(NDEBUG_ANY, instance);
} /* switch(phase) */
} /* if (tmp * SR_REQ) */
else {
@ -2476,7 +2467,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
*/
if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {
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;
}
}
@ -2517,7 +2508,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
hostdata->restart_select = 1;
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,
@ -2597,7 +2588,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
do_abort(instance);
} else {
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);
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, "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));
#if 0
/*
@ -2693,7 +2684,7 @@ static int NCR5380_abort(Scsi_Cmnd * 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;
/*
* 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.
*/
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)
if (cmd == tmp) {
REMOVE(5, *prev, tmp, tmp->host_scribble);
(*prev) = (Scsi_Cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
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);
return SUCCESS;
}
@ -2750,7 +2741,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
*/
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;
}
/*
@ -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)
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))
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);

View File

@ -21,10 +21,6 @@
* 1+ (800) 334-5454
*/
/*
* $Log: NCR5380.h,v $
*/
#ifndef NCR5380_H
#define NCR5380_H
@ -60,6 +56,9 @@
#define NDEBUG_C400_PREAD 0x100000
#define NDEBUG_C400_PWRITE 0x200000
#define NDEBUG_LISTS 0x400000
#define NDEBUG_ABORT 0x800000
#define NDEBUG_TAGS 0x1000000
#define NDEBUG_MERGING 0x2000000
#define NDEBUG_ANY 0xFFFFFFFFUL
@ -292,9 +291,24 @@ struct NCR5380_hostdata {
#ifdef __KERNEL__
#define dprintk(a,b) do {} while(0)
#define NCR5380_dprint(a,b) do {} while(0)
#define NCR5380_dprint_phase(a,b) do {} while(0)
#ifndef NDEBUG
#define NDEBUG (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)
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
static void NCR5380_main(struct work_struct *work);
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_bus_reset(Scsi_Cmnd * cmd);
static int NCR5380_queue_command(struct Scsi_Host *, struct scsi_cmnd *);

View File

@ -827,7 +827,7 @@ ahd_pci_intr(struct ahd_softc *ahd)
for (bit = 0; bit < 8; bit++) {
if ((pci_status[i] & (0x1 << bit)) != 0) {
static const char *s;
const char *s;
s = pci_status_strings[bit];
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++) {
if ((split_status[i] & (0x1 << bit)) != 0) {
static const char *s;
s = split_status_strings[bit];
printk(s, ahd_name(ahd),
if ((split_status[i] & (0x1 << bit)) != 0)
printk(split_status_strings[bit], ahd_name(ahd),
split_status_source[i]);
}
if (i > 1)
continue;
if ((sg_split_status[i] & (0x1 << bit)) != 0) {
static const char *s;
s = split_status_strings[bit];
printk(s, ahd_name(ahd), "SG");
}
if ((sg_split_status[i] & (0x1 << bit)) != 0)
printk(split_status_strings[bit], ahd_name(ahd), "SG");
}
}
/*

View File

@ -61,13 +61,6 @@
* comment out the undef.
*/
#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.
*
@ -160,10 +153,6 @@
#error "Yippee! ABORT TAG is now defined! Remove this error!"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
#error SCSI2 LINKed commands not supported (yet)!
#endif
#ifdef USE_DMAC
/*
* DMAC setup parameters
@ -1668,42 +1657,6 @@ void acornscsi_message(AS_Host *host)
}
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 */
printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n",
host->host->host_no, acornscsi_target(host),
@ -2825,9 +2778,6 @@ char *acornscsi_info(struct Scsi_Host *host)
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
" TAG"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
" NOWRITE (" __stringify(NO_WRITE) ")"
#endif
@ -2851,9 +2801,6 @@ static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance)
#ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE
" TAG"
#endif
#ifdef CONFIG_SCSI_ACORNSCSI_LINK
" LINK"
#endif
#if (DEBUG & DEBUG_NO_WRITE)
" NOWRITE (" __stringify(NO_WRITE) ")"
#endif

View File

@ -36,9 +36,6 @@
void __iomem *base; \
void __iomem *dma
#define BOARD_NORMAL 0
#define BOARD_NCR53C400 1
#include "../NCR5380.h"
void cumanascsi_setup(char *str, int *ints)

View File

@ -37,9 +37,6 @@
#define NCR5380_implementation_fields \
void __iomem *base
#define BOARD_NORMAL 0
#define BOARD_NCR53C400 1
#include "../NCR5380.h"
#undef START_DMA_INITIATOR_RECEIVE_REG

View File

@ -370,7 +370,7 @@ static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged)
return 0;
if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
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);
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) {
cmd->tag = TAG_NONE;
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);
} else {
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);
set_bit(cmd->tag, ta->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",
H_NO(cmd), cmd->tag, cmd->device->id,
cmd->device->lun, ta->nr_allocated);
@ -420,7 +420,7 @@ static void cmd_free_tag(Scsi_Cmnd *cmd)
if (cmd->tag == TAG_NONE) {
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);
} else if (cmd->tag >= MAX_TAGS) {
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];
clear_bit(cmd->tag, ta->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);
}
}
@ -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;
cmd->SCp.buffers_residual &&
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);
#if (NDEBUG & NDEBUG_MERGING)
++cnt;
@ -490,7 +490,7 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
}
#if (NDEBUG & NDEBUG_MERGING)
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);
#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
/*
@ -676,7 +666,7 @@ static inline void NCR5380_all_init(void)
{
static int done = 0;
if (!done) {
INI_PRINTK("scsi : NCR5380_all_init()\n");
dprintk(NDEBUG_INIT, "scsi : NCR5380_all_init()\n");
done = 1;
}
}
@ -739,8 +729,8 @@ static void NCR5380_print_status(struct Scsi_Host *instance)
Scsi_Cmnd *ptr;
unsigned long flags;
NCR_PRINT(NDEBUG_ANY);
NCR_PRINT_PHASE(NDEBUG_ANY);
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
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);
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");
/* 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;
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
* 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
* 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",
HOSTNO, tmp->device->id, tmp->device->lun);
/*
@ -1140,7 +1130,7 @@ static void NCR5380_main(struct work_struct *work)
#endif
falcon_dont_release--;
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);
if (hostdata->connected)
break;
@ -1155,10 +1145,10 @@ static void NCR5380_main(struct work_struct *work)
#endif
) {
local_irq_restore(flags);
MAIN_PRINTK("scsi%d: main: performing information transfer\n",
dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
HOSTNO);
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;
}
} while (!done);
@ -1204,12 +1194,12 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
(BASR_PHASE_MATCH|BASR_ACK)) {
saved_data = NCR5380_read(INPUT_DATA_REG);
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),
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)) {
cnt = toPIO = atari_read_overruns;
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;
(*count)--;
cnt--;
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);
*count -= toPIO - cnt;
}
@ -1261,25 +1251,25 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
int done = 1, handled = 0;
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 */
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 */
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)) {
done = 0;
ENABLE_IRQ();
INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO);
NCR5380_reselect(instance);
(void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
} 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);
} 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);
} else {
/*
@ -1298,7 +1288,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
((basr & BASR_END_DMA_TRANSFER) ||
!(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 );
done = 0;
ENABLE_IRQ();
@ -1323,7 +1313,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
}
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... */
queue_main();
}
@ -1396,8 +1386,8 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
unsigned long flags;
hostdata->restart_select = 0;
NCR_PRINT(NDEBUG_ARBITRATION);
ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO,
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
instance->this_id);
/*
@ -1442,7 +1432,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
;
#endif
ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO);
dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
if (hostdata->connected) {
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) ||
hostdata->connected) {
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);
return -1;
}
@ -1478,7 +1468,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
hostdata->connected) {
NCR5380_write(MODE_REG, MR_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);
return -1;
}
@ -1501,7 +1491,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
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
@ -1561,7 +1551,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
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
@ -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);
if (hostdata->restart_select)
printk(KERN_NOTICE "\trestart select\n");
NCR_PRINT(NDEBUG_ANY);
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
@ -1630,7 +1620,7 @@ static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
#endif
cmd->scsi_done(cmd);
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);
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))
;
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);
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;
phase = PHASE_MSGOUT;
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 */
hostdata->connected = cmd;
#ifndef SUPPORT_TAGS
@ -1737,12 +1727,12 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
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 */
if ((tmp & PHASE_MASK) != p) {
PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO);
NCR_PRINT_PHASE(NDEBUG_PIO);
dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
NCR5380_dprint_phase(NDEBUG_PIO, instance);
break;
}
@ -1764,25 +1754,25 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
if (!(p & SR_IO)) {
if (!((p & SR_MSG) && c > 1)) {
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 |
ICR_ASSERT_DATA | ICR_ASSERT_ACK);
} else {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
ICR_ASSERT_DATA | ICR_ASSERT_ATN);
NCR_PRINT(NDEBUG_PIO);
NCR5380_dprint(NDEBUG_PIO, instance);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
}
} else {
NCR_PRINT(NDEBUG_PIO);
NCR5380_dprint(NDEBUG_PIO, instance);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
}
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 :
@ -1803,7 +1793,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance,
}
} while (--c);
PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c);
dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
*count = c;
*data = d;
@ -1917,7 +1907,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
if (atari_read_overruns && (p & SR_IO))
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",
c, (p & SR_IO) ? "to" : "from", d);
@ -1997,7 +1987,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
phase = (tmp & PHASE_MASK);
if (phase != old_phase) {
old_phase = phase;
NCR_PRINT_PHASE(NDEBUG_INFORMATION);
NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);
}
if (sink && (phase != PHASE_MSGOUT)) {
@ -2039,7 +2029,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
* they are at contiguous physical addresses.
*/
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,
cmd->SCp.buffers_residual);
}
@ -2123,7 +2113,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* Accept message by clearing ACK */
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);
/* Enable reselect interrupts */
@ -2148,7 +2138,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
* and don't free it! */
cmd->next_link->tag = cmd->tag;
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",
HOSTNO, cmd->device->id, cmd->device->lun);
#ifdef NCR5380_STATS
@ -2165,7 +2155,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* ++guenther: possible race with Falcon locking */
falcon_dont_release++;
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);
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
@ -2179,7 +2169,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* ++Andreas: the mid level code knows about
QUEUE_FULL now. */
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",
HOSTNO, cmd->device->id, cmd->device->lun,
ta->nr_allocated);
@ -2224,14 +2214,14 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
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);
LIST(cmd,hostdata->issue_queue);
SET_NEXT(cmd, hostdata->issue_queue);
hostdata->issue_queue = (Scsi_Cmnd *) cmd;
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));
} else
#endif /* def AUTOSENSE */
@ -2277,7 +2267,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
cmd->device->tagged_supported = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
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 "
"disabled\n",
HOSTNO, cmd->device->id, cmd->device->lun);
@ -2294,7 +2284,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
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 "
"disconnected_queue\n", HOSTNO,
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 */
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;
data = extended_msg + 1;
phase = PHASE_MSGIN;
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]);
if (!len && extended_msg[1] <=
@ -2362,7 +2352,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
phase = PHASE_MSGIN;
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);
switch (extended_msg[2]) {
@ -2451,7 +2441,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
break;
default:
printk("scsi%d: unknown phase\n", HOSTNO);
NCR_PRINT(NDEBUG_ANY);
NCR5380_dprint(NDEBUG_ANY, instance);
} /* switch(phase) */
} /* if (tmp * SR_REQ) */
} /* 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);
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,
@ -2544,7 +2534,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
msg[1] == SIMPLE_QUEUE_TAG)
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);
}
#endif
@ -2598,7 +2588,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
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);
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",
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(STATUS_REG));
@ -2653,7 +2643,7 @@ int NCR5380_abort(Scsi_Cmnd *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
* into BUS FREE.
@ -2683,11 +2673,11 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
local_irq_restore(flags);
cmd->scsi_done(cmd);
falcon_release_lock_if_possible(hostdata);
return SCSI_ABORT_SUCCESS;
return SUCCESS;
} else {
/* local_irq_restore(flags); */
printk("scsi%d: abort of connected command failed!\n", HOSTNO);
return SCSI_ABORT_ERROR;
return FAILED;
}
}
#endif
@ -2705,13 +2695,13 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
SET_NEXT(tmp, NULL);
tmp->result = DID_ABORT << 16;
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);
/* Tagged queuing note: no tag to free here, hasn't been assigned
* yet... */
tmp->scsi_done(tmp);
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) {
local_irq_restore(flags);
ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
return SCSI_ABORT_SNOOZE;
dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
return FAILED;
}
/*
@ -2761,12 +2751,12 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
tmp = NEXT(tmp)) {
if (cmd == tmp) {
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))
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);
@ -2791,7 +2781,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
local_irq_restore(flags);
tmp->scsi_done(tmp);
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);
return SCSI_ABORT_NOT_RUNNING;
return FAILED;
}
@ -2825,7 +2815,7 @@ int NCR5380_abort(Scsi_Cmnd *cmd)
*
* 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);
int i;
unsigned long flags;
#if 1
#if defined(RESET_RUN_DONE)
Scsi_Cmnd *connected, *disconnected_queue;
#endif
@ -2859,7 +2849,14 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
* through anymore ... */
(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 */
/* 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)) {
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->scsi_done(cmd);
}
@ -2902,7 +2899,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
cmd->scsi_done(cmd);
}
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...
*/
@ -2915,7 +2912,7 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
* the midlevel code that the reset was SUCCESSFUL, and there is no
* need to 'wake up' the commands by a request_sense
*/
return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
return SUCCESS;
#else /* 1 */
/* 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)
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)
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)
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);
hostdata->issue_queue = NULL;
@ -2963,6 +2960,6 @@ static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
local_irq_restore(flags);
/* 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 */
}

View File

@ -67,12 +67,6 @@
#include <linux/module.h>
#define NDEBUG (0)
#define NDEBUG_ABORT 0x00100000
#define NDEBUG_TAGS 0x00200000
#define NDEBUG_MERGING 0x00400000
#define AUTOSENSE
/* For the Atari version, use only polled IO or 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;
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);
/* 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)) {
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);
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.
*/
if (atari_dma_residual & 0x1ff) {
DMA_PRINTK("SCSI DMA: DMA bug corrected, "
dprintk(NDEBUG_DMA, "SCSI DMA: DMA bug corrected, "
"difference %ld bytes\n",
512 - (atari_dma_residual & 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);
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);
} else
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
before the DMA pointer */
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);
/* The content of the DMA pointer is a physical address! */
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)
*dst++ = *src++;
}
@ -827,7 +821,7 @@ static int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
} else {
atari_turnon_irq(IRQ_MFP_FSCSI);
}
if ((rv & SCSI_RESET_ACTION) == SCSI_RESET_SUCCESS)
if (rv == SUCCESS)
falcon_release_lock_if_possible(hostdata);
return rv;
@ -883,7 +877,7 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
{
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);
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;
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);
return possible_len;

View File

@ -54,125 +54,6 @@
#define NCR5380_dma_xfer_len(i,cmd,phase) \
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 /* ATARI_SCSI_H */

View File

@ -83,9 +83,20 @@ static inline void queue_tail_inc(struct be_queue_info *q)
/*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 {
bool todo_mcc_cq;
bool todo_cq;
u32 cq_count;
struct be_queue_info q;
struct beiscsi_hba *phba;
struct be_queue_info *cq;

View File

@ -71,6 +71,7 @@ struct be_mcc_wrb {
#define BEISCSI_FW_MBX_TIMEOUT 100
/* MBOX Command VER */
#define MBX_CMD_VER1 0x01
#define MBX_CMD_VER2 0x02
struct be_mcc_compl {
@ -271,6 +272,12 @@ struct be_cmd_resp_eq_create {
u16 rsvd0; /* sword */
} __packed;
struct be_set_eqd {
u32 eq_id;
u32 phase;
u32 delay_multiplier;
} __packed;
struct mgmt_chap_format {
u32 flags;
u8 intr_chap_name[256];
@ -622,7 +629,7 @@ struct be_cmd_req_modify_eq_delay {
u32 eq_id;
u32 phase;
u32 delay_multiplier;
} delay[8];
} delay[MAX_CPUS];
} __packed;
/******************** 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);
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
int num);
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb,
struct be_dma_mem *mbx_cmd_mem);
@ -1005,6 +1014,26 @@ struct tcp_connect_and_offload_in {
u8 rsvd0[3];
} __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 be_cmd_resp_hdr hdr;
u32 connection_handle;

View File

@ -1106,7 +1106,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
struct beiscsi_hba *phba = beiscsi_ep->phba;
struct tcp_connect_and_offload_out *ptcpcnct_out;
struct be_dma_mem nonemb_cmd;
unsigned int tag;
unsigned int tag, req_memsize;
int ret = -ENOMEM;
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->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,
sizeof(struct tcp_connect_and_offload_in),
req_memsize,
&nonemb_cmd.dma);
if (nonemb_cmd.va == NULL) {
@ -1139,7 +1145,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
beiscsi_free_ep(beiscsi_ep);
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);
tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
if (tag <= 0) {

View File

@ -599,15 +599,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
pci_set_drvdata(pcidev, phba);
phba->interface_handle = 0xFFFFFFFF;
if (iscsi_host_add(shost, &phba->pcidev->dev))
goto free_devices;
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)
@ -2279,6 +2271,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
ret = beiscsi_process_cq(pbe_eq);
pbe_eq->cq_count += ret;
if (ret < budget) {
phba = pbe_eq->phba;
blk_iopoll_complete(iop);
@ -3692,7 +3685,7 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
struct hwi_controller *phwi_ctrlr;
struct hwi_context_memory *phwi_context;
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_context = phwi_ctrlr->phwi_ctxt;
@ -3729,16 +3722,17 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
if (q->created)
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
}
be_mcc_queues_destroy(phba);
if (phba->msix_enabled)
eq_num = 1;
eq_for_mcc = 1;
else
eq_num = 0;
for (i = 0; i < (phba->num_cpus + eq_num); i++) {
eq_for_mcc = 0;
for (i = 0; i < (phba->num_cpus + eq_for_mcc); i++) {
q = &phwi_context->be_eq[i].q;
if (q->created)
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
}
be_mcc_queues_destroy(phba);
be_cmd_fw_uninit(ctrl);
}
@ -3833,9 +3827,9 @@ static int hwi_init_port(struct beiscsi_hba *phba)
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
phwi_context->max_eqd = 0;
phwi_context->max_eqd = 128;
phwi_context->min_eqd = 0;
phwi_context->cur_eqd = 64;
phwi_context->cur_eqd = 0;
be_cmd_fw_initialize(&phba->ctrl);
status = beiscsi_create_eqs(phba, phwi_context);
@ -5290,6 +5284,57 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
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
* @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,
beiscsi_hw_check_task.work);
be_eqd_update(phba);
beiscsi_ue_detect(phba);
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_tag_available++;
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;
@ -5621,6 +5668,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
}
hwi_enable_intr(phba);
if (iscsi_host_add(phba->shost, &phba->pcidev->dev))
goto free_blkenbld;
if (beiscsi_setup_boot_info(phba))
/*
* log error but continue, because we may not be using

View File

@ -36,7 +36,7 @@
#include <scsi/scsi_transport_iscsi.h>
#define DRV_NAME "be2iscsi"
#define BUILD_STR "10.2.125.0"
#define BUILD_STR "10.2.273.0"
#define BE_NAME "Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver"
@ -71,8 +71,8 @@
#define BEISCSI_SGLIST_ELEMENTS 30
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */
#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
#define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
#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 invalidate_command_table inv_tbl[128];
struct be_aic_obj aic_obj[MAX_CPUS];
unsigned int attr_log_enable;
int (*iotask_fn)(struct iscsi_task *,
struct scatterlist *sg,

View File

@ -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
* @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_cmd_resp_hdr *resp;
struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
struct be_sge *mcc_sge = nonembedded_sgl(wrb);
struct be_mcc_wrb *wrb;
struct be_sge *mcc_sge;
unsigned int tag = 0;
struct iscsi_bsg_request *bsg_req = job->request;
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->offset = offset;
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
case BEISCSI_WRITE_FLASH:
@ -495,6 +531,8 @@ unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
return tag;
}
wrb = wrb_from_mccq(phba);
mcc_sge = nonembedded_sgl(wrb);
be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
job->request_payload.sg_cnt);
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;
spin_lock(&ctrl->mbox_lock);
memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
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 be_ctrl_info *ctrl = &phba->ctrl;
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_data_id;
struct phys_addr template_address = { 0, 0 };
@ -702,17 +739,16 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
return tag;
}
wrb = wrb_from_mccq(phba);
memset(wrb, 0, sizeof(*wrb));
sge = nonembedded_sgl(wrb);
req = nonemb_cmd->va;
memset(req, 0, sizeof(*req));
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,
OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
sizeof(*req));
nonemb_cmd->size);
if (dst_addr->sa_family == PF_INET) {
__be32 s_addr = daddr_in->sin_addr.s_addr;
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_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
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);
spin_unlock(&ctrl->mbox_lock);
return tag;
@ -804,7 +847,7 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
int resp_buf_len)
{
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;
unsigned int tag;
int rc = 0;
@ -816,7 +859,8 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
rc = -ENOMEM;
goto free_cmd;
}
memset(wrb, 0, sizeof(*wrb));
wrb = wrb_from_mccq(phba);
wrb->tag0 |= tag;
sge = nonembedded_sgl(wrb);

View File

@ -335,5 +335,7 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle);
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

View File

@ -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;
int rc;
vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
vport = kzalloc(sizeof(struct bfad_vport_s), GFP_ATOMIC);
if (!vport) {
bfa_trc(bfad, 0);
return;

View File

@ -1966,26 +1966,29 @@ static void bnx2fc_free_hash_table(struct bnx2fc_hba *hba)
{
int i;
int segment_count;
int hash_table_size;
u32 *pbl;
segment_count = hba->hash_tbl_segment_count;
hash_table_size = BNX2FC_NUM_MAX_SESS * BNX2FC_MAX_ROWS_IN_HASH_TBL *
sizeof(struct fcoe_hash_table_entry);
if (hba->hash_tbl_segments) {
pbl = hba->hash_tbl_pbl;
for (i = 0; i < segment_count; ++i) {
dma_addr_t dma_address;
pbl = hba->hash_tbl_pbl;
if (pbl) {
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);
++pbl;
dma_address += ((u64)le32_to_cpu(*pbl)) << 32;
++pbl;
dma_free_coherent(&hba->pcidev->dev,
BNX2FC_HASH_TBL_CHUNK_SIZE,
hba->hash_tbl_segments[i],
dma_address);
dma_address = le32_to_cpu(*pbl);
++pbl;
dma_address += ((u64)le32_to_cpu(*pbl)) << 32;
++pbl;
dma_free_coherent(&hba->pcidev->dev,
BNX2FC_HASH_TBL_CHUNK_SIZE,
hba->hash_tbl_segments[i],
dma_address);
}
}
kfree(hba->hash_tbl_segments);
hba->hash_tbl_segments = NULL;
}
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);
if (!dma_segment_array) {
printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
return -ENOMEM;
goto cleanup_ht;
}
for (i = 0; i < segment_count; ++i) {
@ -2034,15 +2037,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
GFP_KERNEL);
if (!hba->hash_tbl_segments[i]) {
printk(KERN_ERR PFX "hash segment alloc failed\n");
while (--i >= 0) {
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;
goto cleanup_dma;
}
memset(hba->hash_tbl_segments[i], 0,
BNX2FC_HASH_TBL_CHUNK_SIZE);
@ -2054,8 +2049,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
GFP_KERNEL);
if (!hba->hash_tbl_pbl) {
printk(KERN_ERR PFX "hash table pbl alloc failed\n");
kfree(dma_segment_array);
return -ENOMEM;
goto cleanup_dma;
}
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);
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;
}
/**

View File

@ -3,8 +3,6 @@
#define PSEUDO_DMA
#define DONT_USE_INTR
#define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
#define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
NDEBUG_SELECTION+NDEBUG_ARBITRATION)
#define DMA_WORKS_RIGHT

View File

@ -390,7 +390,7 @@ static int esas2r_probe(struct pci_dev *pcid,
esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev),
"pci_enable_device() OK");
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);
host = scsi_host_alloc(&driver_template, host_alloc_size);

View File

@ -39,14 +39,15 @@
#define DRV_NAME "fnic"
#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 DFX DRV_NAME "%d: "
#define DESC_CLEAN_LOW_WATERMARK 8
#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD 16 /* UCSM default 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_DFLT_QUEUE_DEPTH 32
#define FNIC_STATS_RATE_LIMIT 4 /* limit rate at which stats are pulled up */

View File

@ -25,6 +25,21 @@ static struct dentry *fnic_trace_debugfs_file;
static struct dentry *fnic_trace_enable;
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
*
@ -56,6 +71,18 @@ int fnic_debugfs_init(void)
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;
return rc;
}
@ -74,15 +101,19 @@ void fnic_debugfs_terminate(void)
debugfs_remove(fnic_trace_debugfs_root);
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.
* @file: The file pointer to attach the trace enable/disable flag.
*
* Description:
* This routine opens a debugsfs file trace_enable.
* This routine opens a debugsfs file trace_enable or fc_trace_enable.
*
* Returns:
* 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.
* @ubuf: The buffer to copy the data to.
* @cnt: The number of bytes to read.
* @ppos: The position in the file to start reading from.
*
* Description:
* This routine reads value of variable fnic_tracing_enabled
* and stores into local @buf. It will start reading file at @ppos and
* This routine reads value of variable fnic_tracing_enabled or
* 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.
*
* Returns:
@ -114,13 +149,25 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
{
char buf[64];
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);
}
/*
* 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.
* @ubuf: The buffer to copy the data from.
* @cnt: The number of bytes to write.
@ -128,7 +175,8 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
*
* Description:
* 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:
* 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];
unsigned long val;
int ret;
u8 *trace_type;
trace_type = (u8 *)filp->private_data;
if (cnt >= sizeof(buf))
return -EINVAL;
@ -153,12 +203,27 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
if (ret < 0)
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)++;
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
* @inode: The inode pointer
@ -178,19 +243,36 @@ static int fnic_trace_debugfs_open(struct inode *inode,
struct file *file)
{
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);
if (!fnic_dbg_prt)
return -ENOMEM;
fnic_dbg_prt->buffer = vmalloc((3*(trace_max_pages * PAGE_SIZE)));
if (!fnic_dbg_prt->buffer) {
kfree(fnic_dbg_prt);
return -ENOMEM;
if (*rdata_ptr == fc_trc_flag->fnic_trace) {
fnic_dbg_prt->buffer = vmalloc(3 *
(trace_max_pages * PAGE_SIZE));
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;
return 0;
}
@ -272,13 +354,6 @@ static int fnic_trace_debugfs_release(struct inode *inode,
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 = {
.owner = THIS_MODULE,
.open = fnic_trace_debugfs_open,
@ -306,9 +381,10 @@ int fnic_trace_debugfs_init(void)
return rc;
}
fnic_trace_enable = debugfs_create_file("tracing_enable",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
NULL, &fnic_trace_ctrl_fops);
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fnic_trace),
&fnic_trace_ctrl_fops);
if (!fnic_trace_enable) {
printk(KERN_DEBUG
@ -317,10 +393,10 @@ int fnic_trace_debugfs_init(void)
}
fnic_trace_debugfs_file = debugfs_create_file("trace",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
NULL,
&fnic_trace_debugfs_fops);
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fnic_trace),
&fnic_trace_debugfs_fops);
if (!fnic_trace_debugfs_file) {
printk(KERN_DEBUG
@ -340,14 +416,104 @@ int fnic_trace_debugfs_init(void)
*/
void fnic_trace_debugfs_terminate(void)
{
if (fnic_trace_debugfs_file) {
debugfs_remove(fnic_trace_debugfs_file);
fnic_trace_debugfs_file = NULL;
debugfs_remove(fnic_trace_debugfs_file);
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_trace_enable = NULL;
fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
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;
}
/*

View File

@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work)
fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
if (old_link_status == fnic->link_status) {
if (!fnic->link_status)
if (!fnic->link_status) {
/* DOWN -> DOWN */
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) {
/* UP -> DOWN -> UP */
fnic->lport->host_stats.link_failure_count++;
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,
"link down\n");
fcoe_ctlr_link_down(&fnic->ctlr);
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* 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);
return;
}
@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work)
} else
/* UP -> UP */
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) {
/* DOWN -> UP */
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* 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);
return;
}
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);
} else {
/* UP -> DOWN */
fnic->lport->host_stats.link_failure_count++;
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
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);
}
@ -267,11 +297,6 @@ static inline int is_fnic_fip_flogi_reject(struct fcoe_ctlr *fip,
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)
return 0;
@ -616,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
"using UCSM\n");
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);
queue_work(fnic_fip_queue, &fnic->fip_frame_work);
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;
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);
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_encapsulated_proto = eth_hdr->h_proto;
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);
@ -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);
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);
if (!vnic_wq_desc_avail(wq)) {

View File

@ -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 "
"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;
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
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,
.this_id = -1,
.cmd_per_lun = 3,
.can_queue = FNIC_MAX_IO_REQ,
.can_queue = FNIC_DFLT_IO_REQ,
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = FNIC_MAX_SG_DESC_CNT,
.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,
"firmware uses non-FIP mode\n");
fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_NON_FIP);
fnic->ctlr.state = FIP_ST_NON_FIP;
}
fnic->state = FNIC_IN_FC_MODE;
@ -1033,11 +1039,20 @@ static int __init fnic_init_module(void)
/* Allocate memory for trace buffer */
err = fnic_trace_buf_init();
if (err < 0) {
printk(KERN_ERR PFX "Trace buffer initialization Failed "
"Fnic Tracing utility is disabled\n");
printk(KERN_ERR PFX
"Trace buffer initialization Failed. "
"Fnic Tracing utility is disabled\n");
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 */
len = sizeof(struct fnic_dflt_sgl_list);
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]);
err_create_fnic_sgl_slab_dflt:
fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate();
return err;
}
@ -1135,6 +1151,7 @@ static void __exit fnic_cleanup_module(void)
kmem_cache_destroy(fnic_io_req_cache);
fc_release_transport(fnic_fc_transport);
fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate();
}

View File

@ -1312,8 +1312,9 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
cleanup_scsi_cmd:
sc->result = DID_TRANSPORT_DISRUPTED << 16;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io:"
" DID_TRANSPORT_DISRUPTED\n");
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"%s: sc duration = %lu DID_TRANSPORT_DISRUPTED\n",
__func__, (jiffies - start_time));
if (atomic64_read(&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 abort_stats *abts_stats;
struct terminate_stats *term_stats;
enum fnic_ioreq_state old_ioreq_state;
int tag;
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
* has already started.
*/
old_ioreq_state = CMD_STATE(sc);
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
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,
fc_lun.scsi_lun, io_req)) {
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);
if (io_req)
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) {
spin_unlock_irqrestore(io_lock, flags);
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);
} else {
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"Terminate Driver Timeout\n");
atomic64_inc(&term_stats->terminate_drv_timeouts);
}
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;

View File

@ -20,6 +20,7 @@
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/kallsyms.h>
#include <linux/time.h>
#include "fnic_io.h"
#include "fnic.h"
@ -32,6 +33,16 @@ static DEFINE_SPINLOCK(fnic_trace_lock);
static fnic_trace_dbg_t fnic_trace_entries;
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
*
@ -428,10 +439,10 @@ int fnic_trace_buf_init(void)
}
err = fnic_trace_debugfs_init();
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;
}
printk(KERN_INFO PFX "Successfully Initialized Trace Buffer\n");
pr_info("fnic: Successfully Initialized Trace Buffer\n");
return err;
err_fnic_trace_debugfs_init:
fnic_trace_free();
@ -456,3 +467,314 @@ void fnic_trace_free(void)
}
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;
}

View File

@ -19,6 +19,17 @@
#define __FNIC_TRACE_H__
#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,
size_t count,
@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages;
extern int fnic_tracing_enabled;
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 {
int wr_idx;
int rd_idx;
@ -56,6 +71,16 @@ struct fnic_trace_data {
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 \
(FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
@ -88,4 +113,17 @@ int fnic_debugfs_init(void);
void fnic_debugfs_terminate(void);
int fnic_trace_debugfs_init(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

View File

@ -78,10 +78,6 @@
*
*/
/*
* $Log: generic_NCR5380.c,v $
*/
/* settings for DTC3181E card with only Mustek scanner attached */
#define USLEEP
#define USLEEP_POLL 1

View File

@ -25,10 +25,6 @@
* 1+ (800) 334-5454
*/
/*
* $Log: generic_NCR5380.h,v $
*/
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H
@ -58,8 +54,6 @@ static const char* generic_NCR5380_info(struct Scsi_Host *);
#define CAN_QUEUE 16
#endif
#ifndef HOSTS_C
#define __STRVAL(x) #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_DTC3181E 3
#endif /* else def HOSTS_C */
#endif /* ndef ASM */
#endif /* GENERIC_NCR5380_H */

View File

@ -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, 0x21C4},
{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, 0x21C8},
{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, 0x0087},
{PCI_VENDOR_ID_HP_3PAR, 0x0075, 0x1590, 0x007D},
@ -165,9 +171,15 @@ static struct board_type products[] = {
{0x21C3103C, "Smart Array", &SA5_access},
{0x21C4103C, "Smart Array", &SA5_access},
{0x21C5103C, "Smart Array", &SA5_access},
{0x21C6103C, "Smart Array", &SA5_access},
{0x21C7103C, "Smart Array", &SA5_access},
{0x21C8103C, "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},
{0x00871590, "HP Storage P1224e 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 */
physicals = kzalloc(reportsize, GFP_KERNEL);
if (physicals == NULL)
return 0;
if (hpsa_scsi_do_report_phys_luns(h, (struct ReportLUNdata *) physicals,
reportsize, extended)) {
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)
{
int rc;
int hba_mode_enabled;
struct bmic_controller_parameters *ctlr_params;
ctlr_params = kzalloc(sizeof(struct bmic_controller_parameters),
GFP_KERNEL);
if (!ctlr_params)
return 0;
return -ENOMEM;
rc = hpsa_bmic_ctrl_mode_sense(h, RAID_CTLR_LUNID, 0, ctlr_params,
sizeof(struct bmic_controller_parameters));
if (rc != 0) {
if (rc) {
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)
@ -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 i, n_ext_target_devs, ndevs_to_allocate;
int raid_ctlr_position;
u8 rescan_hba_mode;
int rescan_hba_mode;
DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
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));
rescan_hba_mode = hpsa_hba_mode_enabled(h);
if (rescan_hba_mode < 0)
goto out;
if (!h->hba_mode_enabled && rescan_hba_mode)
dev_warn(&h->pdev->dev, "HBA mode enabled\n");

View File

@ -90,6 +90,7 @@ struct bmic_controller_parameters {
u8 automatic_drive_slamming;
u8 reserved1;
u8 nvram_flags;
#define HBA_MODE_ENABLED_FLAG (1 << 3)
u8 cache_nvram_flags;
u8 drive_config_flags;
u16 reserved2;

View File

@ -1442,9 +1442,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
conn->task = NULL;
}
/* regular RX path uses back_lock */
spin_lock_bh(&conn->session->back_lock);
spin_lock(&conn->session->back_lock);
__iscsi_put_task(task);
spin_unlock_bh(&conn->session->back_lock);
spin_unlock(&conn->session->back_lock);
return rc;
}

View File

@ -265,6 +265,16 @@ lpfc_sli4_eq_get(struct lpfc_queue *q)
return NULL;
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;
}
@ -370,6 +380,17 @@ lpfc_sli4_cq_get(struct lpfc_queue *q)
cqe = q->qe[q->hba_index].cqe;
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;
}

View File

@ -25,10 +25,6 @@
* 1+ (800) 334-5454
*/
/*
* $Log: mac_NCR5380.c,v $
*/
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/ctype.h>
@ -58,12 +54,6 @@
#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 DRIVER_SETUP

View File

@ -22,10 +22,6 @@
* 1+ (800) 334-5454
*/
/*
* $Log: cumana_NCR5380.h,v $
*/
#ifndef MAC_NCR5380_H
#define MAC_NCR5380_H
@ -51,8 +47,6 @@
#include <scsi/scsicam.h>
#ifndef HOSTS_C
#define NCR5380_implementation_fields \
int port, ctrl
@ -75,10 +69,6 @@
#define NCR5380_show_info macscsi_show_info
#define NCR5380_write_info macscsi_write_info
#define BOARD_NORMAL 0
#define BOARD_NCR53C400 1
#endif /* ndef HOSTS_C */
#endif /* ndef ASM */
#endif /* MAC_NCR5380_H */

View File

@ -3061,7 +3061,8 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
u32 cur_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)
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) {
abs_state =
instance->instancet->read_fw_status_reg(instance->reg_set);
switch (fw_state) {
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
*/
for (i = 0; i < (max_wait * 1000); i++) {
fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
MFI_STATE_MASK ;
curr_abs_state =
instance->instancet->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) {
msleep(1);
@ -3242,6 +3238,9 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr)
"in %d secs\n", fw_state, max_wait);
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");

View File

@ -1739,14 +1739,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
list_for_each_entry_safe(chain_req, next,
&ioc->scsi_lookup[i].chain_list, 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->scsi_lookup[i].cb_idx = 0xFF;
ioc->scsi_lookup[i].scmd = NULL;
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);
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@ -1764,13 +1764,13 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
/* hi-priority */
i = smid - ioc->hi_priority_smid;
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);
} else if (smid <= ioc->hba_queue_depth) {
/* internal queue */
i = smid - ioc->internal_smid;
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);
}
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);

View File

@ -1065,7 +1065,7 @@ void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u32 reply);
int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
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_clear_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
void mpt2sas_expander_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address);

View File

@ -987,7 +987,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg,
mpt2sas_scsih_issue_tm(ioc,
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 10,
0, TM_MUTEX_ON);
TM_MUTEX_ON);
ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
} else
mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,

View File

@ -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)
* @smid_task: smid assigned to the task
* @timeout: timeout in seconds
* @serial_number: the serial_number from scmd
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
* Context: user
*
@ -2381,7 +2380,7 @@ mpt2sas_scsih_clear_tm_flag(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, ulong timeout,
unsigned long serial_number, enum mutex_type m_type)
enum mutex_type m_type)
{
Mpi2SCSITaskManagementRequest_t *mpi_request;
Mpi2SCSITaskManagementReply_t *mpi_reply;
@ -2634,8 +2633,7 @@ _scsih_abort(struct scsi_cmnd *scmd)
handle = sas_device_priv_data->sas_target->handle;
r = mpt2sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
scmd->device->id, scmd->device->lun,
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
scmd->serial_number, TM_MUTEX_ON);
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
out:
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,
scmd->device->id, scmd->device->lun,
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, 0,
TM_MUTEX_ON);
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
out:
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,
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
30, 0, TM_MUTEX_ON);
30, TM_MUTEX_ON);
out:
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
*/
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_TARGET *sas_target_priv_data;
struct _raid_device *raid_device;
@ -3963,7 +3960,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
u32 mpi_control;
u16 smid;
scmd->scsi_done = done;
sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
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)
mpi_request->Function = MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
else
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
mpi_request->DevHandle =
cpu_to_le16(sas_device_priv_data->sas_target->handle);
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;
}
static DEF_SCSI_QCMD(_scsih_qcmd)
/**
* _scsih_normalize_sense - normalize descriptor and fixed format sense data
* @sense_buffer: sense data returned by target
@ -5880,7 +5874,7 @@ broadcast_aen_retry:
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
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);
if (r == FAILED) {
sdev_printk(KERN_WARNING, sdev,
@ -5922,7 +5916,7 @@ broadcast_aen_retry:
r = mpt2sas_scsih_issue_tm(ioc, handle, sdev->channel, sdev->id,
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
scmd->serial_number, TM_MUTEX_OFF);
TM_MUTEX_OFF);
if (r == FAILED) {
sdev_printk(KERN_WARNING, sdev,
"mpt2sas_scsih_issue_tm: ABORT_TASK: FAILED : "

View File

@ -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,
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_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address);

View File

@ -980,7 +980,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
mpt3sas_scsih_issue_tm(ioc,
le16_to_cpu(mpi_request->FunctionDependent1), 0, 0,
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 30,
0, TM_MUTEX_ON);
TM_MUTEX_ON);
} else
mpt3sas_base_hard_reset_handler(ioc, CAN_SLEEP,
FORCE_BIG_HAMMER);

View File

@ -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)
* @smid_task: smid assigned to the task
* @timeout: timeout in seconds
* @serial_number: the serial_number from scmd
* @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
* Context: user
*
@ -2042,7 +2041,7 @@ mpt3sas_scsih_clear_tm_flag(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, ulong timeout,
unsigned long serial_number, enum mutex_type m_type)
enum mutex_type m_type)
{
Mpi2SCSITaskManagementRequest_t *mpi_request;
Mpi2SCSITaskManagementReply_t *mpi_reply;
@ -2293,8 +2292,7 @@ _scsih_abort(struct scsi_cmnd *scmd)
handle = sas_device_priv_data->sas_target->handle;
r = mpt3sas_scsih_issue_tm(ioc, handle, scmd->device->channel,
scmd->device->id, scmd->device->lun,
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
scmd->serial_number, TM_MUTEX_ON);
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30, TM_MUTEX_ON);
out:
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,
scmd->device->id, scmd->device->lun,
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, 0,
TM_MUTEX_ON);
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30, TM_MUTEX_ON);
out:
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,
scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
30, 0, TM_MUTEX_ON);
30, TM_MUTEX_ON);
out:
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
* @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
*/
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_TARGET *sas_target_priv_data;
Mpi2SCSIIORequest_t *mpi_request;
@ -3544,7 +3541,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
scsi_print_command(scmd);
#endif
scmd->scsi_done = done;
sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
scmd->result = DID_NO_CONNECT << 16;
@ -3659,8 +3655,6 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
out:
return SCSI_MLQUEUE_HOST_BUSY;
}
static DEF_SCSI_QCMD(_scsih_qcmd)
/**
* _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);
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);
if (r == FAILED) {
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,
sdev->lun, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, smid, 30,
scmd->serial_number, TM_MUTEX_OFF);
TM_MUTEX_OFF);
if (r == FAILED) {
sdev_printk(KERN_WARNING, sdev,
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "

View File

@ -728,6 +728,15 @@ static struct pci_device_id mvs_pci_table[] = {
.class_mask = 0,
.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, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
{ PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */

View File

@ -129,8 +129,6 @@ static int pas16_bus_reset(Scsi_Cmnd *);
#define CAN_QUEUE 32
#endif
#ifndef HOSTS_C
#define NCR5380_implementation_fields \
volatile unsigned short io_port
@ -171,6 +169,5 @@ static int pas16_bus_reset(Scsi_Cmnd *);
#define PAS16_IRQS 0xd4a8
#endif /* else def HOSTS_C */
#endif /* ndef ASM */
#endif /* PAS16_H */

View File

@ -395,6 +395,8 @@ static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
payload.offset = 0;
payload.length = 4096;
payload.func_specific = kzalloc(4096, GFP_KERNEL);
if (!payload.func_specific)
return -ENOMEM;
PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload);
wait_for_completion(&completion);
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++)
str += sprintf(str, "%c",
*((u8 *)((u8 *)virt_addr+bios_index)));
kfree(payload.func_specific);
return str - buf;
}
static DEVICE_ATTR(bios_version, S_IRUGO, pm8001_ctl_bios_version_show, NULL);

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -664,7 +664,7 @@ do_read:
}
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) {
ql_log(ql_log_warn, vha, 0x706d,
"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)
size = 0;
else if (IS_QLA82XX(ha))
else if (IS_P3P_TYPE(ha))
size = ha->md_template_size + ha->md_dump_size;
else
size = ha->fw_dump_len;

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -2054,9 +2054,49 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
break;
default:
ql_log(ql_log_warn, vha, 0x708c,
ql_dbg(ql_dbg_user, vha, 0x708c,
"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;
}
@ -2121,6 +2161,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
case QL_VND_SERDES_OP:
return qla26xx_serdes_op(bsg_job);
case QL_VND_SERDES_OP_EX:
return qla8044_serdes_op(bsg_job);
default:
return -ENOSYS;
}

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -24,6 +24,7 @@
#define QL_VND_READ_I2C 0x11
#define QL_VND_FX00_MGMT_CMD 0x12
#define QL_VND_SERDES_OP 0x13
#define QL_VND_SERDES_OP_EX 0x14
/* BSG Vendor specific subcode returns */
#define EXT_STATUS_OK 0
@ -225,4 +226,10 @@ struct qla_serdes_reg {
uint16_t val;
} __packed;
struct qla_serdes_reg_ex {
uint16_t cmd;
uint32_t addr;
uint32_t val;
} __packed;
#endif

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -15,7 +15,7 @@
* | | | 0x0144,0x0146 |
* | | | 0x015b-0x0160 |
* | | | 0x016e-0x0170 |
* | Mailbox commands | 0x1187 | 0x1018-0x1019 |
* | Mailbox commands | 0x118d | 0x1018-0x1019 |
* | | | 0x10ca |
* | | | 0x1115-0x1116 |
* | | | 0x111a-0x111b |
@ -45,12 +45,16 @@
* | | | 0x70ad-0x70ae |
* | | | 0x70d7-0x70db |
* | | | 0x70de-0x70df |
* | Task Management | 0x803d | 0x8025-0x8026 |
* | | | 0x800b,0x8039 |
* | Task Management | 0x803d | 0x8000,0x800b |
* | | | 0x8019 |
* | | | 0x8025,0x8026 |
* | | | 0x8031,0x8032 |
* | | | 0x8039,0x803c |
* | AER/EEH | 0x9011 | |
* | Virtual Port | 0xa007 | |
* | ISP82XX Specific | 0xb14c | 0xb002,0xb024 |
* | ISP82XX Specific | 0xb157 | 0xb002,0xb024 |
* | | | 0xb09e,0xb0ae |
* | | | 0xb0c3,0xb0c6 |
* | | | 0xb0e0-0xb0ef |
* | | | 0xb085,0xb0dc |
* | | | 0xb107,0xb108 |
@ -60,12 +64,12 @@
* | | | 0xb13c-0xb140 |
* | | | 0xb149 |
* | MultiQ | 0xc00c | |
* | Misc | 0xd2ff | 0xd017-0xd019 |
* | Misc | 0xd212 | 0xd017-0xd019 |
* | | | 0xd020 |
* | | | 0xd02e-0xd0ff |
* | | | 0xd030-0xd0ff |
* | | | 0xd101-0xd1fe |
* | | | 0xd212-0xd2fe |
* | Target Mode | 0xe070 | 0xe021 |
* | | | 0xd213-0xd2fe |
* | Target Mode | 0xe078 | |
* | Target Mode Management | 0xf072 | 0xf002-0xf003 |
* | | | 0xf046-0xf049 |
* | 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)
return rval;
set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
/* External Memory. */
return qla24xx_dump_ram(ha, 0x100000, *nxt,
rval = qla24xx_dump_ram(ha, 0x100000, *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 *
@ -296,23 +306,15 @@ qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
return buf;
}
int
qla24xx_pause_risc(struct device_reg_24xx __iomem *reg)
void
qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
{
int rval = QLA_SUCCESS;
uint32_t cnt;
WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
for (cnt = 30000;
((RD_REG_DWORD(&reg->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(&reg->host_status) & HSRX_RISC_PAUSED)
set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
}
int
@ -320,10 +322,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
{
int rval = QLA_SUCCESS;
uint32_t cnt;
uint16_t mb0, wd;
uint16_t wd;
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(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
for (cnt = 0; cnt < 30000; cnt++) {
if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
@ -331,19 +337,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
udelay(10);
}
if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
WRT_REG_DWORD(&reg->ctrl_status,
CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
udelay(100);
/* Wait for firmware to complete NVRAM accesses. */
mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
for (cnt = 10000 ; cnt && mb0; cnt--) {
udelay(5);
mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
barrier();
}
/* Wait for soft-reset to complete. */
for (cnt = 0; cnt < 30000; cnt++) {
@ -353,16 +354,21 @@ qla24xx_soft_reset(struct qla_hw_data *ha)
udelay(10);
}
if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
for (cnt = 10000; RD_REG_WORD(&reg->mailbox0) != 0 &&
rval == QLA_SUCCESS; cnt--) {
if (cnt)
udelay(100);
udelay(10);
else
rval = QLA_FUNCTION_TIMEOUT;
}
if (rval == QLA_SUCCESS)
set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
return rval;
}
@ -659,12 +665,13 @@ qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
if (rval != QLA_SUCCESS) {
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;
} else {
ql_log(ql_log_info, vha, 0xd001,
"Firmware dump saved to temp buffer (%ld/%p).\n",
vha->host_no, ha->fw_dump);
"Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
ha->fw_dumped = 1;
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;
flags = 0;
ha->fw_dump_cap_flags = 0;
if (!hardware_locked)
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(&reg->host_status));
/* Pause RISC. */
rval = qla24xx_pause_risc(reg);
if (rval != QLA_SUCCESS)
goto qla24xx_fw_dump_failed_0;
/*
* Pause RISC. No need to track timeout, as resetting the chip
* is the right approach incase of pause timeout
*/
qla24xx_pause_risc(reg, ha);
/* Host interface registers. */
dmp_reg = &reg->flash_addr;
@ -1302,6 +1311,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
risc_address = ext_mem_cnt = 0;
flags = 0;
ha->fw_dump_cap_flags = 0;
if (!hardware_locked)
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(&reg->host_status));
/* Pause RISC. */
rval = qla24xx_pause_risc(reg);
if (rval != QLA_SUCCESS)
goto qla25xx_fw_dump_failed_0;
/*
* Pause RISC. No need to track timeout, as resetting the chip
* is the right approach incase of pause timeout
*/
qla24xx_pause_risc(reg, ha);
/* Host/Risc registers. */
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;
flags = 0;
ha->fw_dump_cap_flags = 0;
if (!hardware_locked)
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(&reg->host_status));
/* Pause RISC. */
rval = qla24xx_pause_risc(reg);
if (rval != QLA_SUCCESS)
goto qla81xx_fw_dump_failed_0;
/*
* Pause RISC. No need to track timeout, as resetting the chip
* is the right approach incase of pause timeout
*/
qla24xx_pause_risc(reg, ha);
/* Host/Risc registers. */
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;
flags = 0;
ha->fw_dump_cap_flags = 0;
if (!hardware_locked)
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(&reg->host_status));
/* Pause RISC. */
rval = qla24xx_pause_risc(reg);
if (rval != QLA_SUCCESS)
goto qla83xx_fw_dump_failed_0;
/*
* Pause RISC. No need to track timeout, as resetting the chip
* is the right approach incase of pause timeout
*/
qla24xx_pause_risc(reg, ha);
WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
dmp_reg = &reg->iobase_window;
@ -2385,9 +2400,11 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
nxt += sizeof(fw->code_ram);
nxt += (ha->fw_memory_size - 0x100000 + 1);
goto copy_queue;
} else
} else {
set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
ql_log(ql_log_warn, vha, 0xd010,
"bigger hammer success?\n");
}
}
rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -353,5 +353,6 @@ extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *,
uint32_t, void **);
extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
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 *);

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -965,6 +965,13 @@ struct mbx_cmd_32 {
*/
#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 */
#define FCAL_MAP_SIZE 128
@ -1622,10 +1629,20 @@ typedef struct {
#define PO_MODE_DIF_PASS 2
#define PO_MODE_DIF_REPLACE 3
#define PO_MODE_DIF_TCP_CKSUM 6
#define PO_ENABLE_DIF_BUNDLING BIT_8
#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_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.
*/
@ -1748,6 +1765,8 @@ typedef struct {
#define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */
#define CS_PORT_BUSY 0x2B /* Port Busy */
#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_UNKNOWN 0x81 /* Driver defined */
#define CS_RETRY 0x82 /* Driver defined */
@ -2676,6 +2695,7 @@ struct rsp_que {
uint32_t __iomem *rsp_q_out;
uint16_t ring_index;
uint16_t out_ptr;
uint16_t *in_ptr; /* queue shadow in index */
uint16_t length;
uint16_t options;
uint16_t rid;
@ -2702,6 +2722,7 @@ struct req_que {
uint32_t __iomem *req_q_out;
uint16_t ring_index;
uint16_t in_ptr;
uint16_t *out_ptr; /* queue shadow out index */
uint16_t cnt;
uint16_t length;
uint16_t options;
@ -2907,6 +2928,8 @@ struct qla_hw_data {
#define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031
#define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031
#define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071
#define PCI_DEVICE_ID_QLOGIC_ISP2271 0x2271
uint32_t device_type;
#define DT_ISP2100 BIT_0
#define DT_ISP2200 BIT_1
@ -2928,7 +2951,8 @@ struct qla_hw_data {
#define DT_ISPFX00 BIT_17
#define DT_ISP8044 BIT_18
#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_IIDMA BIT_26
@ -2959,6 +2983,7 @@ struct qla_hw_data {
#define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031)
#define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00)
#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) || \
IS_QLA6312(ha) || IS_QLA6322(ha))
@ -2967,7 +2992,7 @@ struct qla_hw_data {
#define IS_QLA25XX(ha) (IS_QLA2532(ha))
#define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(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) || \
IS_QLA84XX(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))
#define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha))
#define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length)
#define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha))
/* HBA serial number */
uint8_t serial0;
@ -3136,7 +3162,15 @@ struct qla_hw_data {
struct qla2xxx_fw_dump *fw_dump;
uint32_t fw_dump_len;
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 prev_minidump_failed;
dma_addr_t eft_dma;
void *eft;
/* Current size of mctp dump is 0x086064 bytes */

View File

@ -1,6 +1,6 @@
/*
* 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.
*/

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -371,7 +371,10 @@ struct init_cb_24xx {
* BIT 14 = Data Rate bit 1
* BIT 15 = Data Rate bit 2
* 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;
uint16_t qos;
@ -1134,13 +1137,6 @@ struct device_reg_24xx {
#define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */
#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 {
uint16_t reserved_1;

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -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 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.
@ -346,6 +353,11 @@ qla2x00_write_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t);
extern int
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
qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);

View File

@ -1,6 +1,6 @@
/*
* 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.
*/

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -1476,6 +1476,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
}
ha->fw_dumped = 0;
ha->fw_dump_cap_flags = 0;
dump_size = fixed_size = mem_size = eft_size = fce_size = mq_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[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)) {
icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS);
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];
if (!req)
continue;
req->out_ptr = (void *)(req->ring + req->length);
*req->out_ptr = 0;
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
req->outstanding_cmds[cnt] = NULL;
@ -2153,6 +2160,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
rsp = ha->rsp_q_map[que];
if (!rsp)
continue;
rsp->in_ptr = (void *)(rsp->ring + rsp->length);
*rsp->in_ptr = 0;
/* Initialize response queue entries */
if (IS_QLAFX00(ha))
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.area,
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)
{
int status = 0;
uint32_t wait_time;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_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))) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
ha->flags.chip_reset_done = 1;
/* Initialize the queues in use */
qla25xx_init_queues(ha);
status = qla2x00_fw_ready(vha);
if (!status) {
ql_dbg(ql_dbg_taskm, vha, 0x8031,
"Start configure loop status = %d.\n", status);
/* Issue a marker after FW becomes ready. */
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);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
/* Wait at most MAX_TARGET RSCNs for a stable link. */
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)));
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
/* if no cable then assume it's good */
if ((vha->device_flags & DFLG_NO_CABLE))
status = 0;
ql_dbg(ql_dbg_taskm, vha, 0x8032,
"Configure loop done, status = 0x%x.\n", status);
}
return (status);
}
@ -6130,7 +6124,6 @@ int
qla82xx_restart_isp(scsi_qla_host_t *vha)
{
int status, rval;
uint32_t wait_time;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_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);
if (!status) {
ql_log(ql_log_info, vha, 0x803c,
"Start configure loop, status =%d.\n", status);
/* Issue a marker after FW becomes ready. */
qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL);
vha->flags.online = 1;
/* Wait at most MAX_TARGET RSCNs for a stable link. */
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)));
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
/* if no cable then assume it's good */
if ((vha->device_flags & DFLG_NO_CABLE))
status = 0;
ql_log(ql_log_info, vha, 0x8000,
"Configure loop done, status = 0x%x.\n", status);
}
if (!status) {
@ -6182,8 +6159,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha)
vha->marker_needed = 1;
}
vha->flags.online = 1;
ha->isp_ops->enable_intrs(ha);
ha->isp_abort_cnt = 0;

View File

@ -1,10 +1,11 @@
/*
* 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.
*/
#include "qla_target.h"
/**
* qla24xx_calc_iocbs() - Determine number of Command Type 3 and
* Continuation Type 1 IOCBs to allocate.
@ -128,12 +129,20 @@ qla2x00_clear_loop_id(fc_port_t *fcport) {
}
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 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 */
list_for_each_entry_safe(dsd_ptr, tdsd_ptr,

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -936,9 +936,9 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx,
return 1;
}
static int
int
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;
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;
uint16_t used_dsds = tot_dsds;
uint32_t prot_int;
uint32_t prot_int; /* protection interval */
uint32_t partial;
struct qla2_sgx sgx;
dma_addr_t sle_dma;
uint32_t sle_dma_len, tot_prot_dma_len = 0;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
prot_int = cmd->device->sector_size;
struct scsi_cmnd *cmd;
struct scsi_qla_host *vha;
memset(&sgx, 0, sizeof(struct qla2_sgx));
sgx.tot_bytes = scsi_bufflen(cmd);
sgx.cur_sg = scsi_sglist(cmd);
sgx.sp = sp;
if (sp) {
vha = sp->fcport->vha;
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)) {
@ -995,10 +1009,18 @@ alloc_and_fill:
return 1;
}
list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
if (sp) {
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 */
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
@ -1033,21 +1055,35 @@ alloc_and_fill:
return 0;
}
static int
int
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;
uint8_t avail_dsds = 0;
uint32_t dsd_list_len;
struct dsd_dma *dsd_ptr;
struct scatterlist *sg;
struct scatterlist *sg, *sgl;
uint32_t *cur_dsd = dsd;
int i;
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;
/* 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;
}
list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
if (sp) {
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 */
*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;
}
static int
int
qla24xx_walk_and_build_prot_sglist(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;
uint8_t avail_dsds = 0;
uint32_t dsd_list_len;
struct dsd_dma *dsd_ptr;
struct scatterlist *sg;
struct scatterlist *sg, *sgl;
int i;
struct scsi_cmnd *cmd;
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);
scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
if (sp) {
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;
/* Allocate additional continuation packets? */
@ -1147,10 +1204,17 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
return 1;
}
list_add_tail(&dsd_ptr->list,
&((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
if (sp) {
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 */
*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 (qla24xx_walk_and_build_sglist_no_difb(ha, sp,
cur_dsd, tot_dsds))
cur_dsd, tot_dsds, NULL))
goto crc_queuing_error;
} 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;
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);
cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address;
if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd,
tot_prot_dsds))
tot_prot_dsds, NULL))
goto crc_queuing_error;
}
return QLA_SUCCESS;
@ -1478,8 +1542,8 @@ qla24xx_start_scsi(srb_t *sp)
tot_dsds = nseg;
req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
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)
req->cnt = cnt - req->ring_index;
else
@ -1697,8 +1761,8 @@ qla24xx_dif_start_scsi(srb_t *sp)
tot_prot_dsds = nseg;
tot_dsds += nseg;
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)
req->cnt = cnt - req->ring_index;
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. */
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)
req->cnt = cnt - req->ring_index;
else

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -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,
"Invalid status handle (0x%x).\n", sts->handle);
if (IS_P3P_TYPE(ha))
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
else
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
if (IS_P3P_TYPE(ha))
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
else
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
return;
}
@ -2472,12 +2474,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
if (pkt->entry_status != 0) {
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;
wmb();
continue;
}
process_err:
switch (pkt->entry_type) {
case STATUS_TYPE:
@ -2494,10 +2498,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
qla24xx_logio_entry(vha, rsp->req,
(struct logio_entry_24xx *)pkt);
break;
case CT_IOCB_TYPE:
case CT_IOCB_TYPE:
qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
break;
case ELS_IOCB_TYPE:
case ELS_IOCB_TYPE:
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
break;
case ABTS_RECV_24XX:
@ -2506,6 +2510,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
case ABTS_RESP_24XX:
case CTIO_TYPE7:
case NOTIFY_ACK_TYPE:
case CTIO_CRC2:
qlt_response_pkt_all_vps(vha, (response_t *)pkt);
break;
case MARKER_TYPE:

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -1319,7 +1319,7 @@ qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
left = 0;
list = kzalloc(dma_size, GFP_KERNEL);
list = kmemdup(pmap, dma_size, GFP_KERNEL);
if (!list) {
ql_log(ql_log_warn, vha, 0x1140,
"%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;
}
memcpy(list, pmap, dma_size);
restart:
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,
"Failed to complete IOCB -- completion status (%x).\n",
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 {
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
"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;
}
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() -
* @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,
"Entered %s.\n", __func__);
if (IS_SHADOW_REG_CAPABLE(ha))
req->options |= BIT_13;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
mcp->mb[1] = req->options;
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 */
mcp->mb[8] = 0;
/* 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|
MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|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))
mcp->in_mb |= MBX_1;
if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) {
if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
mcp->out_mb |= MBX_15;
/* debug q create issue in SR-IOV */
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);
if (!(req->options & BIT_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);
}
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,
"Entered %s.\n", __func__);
if (IS_SHADOW_REG_CAPABLE(ha))
rsp->options |= BIT_13;
mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
mcp->mb[1] = rsp->options;
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;
/* que in ptr index */
mcp->mb[8] = 0;
mcp->mb[8] = *rsp->in_ptr = 0;
/* que out ptr index */
mcp->mb[9] = 0;
mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7

View File

@ -1,6 +1,6 @@
/*
* 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.
*/

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -527,21 +527,63 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
int i, core;
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 */
for (i = 0; i < 4; i++) {
QLAFX00_SET_HBA_SOC_REG(ha,
(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,
(SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101));
}
/* 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 */
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_CONFIG_REG, (0x3));
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Kick in Fabric units */
QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0));
/* Kick in Core0 to start boot process */
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. */
for (cnt = 10; cnt; cnt--) {
msleep(1000);
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);
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;
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) {
lptr = rsp->ring_ptr;
@ -3426,7 +3466,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb)
sp->fcport->vha, 0x3047,
(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));
wmb();
}

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -351,6 +351,7 @@ struct config_info_data {
#define SOC_FABRIC_RST_CONTROL_REG 0x0020840
#define SOC_FABRIC_CONTROL_REG 0x0020200
#define SOC_FABRIC_CONFIG_REG 0x0020204
#define SOC_PWR_MANAGEMENT_PWR_DOWN_REG 0x001820C
#define SOC_INTERRUPT_SOURCE_I_CONTROL_REG 0x0020B00
#define SOC_CORE_TIMER_REG 0x0021850

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -848,6 +848,7 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
{
int done = 0, timeout = 0;
uint32_t lock_owner = 0;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
while (!done) {
/* acquire semaphore2 from PCI HW block */
@ -856,17 +857,21 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
break;
if (timeout >= qla82xx_rom_lock_timeout) {
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;
}
timeout++;
}
qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER);
qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ha->portnum);
return 0;
}
static void
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));
}
@ -950,6 +955,7 @@ static int
qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
{
int ret, loops = 0;
uint32_t lock_owner = 0;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
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++;
}
if (loops >= 50000) {
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
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;
}
ret = qla82xx_do_rom_fast_read(ha, addr, valp);
@ -1057,6 +1065,7 @@ static int
ql82xx_rom_lock_d(struct qla_hw_data *ha)
{
int loops = 0;
uint32_t lock_owner = 0;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {
@ -1065,8 +1074,9 @@ ql82xx_rom_lock_d(struct qla_hw_data *ha)
loops++;
}
if (loops >= 50000) {
lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
ql_log(ql_log_warn, vha, 0xb010,
"ROM lock failed.\n");
"ROM lock failed, Lock Owner %u.\n", lock_owner);
return -1;
}
return 0;
@ -2811,12 +2821,14 @@ static void
qla82xx_rom_lock_recovery(struct qla_hw_data *ha)
{
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. */
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
* else died while holding it.
@ -2840,47 +2852,30 @@ static int
qla82xx_device_bootstrap(scsi_qla_host_t *vha)
{
int rval = QLA_SUCCESS;
int i, timeout;
int i;
uint32_t old_count, count;
struct qla_hw_data *ha = vha->hw;
int need_reset = 0, peg_stuck = 1;
int need_reset = 0;
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) {
/* We are trying to perform a recovery here. */
if (peg_stuck)
if (ha->flags.isp82xx_fw_hung)
qla82xx_rom_lock_recovery(ha);
goto dev_initialize;
} else {
/* Start of day for this ha context. */
if (peg_stuck) {
/* Either we are the first or recovery in progress. */
qla82xx_rom_lock_recovery(ha);
goto dev_initialize;
} else
/* Firmware already running. */
goto dev_ready;
old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
for (i = 0; i < 10; i++) {
msleep(200);
count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
if (count != old_count) {
rval = QLA_SUCCESS;
goto dev_ready;
}
}
qla82xx_rom_lock_recovery(ha);
}
return rval;
dev_initialize:
/* set to DEV_INITIALIZING */
ql_log(ql_log_info, vha, 0x009e,
"HW State: INITIALIZING.\n");
@ -3142,18 +3137,18 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
if (ql2xmdenable) {
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_subminor_version != ha->fw_subminor_version) {
fw_subminor_version != ha->fw_subminor_version) ||
(ha->prev_minidump_failed)) {
ql_dbg(ql_dbg_p3p, vha, 0xb02d,
"Firmware version differs "
"Previous version: %d:%d:%d - "
"New version: %d:%d:%d\n",
"Firmware version differs Previous version: %d:%d:%d - New version: %d:%d:%d, prev_minidump_failed: %d.\n",
fw_major_version, fw_minor_version,
fw_subminor_version,
ha->fw_major_version,
ha->fw_minor_version,
ha->fw_subminor_version);
ha->fw_subminor_version,
ha->prev_minidump_failed);
/* Release MiniDump resources */
qla82xx_md_free(vha);
/* 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++) {
sp = req->outstanding_cmds[cnt];
if (sp) {
if (!sp->u.scmd.ctx ||
(sp->flags & SRB_FCP_CMND_DMA_VALID)) {
if ((!sp->u.scmd.ctx ||
(sp->flags &
SRB_FCP_CMND_DMA_VALID)) &&
!ha->flags.isp82xx_fw_hung) {
spin_unlock_irqrestore(
&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -333,9 +333,6 @@
#define QLA82XX_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004)
#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_WINDOW(A) \
(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 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_encode_temp(val, state) (((val) << 16) | (state))

View File

@ -1,17 +1,20 @@
/*
* 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.
*/
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include "qla_def.h"
#include "qla_gbl.h"
#include <linux/delay.h>
#define TIMEOUT_100_MS 100
/* 8044 Flash Read/Write functions */
uint32_t
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);
}
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,
* 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,
QLA8044_FLASH_LOCK_ID);
ql_log(ql_log_warn, vha, 0xb113,
"%s: flash lock by %d failed, held by %d\n",
__func__, ha->portnum, lock_owner);
"%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d",
__func__, ha->portnum, lock_owner);
ret_val = QLA_FUNCTION_FAILED;
break;
}
@ -1541,7 +1633,7 @@ static void
qla8044_need_reset_handler(struct scsi_qla_host *vha)
{
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;
ql_log(ql_log_fatal, vha, 0xb0c2,
@ -1555,84 +1647,78 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
qla8044_idc_lock(ha);
}
dev_state = qla8044_rd_direct(vha,
QLA8044_CRB_DEV_STATE_INDEX);
drv_state = qla8044_rd_direct(vha,
QLA8044_CRB_DRV_STATE_INDEX);
drv_active = qla8044_rd_direct(vha,
QLA8044_CRB_DRV_ACTIVE_INDEX);
ql_log(ql_log_info, vha, 0xb0c5,
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
__func__, vha->host_no, drv_state, drv_active);
"%s(%ld): drv_state = 0x%x, drv_active = 0x%x dev_state = 0x%x\n",
__func__, vha->host_no, drv_state, drv_active, dev_state);
if (!ha->flags.nic_core_reset_owner) {
ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
"%s(%ld): reset acknowledged\n",
__func__, vha->host_no);
qla8044_set_rst_ready(vha);
qla8044_set_rst_ready(vha);
/* Non-reset owners ACK Reset and wait for device INIT state
* as part of Reset Recovery by Reset Owner
*/
dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
/* wait for 10 seconds for reset ack from all functions */
reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
do {
if (time_after_eq(jiffies, dev_init_timeout)) {
ql_log(ql_log_info, vha, 0xb0c4,
"%s: Non Reset owner: Reset Ack Timeout!\n",
__func__);
break;
}
do {
if (time_after_eq(jiffies, reset_timeout)) {
ql_log(ql_log_info, vha, 0xb0c4,
"%s: Function %d: Reset Ack Timeout!, drv_state: 0x%08x, drv_active: 0x%08x\n",
__func__, ha->portnum, drv_state, drv_active);
break;
}
qla8044_idc_unlock(ha);
msleep(1000);
qla8044_idc_lock(ha);
qla8044_idc_unlock(ha);
msleep(1000);
qla8044_idc_lock(ha);
dev_state = qla8044_rd_direct(vha,
QLA8044_CRB_DEV_STATE_INDEX);
} while (((drv_state & drv_active) != drv_active) &&
(dev_state == QLA8XXX_DEV_NEED_RESET));
dev_state = qla8044_rd_direct(vha,
QLA8044_CRB_DEV_STATE_INDEX);
drv_state = qla8044_rd_direct(vha,
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 {
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
* by next RST_OWNER
*/
ha->flags.nic_core_reset_owner = 0;
* Reset owner should execute reset recovery,
* if all functions acknowledged
*/
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);
}
}
@ -1655,6 +1741,19 @@ qla8044_set_drv_active(struct scsi_qla_host *vha)
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
qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
{
@ -1837,14 +1936,16 @@ qla8044_device_state_handler(struct scsi_qla_host *vha)
while (1) {
if (time_after_eq(jiffies, dev_init_timeout)) {
ql_log(ql_log_warn, vha, 0xb0cf,
"%s: Device Init Failed 0x%x = %s\n",
QLA2XXX_DRIVER_NAME, dev_state,
dev_state < MAX_STATES ?
qdev_state(dev_state) : "Unknown");
qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
QLA8XXX_DEV_FAILED);
if (qla8044_check_drv_active(vha) == QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0xb0cf,
"%s: Device Init Failed 0x%x = %s\n",
QLA2XXX_DRIVER_NAME, dev_state,
dev_state < MAX_STATES ?
qdev_state(dev_state) : "Unknown");
qla8044_wr_direct(vha,
QLA8044_CRB_DEV_STATE_INDEX,
QLA8XXX_DEV_FAILED);
}
}
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))) {
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)) {
set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
ha->flags.isp82xx_fw_hung = 1;
@ -2037,7 +2145,7 @@ qla8044_watchdog(struct scsi_qla_host *vha)
qla2xxx_wake_dpc(vha);
} else {
/* Check firmware health */
if (qla8044_check_fw_alive(vha)) {
if (ha->flags.isp82xx_fw_hung) {
halt_status = qla8044_rd_direct(vha,
QLA8044_PEG_HALT_STATUS1_INDEX);
if (halt_status &
@ -2073,12 +2181,8 @@ qla8044_watchdog(struct scsi_qla_host *vha)
__func__);
set_bit(ISP_ABORT_NEEDED,
&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);
}
}
@ -2286,8 +2390,6 @@ qla8044_minidump_process_rdmem(struct scsi_qla_host *vha,
}
if (j >= MAX_CTL_CHECK) {
printk_ratelimited(KERN_ERR
"%s: failed to read through agent\n", __func__);
write_unlock_irqrestore(&ha->hw_lock, flags);
return QLA_SUCCESS;
}
@ -2882,6 +2984,231 @@ error_exit:
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.
@ -3089,6 +3416,24 @@ qla8044_collect_md_data(struct scsi_qla_host *vha)
if (rval != QLA_SUCCESS)
qla8044_mark_entry_skipped(vha, entry_hdr, i);
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:
default:
qla8044_mark_entry_skipped(vha, entry_hdr, i);
@ -3110,6 +3455,7 @@ skip_nxt_entry:
"Dump data mismatch: Data collected: "
"[0x%x], total_data_size:[0x%x]\n",
data_collected, ha->md_dump_size);
rval = QLA_FUNCTION_FAILED;
goto md_failed;
}
@ -3134,10 +3480,12 @@ qla8044_get_minidump(struct scsi_qla_host *vha)
if (!qla8044_collect_md_data(vha)) {
ha->fw_dumped = 1;
ha->prev_minidump_failed = 0;
} else {
ql_log(ql_log_fatal, vha, 0xb0db,
"%s: Unable to collect minidump\n",
__func__);
ha->prev_minidump_failed = 1;
}
}

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -133,6 +133,7 @@
#define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
#define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
#define QLA8044_LINK_SPEED_FACTOR 10
#define QLA8044_FUN7_ACTIVE_INDEX 0x80
/* FLASH API Defines */
#define QLA8044_FLASH_MAX_WAIT_USEC 100
@ -431,6 +432,50 @@ struct qla8044_minidump_entry_pollrd {
uint32_t rsvd_1;
} __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 */
struct qla8044_minidump_entry_rdmux2 {
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_OCM_WNDREG_ARRAY_LEN 16
#define QLA8044_SS_PCI_INDEX 0
#define QLA8044_RDDFE 38
#define QLA8044_RDMDIO 39
#define QLA8044_POLLWR 40
struct qla8044_minidump_template_hdr {
uint32_t entry_type;

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -616,7 +616,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr)
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* 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;
}
@ -781,7 +781,7 @@ static int
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
{
#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;
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
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
* Wait till the HBA is online after going through
* <= MAX_RETRIES_OF_ISP_ABORT or
* finally HBA is disabled ie marked offline or flash
* operations are in progress.
* qla2x00_wait_for_hba_ready
* Wait till the HBA is ready before doing driver unload
*
* Input:
* 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
* (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
qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha)
static void
qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
{
int return_status;
unsigned long wait_online;
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 (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
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))
while ((!(vha->flags.online) || ha->dpc_active ||
ha->flags.mbox_busy))
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
@ -945,7 +922,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int ret;
unsigned int id, lun;
unsigned long flags;
int wait = 0;
int rval, wait = 0;
struct qla_hw_data *ha = vha->hw;
if (!CMD_SP(cmd))
@ -974,10 +951,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
sp_get(sp);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {
ret = FAILED;
rval = ha->isp_ops->abort_command(sp);
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,
"Abort command mbx failed cmd=%p.\n", cmd);
"Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval);
} else {
ql_dbg(ql_dbg_taskm, vha, 0x8004,
"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);
/*
* 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);
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,
"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;
if (vha != base_vha) {
@ -2270,6 +2267,13 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
ha->device_type |= DT_IIDMA;
ha->fw_srisc_address = RISC_START_ADDRESS_2400;
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))
@ -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_ISPF001 ||
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);
mem_only = 1;
ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
@ -2877,6 +2882,7 @@ skip_dpc:
base_vha->flags.init_done = 1;
base_vha->flags.online = 1;
ha->prev_minidump_failed = 0;
ql_dbg(ql_dbg_init, base_vha, 0x00f2,
"Init done and hba is online.\n");
@ -3136,6 +3142,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
base_vha = pci_get_drvdata(pdev);
ha = base_vha->hw;
qla2x00_wait_for_hba_ready(base_vha);
set_bit(UNLOADING, &base_vha->dpc_flags);
if (IS_QLAFX00(ha))
@ -3645,6 +3653,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
ha->eft = NULL;
ha->eft_dma = 0;
ha->fw_dumped = 0;
ha->fw_dump_cap_flags = 0;
ha->fw_dump_reading = 0;
ha->fw_dump = NULL;
ha->fw_dump_len = 0;
@ -4913,12 +4922,13 @@ qla2x00_do_dpc(void *data)
if (qlafx00_reset_initialize(base_vha)) {
/* Failed. Abort isp later. */
if (!test_bit(UNLOADING,
&base_vha->dpc_flags))
&base_vha->dpc_flags)) {
set_bit(ISP_UNRECOVERABLE,
&base_vha->dpc_flags);
ql_dbg(ql_dbg_dpc, base_vha,
0x4021,
"Reset Recovery Failed\n");
}
}
}
@ -5077,8 +5087,10 @@ intr_on_check:
ha->isp_ops->enable_intrs(ha);
if (test_and_clear_bit(BEACON_BLINK_NEEDED,
&base_vha->dpc_flags))
ha->isp_ops->beacon_blink(base_vha);
&base_vha->dpc_flags)) {
if (ha->beacon_blink_led == 1)
ha->isp_ops->beacon_blink(base_vha);
}
if (!IS_QLAFX00(ha))
qla2x00_do_dpc_all_vps(base_vha);
@ -5325,7 +5337,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
#define FW_ISP82XX 7
#define FW_ISP2031 8
#define FW_ISP8031 9
#define FW_ISP2071 10
#define FW_ISP27XX 10
#define FW_FILE_ISP21XX "ql2100_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_ISP2031 "ql2600_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);
@ -5353,7 +5365,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
{ .name = FW_FILE_ISP82XX, },
{ .name = FW_FILE_ISP2031, },
{ .name = FW_FILE_ISP8031, },
{ .name = FW_FILE_ISP2071, },
{ .name = FW_FILE_ISP27XX, },
};
struct fw_blob *
@ -5382,8 +5394,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha)
blob = &qla_fw_blobs[FW_ISP2031];
} else if (IS_QLA8031(ha)) {
blob = &qla_fw_blobs[FW_ISP8031];
} else if (IS_QLA2071(ha)) {
blob = &qla_fw_blobs[FW_ISP2071];
} else if (IS_QLA27XX(ha)) {
blob = &qla_fw_blobs[FW_ISP27XX];
} else {
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_ISP8044) },
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) },
{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) },
{ 0 },
};
MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);

View File

@ -1,6 +1,6 @@
/*
* 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.
*/

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -1727,11 +1727,8 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha)
if (IS_QLA2031(ha)) {
led_select_value = qla83xx_select_led_port(ha);
qla83xx_wr_reg(vha, led_select_value, 0x40002000);
qla83xx_wr_reg(vha, led_select_value + 4, 0x40002000);
msleep(1000);
qla83xx_wr_reg(vha, led_select_value, 0x40004000);
qla83xx_wr_reg(vha, led_select_value + 4, 0x40004000);
qla83xx_wr_reg(vha, led_select_value, 0x40000230);
qla83xx_wr_reg(vha, led_select_value + 4, 0x40000230);
} else if (IS_QLA8031(ha)) {
led_select_value = qla83xx_select_led_port(ha);

View File

@ -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,
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) {
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)
{
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:
{
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;
/*
* 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 -
prm->tgt->datasegs_per_cmd, prm->tgt->datasegs_per_cont);
if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) {
/*
* 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 -
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",
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);
pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
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,
@ -1665,8 +1713,9 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
}
ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u\n",
vha->vp_idx, cmd->tag);
ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u ox_id %04x\n",
vha->vp_idx, cmd->tag,
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
prm->cmd = cmd;
prm->tgt = tgt;
@ -1902,6 +1951,323 @@ skip_explict_conf:
/* 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 *
* 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);
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018,
"is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, "
"cmd->dma_data_direction=%d\n", (xmit_type & QLA_TGT_XMIT_STATUS) ?
1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction);
"is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n",
(xmit_type & QLA_TGT_XMIT_STATUS) ?
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,
&full_req_cnt);
@ -1941,7 +2308,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
if (unlikely(res))
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))
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 |
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 (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,
"Building additional status packet\n");
/*
* T10Dif: ctio_crc2_to_fw overlay ontop of
* ctio7_to_24xx
*/
memcpy(ctio, pkt, sizeof(*ctio));
/* reset back to CTIO7 */
ctio->entry_count = 1;
ctio->entry_type = CTIO_TYPE7;
ctio->dseg_count = 0;
ctio->u.status1.flags &= ~__constant_cpu_to_le16(
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->u.status0.flags |= __constant_cpu_to_le16(
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,
&prm);
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)
return -EIO;
ql_dbg(ql_dbg_tgt, vha, 0xe01b, "CTIO_start: vha(%d)",
(int)vha->vp_idx);
ql_dbg(ql_dbg_tgt, vha, 0xe01b,
"%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 */
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);
if (res != 0)
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))
goto out_unlock_free_unmap;
pkt = (struct ctio7_to_24xx *)prm.pkt;
pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT |
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;
@ -2079,6 +2468,143 @@ out_unlock_free_unmap:
}
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 */
/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
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);
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
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())
msleep(250); /* just in case */
if (cmd->sg_mapped)
qlt_unmap_sg(vha, cmd);
vha->hw->tgt.tgt_ops->free_cmd(cmd);
}
return;
}
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))
kfree(cmd->sg);
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_TARGET_RESET:
case CTIO_ABORTED:
/* driver request abort via Terminate exchange */
case CTIO_TIMEOUT:
case CTIO_INVALID_RX_ID:
/* They are OK */
@ -2404,18 +2949,58 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
else
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:
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b,
"qla_target(%d): CTIO with error status "
"0x%x received (state %x, se_cmd %p\n",
"qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n",
vha->vp_idx, status, cmd->state, se_cmd);
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))
return;
}
}
skip_term:
if (cmd->state == QLA_TGT_STATE_PROCESSED) {
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);
}
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");
dump_stack();
}
@ -2563,8 +3149,9 @@ static void qlt_do_work(struct work_struct *work)
atio->u.isp24.fcp_cmnd.add_cdb_len]));
ql_dbg(ql_dbg_tgt, vha, 0xe022,
"qla_target: START qla command: %p lun: 0x%04x (tag %d)\n",
cmd, cmd->unpacked_lun, cmd->tag);
"qla_target: START qla cmd: %p se_cmd %p lun: 0x%04x (tag %d) len(%d) ox_id %x\n",
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,
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) {
case ATIO_TYPE7:
ql_dbg(ql_dbg_tgt, vha, 0xe02d,
"ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, "
"add_cdb_len %d, data_length %04x, s_id %x:%x:%x\n",
"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",
vha->vp_idx, atio->u.isp24.fcp_cmnd.lun,
atio->u.isp24.fcp_cmnd.rddata,
atio->u.isp24.fcp_cmnd.wrdata,
atio->u.isp24.fcp_cmnd.cdb[0],
atio->u.isp24.fcp_cmnd.add_cdb_len,
be32_to_cpu(get_unaligned((uint32_t *)
&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++;
switch (pkt->entry_type) {
case CTIO_CRC2:
case CTIO_TYPE7:
{
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
ql_dbg(ql_dbg_tgt, vha, 0xe030, "CTIO_TYPE7: instance %d\n",
vha->vp_idx);
ql_dbg(ql_dbg_tgt, vha, 0xe030,
"CTIO[0x%x] 12/CTIO7 7A/CRC2: instance %d\n",
entry->entry_type, vha->vp_idx);
qlt_do_ctio_completion(vha, entry->handle,
le16_to_cpu(entry->status)|(pkt->entry_status << 16),
entry);
@ -4768,6 +5357,7 @@ qlt_24xx_process_response_error(struct scsi_qla_host *vha,
case ABTS_RESP_24XX:
case CTIO_TYPE7:
case NOTIFY_ACK_TYPE:
case CTIO_CRC2:
return 1;
default:
return 0;

View File

@ -293,6 +293,7 @@ struct ctio_to_2xxx {
#define CTIO_ABORTED 0x02
#define CTIO_INVALID_RX_ID 0x08
#define CTIO_TIMEOUT 0x0B
#define CTIO_DIF_ERROR 0x0C /* DIF error detected */
#define CTIO_LIP_RESET 0x0E
#define CTIO_TARGET_RESET 0x17
#define CTIO_PORT_UNAVAILABLE 0x28
@ -498,11 +499,12 @@ struct ctio7_from_24xx {
#define CTIO7_FLAGS_DONT_RET_CTIO BIT_8
#define CTIO7_FLAGS_STATUS_MODE_0 0
#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_CONFIRM_SATISF BIT_4
#define CTIO7_FLAGS_DSD_PTR BIT_2
#define CTIO7_FLAGS_DATA_IN BIT_1
#define CTIO7_FLAGS_DATA_OUT BIT_0
#define CTIO7_FLAGS_DATA_IN BIT_1 /* data to initiator */
#define CTIO7_FLAGS_DATA_OUT BIT_0 /* data from initiator */
#define ELS_PLOGI 0x3
#define ELS_FLOGI 0x4
@ -513,6 +515,68 @@ struct ctio7_from_24xx {
#define ELS_PDISC 0x50
#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.
*/
@ -641,6 +705,7 @@ struct qla_tgt_func_tmpl {
int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *,
unsigned char *, uint32_t, int, int, int);
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,
uint32_t);
void (*free_cmd)(struct qla_tgt_cmd *);
@ -829,9 +894,9 @@ struct qla_tgt_sess {
};
struct qla_tgt_cmd {
struct se_cmd se_cmd;
struct qla_tgt_sess *sess;
int state;
struct se_cmd se_cmd;
struct work_struct free_work;
struct work_struct work;
/* Sense buffer that will be mapped into outgoing status */
@ -843,6 +908,7 @@ struct qla_tgt_cmd {
unsigned int free_sg:1;
unsigned int aborted:1; /* Needed in case of SRR */
unsigned int write_data_transferred:1;
unsigned int ctx_dsd_alloced:1;
struct scatterlist *sg; /* cmd data buffer SG vector */
int sg_cnt; /* SG segments count */
@ -857,6 +923,12 @@ struct qla_tgt_cmd {
struct scsi_qla_host *vha;
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 {
@ -901,6 +973,10 @@ struct qla_tgt_prm {
int sense_buffer_len;
int residual;
int add_status_pkt;
/* dif */
struct scatterlist *prot_sg;
uint16_t prot_seg_cnt;
uint16_t tot_dsds;
};
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 int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
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_free_mcmd(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -201,7 +201,6 @@ qla27xx_read_reg(__iomem struct device_reg_24xx *reg,
ql_dbg(ql_dbg_misc, NULL, 0xd014,
"%s: @%x\n", __func__, offset);
}
qla27xx_insert32(offset, buf, len);
qla27xx_read32(window, buf, len);
}
@ -220,7 +219,7 @@ qla27xx_write_reg(__iomem struct device_reg_24xx *reg,
static inline void
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)
{
void *window = (void *)reg + offset;
@ -229,14 +228,14 @@ qla27xx_read_window(__iomem struct device_reg_24xx *reg,
if (buf) {
ql_dbg(ql_dbg_misc, NULL, 0xd016,
"%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--) {
qla27xx_insert32(base, buf, len);
qla27xx_insert32(addr, buf, len);
readn(window, buf, len);
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,
"%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;
}
@ -349,7 +349,7 @@ qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd205,
"%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;
}
@ -392,9 +392,9 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
goto done;
}
if (end < start) {
if (end < start || end == 0) {
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);
qla27xx_skip_entry(ent, buf);
goto done;
@ -452,17 +452,15 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd025,
"%s: unsupported atio queue\n", __func__);
qla27xx_skip_entry(ent, buf);
goto done;
} else {
ql_dbg(ql_dbg_misc, vha, 0xd026,
"%s: unknown queue %u\n", __func__, ent->t263.queue_type);
qla27xx_skip_entry(ent, buf);
goto done;
}
if (buf)
ent->t263.num_queues = count;
done:
return false;
}
@ -503,7 +501,7 @@ qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
ql_dbg(ql_dbg_misc, vha, 0xd209,
"%s: pause risc [%lx]\n", __func__, *len);
if (buf)
qla24xx_pause_risc(reg);
qla24xx_pause_risc(reg, vha->hw);
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 device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
void *window = (void *)reg + 0xc4;
ulong dwords = ent->t270.count;
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);
while (dwords--) {
qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf);
qla27xx_read_reg(reg, 0xc4, buf, len);
qla27xx_insert32(addr, buf, len);
qla27xx_read32(window, buf, len);
addr++;
qla27xx_read_reg(reg, 0xc4, buf, len);
addr += sizeof(uint32_t);
}
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);
ulong addr = ent->t271.addr;
ulong data = ent->t271.data;
ql_dbg(ql_dbg_misc, vha, 0xd20f,
"%s: wrremreg [%lx]\n", __func__, *len);
qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf);
qla27xx_read_reg(reg, 0xc4, buf, len);
qla27xx_insert32(addr, buf, len);
qla27xx_write_reg(reg, 0xc4, data, buf);
qla27xx_write_reg(reg, 0xc0, addr, buf);
return false;
@ -662,12 +658,62 @@ qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
"%s: failed pcicfg read at %lx\n", __func__, addr);
qla27xx_insert32(addr, buf, len);
qla27xx_insert32(value, buf, len);
addr += 4;
addr += sizeof(uint32_t);
}
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
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
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_RDREMRAM , qla27xx_fwdt_entry_t272 } ,
{ ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } ,
{ ENTRY_TYPE_GET_SHADOW , qla27xx_fwdt_entry_t274 } ,
{ -1 , qla27xx_fwdt_entry_other }
};

View File

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -52,6 +52,7 @@ struct __packed qla27xx_fwdt_template {
#define ENTRY_TYPE_WRREMREG 271
#define ENTRY_TYPE_RDREMRAM 272
#define ENTRY_TYPE_PCICFG 273
#define ENTRY_TYPE_GET_SHADOW 274
#define CAPTURE_FLAG_PHYS_ONLY BIT_0
#define CAPTURE_FLAG_PHYS_VIRT BIT_1
@ -109,12 +110,12 @@ struct __packed qla27xx_fwdt_entry {
} t259;
struct __packed {
uint8_t pci_addr;
uint8_t pci_offset;
uint8_t reserved[3];
} t260;
struct __packed {
uint8_t pci_addr;
uint8_t pci_offset;
uint8_t reserved[3];
uint32_t write_data;
} t261;
@ -186,6 +187,12 @@ struct __packed qla27xx_fwdt_entry {
uint32_t addr;
uint32_t count;
} 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_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

View File

@ -1,13 +1,13 @@
/*
* 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.
*/
/*
* 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_MINOR_VER 7

View File

@ -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 = 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
* 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;
}
transport_generic_request_failure(&cmd->se_cmd,
TCM_CHECK_CONDITION_ABORT_CMD);
if (cmd->se_cmd.pi_err)
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;
}
@ -584,6 +594,27 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd)
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()
*/
@ -610,6 +641,11 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
cmd->sg = se_cmd->t_data_sg;
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
*/
@ -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 = {
.handle_cmd = tcm_qla2xxx_handle_cmd,
.handle_data = tcm_qla2xxx_handle_data,
.handle_dif_err = tcm_qla2xxx_handle_dif_err,
.handle_tmr = tcm_qla2xxx_handle_tmr,
.free_cmd = tcm_qla2xxx_free_cmd,
.free_mcmd = tcm_qla2xxx_free_mcmd,

View File

@ -249,110 +249,6 @@ void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *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 PROCEED_TO_RECOVER 0x02
@ -760,7 +656,7 @@ static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
__func__));
/* 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);
if (ret_val == QLA_ERROR) {
ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",

View File

@ -254,6 +254,50 @@ struct qla83xx_minidump_entry_pollrd {
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 */
struct qla83xx_minidump_entry_rdmux2 {
struct qla8xxx_minidump_entry_hdr h;

View File

@ -601,6 +601,7 @@ struct scsi_qla_host {
#define DPC_HA_NEED_QUIESCENT 22 /* 0x00400000 ISP-82xx only*/
#define DPC_POST_IDC_ACK 23 /* 0x00800000 */
#define DPC_RESTORE_ACB 24 /* 0x01000000 */
#define DPC_SYSFS_DDB_EXPORT 25 /* 0x02000000 */
struct Scsi_Host *host; /* pointer to host data */
uint32_t tot_ddbs;

View File

@ -1415,6 +1415,9 @@ struct ql_iscsi_stats {
#define QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN 16
#define QLA83XX_SS_OCM_WNDREG_INDEX 3
#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 {
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 capture_size_array[QLA8XXX_DBG_CAP_SIZE_ARRAY_LEN];
uint32_t ocm_window_reg[QLA83XX_DBG_OCM_WNDREG_ARRAY_LEN];
uint32_t capabilities[QLA80XX_TEMPLATE_RESERVED_BITS];
};
#endif /* _QLA4X_FW_H */

View File

@ -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,
uint32_t acb_type, uint32_t len);
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);
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_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_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 ql4xdontresethba;

View File

@ -282,6 +282,25 @@ qla4xxx_wait_for_ip_config(struct scsi_qla_host *ha)
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.
* @ha: pointer to host adapter structure.
@ -294,6 +313,7 @@ void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha)
void *md_tmp;
dma_addr_t md_tmp_dma;
struct qla4_8xxx_minidump_template_hdr *md_hdr;
int dma_capable;
if (ha->fw_dump) {
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;
dma_capable = qla4_80xx_is_minidump_dma_capable(ha, md_hdr);
capture_debug_level = md_hdr->capture_debug_level;
/* 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;
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;
}
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 (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
qla4xxx_get_crash_record(ha);
qla4xxx_init_rings(ha);
} else {
DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n",
ha->host_no, __func__));

View File

@ -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 ret;
int ret = 0;
int rval = QLA_ERROR;
if (is_qla40XX(ha))
@ -1580,15 +1580,13 @@ try_msi:
}
}
/*
* Prevent interrupts from falling back to INTx mode in cases where
* interrupts cannot get acquired through MSI-X or MSI mode.
*/
try_intx:
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;
}
try_intx:
/* Trying INTx */
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
IRQF_SHARED, DRIVER_NAME, ha);

View File

@ -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",
__func__);
rval = QLA_ERROR;
goto exit_config_acb;
goto exit_free_acb;
}
memcpy(ha->saved_acb, acb, acb_len);
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);
kfree(ha->saved_acb);
ha->saved_acb = NULL;
rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);
if (rval != QLA_SUCCESS)
@ -2412,6 +2410,10 @@ exit_free_acb:
dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), acb,
acb_dma);
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,
"%s %s\n", __func__,
rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));

View File

@ -14,6 +14,7 @@
#include <asm-generic/io-64-nonatomic-lo-hi.h>
#define TIMEOUT_100_MS 100
#define MASK(n) DMA_BIT_MASK(n)
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 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;
}
/**
* 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
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);
}
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,
struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
@ -1822,7 +2024,7 @@ error_exit:
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,
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;
/* 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,
(uint32_t *)&dma_desc,
(sizeof(struct qla4_83xx_pex_dma_descriptor)/16));
if (rval == -1) {
if (rval != QLA_SUCCESS) {
ql4_printk(KERN_INFO, ha,
"%s: Error writing rdmem-dma-init to MS !!!\n",
__func__);
@ -2359,17 +2561,10 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
uint32_t *data_ptr = *d_ptr;
int rval = QLA_SUCCESS;
if (is_qla8032(ha) || is_qla8042(ha)) {
rval = qla4_83xx_minidump_pex_dma_read(ha, entry_hdr,
&data_ptr);
if (rval != QLA_SUCCESS) {
rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
&data_ptr);
}
} else {
rval = qla4_8xxx_minidump_pex_dma_read(ha, entry_hdr, &data_ptr);
if (rval != QLA_SUCCESS)
rval = __qla4_8xxx_minidump_process_rdmem(ha, entry_hdr,
&data_ptr);
}
*d_ptr = data_ptr;
return rval;
}
@ -2440,6 +2635,227 @@ exit_process_pollrd:
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,
struct qla8xxx_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
@ -2753,6 +3169,24 @@ static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha)
if (rval != QLA_SUCCESS)
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);
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:
default:
qla4_8xxx_mark_entry_skipped(ha, entry_hdr, i);

View File

@ -858,6 +858,9 @@ struct crb_addr_pair {
#define QLA83XX_POLLRD 35
#define QLA83XX_RDMUX2 36
#define QLA83XX_POLLRDMWR 37
#define QLA8044_RDDFE 38
#define QLA8044_RDMDIO 39
#define QLA8044_POLLWR 40
#define QLA8XXX_RDROM 71
#define QLA8XXX_RDMEM 72
#define QLA8XXX_CNTRL 98

View File

@ -83,12 +83,12 @@ MODULE_PARM_DESC(ql4xsess_recovery_tmo,
" Target Session Recovery Timeout.\n"
"\t\t Default: 120 sec.");
int ql4xmdcapmask = 0x1F;
int ql4xmdcapmask = 0;
module_param(ql4xmdcapmask, int, S_IRUGO);
MODULE_PARM_DESC(ql4xmdcapmask,
" Set the Minidump driver capture mask level.\n"
"\t\t Default is 0x1F.\n"
"\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F");
"\t\t Default is 0 (firmware default capture mask)\n"
"\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF");
int ql4xenablemd = 1;
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 scsi_qla_host *ha;
if (!qla_ep)
return -ENOTCONN;
ha = to_qla_host(qla_ep->host);
DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,
ha->host_no));
@ -1749,9 +1752,6 @@ static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep,
switch (param) {
case ISCSI_PARAM_CONN_PORT:
case ISCSI_PARAM_CONN_ADDRESS:
if (!qla_ep)
return -ENOTCONN;
dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
if (!dst_addr)
return -ENOTCONN;
@ -2879,7 +2879,6 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
struct iscsi_conn *conn;
struct qla_conn *qla_conn;
struct sockaddr *dst_addr;
int len = 0;
conn = cls_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:
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)
@ -3569,14 +3565,13 @@ static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,
if (test_bit(OPT_IPV6_DEVICE, &options)) {
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) {
rc = -ENOMEM;
goto exit_copy;
}
memcpy(conn->link_local_ipv6_addr,
fw_ddb_entry->link_local_ipv6_addr, IPv6_ADDR_LEN);
} else {
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_HA_UNRECOVERABLE, &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)) {
DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
" - dpc flags = 0x%lx\n",
@ -4862,9 +4858,6 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
ha->host_no, __func__));
status = ha->isp_ops->reset_firmware(ha);
if (status == QLA_SUCCESS) {
if (!test_bit(AF_FW_RECOVERY, &ha->flags))
qla4xxx_cmd_wait(ha);
ha->isp_ops->disable_intrs(ha);
qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
qla4xxx_abort_active_cmds(ha, DID_RESET << 16);
@ -5432,6 +5425,11 @@ dpc_post_reset_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.
**/
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;
dma_addr_t fw_ddb_entry_dma;
@ -8847,11 +8845,8 @@ skip_retry_init:
ql4_printk(KERN_ERR, ha,
"%s: No iSCSI boot target configured\n", __func__);
if (qla4xxx_sysfs_ddb_export(ha))
ql4_printk(KERN_ERR, ha,
"%s: Error exporting ddb to sysfs\n", __func__);
/* Perform the build ddb list and login to each */
set_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags);
/* Perform the build ddb list and login to each */
qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
qla4xxx_wait_login_resp_boot_tgt(ha);

View File

@ -5,4 +5,4 @@
* See LICENSE.qla4xxx for copyright and licensing details.
*/
#define QLA4XXX_DRIVER_VERSION "5.04.00-k4"
#define QLA4XXX_DRIVER_VERSION "5.04.00-k6"

View File

@ -130,6 +130,7 @@ static const char * scsi_debug_version_date = "20100324";
#define SCSI_DEBUG_OPT_DIF_ERR 32
#define SCSI_DEBUG_OPT_DIX_ERR 64
#define SCSI_DEBUG_OPT_MAC_TIMEOUT 128
#define SCSI_DEBUG_OPT_SHORT_TRANSFER 256
/* When "every_nth" > 0 then modulo "every_nth" commands:
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
* - 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_dif = 0;
int inj_dix = 0;
int inj_short = 0;
int delay_override = 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 */
else if (SCSI_DEBUG_OPT_DIX_ERR & scsi_debug_opts)
inj_dix = 1; /* to reads and writes below */
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & scsi_debug_opts)
inj_short = 1;
}
if (devip->wlun) {
@ -3744,6 +3748,10 @@ read:
if (scsi_debug_fake_rw)
break;
get_data_transfer_info(cmd, &lba, &num, &ei_lba);
if (inj_short)
num /= 2;
errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
if (inj_recovered && (0 == errsts)) {
mk_sense_buffer(devip, RECOVERED_ERROR,

View File

@ -1029,6 +1029,7 @@ retry:
rtn = NEEDS_RETRY;
} else {
timeleft = wait_for_completion_timeout(&done, timeout);
rtn = SUCCESS;
}
shost->eh_action = NULL;
@ -2306,6 +2307,12 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
}
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);
scmd->request = &req;

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