SCSI misc on 20150622

This is the usual grab bag of driver updates (lpfc, hpsa,
 megaraid_sas, cxgbi, be2iscsi) plus an assortment of minor updates.
 There are also one new driver: the Cisco snic; the advansys driver has
 been rewritten to get rid of the warning about converting it to the
 DMA API, the tape statistics patch got in and finally, there's a
 resuffle of SCSI header files to separate more cleanly initiator from
 target mode (and better share the common definitions).
 
 Signed-off-by: James Bottomley <JBottomley@Odin.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABAgAGBQJViKWdAAoJEDeqqVYsXL0MAr8IAMmlA6HBVjMJJFCEOY9corHj
 e70MNQa7LUgf+JCdOtzGcvHXTiFFd4IHZAwXUJAnsC4IU2QWEfi1bjUTErlqBIGk
 LoZlXXpEHnFpmWot3OluOzzcGcxede8rVgPiKWVVdojIngBC2+LL/i2vPCJ84ri9
 WCVlk6KBvWZXuU6JuOKAb2FO9HOX7Q61wuKAMast2Qc6RNc2ksgc7VbstsITqzZ9
 FVEsjmQ5lqUj+xdxBpiUOdUpc22IJ4VcpBgQ2HrThvg6vf4aq937RJ/g4vi/g0SU
 Utk0a3bUw1H/WnYAfJVFx83nVEsS/954Z7/ERDg1sjlfLYwQtQnpov0XIbPIbZU=
 =k9IT
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
 "This is the usual grab bag of driver updates (lpfc, hpsa,
  megaraid_sas, cxgbi, be2iscsi) plus an assortment of minor updates.

  There is also one new driver: the Cisco snic.  The advansys driver has
  been rewritten to get rid of the warning about converting it to the
  DMA API, the tape statistics patch got in and finally, there's a
  resuffle of SCSI header files to separate more cleanly initiator from
  target mode (and better share the common definitions)"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (156 commits)
  snic: driver for Cisco SCSI HBA
  qla2xxx: Fix indentation
  qla2xxx: Comment out unreachable code
  fusion: remove dead MTRR code
  advansys: fix compilation errors and warnings when CONFIG_PCI is not set
  mptsas: fix depth param in scsi_track_queue_full
  megaraid: fix irq setup process regression
  lpfc: Update version to 10.7.0.0 for upstream patch set.
  lpfc: Fix to drop PLOGIs from fabric node till LOGO processing completes
  lpfc: Fix scsi task management error message.
  lpfc: Fix cq_id masking problem.
  lpfc: Fix scsi prep dma buf error.
  lpfc: Add support for using block multi-queue
  lpfc: Devices are not discovered during takeaway/giveback testing
  lpfc: Fix vport deletion failure.
  lpfc: Check for active portpeerbeacon.
  lpfc: Update driver version for upstream patch set 10.6.0.1.
  lpfc: Change buffer pool empty message to miscellaneous category
  lpfc: Fix incorrect log message reported for empty FCF record.
  lpfc: Fix rport leak.
  ...
This commit is contained in:
Linus Torvalds 2015-06-23 15:55:44 -07:00
commit acd53127c4
187 changed files with 16801 additions and 3747 deletions

View file

@ -0,0 +1,109 @@
What: /sys/class/scsi_tape/*/stats/in_flight
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Show the number of I/Os currently in-flight between the st
module and the SCSI mid-layer.
Users:
What: /sys/class/scsi_tape/*/stats/io_ns
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total amount of time spent waiting for all I/O
to and from the tape drive to complete. This includes all
reads, writes, and other SCSI commands issued to the tape
drive. An example of other SCSI commands would be tape
movement such as a rewind when a rewind tape device is
closed. This item is measured in nanoseconds.
To determine the amount of time spent waiting for other I/O
to complete subtract read_ns and write_ns from this value.
Users:
What: /sys/class/scsi_tape/*/stats/other_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
The number of I/O requests issued to the tape drive other
than SCSI read/write requests.
Users:
What: /sys/class/scsi_tape/*/stats/read_byte_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total number of bytes requested from the tape drive.
This value is presented in bytes because tape drives support
variable length block sizes.
Users:
What: /sys/class/scsi_tape/*/stats/read_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total number of read requests issued to the tape
drive.
Users:
What: /sys/class/scsi_tape/*/stats/read_ns
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total amount of time in nanoseconds waiting for
read I/O requests to complete.
Users:
What: /sys/class/scsi_tape/*/stats/write_byte_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total number of bytes written to the tape drive.
This value is presented in bytes because tape drives support
variable length block sizes.
Users:
What: /sys/class/scsi_tape/*/stats/write_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total number of write requests issued to the tape
drive.
Users:
What: /sys/class/scsi_tape/*/stats/write_ms
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the total amount of time in nanoseconds waiting for
write I/O requests to complete.
Users:
What: /sys/class/scsi_tape/*/stats/resid_cnt
Date: Apr 2015
KernelVersion: 4.2
Contact: Shane Seymour <shane.seymour@hp.com>
Description:
Shows the number of times we found that a residual >0
was found when the SCSI midlayer indicated that there was
an error. For reads this may be a case of someone issuing
reads greater than the block size.
Users:

View file

@ -151,6 +151,65 @@ A link named 'tape' is made from the SCSI device directory to the class
directory corresponding to the mode 0 auto-rewind device (e.g., st0).
SYSFS AND STATISTICS FOR TAPE DEVICES
The st driver maintains statistics for tape drives inside the sysfs filesystem.
The following method can be used to locate the statistics that are
available (assuming that sysfs is mounted at /sys):
1. Use opendir(3) on the directory /sys/class/scsi_tape
2. Use readdir(3) to read the directory contents
3. Use regcomp(3)/regexec(3) to match directory entries to the extended
regular expression "^st[0-9]+$"
4. Access the statistics from the /sys/class/scsi_tape/<match>/stats
directory (where <match> is a directory entry from /sys/class/scsi_tape
that matched the extended regular expression)
The reason for using this approach is that all the character devices
pointing to the same tape drive use the same statistics. That means
that st0 would have the same statistics as nst0.
The directory contains the following statistics files:
1. in_flight - The number of I/Os currently outstanding to this device.
2. io_ns - The amount of time spent waiting (in nanoseconds) for all I/O
to complete (including read and write). This includes tape movement
commands such as seeking between file or set marks and implicit tape
movement such as when rewind on close tape devices are used.
3. other_cnt - The number of I/Os issued to the tape drive other than read or
write commands. The time taken to complete these commands uses the
following calculation io_ms-read_ms-write_ms.
4. read_byte_cnt - The number of bytes read from the tape drive.
5. read_cnt - The number of read requests issued to the tape drive.
6. read_ns - The amount of time (in nanoseconds) spent waiting for read
requests to complete.
7. write_byte_cnt - The number of bytes written to the tape drive.
8. write_cnt - The number of write requests issued to the tape drive.
9. write_ns - The amount of time (in nanoseconds) spent waiting for write
requests to complete.
10. resid_cnt - The number of times during a read or write we found
the residual amount to be non-zero. This should mean that a program
is issuing a read larger thean the block size on tape. For write
not all data made it to tape.
Note: The in_flight value is incremented when an I/O starts the I/O
itself is not added to the statistics until it completes.
The total of read_cnt, write_cnt, and other_cnt may not total to the same
value as iodone_cnt at the device level. The tape statistics only count
I/O issued via the st module.
When read the statistics may not be temporally consistent while I/O is in
progress. The individual values are read and written to atomically however
when reading them back via sysfs they may be in the process of being
updated when starting an I/O or when it is completed.
The value shown in in_flight is incremented before any statstics are
updated and decremented when an I/O completes after updating statistics.
The value of in_flight is 0 when there are no I/Os outstanding that are
issued by the st driver. Tape statistics do not take into account any
I/O performed via the sg device.
BSD AND SYS V SEMANTICS
The user can choose between these two behaviours of the tape driver by

View file

@ -503,11 +503,8 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
buf += "#include <linux/string.h>\n"
buf += "#include <linux/ctype.h>\n"
buf += "#include <asm/unaligned.h>\n"
buf += "#include <scsi/scsi.h>\n"
buf += "#include <scsi/scsi_host.h>\n"
buf += "#include <scsi/scsi_device.h>\n"
buf += "#include <scsi/scsi_cmnd.h>\n"
buf += "#include <scsi/libfc.h>\n\n"
buf += "#include <scsi/scsi_common.h>\n"
buf += "#include <scsi/scsi_proto.h>\n"
buf += "#include <target/target_core_base.h>\n"
buf += "#include <target/target_core_fabric.h>\n"
buf += "#include <target/target_core_configfs.h>\n\n"

View file

@ -445,6 +445,7 @@ F: drivers/input/misc/adxl34x.c
ADVANSYS SCSI DRIVER
M: Matthew Wilcox <matthew@wil.cx>
M: Hannes Reinecke <hare@suse.de>
L: linux-scsi@vger.kernel.org
S: Maintained
F: Documentation/scsi/advansys.txt
@ -2610,6 +2611,13 @@ L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/fnic/
CISCO SCSI HBA DRIVER
M: Narsimhulu Musini <nmusini@cisco.com>
M: Sesidhar Baddela <sebaddel@cisco.com>
L: linux-scsi@vger.kernel.org
S: Supported
F: drivers/scsi/snic/
CMPC ACPI DRIVER
M: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
M: Daniel Oliveira Nascimento <don@syst.com.br>

View file

@ -139,8 +139,6 @@ static struct board_type products[] = {
{0x3214103C, "Smart Array E200i", &SA5_access},
{0x3215103C, "Smart Array E200i", &SA5_access},
{0x3237103C, "Smart Array E500", &SA5_access},
{0x3223103C, "Smart Array P800", &SA5_access},
{0x3234103C, "Smart Array P400", &SA5_access},
{0x323D103C, "Smart Array P700m", &SA5_access},
};
@ -574,8 +572,6 @@ static void cciss_procinit(ctlr_info_t *h)
/* List of controllers which cannot be hard reset on kexec with reset_devices */
static u32 unresettable_controller[] = {
0x324a103C, /* Smart Array P712m */
0x324b103C, /* SmartArray P711m */
0x3223103C, /* Smart Array P800 */
0x3234103C, /* Smart Array P400 */
0x3235103C, /* Smart Array P400i */
@ -586,12 +582,32 @@ static u32 unresettable_controller[] = {
0x3215103C, /* Smart Array E200i */
0x3237103C, /* Smart Array E500 */
0x323D103C, /* Smart Array P700m */
0x40800E11, /* Smart Array 5i */
0x409C0E11, /* Smart Array 6400 */
0x409D0E11, /* Smart Array 6400 EM */
0x40700E11, /* Smart Array 5300 */
0x40820E11, /* Smart Array 532 */
0x40830E11, /* Smart Array 5312 */
0x409A0E11, /* Smart Array 641 */
0x409B0E11, /* Smart Array 642 */
0x40910E11, /* Smart Array 6i */
};
/* List of controllers which cannot even be soft reset */
static u32 soft_unresettable_controller[] = {
0x40800E11, /* Smart Array 5i */
0x40700E11, /* Smart Array 5300 */
0x40820E11, /* Smart Array 532 */
0x40830E11, /* Smart Array 5312 */
0x409A0E11, /* Smart Array 641 */
0x409B0E11, /* Smart Array 642 */
0x40910E11, /* Smart Array 6i */
/* Exclude 640x boards. These are two pci devices in one slot
* which share a battery backed cache module. One controls the
* cache, the other accesses the cache through the one that controls
* it. If we reset the one controlling the cache, the other will
* likely not be happy. Just forbid resetting this conjoined mess.
*/
0x409C0E11, /* Smart Array 6400 */
0x409D0E11, /* Smart Array 6400 EM */
};
@ -4667,8 +4683,7 @@ static int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
*/
cciss_lookup_board_id(pdev, &board_id);
if (!ctlr_is_resettable(board_id)) {
dev_warn(&pdev->dev, "Cannot reset Smart Array 640x "
"due to shared cache module.");
dev_warn(&pdev->dev, "Controller not resettable\n");
return -ENODEV;
}

View file

@ -84,7 +84,6 @@ static struct scsi_host_template cciss_driver_template = {
.show_info = cciss_scsi_show_info,
.queuecommand = cciss_scsi_queue_command,
.this_id = 7,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
/* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
.eh_device_reset_handler= cciss_eh_device_reset_handler,

View file

@ -1611,7 +1611,6 @@ static struct scsi_host_template scsi_driver_template = {
.this_id = -1,
.sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
.cmd_per_lun = 1,
.can_queue = 1,
.sdev_attrs = sbp2_scsi_sysfs_attrs,
};

View file

@ -41,6 +41,7 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <scsi/scsi_proto.h>
#include <scsi/scsi_tcq.h>
#include <target/configfs_macros.h>
#include <target/target_core_base.h>

View file

@ -245,7 +245,7 @@ struct srpt_send_ioctx {
u8 n_rdma;
u8 n_rbuf;
bool queue_status_only;
u8 sense_data[SCSI_SENSE_BUFFERSIZE];
u8 sense_data[TRANSPORT_SENSE_BUFFER];
};
/**

View file

@ -59,10 +59,6 @@
#include <linux/delay.h>
#include <linux/interrupt.h> /* needed for in_interrupt() proto */
#include <linux/dma-mapping.h>
#include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <linux/kthread.h>
#include <scsi/scsi_host.h>
@ -2820,13 +2816,6 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
pci_disable_device(ioc->pcidev);
pci_release_selected_regions(ioc->pcidev, ioc->bars);
#if defined(CONFIG_MTRR) && 0
if (ioc->mtrr_reg > 0) {
mtrr_del(ioc->mtrr_reg, 0, 0);
dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
}
#endif
/* Zap the adapter lookup ptr! */
list_del(&ioc->list);
@ -4512,19 +4501,6 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
#if defined(CONFIG_MTRR) && 0
/*
* Enable Write Combining MTRR for IOC's memory region.
* (at least as much as we can; "size and base must be
* multiples of 4 kiB"
*/
ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
sz,
MTRR_TYPE_WRCOMB, 1);
dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
ioc->name, ioc->req_frames_dma, sz));
#endif
for (i = 0; i < ioc->req_depth; i++) {
alloc_dma += ioc->req_sz;
mem += ioc->req_sz;

View file

@ -671,7 +671,6 @@ typedef struct _MPT_ADAPTER
u8 *HostPageBuffer; /* SAS - host page buffer support */
u32 HostPageBuffer_sz;
dma_addr_t HostPageBuffer_dma;
int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
int bars; /* bitmask of BAR's that must be configured */
int msi_enable;

View file

@ -4090,7 +4090,7 @@ mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
continue;
}
depth = scsi_track_queue_full(sdev,
current_depth - 1);
sdev->queue_depth - 1);
if (depth > 0)
sdev_printk(KERN_INFO, sdev,
"Queue depth reduced to (%d)\n",
@ -4100,7 +4100,7 @@ mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
"Tagged Command Queueing is being "
"disabled\n");
else if (depth == 0)
sdev_printk(KERN_INFO, sdev,
sdev_printk(KERN_DEBUG, sdev,
"Queue depth not changed yet\n");
}
}

View file

@ -297,7 +297,6 @@ static struct scsi_host_template zfcp_scsi_host_template = {
* ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8,
/* GCD, adjusted later */
.dma_boundary = ZFCP_QDIO_SBALE_LEN - 1,
.cmd_per_lun = 1,
.use_clustering = 1,
.shost_attrs = zfcp_sysfs_shost_attrs,
.sdev_attrs = zfcp_sysfs_sdev_attrs,

View file

@ -503,7 +503,7 @@ config SCSI_DPT_I2O
config SCSI_ADVANSYS
tristate "AdvanSys SCSI support"
depends on SCSI && VIRT_TO_BUS && !ARM
depends on SCSI
depends on ISA || EISA || PCI
help
This is a driver for all SCSI host adapters manufactured by
@ -634,6 +634,23 @@ config FCOE_FNIC
<file:Documentation/scsi/scsi.txt>.
The module will be called fnic.
config SCSI_SNIC
tristate "Cisco SNIC Driver"
depends on PCI && SCSI
help
This is support for the Cisco PCI-Express SCSI HBA.
To compile this driver as a module, choose M here and read
<file:Documentation/scsi/scsi.txt>.
The module will be called snic.
config SCSI_SNIC_DEBUG_FS
bool "Cisco SNIC Driver Debugfs Support"
depends on SCSI_SNIC && DEBUG_FS
help
This enables to list debugging information from SNIC Driver
available via debugfs file system
config SCSI_DMX3191D
tristate "DMX3191D SCSI support"
depends on PCI && SCSI
@ -1743,7 +1760,6 @@ config SCSI_BFA_FC
config SCSI_VIRTIO
tristate "virtio-scsi support"
depends on VIRTIO
select BLK_DEV_INTEGRITY
help
This is the virtual HBA driver for virtio. If the kernel will
be used in a virtual machine, say Y or M.

View file

@ -39,6 +39,7 @@ obj-$(CONFIG_LIBFC) += libfc/
obj-$(CONFIG_LIBFCOE) += fcoe/
obj-$(CONFIG_FCOE) += fcoe/
obj-$(CONFIG_FCOE_FNIC) += fnic/
obj-$(CONFIG_SCSI_SNIC) += snic/
obj-$(CONFIG_SCSI_BNX2X_FCOE) += libfc/ fcoe/ bnx2fc/
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
@ -161,6 +162,7 @@ obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
scsi_mod-y += scsi.o hosts.o scsi_ioctl.o \
scsicam.o scsi_error.o scsi_lib.o
scsi_mod-y += scsi_common.o
scsi_mod-$(CONFIG_SCSI_CONSTANTS) += constants.o
scsi_mod-$(CONFIG_SCSI_DMA) += scsi_lib_dma.o
scsi_mod-y += scsi_scan.o scsi_sysfs.o scsi_devinfo.o

View file

@ -1064,7 +1064,6 @@ static struct scsi_host_template driver_template =
.can_queue = 1 /* can_queue */,
.this_id = 7 /* SCSI ID of the chip */,
.sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/,
.cmd_per_lun = 1 /* commands per lun */,
.unchecked_isa_dma = 1 /* unchecked_isa_dma */,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -1078,7 +1078,6 @@ static struct scsi_host_template inia100_template = {
.can_queue = 1,
.this_id = 1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -46,7 +46,7 @@
static int aac_src_get_sync_status(struct aac_dev *dev);
irqreturn_t aac_src_intr_message(int irq, void *dev_id)
static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
{
struct aac_msix_ctx *ctx;
struct aac_dev *dev;

File diff suppressed because it is too large Load diff

View file

@ -2922,7 +2922,6 @@ static struct scsi_host_template aha152x_driver_template = {
.can_queue = 1,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.slave_alloc = aha152x_adjust_queue,
};

View file

@ -950,7 +950,6 @@ static struct scsi_host_template driver_template = {
.can_queue = AHA1542_MAILBOXES,
.this_id = 7,
.sg_tablesize = 16,
.cmd_per_lun = 1,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -544,7 +544,6 @@ static struct scsi_host_template aha1740_template = {
.can_queue = AHA1740_ECBS,
.this_id = 7,
.sg_tablesize = AHA1740_SCATTER,
.cmd_per_lun = AHA1740_CMDLUN,
.use_clustering = ENABLE_CLUSTERING,
.eh_abort_handler = aha1740_eh_abort_handler,
};

View file

@ -149,6 +149,5 @@ struct ecb { /* Enhanced Control Block 6.1 */
#define AHA1740_ECBS 32
#define AHA1740_SCATTER 16
#define AHA1740_CMDLUN 1
#endif

View file

@ -65,7 +65,6 @@ static struct scsi_host_template aic94xx_sht = {
.change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param,
.can_queue = 1,
.cmd_per_lun = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,

View file

@ -245,7 +245,6 @@ static struct scsi_host_template arxescsi_template = {
.can_queue = 0,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "arxescsi",
};

View file

@ -367,7 +367,6 @@ static struct scsi_host_template cumanascsi2_template = {
.this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "cumanascsi2",
};

View file

@ -486,7 +486,6 @@ static struct scsi_host_template eesox_template = {
.this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "eesox",
};

View file

@ -3158,7 +3158,6 @@ static struct scsi_host_template atp870u_template = {
.can_queue = qcnt /* can_queue */,
.this_id = 7 /* SCSI ID */,
.sg_tablesize = ATP870U_SCATTER /*SG_ALL*/ /*SG_NONE*/,
.cmd_per_lun = ATP870U_CMDLUN /* commands per lun */,
.use_clustering = ENABLE_CLUSTERING,
.max_sectors = ATP870U_MAX_SECTORS,
};

View file

@ -10,7 +10,6 @@
#define MAX_SENSE 14
#define qcnt 32
#define ATP870U_SCATTER 128
#define ATP870U_CMDLUN 1
#define MAX_ADAPTER 8
#define MAX_SCSI_ID 16

View file

@ -452,6 +452,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
@ -480,6 +481,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
case ASYNC_EVENT_NEW_ISCSI_CONN:
case ASYNC_EVENT_NEW_TCP_CONN:
phba->state |= BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG |
BEISCSI_LOG_MBOX,
@ -488,6 +490,8 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
compl->flags);
break;
default:
phba->state |= BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG |
BEISCSI_LOG_MBOX,

View file

@ -304,6 +304,17 @@ struct mgmt_auth_method_format {
struct mgmt_chap_format chap;
} __packed;
struct be_cmd_req_logout_fw_sess {
struct be_cmd_req_hdr hdr; /* dw[4] */
uint32_t session_handle;
} __packed;
struct be_cmd_resp_logout_fw_sess {
struct be_cmd_resp_hdr hdr; /* dw[4] */
#define BEISCSI_MGMT_SESSION_CLOSE 0x20
uint32_t session_status;
} __packed;
struct mgmt_conn_login_options {
u8 flags;
u8 header_digest;
@ -1136,6 +1147,7 @@ struct be_cmd_get_all_if_id_req {
#define OPCODE_ISCSI_INI_CFG_GET_HBA_NAME 6
#define OPCODE_ISCSI_INI_CFG_SET_HBA_NAME 7
#define OPCODE_ISCSI_INI_SESSION_GET_A_SESSION 14
#define OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET 24
#define OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS 36
#define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41
#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42

View file

@ -668,14 +668,20 @@ static int beiscsi_enable_pci(struct pci_dev *pcidev)
return ret;
}
ret = pci_request_regions(pcidev, DRV_NAME);
if (ret) {
dev_err(&pcidev->dev,
"beiscsi_enable_pci - request region failed\n");
goto pci_dev_disable;
}
pci_set_master(pcidev);
ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret) {
ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pcidev->dev, "Could not set PCI DMA Mask\n");
pci_disable_device(pcidev);
return ret;
goto pci_region_release;
} else {
ret = pci_set_consistent_dma_mask(pcidev,
DMA_BIT_MASK(32));
@ -684,11 +690,17 @@ static int beiscsi_enable_pci(struct pci_dev *pcidev)
ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
if (ret) {
dev_err(&pcidev->dev, "Could not set PCI DMA Mask\n");
pci_disable_device(pcidev);
return ret;
goto pci_region_release;
}
}
return 0;
pci_region_release:
pci_release_regions(pcidev);
pci_dev_disable:
pci_disable_device(pcidev);
return ret;
}
static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
@ -1356,8 +1368,10 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ)
conn->rxdata_octets += resid;
unmap:
scsi_dma_unmap(io_task->scsi_cmnd);
io_task->scsi_cmnd = NULL;
if (io_task->scsi_cmnd) {
scsi_dma_unmap(io_task->scsi_cmnd);
io_task->scsi_cmnd = NULL;
}
iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
}
@ -2037,11 +2051,16 @@ static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
/* Interpret compl as a async link evt */
beiscsi_async_link_state_process(phba,
(struct be_async_event_link_state *) mcc_compl);
else
else {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX,
"BM_%d : Unsupported Async Event, flags"
" = 0x%08x\n",
mcc_compl->flags);
if (phba->state & BE_ADAPTER_LINK_UP) {
phba->state |= BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
}
}
} else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
atomic_dec(&phba->ctrl.mcc_obj.q.used);
@ -3678,14 +3697,16 @@ static void be_mcc_queues_destroy(struct beiscsi_hba *phba)
struct be_ctrl_info *ctrl = &phba->ctrl;
q = &phba->ctrl.mcc_obj.q;
if (q->created)
if (q->created) {
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
be_queue_free(phba, q);
be_queue_free(phba, q);
}
q = &phba->ctrl.mcc_obj.cq;
if (q->created)
if (q->created) {
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
be_queue_free(phba, q);
be_queue_free(phba, q);
}
}
static void hwi_cleanup(struct beiscsi_hba *phba)
@ -3729,8 +3750,10 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
for (i = 0; i < (phba->num_cpus); i++) {
q = &phwi_context->be_cq[i];
if (q->created)
if (q->created) {
be_queue_free(phba, q);
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
}
}
be_mcc_queues_destroy(phba);
@ -3740,8 +3763,10 @@ static void hwi_cleanup(struct beiscsi_hba *phba)
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)
if (q->created) {
be_queue_free(phba, q);
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
}
}
be_cmd_fw_uninit(ctrl);
}
@ -4328,8 +4353,14 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BM_%d : No boot session\n");
if (ret == -ENXIO)
phba->get_boot = 0;
return ret;
}
phba->get_boot = 0;
nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
sizeof(*session_resp),
&nonemb_cmd.dma);
@ -4369,6 +4400,9 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
memcpy(&phba->boot_sess, &session_resp->session_info,
sizeof(struct mgmt_session_info));
beiscsi_logout_fw_sess(phba,
phba->boot_sess.session_handle);
ret = 0;
boot_freemem:
@ -4580,11 +4614,13 @@ beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn,
spin_unlock_bh(&phba->mgmt_sgl_lock);
}
if (io_task->mtask_addr)
if (io_task->mtask_addr) {
pci_unmap_single(phba->pcidev,
io_task->mtask_addr,
io_task->mtask_data_count,
PCI_DMA_TODEVICE);
io_task->mtask_addr = 0;
}
}
/**
@ -5264,6 +5300,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
iscsi_host_free(phba->shost);
pci_disable_pcie_error_reporting(pcidev);
pci_set_drvdata(pcidev, NULL);
pci_release_regions(pcidev);
pci_disable_device(pcidev);
}
@ -5374,8 +5411,14 @@ beiscsi_hw_health_check(struct work_struct *work)
be_eqd_update(phba);
if (phba->state & BE_ADAPTER_CHECK_BOOT) {
phba->state &= ~BE_ADAPTER_CHECK_BOOT;
be_check_boot_session(phba);
if ((phba->get_boot > 0) && (!phba->boot_kset)) {
phba->get_boot--;
if (!(phba->get_boot % BE_GET_BOOT_TO))
be_check_boot_session(phba);
} else {
phba->state &= ~BE_ADAPTER_CHECK_BOOT;
phba->get_boot = 0;
}
}
beiscsi_ue_detect(phba);
@ -5738,6 +5781,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
iscsi_host_free(phba->shost);
pci_set_drvdata(pcidev, NULL);
disable_pci:
pci_release_regions(pcidev);
pci_disable_device(pcidev);
return ret;
}

View file

@ -36,7 +36,7 @@
#include <scsi/scsi_transport_iscsi.h>
#define DRV_NAME "be2iscsi"
#define BUILD_STR "10.4.114.0"
#define BUILD_STR "10.6.0.0"
#define BE_NAME "Avago Technologies OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
#define DRV_DESC BE_NAME " " "Driver"
@ -109,6 +109,9 @@
#define BEISCSI_CLEAN_UNLOAD 0x01
#define BEISCSI_EEH_UNLOAD 0x02
#define BE_GET_BOOT_RETRIES 45
#define BE_GET_BOOT_TO 20
/**
* hardware needs the async PDU buffers to be posted in multiples of 8
* So have atleast 8 of them by default
@ -413,6 +416,7 @@ struct beiscsi_hba {
} fw_config;
unsigned int state;
int get_boot;
bool fw_timeout;
bool ue_detected;
struct delayed_work beiscsi_hw_check_task;

View file

@ -1707,3 +1707,72 @@ void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
(params->dw[offsetof(struct amap_beiscsi_offload_params,
exp_statsn) / 32] + 1));
}
/**
* beiscsi_logout_fw_sess()- Firmware Session Logout
* @phba: Device priv structure instance
* @fw_sess_handle: FW session handle
*
* Logout from the FW established sessions.
* returns
* Success: 0
* Failure: Non-Zero Value
*
*/
int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
uint32_t fw_sess_handle)
{
struct be_ctrl_info *ctrl = &phba->ctrl;
struct be_mcc_wrb *wrb;
struct be_cmd_req_logout_fw_sess *req;
struct be_cmd_resp_logout_fw_sess *resp;
unsigned int tag;
int rc;
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : In bescsi_logout_fwboot_sess\n");
spin_lock(&ctrl->mbox_lock);
tag = alloc_mcc_tag(phba);
if (!tag) {
spin_unlock(&ctrl->mbox_lock);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
"BG_%d : MBX Tag Failure\n");
return -EINVAL;
}
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_ISCSI_INI,
OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
sizeof(struct be_cmd_req_logout_fw_sess));
/* Set the session handle */
req->session_handle = fw_sess_handle;
be_mcc_notify(phba);
spin_unlock(&ctrl->mbox_lock);
rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
if (rc) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
return -EBUSY;
}
resp = embedded_payload(wrb);
if (resp->session_status !=
BEISCSI_MGMT_SESSION_CLOSE) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
"BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
resp->session_status);
rc = -EINVAL;
}
return rc;
}

View file

@ -338,4 +338,7 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba);
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
struct be_set_eqd *, int num);
int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
uint32_t fw_sess_handle);
#endif

View file

@ -1173,8 +1173,10 @@ static void bnx2i_cleanup_task(struct iscsi_task *task)
bnx2i_send_cmd_cleanup_req(hba, task->dd_data);
spin_unlock_bh(&conn->session->back_lock);
spin_unlock_bh(&conn->session->frwd_lock);
wait_for_completion_timeout(&bnx2i_conn->cmd_cleanup_cmpl,
msecs_to_jiffies(ISCSI_CMD_CLEANUP_TIMEOUT));
spin_lock_bh(&conn->session->frwd_lock);
spin_lock_bh(&conn->session->back_lock);
}
bnx2i_iscsi_unmap_sg_list(task->dd_data);
@ -2093,7 +2095,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
else
/* wait for option-2 conn teardown */
wait_event_interruptible(bnx2i_ep->ofld_wait,
bnx2i_ep->state != EP_STATE_DISCONN_START);
((bnx2i_ep->state != EP_STATE_DISCONN_START)
&& (bnx2i_ep->state != EP_STATE_TCP_FIN_RCVD)));
if (signal_pending(current))
flush_signals(current);

View file

@ -3928,6 +3928,7 @@ csio_hw_init(struct csio_hw *hw)
evt_entry = kzalloc(sizeof(struct csio_evt_msg), GFP_KERNEL);
if (!evt_entry) {
rv = -ENOMEM;
csio_err(hw, "Failed to initialize eventq");
goto err_evtq_cleanup;
}

View file

@ -1,7 +1,7 @@
/*
* cxgb3i_offload.c: Chelsio S3xx iscsi offloaded tcp connection management
*
* Copyright (C) 2003-2008 Chelsio Communications. All rights reserved.
* Copyright (C) 2003-2015 Chelsio Communications. All rights reserved.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -32,8 +32,8 @@ static unsigned int dbg_level;
#define DRV_MODULE_NAME "cxgb3i"
#define DRV_MODULE_DESC "Chelsio T3 iSCSI Driver"
#define DRV_MODULE_VERSION "2.0.0"
#define DRV_MODULE_RELDATE "Jun. 2010"
#define DRV_MODULE_VERSION "2.0.1-ko"
#define DRV_MODULE_RELDATE "Apr. 2015"
static char version[] =
DRV_MODULE_DESC " " DRV_MODULE_NAME
@ -156,7 +156,7 @@ static int push_tx_frames(struct cxgbi_sock *csk, int req_completion);
static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
const struct l2t_entry *e)
{
unsigned int wscale = cxgbi_sock_compute_wscale(cxgb3i_rcv_win);
unsigned int wscale = cxgbi_sock_compute_wscale(csk->rcv_win);
struct cpl_act_open_req *req = (struct cpl_act_open_req *)skb->head;
skb->priority = CPL_PRIORITY_SETUP;
@ -172,7 +172,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
V_WND_SCALE(wscale) | V_MSS_IDX(csk->mss_idx) |
V_L2T_IDX(e->idx) | V_TX_CHANNEL(e->smt_idx));
req->opt0l = htonl(V_ULP_MODE(ULP2_MODE_ISCSI) |
V_RCV_BUFSIZ(cxgb3i_rcv_win>>10));
V_RCV_BUFSIZ(csk->rcv_win >> 10));
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p,%u,0x%lx,%u, %pI4:%u-%pI4:%u, %u,%u,%u.\n",
@ -369,7 +369,7 @@ static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb,
req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT |
V_TX_CPU_IDX(csk->rss_qid));
/* sendbuffer is in units of 32KB. */
req->param |= htonl(V_TX_SNDBUF(cxgb3i_snd_win >> 15));
req->param |= htonl(V_TX_SNDBUF(csk->snd_win >> 15));
cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT);
}
}
@ -503,8 +503,8 @@ static int do_act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
csk, csk->state, csk->flags, csk->tid);
csk->copied_seq = csk->rcv_wup = csk->rcv_nxt = rcv_isn;
if (cxgb3i_rcv_win > (M_RCV_BUFSIZ << 10))
csk->rcv_wup -= cxgb3i_rcv_win - (M_RCV_BUFSIZ << 10);
if (csk->rcv_win > (M_RCV_BUFSIZ << 10))
csk->rcv_wup -= csk->rcv_win - (M_RCV_BUFSIZ << 10);
cxgbi_sock_established(csk, ntohl(req->snd_isn), ntohs(req->tcp_opt));
@ -988,6 +988,8 @@ static int init_act_open(struct cxgbi_sock *csk)
goto rel_resource;
skb->sk = (struct sock *)csk;
set_arp_failure_handler(skb, act_open_arp_failure);
csk->snd_win = cxgb3i_snd_win;
csk->rcv_win = cxgb3i_rcv_win;
csk->wr_max_cred = csk->wr_cred = T3C_DATA(t3dev)->max_wrs - 1;
csk->wr_una_cred = 0;
@ -1320,8 +1322,6 @@ static void cxgb3i_dev_open(struct t3cdev *t3dev)
cdev->nports = adapter->params.nports;
cdev->mtus = adapter->params.mtus;
cdev->nmtus = NMTUS;
cdev->snd_win = cxgb3i_snd_win;
cdev->rcv_win = cxgb3i_rcv_win;
cdev->rx_credit_thres = cxgb3i_rx_credit_thres;
cdev->skb_tx_rsvd = CXGB3I_TX_HEADER_LEN;
cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr_norss);

View file

@ -1,7 +1,7 @@
/*
* cxgb3i.h: Chelsio S3xx iSCSI driver.
*
* Copyright (c) 2008 Chelsio Communications, Inc.
* Copyright (c) 2008-2015 Chelsio Communications, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1,7 +1,7 @@
/*
* cxgb4i.c: Chelsio T4 iSCSI driver.
*
* Copyright (c) 2010 Chelsio Communications, Inc.
* Copyright (c) 2010-2015 Chelsio Communications, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -36,11 +36,12 @@ static unsigned int dbg_level;
#define DRV_MODULE_NAME "cxgb4i"
#define DRV_MODULE_DESC "Chelsio T4/T5 iSCSI Driver"
#define DRV_MODULE_VERSION "0.9.4"
#define DRV_MODULE_VERSION "0.9.5-ko"
#define DRV_MODULE_RELDATE "Apr. 2015"
static char version[] =
DRV_MODULE_DESC " " DRV_MODULE_NAME
" v" DRV_MODULE_VERSION "\n";
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Chelsio Communications, Inc.");
MODULE_DESCRIPTION(DRV_MODULE_DESC);
@ -50,11 +51,13 @@ MODULE_LICENSE("GPL");
module_param(dbg_level, uint, 0644);
MODULE_PARM_DESC(dbg_level, "Debug flag (default=0)");
static int cxgb4i_rcv_win = 256 * 1024;
#define CXGB4I_DEFAULT_10G_RCV_WIN (256 * 1024)
static int cxgb4i_rcv_win = -1;
module_param(cxgb4i_rcv_win, int, 0644);
MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP reveive window in bytes");
static int cxgb4i_snd_win = 128 * 1024;
#define CXGB4I_DEFAULT_10G_SND_WIN (128 * 1024)
static int cxgb4i_snd_win = -1;
module_param(cxgb4i_snd_win, int, 0644);
MODULE_PARM_DESC(cxgb4i_snd_win, "TCP send window in bytes");
@ -196,10 +199,10 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
TX_CHAN_V(csk->tx_chan) |
SMAC_SEL_V(csk->smac_idx) |
ULP_MODE_V(ULP_MODE_ISCSI) |
RCV_BUFSIZ_V(cxgb4i_rcv_win >> 10);
RCV_BUFSIZ_V(csk->rcv_win >> 10);
opt2 = RX_CHANNEL_V(0) |
RSS_QUEUE_VALID_F |
(RX_FC_DISABLE_F) |
RSS_QUEUE_V(csk->rss_qid);
if (is_t4(lldi->adapter_type)) {
@ -228,6 +231,7 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
} else {
struct cpl_t5_act_open_req *req =
(struct cpl_t5_act_open_req *)skb->head;
u32 isn = (prandom_u32() & ~7UL) - 1;
INIT_TP_WR(req, 0);
OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
@ -241,7 +245,10 @@ static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb,
cxgb4_select_ntuple(
csk->cdev->ports[csk->port_id],
csk->l2t)));
opt2 |= 1 << 31;
req->rsvd = cpu_to_be32(isn);
opt2 |= T5_ISS_VALID;
opt2 |= T5_OPT_2_VALID_F;
req->opt2 = cpu_to_be32(opt2);
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@ -279,7 +286,7 @@ static void send_act_open_req6(struct cxgbi_sock *csk, struct sk_buff *skb,
TX_CHAN_V(csk->tx_chan) |
SMAC_SEL_V(csk->smac_idx) |
ULP_MODE_V(ULP_MODE_ISCSI) |
RCV_BUFSIZ_V(cxgb4i_rcv_win >> 10);
RCV_BUFSIZ_V(csk->rcv_win >> 10);
opt2 = RX_CHANNEL_V(0) |
RSS_QUEUE_VALID_F |
@ -544,7 +551,7 @@ static inline int send_tx_flowc_wr(struct cxgbi_sock *csk)
flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_RCVNXT;
flowc->mnemval[5].val = htonl(csk->rcv_nxt);
flowc->mnemval[6].mnemonic = FW_FLOWC_MNEM_SNDBUF;
flowc->mnemval[6].val = htonl(cxgb4i_snd_win);
flowc->mnemval[6].val = htonl(csk->snd_win);
flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;
flowc->mnemval[7].val = htonl(csk->advmss);
flowc->mnemval[8].mnemonic = 0;
@ -557,7 +564,7 @@ static inline int send_tx_flowc_wr(struct cxgbi_sock *csk)
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p, tid 0x%x, %u,%u,%u,%u,%u,%u,%u.\n",
csk, csk->tid, 0, csk->tx_chan, csk->rss_qid,
csk->snd_nxt, csk->rcv_nxt, cxgb4i_snd_win,
csk->snd_nxt, csk->rcv_nxt, csk->snd_win,
csk->advmss);
cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
@ -750,8 +757,8 @@ static void do_act_establish(struct cxgbi_device *cdev, struct sk_buff *skb)
* Causes the first RX_DATA_ACK to supply any Rx credits we couldn't
* pass through opt0.
*/
if (cxgb4i_rcv_win > (RCV_BUFSIZ_MASK << 10))
csk->rcv_wup -= cxgb4i_rcv_win - (RCV_BUFSIZ_MASK << 10);
if (csk->rcv_win > (RCV_BUFSIZ_MASK << 10))
csk->rcv_wup -= csk->rcv_win - (RCV_BUFSIZ_MASK << 10);
csk->advmss = lldi->mtus[TCPOPT_MSS_G(tcp_opt)] - 40;
if (TCPOPT_TSTAMP_G(tcp_opt))
@ -1367,6 +1374,8 @@ static int init_act_open(struct cxgbi_sock *csk)
unsigned int step;
unsigned int size, size6;
int t4 = is_t4(lldi->adapter_type);
unsigned int linkspeed;
unsigned int rcv_winf, snd_winf;
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
"csk 0x%p,%u,0x%lx,%u.\n",
@ -1440,6 +1449,21 @@ static int init_act_open(struct cxgbi_sock *csk)
csk->txq_idx = cxgb4_port_idx(ndev) * step;
step = lldi->nrxq / lldi->nchan;
csk->rss_qid = lldi->rxq_ids[cxgb4_port_idx(ndev) * step];
linkspeed = ((struct port_info *)netdev_priv(ndev))->link_cfg.speed;
csk->snd_win = cxgb4i_snd_win;
csk->rcv_win = cxgb4i_rcv_win;
if (cxgb4i_rcv_win <= 0) {
csk->rcv_win = CXGB4I_DEFAULT_10G_RCV_WIN;
rcv_winf = linkspeed / SPEED_10000;
if (rcv_winf)
csk->rcv_win *= rcv_winf;
}
if (cxgb4i_snd_win <= 0) {
csk->snd_win = CXGB4I_DEFAULT_10G_SND_WIN;
snd_winf = linkspeed / SPEED_10000;
if (snd_winf)
csk->snd_win *= snd_winf;
}
csk->wr_cred = lldi->wr_cred -
DIV_ROUND_UP(sizeof(struct cpl_abort_req), 16);
csk->wr_max_cred = csk->wr_cred;
@ -1758,8 +1782,6 @@ static void *t4_uld_add(const struct cxgb4_lld_info *lldi)
cdev->nports = lldi->nports;
cdev->mtus = lldi->mtus;
cdev->nmtus = NMTUS;
cdev->snd_win = cxgb4i_snd_win;
cdev->rcv_win = cxgb4i_rcv_win;
cdev->rx_credit_thres = cxgb4i_rx_credit_thres;
cdev->skb_tx_rsvd = CXGB4I_TX_HEADER_LEN;
cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr);

View file

@ -1,7 +1,7 @@
/*
* cxgb4i.h: Chelsio T4 iSCSI driver.
*
* Copyright (c) 2010 Chelsio Communications, Inc.
* Copyright (c) 2010-2015 Chelsio Communications, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +23,8 @@
#define CXGB4I_TX_HEADER_LEN \
(sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr))
#define T5_ISS_VALID (1 << 18)
struct ulptx_idata {
__be32 cmd_more;
__be32 len;

View file

@ -1,7 +1,7 @@
/*
* libcxgbi.c: Chelsio common library for T3/T4 iSCSI driver.
*
* Copyright (c) 2010 Chelsio Communications, Inc.
* Copyright (c) 2010-2015 Chelsio Communications, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -38,8 +38,12 @@ static unsigned int dbg_level;
#define DRV_MODULE_NAME "libcxgbi"
#define DRV_MODULE_DESC "Chelsio iSCSI driver library"
#define DRV_MODULE_VERSION "0.9.0"
#define DRV_MODULE_RELDATE "Jun. 2010"
#define DRV_MODULE_VERSION "0.9.1-ko"
#define DRV_MODULE_RELDATE "Apr. 2015"
static char version[] =
DRV_MODULE_DESC " " DRV_MODULE_NAME
" v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Chelsio Communications, Inc.");
MODULE_DESCRIPTION(DRV_MODULE_DESC);
@ -1126,11 +1130,11 @@ static int cxgbi_sock_send_pdus(struct cxgbi_sock *csk, struct sk_buff *skb)
goto out_err;
}
if (csk->write_seq - csk->snd_una >= cdev->snd_win) {
if (csk->write_seq - csk->snd_una >= csk->snd_win) {
log_debug(1 << CXGBI_DBG_PDU_TX,
"csk 0x%p,%u,0x%lx,%u, FULL %u-%u >= %u.\n",
csk, csk->state, csk->flags, csk->tid, csk->write_seq,
csk->snd_una, cdev->snd_win);
csk->snd_una, csk->snd_win);
err = -ENOBUFS;
goto out_err;
}
@ -1885,7 +1889,7 @@ static void csk_return_rx_credits(struct cxgbi_sock *csk, int copied)
"csk 0x%p,%u,0x%lx,%u, seq %u, wup %u, thre %u, %u.\n",
csk, csk->state, csk->flags, csk->tid, csk->copied_seq,
csk->rcv_wup, cdev->rx_credit_thres,
cdev->rcv_win);
csk->rcv_win);
if (csk->state != CTP_ESTABLISHED)
return;
@ -1896,7 +1900,7 @@ static void csk_return_rx_credits(struct cxgbi_sock *csk, int copied)
if (unlikely(cdev->rx_credit_thres == 0))
return;
must_send = credits + 16384 >= cdev->rcv_win;
must_send = credits + 16384 >= csk->rcv_win;
if (must_send || credits >= cdev->rx_credit_thres)
csk->rcv_wup += cdev->csk_send_rx_credits(csk, credits);
}
@ -2913,6 +2917,8 @@ static int __init libcxgbi_init_module(void)
sw_tag_idx_bits = (__ilog2_u32(ISCSI_ITT_MASK)) + 1;
sw_tag_age_bits = (__ilog2_u32(ISCSI_AGE_MASK)) + 1;
pr_info("%s", version);
pr_info("tag itt 0x%x, %u bits, age 0x%x, %u bits.\n",
ISCSI_ITT_MASK, sw_tag_idx_bits,
ISCSI_AGE_MASK, sw_tag_age_bits);

View file

@ -1,7 +1,7 @@
/*
* libcxgbi.h: Chelsio common library for T3/T4 iSCSI driver.
*
* Copyright (c) 2010 Chelsio Communications, Inc.
* Copyright (c) 2010-2015 Chelsio Communications, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -234,6 +234,8 @@ struct cxgbi_sock {
u32 snd_nxt;
u32 snd_una;
u32 write_seq;
u32 snd_win;
u32 rcv_win;
};
/*
@ -540,8 +542,6 @@ struct cxgbi_device {
struct iscsi_transport *itp;
unsigned int pfvf;
unsigned int snd_win;
unsigned int rcv_win;
unsigned int rx_credit_thres;
unsigned int skb_tx_rsvd;
unsigned int skb_rx_extra; /* for msg coalesced mode */

View file

@ -3562,7 +3562,6 @@ static struct scsi_host_template driver_template = {
.slave_configure = adpt_slave_configure,
.can_queue = MAX_TO_IOP_MESSAGES,
.this_id = 7,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -1764,7 +1764,6 @@ struct scsi_host_template fdomain_driver_template = {
.can_queue = 1,
.this_id = 6,
.sg_tablesize = 64,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};

File diff suppressed because it is too large Load diff

View file

@ -47,6 +47,7 @@ struct hpsa_scsi_dev_t {
unsigned char raid_level; /* from inquiry page 0xC1 */
unsigned char volume_offline; /* discovered via TUR or VPD */
u16 queue_depth; /* max queue_depth for this device */
atomic_t reset_cmds_out; /* Count of commands to-be affected */
atomic_t ioaccel_cmds_out; /* Only used for physical devices
* counts commands sent to physical
* device via "ioaccel" path.
@ -54,6 +55,8 @@ struct hpsa_scsi_dev_t {
u32 ioaccel_handle;
int offload_config; /* I/O accel RAID offload configured */
int offload_enabled; /* I/O accel RAID offload enabled */
int offload_to_be_enabled;
int hba_ioaccel_enabled;
int offload_to_mirror; /* Send next I/O accelerator RAID
* offload request to mirror drive
*/
@ -68,6 +71,13 @@ struct hpsa_scsi_dev_t {
* devices in order to honor physical device queue depth limits.
*/
struct hpsa_scsi_dev_t *phys_disk[RAID_MAP_MAX_ENTRIES];
int nphysical_disks;
int supports_aborts;
#define HPSA_DO_NOT_EXPOSE 0x0
#define HPSA_SG_ATTACH 0x1
#define HPSA_ULD_ATTACH 0x2
#define HPSA_SCSI_ADD (HPSA_SG_ATTACH | HPSA_ULD_ATTACH)
u8 expose_state;
};
struct reply_queue_buffer {
@ -133,7 +143,6 @@ struct ctlr_info {
struct CfgTable __iomem *cfgtable;
int interrupts_enabled;
int max_commands;
int last_allocation;
atomic_t commands_outstanding;
# define PERF_MODE_INT 0
# define DOORBELL_INT 1
@ -154,6 +163,7 @@ struct ctlr_info {
u8 max_cmd_sg_entries;
int chainsize;
struct SGDescriptor **cmd_sg_list;
struct ioaccel2_sg_element **ioaccel2_cmd_sg_list;
/* pointers to command and error info pool */
struct CommandList *cmd_pool;
@ -211,6 +221,7 @@ struct ctlr_info {
int remove_in_progress;
/* Address of h->q[x] is passed to intr handler to know which queue */
u8 q[MAX_REPLY_QUEUES];
char intrname[MAX_REPLY_QUEUES][16]; /* "hpsa0-msix00" names */
u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */
#define HPSATMF_BITS_SUPPORTED (1 << 0)
#define HPSATMF_PHYS_LUN_RESET (1 << 1)
@ -222,6 +233,7 @@ struct ctlr_info {
#define HPSATMF_PHYS_QRY_TASK (1 << 7)
#define HPSATMF_PHYS_QRY_TSET (1 << 8)
#define HPSATMF_PHYS_QRY_ASYNC (1 << 9)
#define HPSATMF_IOACCEL_ENABLED (1 << 15)
#define HPSATMF_MASK_SUPPORTED (1 << 16)
#define HPSATMF_LOG_LUN_RESET (1 << 17)
#define HPSATMF_LOG_NEX_RESET (1 << 18)
@ -251,8 +263,13 @@ struct ctlr_info {
struct list_head offline_device_list;
int acciopath_status;
int raid_offload_debug;
int needs_abort_tags_swizzled;
struct workqueue_struct *resubmit_wq;
struct workqueue_struct *rescan_ctlr_wq;
atomic_t abort_cmds_available;
wait_queue_head_t abort_cmd_wait_queue;
wait_queue_head_t event_sync_wait_queue;
struct mutex reset_mutex;
};
struct offline_device_entry {

View file

@ -42,8 +42,22 @@
#define CMD_UNSOLICITED_ABORT 0x000A
#define CMD_TIMEOUT 0x000B
#define CMD_UNABORTABLE 0x000C
#define CMD_TMF_STATUS 0x000D
#define CMD_IOACCEL_DISABLED 0x000E
#define CMD_CTLR_LOCKUP 0xffff
/* Note: CMD_CTLR_LOCKUP is not a value defined by the CISS spec
* it is a value defined by the driver that commands can be marked
* with when a controller lockup has been detected by the driver
*/
/* TMF function status values */
#define CISS_TMF_COMPLETE 0x00
#define CISS_TMF_INVALID_FRAME 0x02
#define CISS_TMF_NOT_SUPPORTED 0x04
#define CISS_TMF_FAILED 0x05
#define CISS_TMF_SUCCESS 0x08
#define CISS_TMF_WRONG_LUN 0x09
#define CISS_TMF_OVERLAPPED_TAG 0x0a
/* Unit Attentions ASC's as defined for the MSA2012sa */
#define POWER_OR_RESET 0x29
@ -240,6 +254,7 @@ struct ReportLUNdata {
struct ext_report_lun_entry {
u8 lunid[8];
#define MASKED_DEVICE(x) ((x)[3] & 0xC0)
#define GET_BMIC_BUS(lunid) ((lunid)[7] & 0x3F)
#define GET_BMIC_LEVEL_TWO_TARGET(lunid) ((lunid)[6])
#define GET_BMIC_DRIVE_NUMBER(lunid) (((GET_BMIC_BUS((lunid)) - 1) << 8) + \
@ -247,6 +262,8 @@ struct ext_report_lun_entry {
u8 wwid[8];
u8 device_type;
u8 device_flags;
#define NON_DISK_PHYS_DEV(x) ((x)[17] & 0x01)
#define PHYS_IOACCEL(x) ((x)[17] & 0x08)
u8 lun_count; /* multi-lun device, how many luns */
u8 redundant_paths;
u32 ioaccel_handle; /* ioaccel1 only uses lower 16 bits */
@ -379,6 +396,7 @@ struct ErrorInfo {
#define CMD_SCSI 0x03
#define CMD_IOACCEL1 0x04
#define CMD_IOACCEL2 0x05
#define IOACCEL2_TMF 0x06
#define DIRECT_LOOKUP_SHIFT 4
#define DIRECT_LOOKUP_MASK (~((1 << DIRECT_LOOKUP_SHIFT) - 1))
@ -421,7 +439,10 @@ struct CommandList {
* not used.
*/
struct hpsa_scsi_dev_t *phys_disk;
atomic_t refcount; /* Must be last to avoid memset in cmd_alloc */
int abort_pending;
struct hpsa_scsi_dev_t *reset_pending;
atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */
} __aligned(COMMANDLIST_ALIGNMENT);
/* Max S/G elements in I/O accelerator command */
@ -515,6 +536,12 @@ struct io_accel2_scsi_response {
#define IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL 0x28
#define IOACCEL2_STATUS_SR_TASK_COMP_ABORTED 0x40
#define IOACCEL2_STATUS_SR_IOACCEL_DISABLED 0x0E
#define IOACCEL2_STATUS_SR_IO_ERROR 0x01
#define IOACCEL2_STATUS_SR_IO_ABORTED 0x02
#define IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE 0x03
#define IOACCEL2_STATUS_SR_INVALID_DEVICE 0x04
#define IOACCEL2_STATUS_SR_UNDERRUN 0x51
#define IOACCEL2_STATUS_SR_OVERRUN 0x75
u8 data_present; /* low 2 bits */
#define IOACCEL2_NO_DATAPRESENT 0x000
#define IOACCEL2_RESPONSE_DATAPRESENT 0x001
@ -567,6 +594,7 @@ struct io_accel2_cmd {
#define IOACCEL2_DIR_NO_DATA 0x00
#define IOACCEL2_DIR_DATA_IN 0x01
#define IOACCEL2_DIR_DATA_OUT 0x02
#define IOACCEL2_TMF_ABORT 0x01
/*
* SCSI Task Management Request format for Accelerator Mode 2
*/
@ -575,13 +603,13 @@ struct hpsa_tmf_struct {
u8 reply_queue; /* Reply Queue ID */
u8 tmf; /* Task Management Function */
u8 reserved1; /* byte 3 Reserved */
u32 it_nexus; /* SCSI I-T Nexus */
__le32 it_nexus; /* SCSI I-T Nexus */
u8 lun_id[8]; /* LUN ID for TMF request */
__le64 tag; /* cciss tag associated w/ request */
__le64 abort_tag; /* cciss tag of SCSI cmd or TMF to abort */
__le64 error_ptr; /* Error Pointer */
__le32 error_len; /* Error Length */
};
} __aligned(IOACCEL2_COMMANDLIST_ALIGNMENT);
/* Configuration Table Structure */
struct HostWrite {

View file

@ -1109,7 +1109,6 @@ static struct scsi_host_template imm_template = {
.bios_param = imm_biosparam,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
.can_queue = 1,
.slave_alloc = imm_adjust_queue,

View file

@ -2833,7 +2833,6 @@ static struct scsi_host_template initio_template = {
.can_queue = MAX_TARGETS * i91u_MAXQUEUE,
.this_id = 1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -272,7 +272,7 @@
#define IPR_RUNTIME_RESET 0x40000000
#define IPR_IPL_INIT_MIN_STAGE_TIME 5
#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 15
#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 30
#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0
#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000
#define IPR_IPL_INIT_STAGE_MASK 0xff000000

View file

@ -206,10 +206,6 @@ module_param(ips, charp, 0);
#define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
#define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
#endif
#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
PCI_DMA_BIDIRECTIONAL : \
@ -6788,6 +6784,11 @@ ips_remove_device(struct pci_dev *pci_dev)
static int __init
ips_module_init(void)
{
#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
printk(KERN_ERR "ips: This driver has only been tested on the x86/ia64/x86_64 platforms\n");
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
#endif
if (pci_register_driver(&ips_pci_driver) < 0)
return -ENODEV;
ips_driver_template.module = THIS_MODULE;

View file

@ -160,7 +160,6 @@ static struct scsi_host_template isci_sht = {
.change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param,
.can_queue = ISCI_CAN_QUEUE_VAL,
.cmd_per_lun = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,

View file

@ -230,6 +230,8 @@ struct lpfc_stats {
uint32_t elsRcvRRQ;
uint32_t elsRcvRTV;
uint32_t elsRcvECHO;
uint32_t elsRcvLCB;
uint32_t elsRcvRDP;
uint32_t elsXmitFLOGI;
uint32_t elsXmitFDISC;
uint32_t elsXmitPLOGI;

View file

@ -498,3 +498,5 @@ bool lpfc_disable_oas_lun(struct lpfc_hba *, struct lpfc_name *,
bool lpfc_find_next_oas_lun(struct lpfc_hba *, struct lpfc_name *,
struct lpfc_name *, uint64_t *, struct lpfc_name *,
struct lpfc_name *, uint64_t *, uint32_t *);
int lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox);
void lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb);

View file

@ -79,7 +79,6 @@ struct lpfc_nodelist {
struct lpfc_name nlp_portname;
struct lpfc_name nlp_nodename;
uint32_t nlp_flag; /* entry flags */
uint32_t nlp_add_flag; /* additional flags */
uint32_t nlp_DID; /* FC D_ID of entry */
uint32_t nlp_last_elscmd; /* Last ELS cmd sent */
uint16_t nlp_type;
@ -147,6 +146,7 @@ struct lpfc_node_rrq {
#define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */
#define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */
#define NLP_ISSUE_LOGO 0x00400000 /* waiting to issue a LOGO */
#define NLP_IN_DEV_LOSS 0x00800000 /* devloss in progress */
#define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful
ACC */
#define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from
@ -158,8 +158,6 @@ struct lpfc_node_rrq {
#define NLP_FIRSTBURST 0x40000000 /* Target supports FirstBurst */
#define NLP_RPI_REGISTERED 0x80000000 /* nlp_rpi is valid */
/* Defines for nlp_add_flag (uint32) */
#define NLP_IN_DEV_LOSS 0x00000001 /* Dev Loss processing in progress */
/* ndlp usage management macros */
#define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \

View file

@ -1509,12 +1509,14 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
struct lpfc_nodelist *ndlp)
{
struct lpfc_vport *vport = ndlp->vport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_nodelist *new_ndlp;
struct lpfc_rport_data *rdata;
struct fc_rport *rport;
struct serv_parm *sp;
uint8_t name[sizeof(struct lpfc_name)];
uint32_t rc, keepDID = 0;
uint32_t rc, keepDID = 0, keep_nlp_flag = 0;
uint16_t keep_nlp_state;
int put_node;
int put_rport;
unsigned long *active_rrqs_xri_bitmap = NULL;
@ -1603,11 +1605,14 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
ndlp->active_rrqs_xri_bitmap,
phba->cfg_rrq_xri_bitmap_sz);
if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_lock_irq(shost->host_lock);
keep_nlp_flag = new_ndlp->nlp_flag;
new_ndlp->nlp_flag = ndlp->nlp_flag;
ndlp->nlp_flag = keep_nlp_flag;
spin_unlock_irq(shost->host_lock);
/* Set state will put new_ndlp on to node list if not already done */
/* Set nlp_states accordingly */
keep_nlp_state = new_ndlp->nlp_state;
lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
/* Move this back to NPR state */
@ -1624,8 +1629,9 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
if (rport) {
rdata = rport->dd_data;
if (rdata->pnode == ndlp) {
lpfc_nlp_put(ndlp);
/* break the link before dropping the ref */
ndlp->rport = NULL;
lpfc_nlp_put(ndlp);
rdata->pnode = lpfc_nlp_get(new_ndlp);
new_ndlp->rport = rport;
}
@ -1648,7 +1654,9 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
memcpy(ndlp->active_rrqs_xri_bitmap,
active_rrqs_xri_bitmap,
phba->cfg_rrq_xri_bitmap_sz);
lpfc_drop_node(vport, ndlp);
if (!NLP_CHK_NODE_ACT(ndlp))
lpfc_drop_node(vport, ndlp);
}
else {
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
@ -1665,20 +1673,13 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
active_rrqs_xri_bitmap,
phba->cfg_rrq_xri_bitmap_sz);
/* Since we are swapping the ndlp passed in with the new one
* and the did has already been swapped, copy over state.
* The new WWNs are already in new_ndlp since thats what
* we looked it up by in the begining of this routine.
*/
new_ndlp->nlp_state = ndlp->nlp_state;
/* Since we are switching over to the new_ndlp, the old
* ndlp should be put in the NPR state, unless we have
* already started re-discovery on it.
/* Since we are switching over to the new_ndlp,
* reset the old ndlp state
*/
if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
(ndlp->nlp_state == NLP_STE_MAPPED_NODE))
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
keep_nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_set_state(vport, ndlp, keep_nlp_state);
/* Fix up the rport accordingly */
rport = ndlp->rport;
@ -3667,15 +3668,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
* At this point, the driver is done so release the IOCB
*/
lpfc_els_free_iocb(phba, cmdiocb);
/*
* Remove the ndlp reference if it's a fabric node that has
* sent us an unsolicted LOGO.
*/
if (ndlp->nlp_type & NLP_FABRIC)
lpfc_nlp_put(ndlp);
return;
}
/**
@ -4020,7 +4012,9 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
ndlp->nlp_rpi, vport->fc_flag);
if (ndlp->nlp_flag & NLP_LOGO_ACC) {
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED ||
ndlp->nlp_flag & NLP_REG_LOGIN_SEND))
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
spin_unlock_irq(shost->host_lock);
elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
} else {
@ -4587,16 +4581,16 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
if (!NLP_CHK_NODE_ACT(ndlp))
continue;
if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
(ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
(ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
(ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
(ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
(ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
(ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
ndlp->nlp_prev_state = ndlp->nlp_state;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
sentplogi++;
vport->num_disc_nodes++;
if (vport->num_disc_nodes >=
vport->cfg_discovery_threads) {
vport->cfg_discovery_threads) {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_NLP_MORE;
spin_unlock_irq(shost->host_lock);
@ -4615,6 +4609,660 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
return sentplogi;
}
void
lpfc_rdp_res_link_service(struct fc_rdp_link_service_desc *desc,
uint32_t word0)
{
desc->tag = cpu_to_be32(RDP_LINK_SERVICE_DESC_TAG);
desc->payload.els_req = word0;
desc->length = cpu_to_be32(sizeof(desc->payload));
}
void
lpfc_rdp_res_sfp_desc(struct fc_rdp_sfp_desc *desc,
uint8_t *page_a0, uint8_t *page_a2)
{
uint16_t wavelength;
uint16_t temperature;
uint16_t rx_power;
uint16_t tx_bias;
uint16_t tx_power;
uint16_t vcc;
uint16_t flag = 0;
struct sff_trasnceiver_codes_byte4 *trasn_code_byte4;
struct sff_trasnceiver_codes_byte5 *trasn_code_byte5;
desc->tag = cpu_to_be32(RDP_SFP_DESC_TAG);
trasn_code_byte4 = (struct sff_trasnceiver_codes_byte4 *)
&page_a0[SSF_TRANSCEIVER_CODE_B4];
trasn_code_byte5 = (struct sff_trasnceiver_codes_byte5 *)
&page_a0[SSF_TRANSCEIVER_CODE_B5];
if ((trasn_code_byte4->fc_sw_laser) ||
(trasn_code_byte5->fc_sw_laser_sl) ||
(trasn_code_byte5->fc_sw_laser_sn)) { /* check if its short WL */
flag |= (SFP_FLAG_PT_SWLASER << SFP_FLAG_PT_SHIFT);
} else if (trasn_code_byte4->fc_lw_laser) {
wavelength = (page_a0[SSF_WAVELENGTH_B1] << 8) |
page_a0[SSF_WAVELENGTH_B0];
if (wavelength == SFP_WAVELENGTH_LC1310)
flag |= SFP_FLAG_PT_LWLASER_LC1310 << SFP_FLAG_PT_SHIFT;
if (wavelength == SFP_WAVELENGTH_LL1550)
flag |= SFP_FLAG_PT_LWLASER_LL1550 << SFP_FLAG_PT_SHIFT;
}
/* check if its SFP+ */
flag |= ((page_a0[SSF_IDENTIFIER] == SFF_PG0_IDENT_SFP) ?
SFP_FLAG_CT_SFP_PLUS : SFP_FLAG_CT_UNKNOWN)
<< SFP_FLAG_CT_SHIFT;
/* check if its OPTICAL */
flag |= ((page_a0[SSF_CONNECTOR] == SFF_PG0_CONNECTOR_LC) ?
SFP_FLAG_IS_OPTICAL_PORT : 0)
<< SFP_FLAG_IS_OPTICAL_SHIFT;
temperature = (page_a2[SFF_TEMPERATURE_B1] << 8 |
page_a2[SFF_TEMPERATURE_B0]);
vcc = (page_a2[SFF_VCC_B1] << 8 |
page_a2[SFF_VCC_B0]);
tx_power = (page_a2[SFF_TXPOWER_B1] << 8 |
page_a2[SFF_TXPOWER_B0]);
tx_bias = (page_a2[SFF_TX_BIAS_CURRENT_B1] << 8 |
page_a2[SFF_TX_BIAS_CURRENT_B0]);
rx_power = (page_a2[SFF_RXPOWER_B1] << 8 |
page_a2[SFF_RXPOWER_B0]);
desc->sfp_info.temperature = cpu_to_be16(temperature);
desc->sfp_info.rx_power = cpu_to_be16(rx_power);
desc->sfp_info.tx_bias = cpu_to_be16(tx_bias);
desc->sfp_info.tx_power = cpu_to_be16(tx_power);
desc->sfp_info.vcc = cpu_to_be16(vcc);
desc->sfp_info.flags = cpu_to_be16(flag);
desc->length = cpu_to_be32(sizeof(desc->sfp_info));
}
void
lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc,
READ_LNK_VAR *stat)
{
uint32_t type;
desc->tag = cpu_to_be32(RDP_LINK_ERROR_STATUS_DESC_TAG);
type = VN_PT_PHY_PF_PORT << VN_PT_PHY_SHIFT;
desc->info.port_type = cpu_to_be32(type);
desc->info.link_status.link_failure_cnt =
cpu_to_be32(stat->linkFailureCnt);
desc->info.link_status.loss_of_synch_cnt =
cpu_to_be32(stat->lossSyncCnt);
desc->info.link_status.loss_of_signal_cnt =
cpu_to_be32(stat->lossSignalCnt);
desc->info.link_status.primitive_seq_proto_err =
cpu_to_be32(stat->primSeqErrCnt);
desc->info.link_status.invalid_trans_word =
cpu_to_be32(stat->invalidXmitWord);
desc->info.link_status.invalid_crc_cnt = cpu_to_be32(stat->crcCnt);
desc->length = cpu_to_be32(sizeof(desc->info));
}
void
lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
{
uint16_t rdp_cap = 0;
uint16_t rdp_speed;
desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG);
switch (phba->sli4_hba.link_state.speed) {
case LPFC_FC_LA_SPEED_1G:
rdp_speed = RDP_PS_1GB;
break;
case LPFC_FC_LA_SPEED_2G:
rdp_speed = RDP_PS_2GB;
break;
case LPFC_FC_LA_SPEED_4G:
rdp_speed = RDP_PS_4GB;
break;
case LPFC_FC_LA_SPEED_8G:
rdp_speed = RDP_PS_8GB;
break;
case LPFC_FC_LA_SPEED_10G:
rdp_speed = RDP_PS_10GB;
break;
case LPFC_FC_LA_SPEED_16G:
rdp_speed = RDP_PS_16GB;
break;
case LPFC_FC_LA_SPEED_32G:
rdp_speed = RDP_PS_32GB;
break;
default:
rdp_speed = RDP_PS_UNKNOWN;
break;
}
desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
if (phba->lmt & LMT_16Gb)
rdp_cap |= RDP_PS_16GB;
if (phba->lmt & LMT_10Gb)
rdp_cap |= RDP_PS_10GB;
if (phba->lmt & LMT_8Gb)
rdp_cap |= RDP_PS_8GB;
if (phba->lmt & LMT_4Gb)
rdp_cap |= RDP_PS_4GB;
if (phba->lmt & LMT_2Gb)
rdp_cap |= RDP_PS_2GB;
if (phba->lmt & LMT_1Gb)
rdp_cap |= RDP_PS_1GB;
if (rdp_cap == 0)
rdp_cap = RDP_CAP_UNKNOWN;
desc->info.port_speed.capabilities = cpu_to_be16(rdp_cap);
desc->length = cpu_to_be32(sizeof(desc->info));
}
void
lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc,
struct lpfc_hba *phba)
{
desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG);
memcpy(desc->port_names.wwnn, phba->wwnn,
sizeof(desc->port_names.wwnn));
memcpy(desc->port_names.wwpn, &phba->wwpn,
sizeof(desc->port_names.wwpn));
desc->length = cpu_to_be32(sizeof(desc->port_names));
}
void
lpfc_rdp_res_attach_port_names(struct fc_rdp_port_name_desc *desc,
struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG);
if (vport->fc_flag & FC_FABRIC) {
memcpy(desc->port_names.wwnn, &vport->fabric_nodename,
sizeof(desc->port_names.wwnn));
memcpy(desc->port_names.wwpn, &vport->fabric_portname,
sizeof(desc->port_names.wwpn));
} else { /* Point to Point */
memcpy(desc->port_names.wwnn, &ndlp->nlp_nodename,
sizeof(desc->port_names.wwnn));
memcpy(desc->port_names.wwnn, &ndlp->nlp_portname,
sizeof(desc->port_names.wwpn));
}
desc->length = cpu_to_be32(sizeof(desc->port_names));
}
void
lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context,
int status)
{
struct lpfc_nodelist *ndlp = rdp_context->ndlp;
struct lpfc_vport *vport = ndlp->vport;
struct lpfc_iocbq *elsiocb;
IOCB_t *icmd;
uint8_t *pcmd;
struct ls_rjt *stat;
struct fc_rdp_res_frame *rdp_res;
uint32_t cmdsize;
int rc;
if (status != SUCCESS)
goto error;
cmdsize = sizeof(struct fc_rdp_res_frame);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize,
lpfc_max_els_tries, rdp_context->ndlp,
rdp_context->ndlp->nlp_DID, ELS_CMD_ACC);
lpfc_nlp_put(ndlp);
if (!elsiocb)
goto free_rdp_context;
icmd = &elsiocb->iocb;
icmd->ulpContext = rdp_context->rx_id;
icmd->unsli3.rcvsli3.ox_id = rdp_context->ox_id;
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"2171 Xmit RDP response tag x%x xri x%x, "
"did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x",
elsiocb->iotag, elsiocb->iocb.ulpContext,
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
ndlp->nlp_rpi);
rdp_res = (struct fc_rdp_res_frame *)
(((struct lpfc_dmabuf *) elsiocb->context2)->virt);
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
memset(pcmd, 0, sizeof(struct fc_rdp_res_frame));
*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
/* For RDP payload */
lpfc_rdp_res_link_service(&rdp_res->link_service_desc, ELS_CMD_RDP);
lpfc_rdp_res_sfp_desc(&rdp_res->sfp_desc,
rdp_context->page_a0, rdp_context->page_a2);
lpfc_rdp_res_speed(&rdp_res->portspeed_desc, phba);
lpfc_rdp_res_link_error(&rdp_res->link_error_desc,
&rdp_context->link_stat);
lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba);
lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc,
vport, ndlp);
rdp_res->length = cpu_to_be32(RDP_DESC_PAYLOAD_SIZE);
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitACC++;
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR)
lpfc_els_free_iocb(phba, elsiocb);
kfree(rdp_context);
return;
error:
cmdsize = 2 * sizeof(uint32_t);
elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, lpfc_max_els_tries,
ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT);
lpfc_nlp_put(ndlp);
if (!elsiocb)
goto free_rdp_context;
icmd = &elsiocb->iocb;
icmd->ulpContext = rdp_context->rx_id;
icmd->unsli3.rcvsli3.ox_id = rdp_context->ox_id;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
stat = (struct ls_rjt *)(pcmd + sizeof(uint32_t));
stat->un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
phba->fc_stat.elsXmitLSRJT++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR)
lpfc_els_free_iocb(phba, elsiocb);
free_rdp_context:
kfree(rdp_context);
}
int
lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
{
LPFC_MBOXQ_t *mbox = NULL;
int rc;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) {
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_ELS,
"7105 failed to allocate mailbox memory");
return 1;
}
if (lpfc_sli4_dump_page_a0(phba, mbox))
goto prep_mbox_fail;
mbox->vport = rdp_context->ndlp->vport;
mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
goto issue_mbox_fail;
return 0;
prep_mbox_fail:
issue_mbox_fail:
mempool_free(mbox, phba->mbox_mem_pool);
return 1;
}
/*
* lpfc_els_rcv_rdp - Process an unsolicited RDP ELS.
* @vport: pointer to a host virtual N_Port data structure.
* @cmdiocb: pointer to lpfc command iocb data structure.
* @ndlp: pointer to a node-list data structure.
*
* This routine processes an unsolicited RDP(Read Diagnostic Parameters)
* IOCB. First, the payload of the unsolicited RDP is checked.
* Then it will (1) send MBX_DUMP_MEMORY, Embedded DMP_LMSD sub command TYPE-3
* for Page A0, (2) send MBX_DUMP_MEMORY, DMP_LMSD for Page A2,
* (3) send MBX_READ_LNK_STAT to get link stat, (4) Call lpfc_els_rdp_cmpl
* gather all data and send RDP response.
*
* Return code
* 0 - Sent the acc response
* 1 - Sent the reject response.
*/
static int
lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
{
struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd;
uint8_t rjt_err, rjt_expl = LSEXP_NOTHING_MORE;
struct fc_rdp_req_frame *rdp_req;
struct lpfc_rdp_context *rdp_context;
IOCB_t *cmd = NULL;
struct ls_rjt stat;
if (phba->sli_rev < LPFC_SLI_REV4 ||
(bf_get(lpfc_sli_intf_if_type,
&phba->sli4_hba.sli_intf) !=
LPFC_SLI_INTF_IF_TYPE_2)) {
rjt_err = LSRJT_UNABLE_TPC;
rjt_expl = LSEXP_REQ_UNSUPPORTED;
goto error;
}
if (phba->sli_rev < LPFC_SLI_REV4 || (phba->hba_flag & HBA_FCOE_MODE)) {
rjt_err = LSRJT_UNABLE_TPC;
rjt_expl = LSEXP_REQ_UNSUPPORTED;
goto error;
}
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
rdp_req = (struct fc_rdp_req_frame *) pcmd->virt;
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"2422 ELS RDP Request "
"dec len %d tag x%x port_id %d len %d\n",
be32_to_cpu(rdp_req->rdp_des_length),
be32_to_cpu(rdp_req->nport_id_desc.tag),
be32_to_cpu(rdp_req->nport_id_desc.nport_id),
be32_to_cpu(rdp_req->nport_id_desc.length));
if (sizeof(struct fc_rdp_nport_desc) !=
be32_to_cpu(rdp_req->rdp_des_length))
goto rjt_logerr;
if (RDP_N_PORT_DESC_TAG != be32_to_cpu(rdp_req->nport_id_desc.tag))
goto rjt_logerr;
if (RDP_NPORT_ID_SIZE !=
be32_to_cpu(rdp_req->nport_id_desc.length))
goto rjt_logerr;
rdp_context = kmalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL);
if (!rdp_context) {
rjt_err = LSRJT_UNABLE_TPC;
goto error;
}
memset(rdp_context, 0, sizeof(struct lpfc_rdp_context));
cmd = &cmdiocb->iocb;
rdp_context->ndlp = lpfc_nlp_get(ndlp);
rdp_context->ox_id = cmd->unsli3.rcvsli3.ox_id;
rdp_context->rx_id = cmd->ulpContext;
rdp_context->cmpl = lpfc_els_rdp_cmpl;
if (lpfc_get_rdp_info(phba, rdp_context)) {
lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_ELS,
"2423 Unable to send mailbox");
kfree(rdp_context);
rjt_err = LSRJT_UNABLE_TPC;
lpfc_nlp_put(ndlp);
goto error;
}
return 0;
rjt_logerr:
rjt_err = LSRJT_LOGICAL_ERR;
error:
memset(&stat, 0, sizeof(stat));
stat.un.b.lsRjtRsnCode = rjt_err;
stat.un.b.lsRjtRsnCodeExp = rjt_expl;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
return 1;
}
static void
lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
MAILBOX_t *mb;
IOCB_t *icmd;
uint8_t *pcmd;
struct lpfc_iocbq *elsiocb;
struct lpfc_nodelist *ndlp;
struct ls_rjt *stat;
union lpfc_sli4_cfg_shdr *shdr;
struct lpfc_lcb_context *lcb_context;
struct fc_lcb_res_frame *lcb_res;
uint32_t cmdsize, shdr_status, shdr_add_status;
int rc;
mb = &pmb->u.mb;
lcb_context = (struct lpfc_lcb_context *)pmb->context1;
ndlp = lcb_context->ndlp;
pmb->context1 = NULL;
pmb->context2 = NULL;
shdr = (union lpfc_sli4_cfg_shdr *)
&pmb->u.mqe.un.beacon_config.header.cfg_shdr;
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX,
"0194 SET_BEACON_CONFIG mailbox "
"completed with status x%x add_status x%x,"
" mbx status x%x\n",
shdr_status, shdr_add_status, mb->mbxStatus);
if (mb->mbxStatus && !(shdr_status &&
shdr_add_status == ADD_STATUS_OPERATION_ALREADY_ACTIVE)) {
mempool_free(pmb, phba->mbox_mem_pool);
goto error;
}
mempool_free(pmb, phba->mbox_mem_pool);
cmdsize = sizeof(struct fc_lcb_res_frame);
elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
lpfc_max_els_tries, ndlp,
ndlp->nlp_DID, ELS_CMD_ACC);
/* Decrement the ndlp reference count from previous mbox command */
lpfc_nlp_put(ndlp);
if (!elsiocb)
goto free_lcb_context;
lcb_res = (struct fc_lcb_res_frame *)
(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
icmd = &elsiocb->iocb;
icmd->ulpContext = lcb_context->rx_id;
icmd->unsli3.rcvsli3.ox_id = lcb_context->ox_id;
pcmd = (uint8_t *)(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
*((uint32_t *)(pcmd)) = ELS_CMD_ACC;
lcb_res->lcb_sub_command = lcb_context->sub_command;
lcb_res->lcb_type = lcb_context->type;
lcb_res->lcb_frequency = lcb_context->frequency;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitACC++;
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR)
lpfc_els_free_iocb(phba, elsiocb);
kfree(lcb_context);
return;
error:
cmdsize = sizeof(struct fc_lcb_res_frame);
elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
lpfc_max_els_tries, ndlp,
ndlp->nlp_DID, ELS_CMD_LS_RJT);
lpfc_nlp_put(ndlp);
if (!elsiocb)
goto free_lcb_context;
icmd = &elsiocb->iocb;
icmd->ulpContext = lcb_context->rx_id;
icmd->unsli3.rcvsli3.ox_id = lcb_context->ox_id;
pcmd = (uint8_t *)(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
*((uint32_t *)(pcmd)) = ELS_CMD_LS_RJT;
stat = (struct ls_rjt *)(pcmd + sizeof(uint32_t));
stat->un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitLSRJT++;
rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
if (rc == IOCB_ERROR)
lpfc_els_free_iocb(phba, elsiocb);
free_lcb_context:
kfree(lcb_context);
}
static int
lpfc_sli4_set_beacon(struct lpfc_vport *vport,
struct lpfc_lcb_context *lcb_context,
uint32_t beacon_state)
{
struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *mbox = NULL;
uint32_t len;
int rc;
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox)
return 1;
len = sizeof(struct lpfc_mbx_set_beacon_config) -
sizeof(struct lpfc_sli4_cfg_mhdr);
lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
LPFC_MBOX_OPCODE_SET_BEACON_CONFIG, len,
LPFC_SLI4_MBX_EMBED);
mbox->context1 = (void *)lcb_context;
mbox->vport = phba->pport;
mbox->mbox_cmpl = lpfc_els_lcb_rsp;
bf_set(lpfc_mbx_set_beacon_port_num, &mbox->u.mqe.un.beacon_config,
phba->sli4_hba.physical_port);
bf_set(lpfc_mbx_set_beacon_state, &mbox->u.mqe.un.beacon_config,
beacon_state);
bf_set(lpfc_mbx_set_beacon_port_type, &mbox->u.mqe.un.beacon_config, 1);
bf_set(lpfc_mbx_set_beacon_duration, &mbox->u.mqe.un.beacon_config, 0);
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
mempool_free(mbox, phba->mbox_mem_pool);
return 1;
}
return 0;
}
/**
* lpfc_els_rcv_lcb - Process an unsolicited LCB
* @vport: pointer to a host virtual N_Port data structure.
* @cmdiocb: pointer to lpfc command iocb data structure.
* @ndlp: pointer to a node-list data structure.
*
* This routine processes an unsolicited LCB(LINK CABLE BEACON) IOCB.
* First, the payload of the unsolicited LCB is checked.
* Then based on Subcommand beacon will either turn on or off.
*
* Return code
* 0 - Sent the acc response
* 1 - Sent the reject response.
**/
static int
lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
{
struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd;
IOCB_t *icmd;
uint8_t *lp;
struct fc_lcb_request_frame *beacon;
struct lpfc_lcb_context *lcb_context;
uint8_t state, rjt_err;
struct ls_rjt stat;
icmd = &cmdiocb->iocb;
pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
lp = (uint8_t *)pcmd->virt;
beacon = (struct fc_lcb_request_frame *)pcmd->virt;
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"0192 ELS LCB Data x%x x%x x%x x%x sub x%x "
"type x%x frequency %x duration x%x\n",
lp[0], lp[1], lp[2],
beacon->lcb_command,
beacon->lcb_sub_command,
beacon->lcb_type,
beacon->lcb_frequency,
be16_to_cpu(beacon->lcb_duration));
if (phba->sli_rev < LPFC_SLI_REV4 ||
(bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
LPFC_SLI_INTF_IF_TYPE_2)) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
lcb_context = kmalloc(sizeof(struct lpfc_lcb_context), GFP_KERNEL);
if (phba->hba_flag & HBA_FCOE_MODE) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
if (beacon->lcb_frequency == 0) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
if ((beacon->lcb_type != LPFC_LCB_GREEN) &&
(beacon->lcb_type != LPFC_LCB_AMBER)) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
if ((beacon->lcb_sub_command != LPFC_LCB_ON) &&
(beacon->lcb_sub_command != LPFC_LCB_OFF)) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
if ((beacon->lcb_sub_command == LPFC_LCB_ON) &&
(beacon->lcb_type != LPFC_LCB_GREEN) &&
(beacon->lcb_type != LPFC_LCB_AMBER)) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
if (be16_to_cpu(beacon->lcb_duration) != 0) {
rjt_err = LSRJT_CMD_UNSUPPORTED;
goto rjt;
}
state = (beacon->lcb_sub_command == LPFC_LCB_ON) ? 1 : 0;
lcb_context->sub_command = beacon->lcb_sub_command;
lcb_context->type = beacon->lcb_type;
lcb_context->frequency = beacon->lcb_frequency;
lcb_context->ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
lcb_context->rx_id = cmdiocb->iocb.ulpContext;
lcb_context->ndlp = lpfc_nlp_get(ndlp);
if (lpfc_sli4_set_beacon(vport, lcb_context, state)) {
lpfc_printf_vlog(ndlp->vport, KERN_ERR,
LOG_ELS, "0193 failed to send mail box");
lpfc_nlp_put(ndlp);
rjt_err = LSRJT_UNABLE_TPC;
goto rjt;
}
return 0;
rjt:
memset(&stat, 0, sizeof(stat));
stat.un.b.lsRjtRsnCode = rjt_err;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
return 1;
}
/**
* lpfc_els_flush_rscn - Clean up any rscn activities with a vport
* @vport: pointer to a host virtual N_Port data structure.
@ -6706,8 +7354,13 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* Do not process any unsolicited ELS commands
* if the ndlp is in DEV_LOSS
*/
if (ndlp->nlp_add_flag & NLP_IN_DEV_LOSS)
shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
if (ndlp->nlp_flag & NLP_IN_DEV_LOSS) {
spin_unlock_irq(shost->host_lock);
goto dropit;
}
spin_unlock_irq(shost->host_lock);
elsiocb->context1 = lpfc_nlp_get(ndlp);
elsiocb->vport = vport;
@ -6751,7 +7404,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
rjt_exp = LSEXP_NOTHING_MORE;
break;
}
shost = lpfc_shost_from_vport(vport);
if (vport->port_state < LPFC_DISC_AUTH) {
if (!(phba->pport->fc_flag & FC_PT2PT) ||
(phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
@ -6821,6 +7473,14 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
break;
case ELS_CMD_LCB:
phba->fc_stat.elsRcvLCB++;
lpfc_els_rcv_lcb(vport, elsiocb, ndlp);
break;
case ELS_CMD_RDP:
phba->fc_stat.elsRcvRDP++;
lpfc_els_rcv_rdp(vport, elsiocb, ndlp);
break;
case ELS_CMD_RSCN:
phba->fc_stat.elsRcvRSCN++;
lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
@ -7586,7 +8246,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_do_scr_ns_plogi(phba, vport);
goto out;
fdisc_failed:
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
if (vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS)
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
/* Cancel discovery timer */
lpfc_can_disctmo(vport);
lpfc_nlp_put(ndlp);
@ -7739,8 +8400,10 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (irsp->ulpStatus == IOSTAT_SUCCESS) {
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~FC_NDISC_ACTIVE;
vport->fc_flag &= ~FC_FABRIC;
spin_unlock_irq(shost->host_lock);
lpfc_can_disctmo(vport);
}
}

View file

@ -106,6 +106,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
struct lpfc_rport_data *rdata;
struct lpfc_nodelist * ndlp;
struct lpfc_vport *vport;
struct Scsi_Host *shost;
struct lpfc_hba *phba;
struct lpfc_work_evt *evtp;
int put_node;
@ -146,48 +147,32 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
return;
if (ndlp->nlp_type & NLP_FABRIC) {
/* If the WWPN of the rport and ndlp don't match, ignore it */
if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
"6789 rport name %lx != node port name %lx",
(unsigned long)rport->port_name,
(unsigned long)wwn_to_u64(
ndlp->nlp_portname.u.wwn));
put_node = rdata->pnode != NULL;
put_rport = ndlp->rport != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
if (put_node)
lpfc_nlp_put(ndlp);
put_device(&rport->dev);
return;
}
put_node = rdata->pnode != NULL;
put_rport = ndlp->rport != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
if (put_node)
lpfc_nlp_put(ndlp);
if (put_rport)
put_device(&rport->dev);
return;
}
if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn))
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
"6789 rport name %llx != node port name %llx",
rport->port_name,
wwn_to_u64(ndlp->nlp_portname.u.wwn));
evtp = &ndlp->dev_loss_evt;
if (!list_empty(&evtp->evt_listp))
if (!list_empty(&evtp->evt_listp)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
"6790 rport name %llx dev_loss_evt pending",
rport->port_name);
return;
}
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
ndlp->nlp_add_flag |= NLP_IN_DEV_LOSS;
shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_IN_DEV_LOSS;
spin_unlock_irq(shost->host_lock);
spin_lock_irq(&phba->hbalock);
/* We need to hold the node by incrementing the reference
* count until this queued work is done
*/
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
spin_lock_irq(&phba->hbalock);
if (evtp->evt_arg1) {
evtp->evt = LPFC_EVT_DEV_LOSS;
list_add_tail(&evtp->evt_listp, &phba->work_list);
@ -215,22 +200,24 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
struct fc_rport *rport;
struct lpfc_vport *vport;
struct lpfc_hba *phba;
struct Scsi_Host *shost;
uint8_t *name;
int put_node;
int put_rport;
int warn_on = 0;
int fcf_inuse = 0;
rport = ndlp->rport;
if (!rport) {
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
return fcf_inuse;
}
rdata = rport->dd_data;
name = (uint8_t *) &ndlp->nlp_portname;
vport = ndlp->vport;
shost = lpfc_shost_from_vport(vport);
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_IN_DEV_LOSS;
spin_unlock_irq(shost->host_lock);
if (!rport)
return fcf_inuse;
name = (uint8_t *) &ndlp->nlp_portname;
phba = vport->phba;
if (phba->sli_rev == LPFC_SLI_REV4)
@ -244,6 +231,13 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
"3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n",
ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag);
/*
* lpfc_nlp_remove if reached with dangling rport drops the
* reference. To make sure that does not happen clear rport
* pointer in ndlp before lpfc_nlp_put.
*/
rdata = rport->dd_data;
/* Don't defer this if we are in the process of deleting the vport
* or unloading the driver. The unload will cleanup the node
* appropriately we just need to cleanup the ndlp rport info here.
@ -256,14 +250,12 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
put_node = rdata->pnode != NULL;
put_rport = ndlp->rport != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
if (put_node)
lpfc_nlp_put(ndlp);
if (put_rport)
put_device(&rport->dev);
put_device(&rport->dev);
return fcf_inuse;
}
@ -275,28 +267,21 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
*name, *(name+1), *(name+2), *(name+3),
*(name+4), *(name+5), *(name+6), *(name+7),
ndlp->nlp_DID);
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
return fcf_inuse;
}
if (ndlp->nlp_type & NLP_FABRIC) {
/* We will clean up these Nodes in linkup */
put_node = rdata->pnode != NULL;
put_rport = ndlp->rport != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
if (put_node)
lpfc_nlp_put(ndlp);
if (put_rport)
put_device(&rport->dev);
put_node = rdata->pnode != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
if (put_node)
lpfc_nlp_put(ndlp);
put_device(&rport->dev);
if (ndlp->nlp_type & NLP_FABRIC)
return fcf_inuse;
}
if (ndlp->nlp_sid != NLP_NO_SID) {
warn_on = 1;
/* flush the target */
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
@ -321,16 +306,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
ndlp->nlp_state, ndlp->nlp_rpi);
}
put_node = rdata->pnode != NULL;
put_rport = ndlp->rport != NULL;
rdata->pnode = NULL;
ndlp->rport = NULL;
ndlp->nlp_add_flag &= ~NLP_IN_DEV_LOSS;
if (put_node)
lpfc_nlp_put(ndlp);
if (put_rport)
put_device(&rport->dev);
if (!(vport->load_flag & FC_UNLOADING) &&
!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
!(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
@ -1802,7 +1777,7 @@ lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
dma_addr_t phys_addr;
struct lpfc_mbx_sge sge;
struct lpfc_mbx_read_fcf_tbl *read_fcf;
uint32_t shdr_status, shdr_add_status;
uint32_t shdr_status, shdr_add_status, if_type;
union lpfc_sli4_cfg_shdr *shdr;
struct fcf_record *new_fcf_record;
@ -1823,9 +1798,11 @@ lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
lpfc_sli_pcimem_bcopy(shdr, shdr,
sizeof(union lpfc_sli4_cfg_shdr));
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
if (shdr_status || shdr_add_status) {
if (shdr_status == STATUS_FCF_TABLE_EMPTY)
if (shdr_status == STATUS_FCF_TABLE_EMPTY ||
if_type == LPFC_SLI_INTF_IF_TYPE_2)
lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
"2726 READ_FCF_RECORD Indicates empty "
"FCF table.\n");
@ -3868,11 +3845,11 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if (vport->port_state < LPFC_VPORT_READY) {
/* Link up discovery requires Fabric registration. */
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, 0); /* Do this first! */
lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, 0);
/* Issue SCR just before NameServer GID_FT Query */
lpfc_issue_els_scr(vport, SCR_DID, 0);
@ -3918,9 +3895,17 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
* registered port, drop the reference that we took the last time we
* registered the port.
*/
if (ndlp->rport && ndlp->rport->dd_data &&
((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp)
lpfc_nlp_put(ndlp);
rport = ndlp->rport;
if (rport) {
rdata = rport->dd_data;
/* break the link before dropping the ref */
ndlp->rport = NULL;
if (rdata && rdata->pnode == ndlp)
lpfc_nlp_put(ndlp);
rdata->pnode = NULL;
/* drop reference for earlier registeration */
put_device(&rport->dev);
}
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
"rport add: did:x%x flg:x%x type x%x",
@ -4296,9 +4281,9 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
lpfc_cleanup_vports_rrqs(vport, ndlp);
lpfc_unreg_rpi(vport, ndlp);
} else {
lpfc_nlp_put(ndlp);
}
lpfc_nlp_put(ndlp);
return;
}
@ -4510,7 +4495,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *mbox;
int rc;
int rc, acc_plogi = 1;
uint16_t rpi;
if (ndlp->nlp_flag & NLP_RPI_REGISTERED ||
@ -4543,14 +4528,20 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
mbox->context1 = lpfc_nlp_get(ndlp);
mbox->mbox_cmpl =
lpfc_sli4_unreg_rpi_cmpl_clr;
/*
* accept PLOGIs after unreg_rpi_cmpl
*/
acc_plogi = 0;
} else
mbox->mbox_cmpl =
lpfc_sli_def_mbox_cmpl;
}
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
if (rc == MBX_NOT_FINISHED) {
mempool_free(mbox, phba->mbox_mem_pool);
acc_plogi = 1;
}
}
lpfc_no_rpi(phba, ndlp);
@ -4558,8 +4549,11 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
ndlp->nlp_rpi = 0;
ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
if (acc_plogi)
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
return 1;
}
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
return 0;
}
@ -4761,6 +4755,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
struct lpfc_hba *phba = vport->phba;
struct lpfc_rport_data *rdata;
struct fc_rport *rport;
LPFC_MBOXQ_t *mbox;
int rc;
@ -4798,14 +4793,24 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
lpfc_cleanup_node(vport, ndlp);
/*
* We can get here with a non-NULL ndlp->rport because when we
* unregister a rport we don't break the rport/node linkage. So if we
* do, make sure we don't leaving any dangling pointers behind.
* ndlp->rport must be set to NULL before it reaches here
* i.e. break rport/node link before doing lpfc_nlp_put for
* registered rport and then drop the reference of rport.
*/
if (ndlp->rport) {
rdata = ndlp->rport->dd_data;
/*
* extra lpfc_nlp_put dropped the reference of ndlp
* for registered rport so need to cleanup rport
*/
lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
"0940 removed node x%p DID x%x "
" rport not null %p\n",
ndlp, ndlp->nlp_DID, ndlp->rport);
rport = ndlp->rport;
rdata = rport->dd_data;
rdata->pnode = NULL;
ndlp->rport = NULL;
put_device(&rport->dev);
}
}
@ -4833,9 +4838,19 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
if (matchdid.un.b.id == ndlpdid.un.b.id) {
if ((mydid.un.b.domain == matchdid.un.b.domain) &&
(mydid.un.b.area == matchdid.un.b.area)) {
/* This code is supposed to match the ID
* for a private loop device that is
* connect to fl_port. But we need to
* check that the port did not just go
* from pt2pt to fabric or we could end
* up matching ndlp->nlp_DID 000001 to
* fabric DID 0x20101
*/
if ((ndlpdid.un.b.domain == 0) &&
(ndlpdid.un.b.area == 0)) {
if (ndlpdid.un.b.id)
if (ndlpdid.un.b.id &&
vport->phba->fc_topology ==
LPFC_TOPOLOGY_LOOP)
return 1;
}
return 0;

View file

@ -543,6 +543,7 @@ struct fc_vft_header {
#define ELS_CMD_TEST 0x11000000
#define ELS_CMD_RRQ 0x12000000
#define ELS_CMD_REC 0x13000000
#define ELS_CMD_RDP 0x18000000
#define ELS_CMD_PRLI 0x20100014
#define ELS_CMD_PRLO 0x21100014
#define ELS_CMD_PRLO_ACC 0x02100014
@ -558,6 +559,7 @@ struct fc_vft_header {
#define ELS_CMD_SCR 0x62000000
#define ELS_CMD_RNID 0x78000000
#define ELS_CMD_LIRR 0x7A000000
#define ELS_CMD_LCB 0x81000000
#else /* __LITTLE_ENDIAN_BITFIELD */
#define ELS_CMD_MASK 0xffff
#define ELS_RSP_MASK 0xff
@ -580,6 +582,7 @@ struct fc_vft_header {
#define ELS_CMD_TEST 0x11
#define ELS_CMD_RRQ 0x12
#define ELS_CMD_REC 0x13
#define ELS_CMD_RDP 0x18
#define ELS_CMD_PRLI 0x14001020
#define ELS_CMD_PRLO 0x14001021
#define ELS_CMD_PRLO_ACC 0x14001002
@ -595,6 +598,7 @@ struct fc_vft_header {
#define ELS_CMD_SCR 0x62
#define ELS_CMD_RNID 0x78
#define ELS_CMD_LIRR 0x7A
#define ELS_CMD_LCB 0x81
#endif
/*
@ -1010,6 +1014,198 @@ typedef struct _ELS_PKT { /* Structure is in Big Endian format */
} un;
} ELS_PKT;
/*
* Link Cable Beacon (LCB) ELS Frame
*/
struct fc_lcb_request_frame {
uint32_t lcb_command; /* ELS command opcode (0x81) */
uint8_t lcb_sub_command;/* LCB Payload Word 1, bit 24:31 */
#define LPFC_LCB_ON 0x1
#define LPFC_LCB_OFF 0x2
uint8_t reserved[3];
uint8_t lcb_type; /* LCB Payload Word 2, bit 24:31 */
#define LPFC_LCB_GREEN 0x1
#define LPFC_LCB_AMBER 0x2
uint8_t lcb_frequency; /* LCB Payload Word 2, bit 16:23 */
uint16_t lcb_duration; /* LCB Payload Word 2, bit 15:0 */
};
/*
* Link Cable Beacon (LCB) ELS Response Frame
*/
struct fc_lcb_res_frame {
uint32_t lcb_ls_acc; /* Acceptance of LCB request (0x02) */
uint8_t lcb_sub_command;/* LCB Payload Word 1, bit 24:31 */
uint8_t reserved[3];
uint8_t lcb_type; /* LCB Payload Word 2, bit 24:31 */
uint8_t lcb_frequency; /* LCB Payload Word 2, bit 16:23 */
uint16_t lcb_duration; /* LCB Payload Word 2, bit 15:0 */
};
/*
* Read Diagnostic Parameters (RDP) ELS frame.
*/
#define SFF_PG0_IDENT_SFP 0x3
#define SFP_FLAG_PT_OPTICAL 0x0
#define SFP_FLAG_PT_SWLASER 0x01
#define SFP_FLAG_PT_LWLASER_LC1310 0x02
#define SFP_FLAG_PT_LWLASER_LL1550 0x03
#define SFP_FLAG_PT_MASK 0x0F
#define SFP_FLAG_PT_SHIFT 0
#define SFP_FLAG_IS_OPTICAL_PORT 0x01
#define SFP_FLAG_IS_OPTICAL_MASK 0x010
#define SFP_FLAG_IS_OPTICAL_SHIFT 4
#define SFP_FLAG_IS_DESC_VALID 0x01
#define SFP_FLAG_IS_DESC_VALID_MASK 0x020
#define SFP_FLAG_IS_DESC_VALID_SHIFT 5
#define SFP_FLAG_CT_UNKNOWN 0x0
#define SFP_FLAG_CT_SFP_PLUS 0x01
#define SFP_FLAG_CT_MASK 0x3C
#define SFP_FLAG_CT_SHIFT 6
struct fc_rdp_port_name_info {
uint8_t wwnn[8];
uint8_t wwpn[8];
};
/*
* Link Error Status Block Structure (FC-FS-3) for RDP
* This similar to RPS ELS
*/
struct fc_link_status {
uint32_t link_failure_cnt;
uint32_t loss_of_synch_cnt;
uint32_t loss_of_signal_cnt;
uint32_t primitive_seq_proto_err;
uint32_t invalid_trans_word;
uint32_t invalid_crc_cnt;
};
#define RDP_PORT_NAMES_DESC_TAG 0x00010003
struct fc_rdp_port_name_desc {
uint32_t tag; /* 0001 0003h */
uint32_t length; /* set to size of payload struct */
struct fc_rdp_port_name_info port_names;
};
struct fc_rdp_link_error_status_payload_info {
struct fc_link_status link_status; /* 24 bytes */
uint32_t port_type; /* bits 31-30 only */
};
#define RDP_LINK_ERROR_STATUS_DESC_TAG 0x00010002
struct fc_rdp_link_error_status_desc {
uint32_t tag; /* 0001 0002h */
uint32_t length; /* set to size of payload struct */
struct fc_rdp_link_error_status_payload_info info;
};
#define VN_PT_PHY_UNKNOWN 0x00
#define VN_PT_PHY_PF_PORT 0x01
#define VN_PT_PHY_ETH_MAC 0x10
#define VN_PT_PHY_SHIFT 30
#define RDP_PS_1GB 0x8000
#define RDP_PS_2GB 0x4000
#define RDP_PS_4GB 0x2000
#define RDP_PS_10GB 0x1000
#define RDP_PS_8GB 0x0800
#define RDP_PS_16GB 0x0400
#define RDP_PS_32GB 0x0200
#define RDP_CAP_UNKNOWN 0x0001
#define RDP_PS_UNKNOWN 0x0002
#define RDP_PS_NOT_ESTABLISHED 0x0001
struct fc_rdp_port_speed {
uint16_t capabilities;
uint16_t speed;
};
struct fc_rdp_port_speed_info {
struct fc_rdp_port_speed port_speed;
};
#define RDP_PORT_SPEED_DESC_TAG 0x00010001
struct fc_rdp_port_speed_desc {
uint32_t tag; /* 00010001h */
uint32_t length; /* set to size of payload struct */
struct fc_rdp_port_speed_info info;
};
#define RDP_NPORT_ID_SIZE 4
#define RDP_N_PORT_DESC_TAG 0x00000003
struct fc_rdp_nport_desc {
uint32_t tag; /* 0000 0003h, big endian */
uint32_t length; /* size of RDP_N_PORT_ID struct */
uint32_t nport_id : 12;
uint32_t reserved : 8;
};
struct fc_rdp_link_service_info {
uint32_t els_req; /* Request payload word 0 value.*/
};
#define RDP_LINK_SERVICE_DESC_TAG 0x00000001
struct fc_rdp_link_service_desc {
uint32_t tag; /* Descriptor tag 1 */
uint32_t length; /* set to size of payload struct. */
struct fc_rdp_link_service_info payload;
/* must be ELS req Word 0(0x18) */
};
struct fc_rdp_sfp_info {
uint16_t temperature;
uint16_t vcc;
uint16_t tx_bias;
uint16_t tx_power;
uint16_t rx_power;
uint16_t flags;
};
#define RDP_SFP_DESC_TAG 0x00010000
struct fc_rdp_sfp_desc {
uint32_t tag;
uint32_t length; /* set to size of sfp_info struct */
struct fc_rdp_sfp_info sfp_info;
};
struct fc_rdp_req_frame {
uint32_t rdp_command; /* ELS command opcode (0x18)*/
uint32_t rdp_des_length; /* RDP Payload Word 1 */
struct fc_rdp_nport_desc nport_id_desc; /* RDP Payload Word 2 - 4 */
};
struct fc_rdp_res_frame {
uint32_t reply_sequence; /* FC word0 LS_ACC or LS_RJT */
uint32_t length; /* FC Word 1 */
struct fc_rdp_link_service_desc link_service_desc; /* Word 2 -4 */
struct fc_rdp_sfp_desc sfp_desc; /* Word 5 -9 */
struct fc_rdp_port_speed_desc portspeed_desc; /* Word 10-12 */
struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */
struct fc_rdp_port_name_desc diag_port_names_desc; /* Word 22-27 */
struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */
};
#define RDP_DESC_PAYLOAD_SIZE (sizeof(struct fc_rdp_link_service_desc) \
+ sizeof(struct fc_rdp_sfp_desc) \
+ sizeof(struct fc_rdp_port_speed_desc) \
+ sizeof(struct fc_rdp_link_error_status_desc) \
+ (sizeof(struct fc_rdp_port_name_desc) * 2))
/******** FDMI ********/
/* lpfc_sli_ct_request defines the CT_IU preamble for FDMI commands */
@ -1586,6 +1782,11 @@ typedef struct { /* FireFly BIU registers */
#define TEMPERATURE_OFFSET 0xB0 /* Slim offset for critical temperature event */
/*
* return code Fail
*/
#define FAILURE 1
/*
* Begin Structure Definitions for Mailbox Commands
*/

View file

@ -291,7 +291,7 @@ struct sli4_bls_rsp {
struct lpfc_eqe {
uint32_t word0;
#define lpfc_eqe_resource_id_SHIFT 16
#define lpfc_eqe_resource_id_MASK 0x000000FF
#define lpfc_eqe_resource_id_MASK 0x0000FFFF
#define lpfc_eqe_resource_id_WORD word0
#define lpfc_eqe_minor_code_SHIFT 4
#define lpfc_eqe_minor_code_MASK 0x00000FFF
@ -914,6 +914,8 @@ struct mbox_header {
#define LPFC_MBOX_OPCODE_FUNCTION_RESET 0x3D
#define LPFC_MBOX_OPCODE_SET_PHYSICAL_LINK_CONFIG 0x3E
#define LPFC_MBOX_OPCODE_SET_BOOT_CONFIG 0x43
#define LPFC_MBOX_OPCODE_SET_BEACON_CONFIG 0x45
#define LPFC_MBOX_OPCODE_GET_BEACON_CONFIG 0x46
#define LPFC_MBOX_OPCODE_GET_PORT_NAME 0x4D
#define LPFC_MBOX_OPCODE_MQ_CREATE_EXT 0x5A
#define LPFC_MBOX_OPCODE_GET_VPD_DATA 0x5B
@ -1479,6 +1481,26 @@ struct lpfc_mbx_query_fw_config {
} rsp;
};
struct lpfc_mbx_set_beacon_config {
struct mbox_header header;
uint32_t word4;
#define lpfc_mbx_set_beacon_port_num_SHIFT 0
#define lpfc_mbx_set_beacon_port_num_MASK 0x0000003F
#define lpfc_mbx_set_beacon_port_num_WORD word4
#define lpfc_mbx_set_beacon_port_type_SHIFT 6
#define lpfc_mbx_set_beacon_port_type_MASK 0x00000003
#define lpfc_mbx_set_beacon_port_type_WORD word4
#define lpfc_mbx_set_beacon_state_SHIFT 8
#define lpfc_mbx_set_beacon_state_MASK 0x000000FF
#define lpfc_mbx_set_beacon_state_WORD word4
#define lpfc_mbx_set_beacon_duration_SHIFT 16
#define lpfc_mbx_set_beacon_duration_MASK 0x000000FF
#define lpfc_mbx_set_beacon_duration_WORD word4
#define lpfc_mbx_set_beacon_status_duration_SHIFT 24
#define lpfc_mbx_set_beacon_status_duration_MASK 0x000000FF
#define lpfc_mbx_set_beacon_status_duration_WORD word4
};
struct lpfc_id_range {
uint32_t word5;
#define lpfc_mbx_rsrc_id_word4_0_SHIFT 0
@ -1921,6 +1943,12 @@ struct lpfc_mbx_redisc_fcf_tbl {
#define STATUS_FCF_IN_USE 0x3a
#define STATUS_FCF_TABLE_EMPTY 0x43
/*
* Additional status field for embedded SLI_CONFIG mailbox
* command.
*/
#define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67
struct lpfc_mbx_sli4_config {
struct mbox_header header;
};
@ -2433,6 +2461,205 @@ struct lpfc_mbx_supp_pages {
#define LPFC_SLI4_PARAMETERS 2
};
struct lpfc_mbx_memory_dump_type3 {
uint32_t word1;
#define lpfc_mbx_memory_dump_type3_type_SHIFT 0
#define lpfc_mbx_memory_dump_type3_type_MASK 0x0000000f
#define lpfc_mbx_memory_dump_type3_type_WORD word1
#define lpfc_mbx_memory_dump_type3_link_SHIFT 24
#define lpfc_mbx_memory_dump_type3_link_MASK 0x000000ff
#define lpfc_mbx_memory_dump_type3_link_WORD word1
uint32_t word2;
#define lpfc_mbx_memory_dump_type3_page_no_SHIFT 0
#define lpfc_mbx_memory_dump_type3_page_no_MASK 0x0000ffff
#define lpfc_mbx_memory_dump_type3_page_no_WORD word2
#define lpfc_mbx_memory_dump_type3_offset_SHIFT 16
#define lpfc_mbx_memory_dump_type3_offset_MASK 0x0000ffff
#define lpfc_mbx_memory_dump_type3_offset_WORD word2
uint32_t word3;
#define lpfc_mbx_memory_dump_type3_length_SHIFT 0
#define lpfc_mbx_memory_dump_type3_length_MASK 0x00ffffff
#define lpfc_mbx_memory_dump_type3_length_WORD word3
uint32_t addr_lo;
uint32_t addr_hi;
uint32_t return_len;
};
#define DMP_PAGE_A0 0xa0
#define DMP_PAGE_A2 0xa2
#define DMP_SFF_PAGE_A0_SIZE 256
#define DMP_SFF_PAGE_A2_SIZE 256
#define SFP_WAVELENGTH_LC1310 1310
#define SFP_WAVELENGTH_LL1550 1550
/*
* * SFF-8472 TABLE 3.4
* */
#define SFF_PG0_CONNECTOR_UNKNOWN 0x00 /* Unknown */
#define SFF_PG0_CONNECTOR_SC 0x01 /* SC */
#define SFF_PG0_CONNECTOR_FC_COPPER1 0x02 /* FC style 1 copper connector */
#define SFF_PG0_CONNECTOR_FC_COPPER2 0x03 /* FC style 2 copper connector */
#define SFF_PG0_CONNECTOR_BNC 0x04 /* BNC / TNC */
#define SFF_PG0_CONNECTOR__FC_COAX 0x05 /* FC coaxial headers */
#define SFF_PG0_CONNECTOR_FIBERJACK 0x06 /* FiberJack */
#define SFF_PG0_CONNECTOR_LC 0x07 /* LC */
#define SFF_PG0_CONNECTOR_MT 0x08 /* MT - RJ */
#define SFF_PG0_CONNECTOR_MU 0x09 /* MU */
#define SFF_PG0_CONNECTOR_SF 0x0A /* SG */
#define SFF_PG0_CONNECTOR_OPTICAL_PIGTAIL 0x0B /* Optical pigtail */
#define SFF_PG0_CONNECTOR_OPTICAL_PARALLEL 0x0C /* MPO Parallel Optic */
#define SFF_PG0_CONNECTOR_HSSDC_II 0x20 /* HSSDC II */
#define SFF_PG0_CONNECTOR_COPPER_PIGTAIL 0x21 /* Copper pigtail */
#define SFF_PG0_CONNECTOR_RJ45 0x22 /* RJ45 */
/* SFF-8472 Table 3.1 Diagnostics: Data Fields Address/Page A0 */
#define SSF_IDENTIFIER 0
#define SSF_EXT_IDENTIFIER 1
#define SSF_CONNECTOR 2
#define SSF_TRANSCEIVER_CODE_B0 3
#define SSF_TRANSCEIVER_CODE_B1 4
#define SSF_TRANSCEIVER_CODE_B2 5
#define SSF_TRANSCEIVER_CODE_B3 6
#define SSF_TRANSCEIVER_CODE_B4 7
#define SSF_TRANSCEIVER_CODE_B5 8
#define SSF_TRANSCEIVER_CODE_B6 9
#define SSF_TRANSCEIVER_CODE_B7 10
#define SSF_ENCODING 11
#define SSF_BR_NOMINAL 12
#define SSF_RATE_IDENTIFIER 13
#define SSF_LENGTH_9UM_KM 14
#define SSF_LENGTH_9UM 15
#define SSF_LENGTH_50UM_OM2 16
#define SSF_LENGTH_62UM_OM1 17
#define SFF_LENGTH_COPPER 18
#define SSF_LENGTH_50UM_OM3 19
#define SSF_VENDOR_NAME 20
#define SSF_VENDOR_OUI 36
#define SSF_VENDOR_PN 40
#define SSF_VENDOR_REV 56
#define SSF_WAVELENGTH_B1 60
#define SSF_WAVELENGTH_B0 61
#define SSF_CC_BASE 63
#define SSF_OPTIONS_B1 64
#define SSF_OPTIONS_B0 65
#define SSF_BR_MAX 66
#define SSF_BR_MIN 67
#define SSF_VENDOR_SN 68
#define SSF_DATE_CODE 84
#define SSF_MONITORING_TYPEDIAGNOSTIC 92
#define SSF_ENHANCED_OPTIONS 93
#define SFF_8472_COMPLIANCE 94
#define SSF_CC_EXT 95
#define SSF_A0_VENDOR_SPECIFIC 96
/* SFF-8472 Table 3.1a Diagnostics: Data Fields Address/Page A2 */
#define SSF_AW_THRESHOLDS 0
#define SSF_EXT_CAL_CONSTANTS 56
#define SSF_CC_DMI 95
#define SFF_TEMPERATURE_B1 96
#define SFF_TEMPERATURE_B0 97
#define SFF_VCC_B1 98
#define SFF_VCC_B0 99
#define SFF_TX_BIAS_CURRENT_B1 100
#define SFF_TX_BIAS_CURRENT_B0 101
#define SFF_TXPOWER_B1 102
#define SFF_TXPOWER_B0 103
#define SFF_RXPOWER_B1 104
#define SFF_RXPOWER_B0 105
#define SSF_STATUS_CONTROL 110
#define SSF_ALARM_FLAGS_B1 112
#define SSF_ALARM_FLAGS_B0 113
#define SSF_WARNING_FLAGS_B1 116
#define SSF_WARNING_FLAGS_B0 117
#define SSF_EXT_TATUS_CONTROL_B1 118
#define SSF_EXT_TATUS_CONTROL_B0 119
#define SSF_A2_VENDOR_SPECIFIC 120
#define SSF_USER_EEPROM 128
#define SSF_VENDOR_CONTROL 148
/*
* Tranceiver codes Fibre Channel SFF-8472
* Table 3.5.
*/
struct sff_trasnceiver_codes_byte0 {
uint8_t inifiband:4;
uint8_t teng_ethernet:4;
};
struct sff_trasnceiver_codes_byte1 {
uint8_t sonet:6;
uint8_t escon:2;
};
struct sff_trasnceiver_codes_byte2 {
uint8_t soNet:8;
};
struct sff_trasnceiver_codes_byte3 {
uint8_t ethernet:8;
};
struct sff_trasnceiver_codes_byte4 {
uint8_t fc_el_lo:1;
uint8_t fc_lw_laser:1;
uint8_t fc_sw_laser:1;
uint8_t fc_md_distance:1;
uint8_t fc_lg_distance:1;
uint8_t fc_int_distance:1;
uint8_t fc_short_distance:1;
uint8_t fc_vld_distance:1;
};
struct sff_trasnceiver_codes_byte5 {
uint8_t reserved1:1;
uint8_t reserved2:1;
uint8_t fc_sfp_active:1; /* Active cable */
uint8_t fc_sfp_passive:1; /* Passive cable */
uint8_t fc_lw_laser:1; /* Longwave laser */
uint8_t fc_sw_laser_sl:1;
uint8_t fc_sw_laser_sn:1;
uint8_t fc_el_hi:1; /* Electrical enclosure high bit */
};
struct sff_trasnceiver_codes_byte6 {
uint8_t fc_tm_sm:1; /* Single Mode */
uint8_t reserved:1;
uint8_t fc_tm_m6:1; /* Multimode, 62.5um (M6) */
uint8_t fc_tm_tv:1; /* Video Coax (TV) */
uint8_t fc_tm_mi:1; /* Miniature Coax (MI) */
uint8_t fc_tm_tp:1; /* Twisted Pair (TP) */
uint8_t fc_tm_tw:1; /* Twin Axial Pair */
};
struct sff_trasnceiver_codes_byte7 {
uint8_t fc_sp_100MB:1; /* 100 MB/sec */
uint8_t reserve:1;
uint8_t fc_sp_200mb:1; /* 200 MB/sec */
uint8_t fc_sp_3200MB:1; /* 3200 MB/sec */
uint8_t fc_sp_400MB:1; /* 400 MB/sec */
uint8_t fc_sp_1600MB:1; /* 1600 MB/sec */
uint8_t fc_sp_800MB:1; /* 800 MB/sec */
uint8_t fc_sp_1200MB:1; /* 1200 MB/sec */
};
/* User writable non-volatile memory, SFF-8472 Table 3.20 */
struct user_eeprom {
uint8_t vendor_name[16];
uint8_t vendor_oui[3];
uint8_t vendor_pn[816];
uint8_t vendor_rev[4];
uint8_t vendor_sn[16];
uint8_t datecode[6];
uint8_t lot_code[2];
uint8_t reserved191[57];
};
struct lpfc_mbx_pc_sli4_params {
uint32_t word1;
#define qs_SHIFT 0
@ -3021,6 +3248,7 @@ struct lpfc_mqe {
struct lpfc_mbx_request_features req_ftrs;
struct lpfc_mbx_post_hdr_tmpl hdr_tmpl;
struct lpfc_mbx_query_fw_config query_fw_cfg;
struct lpfc_mbx_set_beacon_config beacon_config;
struct lpfc_mbx_supp_pages supp_pages;
struct lpfc_mbx_pc_sli4_params sli4_params;
struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
@ -3031,6 +3259,7 @@ struct lpfc_mqe {
struct lpfc_mbx_get_prof_cfg get_prof_cfg;
struct lpfc_mbx_wr_object wr_object;
struct lpfc_mbx_get_port_name get_port_name;
struct lpfc_mbx_memory_dump_type3 mem_dump_type3;
struct lpfc_mbx_nop nop;
} un;
};
@ -3041,8 +3270,8 @@ struct lpfc_mcqe {
#define lpfc_mcqe_status_MASK 0x0000FFFF
#define lpfc_mcqe_status_WORD word0
#define lpfc_mcqe_ext_status_SHIFT 16
#define lpfc_mcqe_ext_status_MASK 0x0000FFFF
#define lpfc_mcqe_ext_status_WORD word0
#define lpfc_mcqe_ext_status_MASK 0x0000FFFF
#define lpfc_mcqe_ext_status_WORD word0
uint32_t mcqe_tag0;
uint32_t mcqe_tag1;
uint32_t trailer;
@ -3176,6 +3405,7 @@ struct lpfc_acqe_fc_la {
#define LPFC_FC_LA_SPEED_8G 0x8
#define LPFC_FC_LA_SPEED_10G 0xA
#define LPFC_FC_LA_SPEED_16G 0x10
#define LPFC_FC_LA_SPEED_32G 0x20
#define lpfc_acqe_fc_la_topology_SHIFT 16
#define lpfc_acqe_fc_la_topology_MASK 0x000000FF
#define lpfc_acqe_fc_la_topology_WORD word0

View file

@ -3303,6 +3303,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
shost->max_lun = vport->cfg_max_luns;
shost->this_id = -1;
shost->max_cmd_len = 16;
shost->nr_hw_queues = phba->cfg_fcp_io_channel;
if (phba->sli_rev == LPFC_SLI_REV4) {
shost->dma_boundary =
phba->sli4_hba.pc_sli4_params.sge_supp_len-1;
@ -4483,7 +4484,13 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba,
lpfc_destroy_vport_work_array(phba, vports);
}
if (active_vlink_present) {
/*
* Don't re-instantiate if vport is marked for deletion.
* If we are here first then vport_delete is going to wait
* for discovery to complete.
*/
if (!(vport->load_flag & FC_UNLOADING) &&
active_vlink_present) {
/*
* If there are other active VLinks present,
* re-instantiate the Vlink using FDISC.
@ -7500,6 +7507,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba)
mboxq->u.mqe.un.query_fw_cfg.rsp.function_mode;
phba->sli4_hba.ulp0_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp0_mode;
phba->sli4_hba.ulp1_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp1_mode;
phba->sli4_hba.physical_port =
mboxq->u.mqe.un.query_fw_cfg.rsp.physical_port;
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3251 QUERY_FW_CFG: func_mode:x%x, ulp0_mode:x%x, "
"ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode,
@ -8367,7 +8376,7 @@ lpfc_sli_enable_msix(struct lpfc_hba *phba)
/* vector-0 is associated to slow-path handler */
rc = request_irq(phba->msix_entries[0].vector,
&lpfc_sli_sp_intr_handler, IRQF_SHARED,
&lpfc_sli_sp_intr_handler, 0,
LPFC_SP_DRIVER_HANDLER_NAME, phba);
if (rc) {
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
@ -8378,7 +8387,7 @@ lpfc_sli_enable_msix(struct lpfc_hba *phba)
/* vector-1 is associated to fast-path handler */
rc = request_irq(phba->msix_entries[1].vector,
&lpfc_sli_fp_intr_handler, IRQF_SHARED,
&lpfc_sli_fp_intr_handler, 0,
LPFC_FP_DRIVER_HANDLER_NAME, phba);
if (rc) {
@ -8487,7 +8496,7 @@ lpfc_sli_enable_msi(struct lpfc_hba *phba)
}
rc = request_irq(phba->pcidev->irq, lpfc_sli_intr_handler,
IRQF_SHARED, LPFC_DRIVER_NAME, phba);
0, LPFC_DRIVER_NAME, phba);
if (rc) {
pci_disable_msi(phba->pcidev);
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
@ -8944,13 +8953,13 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
if (phba->cfg_fof && (index == (vectors - 1)))
rc = request_irq(
phba->sli4_hba.msix_entries[index].vector,
&lpfc_sli4_fof_intr_handler, IRQF_SHARED,
&lpfc_sli4_fof_intr_handler, 0,
(char *)&phba->sli4_hba.handler_name[index],
&phba->sli4_hba.fcp_eq_hdl[index]);
else
rc = request_irq(
phba->sli4_hba.msix_entries[index].vector,
&lpfc_sli4_hba_intr_handler, IRQF_SHARED,
&lpfc_sli4_hba_intr_handler, 0,
(char *)&phba->sli4_hba.handler_name[index],
&phba->sli4_hba.fcp_eq_hdl[index]);
if (rc) {
@ -8972,7 +8981,8 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
phba->cfg_fcp_io_channel = vectors;
}
lpfc_sli4_set_affinity(phba, vectors);
if (!shost_use_blk_mq(lpfc_shost_from_vport(phba->pport)))
lpfc_sli4_set_affinity(phba, vectors);
return rc;
cfg_fail_out:
@ -9050,7 +9060,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
}
rc = request_irq(phba->pcidev->irq, lpfc_sli4_intr_handler,
IRQF_SHARED, LPFC_DRIVER_NAME, phba);
0, LPFC_DRIVER_NAME, phba);
if (rc) {
pci_disable_msi(phba->pcidev);
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,

View file

@ -2255,6 +2255,158 @@ lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
return 0;
}
void
lpfc_mbx_cmpl_rdp_link_stat(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
{
MAILBOX_t *mb;
int rc = FAILURE;
struct lpfc_rdp_context *rdp_context =
(struct lpfc_rdp_context *)(mboxq->context2);
mb = &mboxq->u.mb;
if (mb->mbxStatus)
goto mbx_failed;
memcpy(&rdp_context->link_stat, &mb->un.varRdLnk, sizeof(READ_LNK_VAR));
rc = SUCCESS;
mbx_failed:
lpfc_sli4_mbox_cmd_free(phba, mboxq);
rdp_context->cmpl(phba, rdp_context, rc);
}
void
lpfc_mbx_cmpl_rdp_page_a2(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
{
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) mbox->context1;
struct lpfc_rdp_context *rdp_context =
(struct lpfc_rdp_context *)(mbox->context2);
if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
goto error;
lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a2,
DMP_SFF_PAGE_A2_SIZE);
/* We don't need dma buffer for link stat. */
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
memset(mbox, 0, sizeof(*mbox));
lpfc_read_lnk_stat(phba, mbox);
mbox->vport = rdp_context->ndlp->vport;
mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_link_stat;
mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED)
goto error;
return;
error:
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
lpfc_sli4_mbox_cmd_free(phba, mbox);
rdp_context->cmpl(phba, rdp_context, FAILURE);
}
void
lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
{
int rc;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (mbox->context1);
struct lpfc_rdp_context *rdp_context =
(struct lpfc_rdp_context *)(mbox->context2);
if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
goto error;
lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a0,
DMP_SFF_PAGE_A0_SIZE);
memset(mbox, 0, sizeof(*mbox));
memset(mp->virt, 0, DMP_SFF_PAGE_A2_SIZE);
INIT_LIST_HEAD(&mp->list);
/* save address for completion */
mbox->context1 = mp;
mbox->vport = rdp_context->ndlp->vport;
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
bf_set(lpfc_mbx_memory_dump_type3_type,
&mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
bf_set(lpfc_mbx_memory_dump_type3_link,
&mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
bf_set(lpfc_mbx_memory_dump_type3_page_no,
&mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A2);
bf_set(lpfc_mbx_memory_dump_type3_length,
&mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A2_SIZE);
mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a2;
mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED)
goto error;
return;
error:
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
lpfc_sli4_mbox_cmd_free(phba, mbox);
rdp_context->cmpl(phba, rdp_context, FAILURE);
}
/*
* lpfc_sli4_dump_sfp_pagea0 - Dump sli4 read SFP Diagnostic.
* @phba: pointer to the hba structure containing.
* @mbox: pointer to lpfc mbox command to initialize.
*
* This function create a SLI4 dump mailbox command to dump configure
* type 3 page 0xA0.
*/
int
lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
{
struct lpfc_dmabuf *mp = NULL;
memset(mbox, 0, sizeof(*mbox));
mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
if (mp)
mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
if (!mp || !mp->virt) {
kfree(mp);
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
"3569 dump type 3 page 0xA0 allocation failed\n");
return 1;
}
memset(mp->virt, 0, LPFC_BPL_SIZE);
INIT_LIST_HEAD(&mp->list);
bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
/* save address for completion */
mbox->context1 = mp;
bf_set(lpfc_mbx_memory_dump_type3_type,
&mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
bf_set(lpfc_mbx_memory_dump_type3_link,
&mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
bf_set(lpfc_mbx_memory_dump_type3_page_no,
&mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A0);
bf_set(lpfc_mbx_memory_dump_type3_length,
&mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A0_SIZE);
mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
return 0;
}
/**
* lpfc_reg_fcfi - Initialize the REG_FCFI mailbox command
* @phba: pointer to the hba structure containing the FCF index and RQ ID.

View file

@ -661,7 +661,13 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
lpfc_destroy_vport_work_array(phba, vports);
}
if (active_vlink_present) {
/*
* Don't re-instantiate if vport is marked for deletion.
* If we are here first then vport_delete is going to wait
* for discovery to complete.
*/
if (!(vport->load_flag & FC_UNLOADING) &&
active_vlink_present) {
/*
* If there are other active VLinks present,
* re-instantiate the Vlink using FDISC.
@ -1868,7 +1874,7 @@ lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= NLP_LOGO_ACC;
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(shost->host_lock);
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
return ndlp->nlp_state;

View file

@ -3257,7 +3257,7 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
*/
nseg = scsi_dma_map(scsi_cmnd);
if (unlikely(!nseg))
if (unlikely(nseg <= 0))
return 1;
sgl += 1;
/* clear the last flag in the fcp_rsp map entry */
@ -3845,6 +3845,49 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
lpfc_send_scsi_error_event(vport->phba, vport, lpfc_cmd, rsp_iocb);
}
/**
* lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution
* @phba: Pointer to HBA context object.
*
* This routine performs a roundrobin SCSI command to SLI4 FCP WQ index
* distribution. This is called by __lpfc_sli_issue_iocb_s4() with the hbalock
* held.
* If scsi-mq is enabled, get the default block layer mapping of software queues
* to hardware queues. This information is saved in request tag.
*
* Return: index into SLI4 fast-path FCP queue index.
**/
int lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba,
struct lpfc_scsi_buf *lpfc_cmd)
{
struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
struct lpfc_vector_map_info *cpup;
int chann, cpu;
uint32_t tag;
uint16_t hwq;
if (shost_use_blk_mq(cmnd->device->host)) {
tag = blk_mq_unique_tag(cmnd->request);
hwq = blk_mq_unique_tag_to_hwq(tag);
return hwq;
}
if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_CPU
&& phba->cfg_fcp_io_channel > 1) {
cpu = smp_processor_id();
if (cpu < phba->sli4_hba.num_present_cpu) {
cpup = phba->sli4_hba.cpu_map;
cpup += cpu;
return cpup->channel_id;
}
}
chann = atomic_add_return(1, &phba->fcp_qidx);
chann = (chann % phba->cfg_fcp_io_channel);
return chann;
}
/**
* lpfc_scsi_cmd_iocb_cmpl - Scsi cmnd IOCB completion routine
* @phba: The Hba for which this call is being executed.
@ -4537,7 +4580,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
if (lpfc_cmd == NULL) {
lpfc_rampdown_queue_depth(phba);
lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
lpfc_printf_vlog(vport, KERN_INFO, LOG_MISC,
"0707 driver's buffer pool is empty, "
"IO busied\n");
goto out_host_busy;
@ -4968,13 +5011,16 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
iocbq, iocbqrsp, lpfc_cmd->timeout);
if ((status != IOCB_SUCCESS) ||
(iocbqrsp->iocb.ulpStatus != IOSTAT_SUCCESS)) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"0727 TMF %s to TGT %d LUN %llu failed (%d, %d) "
"iocb_flag x%x\n",
lpfc_taskmgmt_name(task_mgmt_cmd),
tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
iocbqrsp->iocb.un.ulpWord[4],
iocbq->iocb_flag);
if (status != IOCB_SUCCESS ||
iocbqrsp->iocb.ulpStatus != IOSTAT_FCP_RSP_ERROR)
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"0727 TMF %s to TGT %d LUN %llu "
"failed (%d, %d) iocb_flag x%x\n",
lpfc_taskmgmt_name(task_mgmt_cmd),
tgt_id, lun_id,
iocbqrsp->iocb.ulpStatus,
iocbqrsp->iocb.un.ulpWord[4],
iocbq->iocb_flag);
/* if ulpStatus != IOCB_SUCCESS, then status == IOCB_SUCCESS */
if (status == IOCB_SUCCESS) {
if (iocbqrsp->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR)
@ -4988,7 +5034,6 @@ lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
} else {
ret = FAILED;
}
lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
} else
ret = SUCCESS;

View file

@ -184,3 +184,6 @@ struct lpfc_scsi_buf {
#define FIND_FIRST_OAS_LUN 0
#define NO_MORE_OAS_LUN -1
#define NOT_OAS_ENABLED_LUN NO_MORE_OAS_LUN
int lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba,
struct lpfc_scsi_buf *lpfc_cmd);

View file

@ -2249,7 +2249,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
vport->vpi, ndlp->nlp_rpi,
ndlp->nlp_DID,
ndlp->nlp_usg_map, ndlp);
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
lpfc_nlp_put(ndlp);
}
}
@ -8137,36 +8137,6 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
return sglq->sli4_xritag;
}
/**
* lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution
* @phba: Pointer to HBA context object.
*
* This routine performs a roundrobin SCSI command to SLI4 FCP WQ index
* distribution. This is called by __lpfc_sli_issue_iocb_s4() with the hbalock
* held.
*
* Return: index into SLI4 fast-path FCP queue index.
**/
static inline int
lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba)
{
struct lpfc_vector_map_info *cpup;
int chann, cpu;
if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_CPU
&& phba->cfg_fcp_io_channel > 1) {
cpu = smp_processor_id();
if (cpu < phba->sli4_hba.num_present_cpu) {
cpup = phba->sli4_hba.cpu_map;
cpup += cpu;
return cpup->channel_id;
}
}
chann = atomic_add_return(1, &phba->fcp_qidx);
chann = (chann % phba->cfg_fcp_io_channel);
return chann;
}
/**
* lpfc_sli_iocb2wqe - Convert the IOCB to a work queue entry.
* @phba: Pointer to HBA context object.
@ -8792,32 +8762,44 @@ lpfc_sli_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
return 0;
}
/**
* lpfc_sli_calc_ring - Calculates which ring to use
* @phba: Pointer to HBA context object.
* @ring_number: Initial ring
* @piocb: Pointer to command iocb.
*
* For SLI4, FCP IO can deferred to one fo many WQs, based on
* fcp_wqidx, thus we need to calculate the corresponding ring.
* Since ABORTS must go on the same WQ of the command they are
* aborting, we use command's fcp_wqidx.
*/
int
lpfc_sli_calc_ring(struct lpfc_hba *phba, uint32_t ring_number,
struct lpfc_iocbq *piocb)
{
uint32_t idx;
if (phba->sli_rev < LPFC_SLI_REV4)
return ring_number;
if (phba->sli_rev == LPFC_SLI_REV4) {
if (piocb->iocb_flag & (LPFC_IO_FCP | LPFC_USE_FCPWQIDX)) {
if (piocb->iocb_flag & (LPFC_IO_FCP | LPFC_USE_FCPWQIDX)) {
if (!(phba->cfg_fof) ||
(!(piocb->iocb_flag & LPFC_IO_FOF))) {
if (unlikely(!phba->sli4_hba.fcp_wq))
return LPFC_HBA_ERROR;
/*
* fcp_wqidx should already be setup based on what
* completion queue we want to use.
* for abort iocb fcp_wqidx should already
* be setup based on what work queue we used.
*/
if (!(phba->cfg_fof) ||
(!(piocb->iocb_flag & LPFC_IO_FOF))) {
if (unlikely(!phba->sli4_hba.fcp_wq))
return LPFC_HBA_ERROR;
idx = lpfc_sli4_scmd_to_wqidx_distr(phba);
piocb->fcp_wqidx = idx;
ring_number = MAX_SLI3_CONFIGURED_RINGS + idx;
} else {
if (unlikely(!phba->sli4_hba.oas_wq))
return LPFC_HBA_ERROR;
idx = 0;
piocb->fcp_wqidx = idx;
ring_number = LPFC_FCP_OAS_RING;
}
if (!(piocb->iocb_flag & LPFC_USE_FCPWQIDX))
piocb->fcp_wqidx =
lpfc_sli4_scmd_to_wqidx_distr(phba,
piocb->context1);
ring_number = MAX_SLI3_CONFIGURED_RINGS +
piocb->fcp_wqidx;
} else {
if (unlikely(!phba->sli4_hba.oas_wq))
return LPFC_HBA_ERROR;
piocb->fcp_wqidx = 0;
ring_number = LPFC_FCP_OAS_RING;
}
}
return ring_number;

View file

@ -602,6 +602,7 @@ struct lpfc_sli4_hba {
struct lpfc_iov iov;
spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */
spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */
uint32_t physical_port;
/* CPU to vector mapping information */
struct lpfc_vector_map_info *cpu_map;
@ -651,6 +652,26 @@ struct lpfc_rsrc_blks {
uint16_t rsrc_used;
};
struct lpfc_rdp_context {
struct lpfc_nodelist *ndlp;
uint16_t ox_id;
uint16_t rx_id;
READ_LNK_VAR link_stat;
uint8_t page_a0[DMP_SFF_PAGE_A0_SIZE];
uint8_t page_a2[DMP_SFF_PAGE_A2_SIZE];
void (*cmpl)(struct lpfc_hba *, struct lpfc_rdp_context*, int);
};
struct lpfc_lcb_context {
uint8_t sub_command;
uint8_t type;
uint8_t frequency;
uint16_t ox_id;
uint16_t rx_id;
struct lpfc_nodelist *ndlp;
};
/*
* SLI4 specific function prototypes
*/

View file

@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "10.5.0.0."
#define LPFC_DRIVER_VERSION "10.7.0.0."
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */

View file

@ -567,8 +567,8 @@ int
lpfc_vport_delete(struct fc_vport *fc_vport)
{
struct lpfc_nodelist *ndlp = NULL;
struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost;
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
long timeout;
bool ns_ndlp_referenced = false;
@ -645,8 +645,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
}
/* Remove FC host and then SCSI host with the vport */
fc_remove_host(lpfc_shost_from_vport(vport));
scsi_remove_host(lpfc_shost_from_vport(vport));
fc_remove_host(shost);
scsi_remove_host(shost);
ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
@ -772,7 +772,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
* Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
* does the scsi_host_put() to release the vport.
*/
if (lpfc_mbx_unreg_vpi(vport))
if (!(vport->vpi_state & LPFC_VPI_REGISTERED) ||
lpfc_mbx_unreg_vpi(vport))
scsi_host_put(shost);
} else
scsi_host_put(shost);

View file

@ -403,7 +403,6 @@ static struct scsi_host_template mac53c94_template = {
.can_queue = 1,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};

View file

@ -35,7 +35,8 @@
/*
* MegaRAID SAS Driver meta data
*/
#define MEGASAS_VERSION "06.806.08.00-rc1"
#define MEGASAS_VERSION "06.807.10.00-rc1"
#define MEGASAS_RELDATE "March 6, 2015"
/*
* Device IDs
@ -153,6 +154,9 @@
#define MFI_FRAME_DIR_BOTH 0x0018
#define MFI_FRAME_IEEE 0x0020
/* Driver internal */
#define DRV_DCMD_POLLED_MODE 0x1
/*
* Definition for cmd_status
*/
@ -408,7 +412,7 @@ enum MR_PD_STATE {
* defines the physical drive address structure
*/
struct MR_PD_ADDRESS {
u16 deviceId;
__le16 deviceId;
u16 enclDeviceId;
union {
@ -433,8 +437,8 @@ struct MR_PD_ADDRESS {
* defines the physical drive list structure
*/
struct MR_PD_LIST {
u32 size;
u32 count;
__le32 size;
__le32 count;
struct MR_PD_ADDRESS addr[1];
} __packed;
@ -451,28 +455,28 @@ union MR_LD_REF {
struct {
u8 targetId;
u8 reserved;
u16 seqNum;
__le16 seqNum;
};
u32 ref;
__le32 ref;
} __packed;
/*
* defines the logical drive list structure
*/
struct MR_LD_LIST {
u32 ldCount;
u32 reserved;
__le32 ldCount;
__le32 reserved;
struct {
union MR_LD_REF ref;
u8 state;
u8 reserved[3];
u64 size;
__le64 size;
} ldList[MAX_LOGICAL_DRIVES_EXT];
} __packed;
struct MR_LD_TARGETID_LIST {
u32 size;
u32 count;
__le32 size;
__le32 count;
u8 pad[3];
u8 targetId[MAX_LOGICAL_DRIVES_EXT];
};
@ -553,7 +557,7 @@ struct megasas_ctrl_prop {
} OnOffProperties;
u8 autoSnapVDSpace;
u8 viewSpace;
u16 spinDownTime;
__le16 spinDownTime;
u8 reserved[24];
} __packed;
@ -567,10 +571,10 @@ struct megasas_ctrl_info {
*/
struct {
u16 vendor_id;
u16 device_id;
u16 sub_vendor_id;
u16 sub_device_id;
__le16 vendor_id;
__le16 device_id;
__le16 sub_vendor_id;
__le16 sub_device_id;
u8 reserved[24];
} __attribute__ ((packed)) pci;
@ -611,8 +615,8 @@ struct megasas_ctrl_info {
/*
* List of components residing in flash. All str are null terminated
*/
u32 image_check_word;
u32 image_component_count;
__le32 image_check_word;
__le32 image_component_count;
struct {
@ -629,7 +633,7 @@ struct megasas_ctrl_info {
* empty if a flash operation has not occurred. All stings are null
* terminated
*/
u32 pending_image_component_count;
__le32 pending_image_component_count;
struct {
@ -662,39 +666,39 @@ struct megasas_ctrl_info {
} __attribute__ ((packed)) hw_present;
u32 current_fw_time;
__le32 current_fw_time;
/*
* Maximum data transfer sizes
*/
u16 max_concurrent_cmds;
u16 max_sge_count;
u32 max_request_size;
__le16 max_concurrent_cmds;
__le16 max_sge_count;
__le32 max_request_size;
/*
* Logical and physical device counts
*/
u16 ld_present_count;
u16 ld_degraded_count;
u16 ld_offline_count;
__le16 ld_present_count;
__le16 ld_degraded_count;
__le16 ld_offline_count;
u16 pd_present_count;
u16 pd_disk_present_count;
u16 pd_disk_pred_failure_count;
u16 pd_disk_failed_count;
__le16 pd_present_count;
__le16 pd_disk_present_count;
__le16 pd_disk_pred_failure_count;
__le16 pd_disk_failed_count;
/*
* Memory size information
*/
u16 nvram_size;
u16 memory_size;
u16 flash_size;
__le16 nvram_size;
__le16 memory_size;
__le16 flash_size;
/*
* Error counters
*/
u16 mem_correctable_error_count;
u16 mem_uncorrectable_error_count;
__le16 mem_correctable_error_count;
__le16 mem_uncorrectable_error_count;
/*
* Cluster information
@ -705,7 +709,7 @@ struct megasas_ctrl_info {
/*
* Additional max data transfer sizes
*/
u16 max_strips_per_io;
__le16 max_strips_per_io;
/*
* Controller capabilities structures
@ -805,7 +809,7 @@ struct megasas_ctrl_info {
* deviceInterface.portAddr, and the rest shall be
* populated in deviceInterfacePortAddr2.
*/
u64 deviceInterfacePortAddr2[8]; /*6a0h */
__le64 deviceInterfacePortAddr2[8]; /*6a0h */
u8 reserved3[128]; /*6e0h */
struct { /*760h */
@ -842,26 +846,26 @@ struct megasas_ctrl_info {
u16 reserved[6];
} pdsForRaidLevels;
u16 maxPds; /*780h */
u16 maxDedHSPs; /*782h */
u16 maxGlobalHSPs; /*784h */
u16 ddfSize; /*786h */
__le16 maxPds; /*780h */
__le16 maxDedHSPs; /*782h */
__le16 maxGlobalHSP; /*784h */
__le16 ddfSize; /*786h */
u8 maxLdsPerArray; /*788h */
u8 partitionsInDDF; /*789h */
u8 lockKeyBinding; /*78ah */
u8 maxPITsPerLd; /*78bh */
u8 maxViewsPerLd; /*78ch */
u8 maxTargetId; /*78dh */
u16 maxBvlVdSize; /*78eh */
__le16 maxBvlVdSize; /*78eh */
u16 maxConfigurableSSCSize; /*790h */
u16 currentSSCsize; /*792h */
__le16 maxConfigurableSSCSize; /*790h */
__le16 currentSSCsize; /*792h */
char expanderFwVersion[12]; /*794h */
u16 PFKTrialTimeRemaining; /*7A0h */
__le16 PFKTrialTimeRemaining; /*7A0h */
u16 cacheMemorySize; /*7A2h */
__le16 cacheMemorySize; /*7A2h */
struct { /*7A4h */
#if defined(__BIG_ENDIAN_BITFIELD)
@ -931,7 +935,7 @@ struct megasas_ctrl_info {
u8 temperatureROC; /*7C9h */
u8 temperatureCtrl; /*7CAh */
u8 reserved4; /*7CBh */
u16 maxConfigurablePds; /*7CCh */
__le16 maxConfigurablePds; /*7CCh */
u8 reserved5[2]; /*0x7CDh */
@ -1042,11 +1046,6 @@ struct megasas_ctrl_info {
#define VD_EXT_DEBUG 0
enum MR_MFI_MPT_PTHR_FLAGS {
MFI_MPT_DETACHED = 0,
MFI_LIST_ADDED = 1,
MFI_MPT_ATTACHED = 2,
};
enum MR_SCSI_CMD_TYPE {
READ_WRITE_LDIO = 0,
@ -1084,6 +1083,7 @@ enum MR_SCSI_CMD_TYPE {
#define MEGASAS_SKINNY_INT_CMDS 5
#define MEGASAS_FUSION_INTERNAL_CMDS 5
#define MEGASAS_FUSION_IOCTL_CMDS 3
#define MEGASAS_MFI_IOCTL_CMDS 27
#define MEGASAS_MAX_MSIX_QUEUES 128
/*
@ -1172,22 +1172,22 @@ struct megasas_register_set {
struct megasas_sge32 {
u32 phys_addr;
u32 length;
__le32 phys_addr;
__le32 length;
} __attribute__ ((packed));
struct megasas_sge64 {
u64 phys_addr;
u32 length;
__le64 phys_addr;
__le32 length;
} __attribute__ ((packed));
struct megasas_sge_skinny {
u64 phys_addr;
u32 length;
u32 flag;
__le64 phys_addr;
__le32 length;
__le32 flag;
} __packed;
union megasas_sgl {
@ -1210,12 +1210,12 @@ struct megasas_header {
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xferlen; /*14h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
__le32 data_xferlen; /*14h */
} __attribute__ ((packed));
@ -1248,7 +1248,7 @@ typedef union _MFI_CAPABILITIES {
u32 reserved:25;
#endif
} mfi_capabilities;
u32 reg;
__le32 reg;
} MFI_CAPABILITIES;
struct megasas_init_frame {
@ -1260,33 +1260,35 @@ struct megasas_init_frame {
u8 reserved_1; /*03h */
MFI_CAPABILITIES driver_operations; /*04h*/
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 reserved_3; /*12h */
u32 data_xfer_len; /*14h */
__le16 flags; /*10h */
__le16 reserved_3; /*12h */
__le32 data_xfer_len; /*14h */
u32 queue_info_new_phys_addr_lo; /*18h */
u32 queue_info_new_phys_addr_hi; /*1Ch */
u32 queue_info_old_phys_addr_lo; /*20h */
u32 queue_info_old_phys_addr_hi; /*24h */
u32 reserved_4[6]; /*28h */
__le32 queue_info_new_phys_addr_lo; /*18h */
__le32 queue_info_new_phys_addr_hi; /*1Ch */
__le32 queue_info_old_phys_addr_lo; /*20h */
__le32 queue_info_old_phys_addr_hi; /*24h */
__le32 reserved_4[2]; /*28h */
__le32 system_info_lo; /*30h */
__le32 system_info_hi; /*34h */
__le32 reserved_5[2]; /*38h */
} __attribute__ ((packed));
struct megasas_init_queue_info {
u32 init_flags; /*00h */
u32 reply_queue_entries; /*04h */
__le32 init_flags; /*00h */
__le32 reply_queue_entries; /*04h */
u32 reply_queue_start_phys_addr_lo; /*08h */
u32 reply_queue_start_phys_addr_hi; /*0Ch */
u32 producer_index_phys_addr_lo; /*10h */
u32 producer_index_phys_addr_hi; /*14h */
u32 consumer_index_phys_addr_lo; /*18h */
u32 consumer_index_phys_addr_hi; /*1Ch */
__le32 reply_queue_start_phys_addr_lo; /*08h */
__le32 reply_queue_start_phys_addr_hi; /*0Ch */
__le32 producer_index_phys_addr_lo; /*10h */
__le32 producer_index_phys_addr_hi; /*14h */
__le32 consumer_index_phys_addr_lo; /*18h */
__le32 consumer_index_phys_addr_hi; /*1Ch */
} __attribute__ ((packed));
@ -1302,18 +1304,18 @@ struct megasas_io_frame {
u8 reserved_0; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 lba_count; /*14h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
__le32 lba_count; /*14h */
u32 sense_buf_phys_addr_lo; /*18h */
u32 sense_buf_phys_addr_hi; /*1Ch */
__le32 sense_buf_phys_addr_lo; /*18h */
__le32 sense_buf_phys_addr_hi; /*1Ch */
u32 start_lba_lo; /*20h */
u32 start_lba_hi; /*24h */
__le32 start_lba_lo; /*20h */
__le32 start_lba_hi; /*24h */
union megasas_sgl sgl; /*28h */
@ -1331,15 +1333,15 @@ struct megasas_pthru_frame {
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xfer_len; /*14h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
__le32 data_xfer_len; /*14h */
u32 sense_buf_phys_addr_lo; /*18h */
u32 sense_buf_phys_addr_hi; /*1Ch */
__le32 sense_buf_phys_addr_lo; /*18h */
__le32 sense_buf_phys_addr_hi; /*1Ch */
u8 cdb[16]; /*20h */
union megasas_sgl sgl; /*30h */
@ -1354,19 +1356,19 @@ struct megasas_dcmd_frame {
u8 reserved_1[4]; /*03h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u32 opcode; /*18h */
__le32 data_xfer_len; /*14h */
__le32 opcode; /*18h */
union { /*1Ch */
u8 b[12];
u16 s[6];
u32 w[3];
__le16 s[6];
__le32 w[3];
} mbox;
union megasas_sgl sgl; /*28h */
@ -1380,22 +1382,22 @@ struct megasas_abort_frame {
u8 cmd_status; /*02h */
u8 reserved_1; /*03h */
u32 reserved_2; /*04h */
__le32 reserved_2; /*04h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 reserved_3; /*12h */
u32 reserved_4; /*14h */
__le16 flags; /*10h */
__le16 reserved_3; /*12h */
__le32 reserved_4; /*14h */
u32 abort_context; /*18h */
u32 pad_1; /*1Ch */
__le32 abort_context; /*18h */
__le32 pad_1; /*1Ch */
u32 abort_mfi_phys_addr_lo; /*20h */
u32 abort_mfi_phys_addr_hi; /*24h */
__le32 abort_mfi_phys_addr_lo; /*20h */
__le32 abort_mfi_phys_addr_hi; /*24h */
u32 reserved_5[6]; /*28h */
__le32 reserved_5[6]; /*28h */
} __attribute__ ((packed));
@ -1409,14 +1411,14 @@ struct megasas_smp_frame {
u8 reserved_2[3]; /*04h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u64 sas_addr; /*18h */
__le32 data_xfer_len; /*14h */
__le64 sas_addr; /*18h */
union {
struct megasas_sge32 sge32[2]; /* [0]: resp [1]: req */
@ -1436,16 +1438,16 @@ struct megasas_stp_frame {
u8 reserved_3[2]; /*05h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
__le32 context; /*08h */
__le32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
__le16 flags; /*10h */
__le16 timeout; /*12h */
u32 data_xfer_len; /*14h */
__le32 data_xfer_len; /*14h */
u16 fis[10]; /*18h */
u32 stp_flags;
__le16 fis[10]; /*18h */
__le32 stp_flags;
union {
struct megasas_sge32 sge32[2]; /* [0]: resp [1]: data */
@ -1489,18 +1491,18 @@ union megasas_evt_class_locale {
} __attribute__ ((packed));
struct megasas_evt_log_info {
u32 newest_seq_num;
u32 oldest_seq_num;
u32 clear_seq_num;
u32 shutdown_seq_num;
u32 boot_seq_num;
__le32 newest_seq_num;
__le32 oldest_seq_num;
__le32 clear_seq_num;
__le32 shutdown_seq_num;
__le32 boot_seq_num;
} __attribute__ ((packed));
struct megasas_progress {
u16 progress;
u16 elapsed_seconds;
__le16 progress;
__le16 elapsed_seconds;
} __attribute__ ((packed));
@ -1521,9 +1523,9 @@ struct megasas_evtarg_pd {
struct megasas_evt_detail {
u32 seq_num;
u32 time_stamp;
u32 code;
__le32 seq_num;
__le32 time_stamp;
__le32 code;
union megasas_evt_class_locale cl;
u8 arg_type;
u8 reserved1[15];
@ -1542,18 +1544,18 @@ struct megasas_evt_detail {
struct {
struct megasas_evtarg_ld ld;
u64 count;
__le64 count;
} __attribute__ ((packed)) ld_count;
struct {
u64 lba;
__le64 lba;
struct megasas_evtarg_ld ld;
} __attribute__ ((packed)) ld_lba;
struct {
struct megasas_evtarg_ld ld;
u32 prevOwner;
u32 newOwner;
__le32 prevOwner;
__le32 newOwner;
} __attribute__ ((packed)) ld_owner;
struct {
@ -1610,7 +1612,7 @@ struct megasas_evt_detail {
struct {
u16 vendorId;
u16 deviceId;
__le16 deviceId;
u16 subVendorId;
u16 subDeviceId;
} __attribute__ ((packed)) pci;
@ -1630,9 +1632,9 @@ struct megasas_evt_detail {
} __attribute__ ((packed)) ecc;
u8 b[96];
u16 s[48];
u32 w[24];
u64 d[12];
__le16 s[48];
__le32 w[24];
__le64 d[12];
} args;
char description[128];
@ -1649,12 +1651,22 @@ struct megasas_irq_context {
u32 MSIxIndex;
};
struct MR_DRV_SYSTEM_INFO {
u8 infoVersion;
u8 systemIdLength;
u16 reserved0;
u8 systemId[64];
u8 reserved[1980];
};
struct megasas_instance {
u32 *producer;
__le32 *producer;
dma_addr_t producer_h;
u32 *consumer;
__le32 *consumer;
dma_addr_t consumer_h;
struct MR_DRV_SYSTEM_INFO *system_info_buf;
dma_addr_t system_info_h;
struct MR_LD_VF_AFFILIATION *vf_affiliation;
dma_addr_t vf_affiliation_h;
struct MR_LD_VF_AFFILIATION_111 *vf_affiliation_111;
@ -1662,7 +1674,7 @@ struct megasas_instance {
struct MR_CTRL_HB_HOST_MEM *hb_host_mem;
dma_addr_t hb_host_mem_h;
u32 *reply_queue;
__le32 *reply_queue;
dma_addr_t reply_queue_h;
u32 *crash_dump_buf;
@ -1681,7 +1693,7 @@ struct megasas_instance {
spinlock_t crashdump_lock;
struct megasas_register_set __iomem *reg_set;
u32 *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];
struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD];
u8 ld_ids[MEGASAS_MAX_LD_IDS];
@ -1769,6 +1781,7 @@ struct megasas_instance {
u16 throttlequeuedepth;
u8 mask_interrupts;
u8 is_imr;
bool dev_handle;
};
struct MR_LD_VF_MAP {
u32 size;
@ -1864,9 +1877,13 @@ struct megasas_instance_template {
#define MEGASAS_IS_LOGICAL(scp) \
(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
#define MEGASAS_DEV_INDEX(inst, scp) \
((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id
#define MEGASAS_DEV_INDEX(scp) \
(((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id)
#define MEGASAS_PD_INDEX(scp) \
((scp->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id)
struct megasas_cmd {
@ -1877,17 +1894,14 @@ struct megasas_cmd {
u32 index;
u8 sync_cmd;
u8 cmd_status;
u8 cmd_status_drv;
u8 abort_aen;
u8 retry_for_fw_reset;
struct list_head list;
struct scsi_cmnd *scmd;
void *mpt_pthr_cmd_blocked;
atomic_t mfi_mpt_pthr;
u8 is_wait_event;
u8 flags;
struct megasas_instance *instance;
union {
@ -1963,10 +1977,10 @@ u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map);
__le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
u16 get_updated_dev_handle(struct megasas_instance *instance,
__le16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info);
void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);

File diff suppressed because it is too large Load diff

View file

@ -150,7 +150,7 @@ u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map)
return le16_to_cpu(map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef);
}
u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
__le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
{
return map->raidMap.devHndlInfo[pd].curDevHdl;
}
@ -743,7 +743,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
u8 retval = TRUE;
u8 do_invader = 0;
u64 *pdBlock = &io_info->pdBlock;
u16 *pDevHandle = &io_info->devHandle;
__le16 *pDevHandle = &io_info->devHandle;
u32 logArm, rowMod, armQ, arm;
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
@ -777,7 +777,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
if (pd != MR_PD_INVALID)
*pDevHandle = MR_PdDevHandleGet(pd, map);
else {
*pDevHandle = MR_PD_INVALID;
*pDevHandle = cpu_to_le16(MR_PD_INVALID);
if ((raid->level >= 5) &&
(!do_invader || (do_invader &&
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
@ -825,7 +825,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
u8 retval = TRUE;
u8 do_invader = 0;
u64 *pdBlock = &io_info->pdBlock;
u16 *pDevHandle = &io_info->devHandle;
__le16 *pDevHandle = &io_info->devHandle;
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER ||
instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
@ -872,7 +872,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
/* Get dev handle from Pd. */
*pDevHandle = MR_PdDevHandleGet(pd, map);
else {
*pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
/* set dev handle as invalid. */
*pDevHandle = cpu_to_le16(MR_PD_INVALID);
if ((raid->level >= 5) &&
(!do_invader || (do_invader &&
(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
@ -1117,7 +1118,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
ref_in_start_stripe, io_info,
pRAID_Context, map);
/* If IO on an invalid Pd, then FP is not possible.*/
if (io_info->devHandle == MR_PD_INVALID)
if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
io_info->fpOkForIo = FALSE;
return retval;
} else if (isRead) {
@ -1349,11 +1350,11 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
return io_info->pd_after_lb;
}
u16 get_updated_dev_handle(struct megasas_instance *instance,
__le16 get_updated_dev_handle(struct megasas_instance *instance,
struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *io_info)
{
u8 arm_pd;
u16 devHandle;
__le16 devHandle;
struct fusion_context *fusion;
struct MR_DRV_RAID_MAP_ALL *drv_map;

View file

@ -53,10 +53,12 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_dbg.h>
#include <linux/dmi.h>
#include "megaraid_sas_fusion.h"
#include "megaraid_sas.h"
extern void megasas_free_cmds(struct megasas_instance *instance);
extern struct megasas_cmd *megasas_get_cmd(struct megasas_instance
*instance);
@ -156,28 +158,15 @@ megasas_clear_intr_fusion(struct megasas_register_set __iomem *regs)
* megasas_get_cmd_fusion - Get a command from the free pool
* @instance: Adapter soft state
*
* Returns a free command from the pool
* Returns a blk_tag indexed mpt frame
*/
struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
*instance)
inline struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
*instance, u32 blk_tag)
{
unsigned long flags;
struct fusion_context *fusion =
(struct fusion_context *)instance->ctrl_context;
struct megasas_cmd_fusion *cmd = NULL;
struct fusion_context *fusion;
spin_lock_irqsave(&fusion->mpt_pool_lock, flags);
if (!list_empty(&fusion->cmd_pool)) {
cmd = list_entry((&fusion->cmd_pool)->next,
struct megasas_cmd_fusion, list);
list_del_init(&cmd->list);
} else {
printk(KERN_ERR "megasas: Command pool (fusion) empty!\n");
}
spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags);
return cmd;
fusion = instance->ctrl_context;
return fusion->cmd_list[blk_tag];
}
/**
@ -188,47 +177,35 @@ struct megasas_cmd_fusion *megasas_get_cmd_fusion(struct megasas_instance
inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd)
{
unsigned long flags;
struct fusion_context *fusion =
(struct fusion_context *)instance->ctrl_context;
spin_lock_irqsave(&fusion->mpt_pool_lock, flags);
cmd->scmd = NULL;
cmd->sync_cmd_idx = (u32)ULONG_MAX;
memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
list_add(&cmd->list, (&fusion->cmd_pool)->next);
spin_unlock_irqrestore(&fusion->mpt_pool_lock, flags);
}
/**
* megasas_return_mfi_mpt_pthr - Return a mfi and mpt to free command pool
* @instance: Adapter soft state
* @cmd_mfi: MFI Command packet to be returned to free command pool
* @cmd_mpt: MPT Command packet to be returned to free command pool
* megasas_fire_cmd_fusion - Sends command to the FW
*/
inline void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
struct megasas_cmd *cmd_mfi,
struct megasas_cmd_fusion *cmd_fusion)
static void
megasas_fire_cmd_fusion(struct megasas_instance *instance,
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
{
#if defined(writeq) && defined(CONFIG_64BIT)
u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
le32_to_cpu(req_desc->u.low));
writeq(req_data, &instance->reg_set->inbound_low_queue_port);
#else
unsigned long flags;
/*
* TO DO: optimize this code and use only one lock instead of two
* locks being used currently- mpt_pool_lock is acquired
* inside mfi_pool_lock
*/
spin_lock_irqsave(&instance->mfi_pool_lock, flags);
megasas_return_cmd_fusion(instance, cmd_fusion);
if (atomic_read(&cmd_mfi->mfi_mpt_pthr) != MFI_MPT_ATTACHED)
dev_err(&instance->pdev->dev, "Possible bug from %s %d\n",
__func__, __LINE__);
atomic_set(&cmd_mfi->mfi_mpt_pthr, MFI_MPT_DETACHED);
__megasas_return_cmd(instance, cmd_mfi);
spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
spin_lock_irqsave(&instance->hba_lock, flags);
writel(le32_to_cpu(req_desc->u.low),
&instance->reg_set->inbound_low_queue_port);
writel(le32_to_cpu(req_desc->u.high),
&instance->reg_set->inbound_high_queue_port);
spin_unlock_irqrestore(&instance->hba_lock, flags);
#endif
}
/**
* megasas_teardown_frame_pool_fusion - Destroy the cmd frame DMA pool
* @instance: Adapter soft state
@ -326,7 +303,6 @@ megasas_free_cmds_fusion(struct megasas_instance *instance)
kfree(fusion->cmd_list);
fusion->cmd_list = NULL;
INIT_LIST_HEAD(&fusion->cmd_pool);
}
/**
@ -464,7 +440,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
reply_desc = fusion->reply_frames_desc;
for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++)
reply_desc->Words = ULLONG_MAX;
reply_desc->Words = cpu_to_le64(ULLONG_MAX);
io_frames_sz = fusion->io_frames_alloc_sz;
@ -535,7 +511,9 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
memset(cmd, 0, sizeof(struct megasas_cmd_fusion));
cmd->index = i + 1;
cmd->scmd = NULL;
cmd->sync_cmd_idx = (u32)ULONG_MAX; /* Set to Invalid */
cmd->sync_cmd_idx = (i >= instance->max_scsi_cmds) ?
(i - instance->max_scsi_cmds) :
(u32)ULONG_MAX; /* Set to Invalid */
cmd->instance = instance;
cmd->io_request =
(struct MPI2_RAID_SCSI_IO_REQUEST *)
@ -543,8 +521,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance)
memset(cmd->io_request, 0,
sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
cmd->io_request_phys_addr = io_req_base_phys + offset;
list_add_tail(&cmd->list, &fusion->cmd_pool);
}
/*
@ -605,14 +581,11 @@ wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
msleep(20);
}
if (frame_hdr->cmd_status == 0xff) {
if (fusion)
megasas_return_mfi_mpt_pthr(instance, cmd,
cmd->mpt_pthr_cmd_blocked);
if (frame_hdr->cmd_status == 0xff)
return -ETIME;
}
return 0;
return (frame_hdr->cmd_status == MFI_STAT_OK) ?
0 : 1;
}
/**
@ -633,6 +606,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
union MEGASAS_REQUEST_DESCRIPTOR_UNION req_desc;
int i;
struct megasas_header *frame_hdr;
const char *sys_info;
fusion = instance->ctrl_context;
@ -673,7 +647,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
frame_hdr = &cmd->frame->hdr;
frame_hdr->cmd_status = 0xFF;
frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
frame_hdr->flags = cpu_to_le16(
le16_to_cpu(frame_hdr->flags) |
MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
init_frame->cmd = MFI_CMD_INIT;
init_frame->cmd_status = 0xFF;
@ -695,6 +671,16 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
/* Convert capability to LE32 */
cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
sys_info = dmi_get_system_info(DMI_PRODUCT_UUID);
if (instance->system_info_buf && sys_info) {
memcpy(instance->system_info_buf->systemId, sys_info,
strlen(sys_info) > 64 ? 64 : strlen(sys_info));
instance->system_info_buf->systemIdLength =
strlen(sys_info) > 64 ? 64 : strlen(sys_info);
init_frame->system_info_lo = instance->system_info_h;
init_frame->system_info_hi = 0;
}
init_frame->queue_info_new_phys_addr_hi =
cpu_to_le32(upper_32_bits(ioc_init_handle));
init_frame->queue_info_new_phys_addr_lo =
@ -719,8 +705,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
break;
}
instance->instancet->fire_cmd(instance, req_desc.u.low,
req_desc.u.high, instance->reg_set);
megasas_fire_cmd_fusion(instance, &req_desc);
wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);
@ -820,11 +805,7 @@ megasas_get_ld_map_info(struct megasas_instance *instance)
else
ret = megasas_issue_polled(instance, cmd);
if (instance->ctrl_context && cmd->mpt_pthr_cmd_blocked)
megasas_return_mfi_mpt_pthr(instance, cmd,
cmd->mpt_pthr_cmd_blocked);
else
megasas_return_cmd(instance, cmd);
megasas_return_cmd(instance, cmd);
return ret;
}
@ -1060,6 +1041,15 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
for (i = 0 ; i < count; i++)
fusion->last_reply_idx[i] = 0;
/*
* For fusion adapters, 3 commands for IOCTL and 5 commands
* for driver's internal DCMDs.
*/
instance->max_scsi_cmds = instance->max_fw_cmds -
(MEGASAS_FUSION_INTERNAL_CMDS +
MEGASAS_FUSION_IOCTL_CMDS);
sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS);
/*
* Allocate memory for descriptors
* Create a pool of commands
@ -1130,34 +1120,6 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
return 1;
}
/**
* megasas_fire_cmd_fusion - Sends command to the FW
* @frame_phys_addr : Physical address of cmd
* @frame_count : Number of frames for the command
* @regs : MFI register set
*/
void
megasas_fire_cmd_fusion(struct megasas_instance *instance,
dma_addr_t req_desc_lo,
u32 req_desc_hi,
struct megasas_register_set __iomem *regs)
{
#if defined(writeq) && defined(CONFIG_64BIT)
u64 req_data = (((u64)le32_to_cpu(req_desc_hi) << 32) |
le32_to_cpu(req_desc_lo));
writeq(req_data, &(regs)->inbound_low_queue_port);
#else
unsigned long flags;
spin_lock_irqsave(&instance->hba_lock, flags);
writel(le32_to_cpu(req_desc_lo), &(regs)->inbound_low_queue_port);
writel(le32_to_cpu(req_desc_hi), &(regs)->inbound_high_queue_port);
spin_unlock_irqrestore(&instance->hba_lock, flags);
#endif
}
/**
* map_cmd_status - Maps FW cmd status to OS cmd status
* @cmd : Pointer to cmd
@ -1497,7 +1459,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
u8 *raidLUN;
device_id = MEGASAS_DEV_INDEX(instance, scp);
device_id = MEGASAS_DEV_INDEX(scp);
fusion = instance->ctrl_context;
@ -1621,6 +1583,14 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
cmd->pd_r1_lb = io_info.pd_after_lb;
} else
scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
if ((raidLUN[0] == 1) &&
(local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 2)) {
instance->dev_handle = !(instance->dev_handle);
io_info.devHandle =
local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].devHandle[instance->dev_handle];
}
cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
io_request->DevHandle = io_info.devHandle;
/* populate the LUN field */
@ -1650,121 +1620,68 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
}
/**
* megasas_build_dcdb_fusion - Prepares IOs to devices
* megasas_build_ld_nonrw_fusion - prepares non rw ios for virtual disk
* @instance: Adapter soft state
* @scp: SCSI command
* @cmd: Command to be prepared
*
* Prepares the io_request frame for non-io cmds
* Prepares the io_request frame for non-rw io cmds for vd.
*/
static void
megasas_build_dcdb_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scmd,
struct megasas_cmd_fusion *cmd)
static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd)
{
u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
u16 pd_index = 0;
u16 os_timeout_value;
u16 timeout_limit;
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
struct fusion_context *fusion = instance->ctrl_context;
u8 span, physArm;
u16 devHandle;
__le16 devHandle;
u32 ld, arRef, pd;
struct MR_LD_RAID *raid;
struct RAID_CONTEXT *pRAID_Context;
u8 fp_possible = 1;
io_request = cmd->io_request;
device_id = MEGASAS_DEV_INDEX(instance, scmd);
pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL)
+scmd->device->id;
device_id = MEGASAS_DEV_INDEX(scmd);
pd_index = MEGASAS_PD_INDEX(scmd);
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
/* get RAID_Context pointer */
pRAID_Context = &io_request->RaidContext;
/* Check with FW team */
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
pRAID_Context->regLockRowLBA = 0;
pRAID_Context->regLockLength = 0;
if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS &&
instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
if (fusion->fast_path_io)
io_request->DevHandle =
local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
io_request->RaidContext.RAIDFlags =
MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
cmd->request_desc->SCSIIO.MSIxIndex =
instance->msix_vectors ?
raw_smp_processor_id() %
instance->msix_vectors :
0;
os_timeout_value = scmd->request->timeout / HZ;
if (instance->secure_jbod_support &&
(megasas_cmd_type(scmd) == NON_READ_WRITE_SYSPDIO)) {
/* system pd firmware path */
io_request->Function =
MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
io_request->RaidContext.timeoutValue =
cpu_to_le16(os_timeout_value);
} else {
/* system pd Fast Path */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
io_request->RaidContext.regLockFlags = 0;
io_request->RaidContext.regLockRowLBA = 0;
io_request->RaidContext.regLockLength = 0;
timeout_limit = (scmd->device->type == TYPE_DISK) ?
255 : 0xFFFF;
io_request->RaidContext.timeoutValue =
cpu_to_le16((os_timeout_value > timeout_limit) ?
timeout_limit : os_timeout_value);
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
io_request->IoFlags |=
cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
}
} else {
if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS)
goto NonFastPath;
/*
* For older firmware, Driver should not access ldTgtIdToLd
* beyond index 127 and for Extended VD firmware, ldTgtIdToLd
* should not go beyond 255.
*/
if ((!fusion->fast_path_io) ||
(device_id >= instance->fw_supported_vd_count))
goto NonFastPath;
if (fusion->fast_path_io && (
device_id < instance->fw_supported_vd_count)) {
ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
if (ld >= instance->fw_supported_vd_count)
goto NonFastPath;
fp_possible = 0;
raid = MR_LdRaidGet(ld, local_map_ptr);
/* check if this LD is FP capable */
if (!(raid->capability.fpNonRWCapable))
/* not FP capable, send as non-FP */
goto NonFastPath;
fp_possible = 0;
} else
fp_possible = 0;
/* get RAID_Context pointer */
pRAID_Context = &io_request->RaidContext;
if (!fp_possible) {
io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
io_request->DevHandle = cpu_to_le16(device_id);
io_request->LUN[1] = scmd->device->lun;
pRAID_Context->timeoutValue =
cpu_to_le16 (scmd->request->timeout / HZ);
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
} else {
/* set RAID context values */
pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
pRAID_Context->regLockRowLBA = 0;
pRAID_Context->regLockLength = 0;
pRAID_Context->configSeqNum = raid->seqNum;
pRAID_Context->configSeqNum = raid->seqNum;
pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
/* get the DevHandle for the PD (since this is
fpNonRWCapable, this is a single disk RAID0) */
@ -1776,7 +1693,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build request descriptor */
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
cmd->request_desc->SCSIIO.DevHandle = devHandle;
/* populate the LUN field */
@ -1785,18 +1702,87 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build the raidScsiIO structure */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
io_request->DevHandle = devHandle;
}
}
return;
/**
* megasas_build_syspd_fusion - prepares rw/non-rw ios for syspd
* @instance: Adapter soft state
* @scp: SCSI command
* @cmd: Command to be prepared
* @fp_possible: parameter to detect fast path or firmware path io.
*
* Prepares the io_request frame for rw/non-rw io cmds for syspds
*/
static void
megasas_build_syspd_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible)
{
u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
u16 pd_index = 0;
u16 os_timeout_value;
u16 timeout_limit;
struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
struct RAID_CONTEXT *pRAID_Context;
struct fusion_context *fusion = instance->ctrl_context;
NonFastPath:
device_id = MEGASAS_DEV_INDEX(scmd);
pd_index = MEGASAS_PD_INDEX(scmd);
os_timeout_value = scmd->request->timeout / HZ;
io_request = cmd->io_request;
/* get RAID_Context pointer */
pRAID_Context = &io_request->RaidContext;
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
io_request->LUN[1] = scmd->device->lun;
pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
pRAID_Context->configSeqNum = 0;
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
io_request->DevHandle =
local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
cmd->request_desc->SCSIIO.MSIxIndex =
instance->msix_vectors ?
(raw_smp_processor_id() % instance->msix_vectors) : 0;
if (!fp_possible) {
/* system pd firmware path */
io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
io_request->DevHandle = cpu_to_le16(device_id);
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
} else {
/* system pd Fast Path */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
pRAID_Context->regLockFlags = 0;
pRAID_Context->regLockRowLBA = 0;
pRAID_Context->regLockLength = 0;
timeout_limit = (scmd->device->type == TYPE_DISK) ?
255 : 0xFFFF;
pRAID_Context->timeoutValue =
cpu_to_le16((os_timeout_value > timeout_limit) ?
timeout_limit : os_timeout_value);
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
cmd->request_desc->SCSIIO.RequestFlags |=
(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
pRAID_Context->Type = MPI2_TYPE_CUDA;
pRAID_Context->nseg = 0x1;
io_request->IoFlags |=
cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
}
cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
}
io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id);
int_to_scsilun(scmd->device->lun, (struct scsi_lun *)io_request->LUN);
}
/**
@ -1813,11 +1799,10 @@ megasas_build_io_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scp,
struct megasas_cmd_fusion *cmd)
{
u32 device_id, sge_count;
u32 sge_count;
u8 cmd_type;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
device_id = MEGASAS_DEV_INDEX(instance, scp);
/* Zero out some fields so they don't get reused */
memset(io_request->LUN, 0x0, 8);
io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
@ -1837,10 +1822,24 @@ megasas_build_io_fusion(struct megasas_instance *instance,
*/
io_request->IoFlags = cpu_to_le16(scp->cmd_len);
if (megasas_cmd_type(scp) == READ_WRITE_LDIO)
switch (cmd_type = megasas_cmd_type(scp)) {
case READ_WRITE_LDIO:
megasas_build_ldio_fusion(instance, scp, cmd);
else
megasas_build_dcdb_fusion(instance, scp, cmd);
break;
case NON_READ_WRITE_LDIO:
megasas_build_ld_nonrw_fusion(instance, scp, cmd);
break;
case READ_WRITE_SYSPDIO:
case NON_READ_WRITE_SYSPDIO:
if (instance->secure_jbod_support &&
(cmd_type == NON_READ_WRITE_SYSPDIO))
megasas_build_syspd_fusion(instance, scp, cmd, 0);
else
megasas_build_syspd_fusion(instance, scp, cmd, 1);
break;
default:
break;
}
/*
* Construct SGL
@ -1915,9 +1914,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
fusion = instance->ctrl_context;
cmd = megasas_get_cmd_fusion(instance);
if (!cmd)
return SCSI_MLQUEUE_HOST_BUSY;
cmd = megasas_get_cmd_fusion(instance, scmd->request->tag);
index = cmd->index;
@ -1948,9 +1945,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance,
*/
atomic_inc(&instance->fw_outstanding);
instance->instancet->fire_cmd(instance,
req_desc->u.low, req_desc->u.high,
instance->reg_set);
megasas_fire_cmd_fusion(instance, req_desc);
return 0;
}
@ -1975,6 +1970,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
union desc_value d_val;
struct LD_LOAD_BALANCE_INFO *lbinfo;
int threshold_reply_count = 0;
struct scsi_cmnd *scmd_local = NULL;
fusion = instance->ctrl_context;
@ -1998,7 +1994,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
num_completed = 0;
while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) {
while (d_val.u.low != cpu_to_le32(UINT_MAX) &&
d_val.u.high != cpu_to_le32(UINT_MAX)) {
smid = le16_to_cpu(reply_desc->SMID);
cmd_fusion = fusion->cmd_list[smid - 1];
@ -2010,14 +2007,14 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
if (cmd_fusion->scmd)
cmd_fusion->scmd->SCp.ptr = NULL;
scmd_local = cmd_fusion->scmd;
status = scsi_io_req->RaidContext.status;
extStatus = scsi_io_req->RaidContext.exStatus;
switch (scsi_io_req->Function) {
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
/* Update load balancing info */
device_id = MEGASAS_DEV_INDEX(instance,
cmd_fusion->scmd);
device_id = MEGASAS_DEV_INDEX(scmd_local);
lbinfo = &fusion->load_balance_info[device_id];
if (cmd_fusion->scmd->SCp.Status &
MEGASAS_LOAD_BALANCE_FLAG) {
@ -2035,29 +2032,25 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
/* Map the FW Cmd Status */
map_cmd_status(cmd_fusion, status, extStatus);
scsi_dma_unmap(cmd_fusion->scmd);
cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
scsi_io_req->RaidContext.status = 0;
scsi_io_req->RaidContext.exStatus = 0;
megasas_return_cmd_fusion(instance, cmd_fusion);
scsi_dma_unmap(scmd_local);
scmd_local->scsi_done(scmd_local);
atomic_dec(&instance->fw_outstanding);
break;
case MEGASAS_MPI2_FUNCTION_PASSTHRU_IO_REQUEST: /*MFI command */
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
if (!cmd_mfi->mpt_pthr_cmd_blocked) {
if (megasas_dbg_lvl == 5)
dev_info(&instance->pdev->dev,
"freeing mfi/mpt pass-through "
"from %s %d\n",
__func__, __LINE__);
megasas_return_mfi_mpt_pthr(instance, cmd_mfi,
cmd_fusion);
}
megasas_complete_cmd(instance, cmd_mfi, DID_OK);
cmd_fusion->flags = 0;
/* Poll mode. Dummy free.
* In case of Interrupt mode, caller has reverse check.
*/
if (cmd_mfi->flags & DRV_DCMD_POLLED_MODE) {
cmd_mfi->flags &= ~DRV_DCMD_POLLED_MODE;
megasas_return_cmd(instance, cmd_mfi);
} else
megasas_complete_cmd(instance, cmd_mfi, DID_OK);
break;
}
@ -2066,7 +2059,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
fusion->reply_q_depth)
fusion->last_reply_idx[MSIxIndex] = 0;
desc->Words = ULLONG_MAX;
desc->Words = cpu_to_le64(ULLONG_MAX);
num_completed++;
threshold_reply_count++;
@ -2217,27 +2210,14 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
struct megasas_cmd_fusion *cmd;
struct fusion_context *fusion;
struct megasas_header *frame_hdr = &mfi_cmd->frame->hdr;
u32 opcode;
cmd = megasas_get_cmd_fusion(instance);
if (!cmd)
return 1;
fusion = instance->ctrl_context;
cmd = megasas_get_cmd_fusion(instance,
instance->max_scsi_cmds + mfi_cmd->index);
/* Save the smid. To be used for returning the cmd */
mfi_cmd->context.smid = cmd->index;
cmd->sync_cmd_idx = mfi_cmd->index;
/* Set this only for Blocked commands */
opcode = le32_to_cpu(mfi_cmd->frame->dcmd.opcode);
if ((opcode == MR_DCMD_LD_MAP_GET_INFO)
&& (mfi_cmd->frame->dcmd.mbox.b[1] == 1))
mfi_cmd->is_wait_event = 1;
if (opcode == MR_DCMD_CTRL_EVENT_WAIT)
mfi_cmd->is_wait_event = 1;
if (mfi_cmd->is_wait_event)
mfi_cmd->mpt_pthr_cmd_blocked = cmd;
/*
* For cmds where the flag is set, store the flag and check
@ -2246,9 +2226,8 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance,
*/
if (frame_hdr->flags & cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE))
cmd->flags = MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
mfi_cmd->flags |= DRV_DCMD_POLLED_MODE;
fusion = instance->ctrl_context;
io_req = cmd->io_request;
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
@ -2327,9 +2306,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance,
printk(KERN_ERR "Couldn't issue MFI pass thru cmd\n");
return;
}
atomic_set(&cmd->mfi_mpt_pthr, MFI_MPT_ATTACHED);
instance->instancet->fire_cmd(instance, req_desc->u.low,
req_desc->u.high, instance->reg_set);
megasas_fire_cmd_fusion(instance, req_desc);
}
/**
@ -2508,7 +2485,42 @@ void megasas_reset_reply_desc(struct megasas_instance *instance)
fusion->last_reply_idx[i] = 0;
reply_desc = fusion->reply_frames_desc;
for (i = 0 ; i < fusion->reply_q_depth * count; i++, reply_desc++)
reply_desc->Words = ULLONG_MAX;
reply_desc->Words = cpu_to_le64(ULLONG_MAX);
}
/*
* megasas_refire_mgmt_cmd : Re-fire management commands
* @instance: Controller's soft instance
*/
void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
{
int j;
struct megasas_cmd_fusion *cmd_fusion;
struct fusion_context *fusion;
struct megasas_cmd *cmd_mfi;
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
u16 smid;
fusion = instance->ctrl_context;
/* Re-fire management commands.
* Do not traverse complet MPT frame pool. Start from max_scsi_cmds.
*/
for (j = instance->max_scsi_cmds ; j < instance->max_fw_cmds; j++) {
cmd_fusion = fusion->cmd_list[j];
cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx];
smid = le16_to_cpu(cmd_mfi->context.smid);
if (!smid)
continue;
req_desc = megasas_get_request_descriptor
(instance, smid - 1);
if (req_desc && (cmd_mfi->frame->dcmd.opcode !=
cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)))
megasas_fire_cmd_fusion(instance, req_desc);
else
megasas_return_cmd(instance, cmd_mfi);
}
}
/* Check for a second path that is currently UP */
@ -2538,14 +2550,13 @@ int megasas_check_mpio_paths(struct megasas_instance *instance,
/* Core fusion reset function */
int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
{
int retval = SUCCESS, i, j, retry = 0, convert = 0;
int retval = SUCCESS, i, retry = 0, convert = 0;
struct megasas_instance *instance;
struct megasas_cmd_fusion *cmd_fusion;
struct fusion_context *fusion;
struct megasas_cmd *cmd_mfi;
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
u32 host_diag, abs_state, status_reg, reset_adapter;
u32 io_timeout_in_crash_mode = 0;
struct scsi_cmnd *scmd_local = NULL;
instance = (struct megasas_instance *)shost->hostdata;
fusion = instance->ctrl_context;
@ -2613,15 +2624,16 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
iotimeout = 0;
/* Now return commands back to the OS */
for (i = 0 ; i < instance->max_fw_cmds; i++) {
for (i = 0 ; i < instance->max_scsi_cmds; i++) {
cmd_fusion = fusion->cmd_list[i];
scmd_local = cmd_fusion->scmd;
if (cmd_fusion->scmd) {
scsi_dma_unmap(cmd_fusion->scmd);
cmd_fusion->scmd->result =
scmd_local->result =
megasas_check_mpio_paths(instance,
cmd_fusion->scmd);
cmd_fusion->scmd->scsi_done(cmd_fusion->scmd);
scmd_local);
megasas_return_cmd_fusion(instance, cmd_fusion);
scsi_dma_unmap(scmd_local);
scmd_local->scsi_done(scmd_local);
atomic_dec(&instance->fw_outstanding);
}
}
@ -2790,44 +2802,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
continue;
}
/* Re-fire management commands */
for (j = 0 ; j < instance->max_fw_cmds; j++) {
cmd_fusion = fusion->cmd_list[j];
if (cmd_fusion->sync_cmd_idx !=
(u32)ULONG_MAX) {
cmd_mfi =
instance->
cmd_list[cmd_fusion->sync_cmd_idx];
if (cmd_mfi->frame->dcmd.opcode ==
cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO)) {
megasas_return_mfi_mpt_pthr(instance, cmd_mfi, cmd_fusion);
} else {
req_desc =
megasas_get_request_descriptor(
instance,
cmd_mfi->context.smid
-1);
if (!req_desc) {
printk(KERN_WARNING
"req_desc NULL"
" for scsi%d\n",
instance->host->host_no);
/* Return leaked MPT
frame */
megasas_return_cmd_fusion(instance, cmd_fusion);
} else {
instance->instancet->
fire_cmd(instance,
req_desc->
u.low,
req_desc->
u.high,
instance->
reg_set);
}
}
}
}
megasas_refire_mgmt_cmd(instance);
if (megasas_get_ctrl_info(instance)) {
dev_info(&instance->pdev->dev,
@ -2978,7 +2953,6 @@ void megasas_fusion_ocr_wq(struct work_struct *work)
}
struct megasas_instance_template megasas_instance_template_fusion = {
.fire_cmd = megasas_fire_cmd_fusion,
.enable_intr = megasas_enable_intr_fusion,
.disable_intr = megasas_disable_intr_fusion,
.clear_intr = megasas_clear_intr_fusion,

View file

@ -104,18 +104,18 @@ struct RAID_CONTEXT {
u8 nseg:4;
#endif
u8 resvd0;
u16 timeoutValue;
__le16 timeoutValue;
u8 regLockFlags;
u8 resvd1;
u16 VirtualDiskTgtId;
u64 regLockRowLBA;
u32 regLockLength;
u16 nextLMId;
__le16 VirtualDiskTgtId;
__le64 regLockRowLBA;
__le32 regLockLength;
__le16 nextLMId;
u8 exStatus;
u8 status;
u8 RAIDFlags;
u8 numSGE;
u16 configSeqNum;
__le16 configSeqNum;
u8 spanArm;
u8 resvd2[3];
};
@ -182,61 +182,61 @@ enum REGION_TYPE {
#define MPI2_WRSEQ_6TH_KEY_VALUE (0xD)
struct MPI25_IEEE_SGE_CHAIN64 {
u64 Address;
u32 Length;
u16 Reserved1;
__le64 Address;
__le32 Length;
__le16 Reserved1;
u8 NextChainOffset;
u8 Flags;
};
struct MPI2_SGE_SIMPLE_UNION {
u32 FlagsLength;
__le32 FlagsLength;
union {
u32 Address32;
u64 Address64;
__le32 Address32;
__le64 Address64;
} u;
};
struct MPI2_SCSI_IO_CDB_EEDP32 {
u8 CDB[20]; /* 0x00 */
u32 PrimaryReferenceTag; /* 0x14 */
u16 PrimaryApplicationTag; /* 0x18 */
u16 PrimaryApplicationTagMask; /* 0x1A */
u32 TransferLength; /* 0x1C */
__be32 PrimaryReferenceTag; /* 0x14 */
__be16 PrimaryApplicationTag; /* 0x18 */
__be16 PrimaryApplicationTagMask; /* 0x1A */
__le32 TransferLength; /* 0x1C */
};
struct MPI2_SGE_CHAIN_UNION {
u16 Length;
__le16 Length;
u8 NextChainOffset;
u8 Flags;
union {
u32 Address32;
u64 Address64;
__le32 Address32;
__le64 Address64;
} u;
};
struct MPI2_IEEE_SGE_SIMPLE32 {
u32 Address;
u32 FlagsLength;
__le32 Address;
__le32 FlagsLength;
};
struct MPI2_IEEE_SGE_CHAIN32 {
u32 Address;
u32 FlagsLength;
__le32 Address;
__le32 FlagsLength;
};
struct MPI2_IEEE_SGE_SIMPLE64 {
u64 Address;
u32 Length;
u16 Reserved1;
__le64 Address;
__le32 Length;
__le16 Reserved1;
u8 Reserved2;
u8 Flags;
};
struct MPI2_IEEE_SGE_CHAIN64 {
u64 Address;
u32 Length;
u16 Reserved1;
__le64 Address;
__le32 Length;
__le16 Reserved1;
u8 Reserved2;
u8 Flags;
};
@ -269,34 +269,34 @@ union MPI2_SCSI_IO_CDB_UNION {
* Total SGE count will be one less than _MPI2_SCSI_IO_REQUEST
*/
struct MPI2_RAID_SCSI_IO_REQUEST {
u16 DevHandle; /* 0x00 */
__le16 DevHandle; /* 0x00 */
u8 ChainOffset; /* 0x02 */
u8 Function; /* 0x03 */
u16 Reserved1; /* 0x04 */
__le16 Reserved1; /* 0x04 */
u8 Reserved2; /* 0x06 */
u8 MsgFlags; /* 0x07 */
u8 VP_ID; /* 0x08 */
u8 VF_ID; /* 0x09 */
u16 Reserved3; /* 0x0A */
u32 SenseBufferLowAddress; /* 0x0C */
u16 SGLFlags; /* 0x10 */
__le16 Reserved3; /* 0x0A */
__le32 SenseBufferLowAddress; /* 0x0C */
__le16 SGLFlags; /* 0x10 */
u8 SenseBufferLength; /* 0x12 */
u8 Reserved4; /* 0x13 */
u8 SGLOffset0; /* 0x14 */
u8 SGLOffset1; /* 0x15 */
u8 SGLOffset2; /* 0x16 */
u8 SGLOffset3; /* 0x17 */
u32 SkipCount; /* 0x18 */
u32 DataLength; /* 0x1C */
u32 BidirectionalDataLength; /* 0x20 */
u16 IoFlags; /* 0x24 */
u16 EEDPFlags; /* 0x26 */
u32 EEDPBlockSize; /* 0x28 */
u32 SecondaryReferenceTag; /* 0x2C */
u16 SecondaryApplicationTag; /* 0x30 */
u16 ApplicationTagTranslationMask; /* 0x32 */
__le32 SkipCount; /* 0x18 */
__le32 DataLength; /* 0x1C */
__le32 BidirectionalDataLength; /* 0x20 */
__le16 IoFlags; /* 0x24 */
__le16 EEDPFlags; /* 0x26 */
__le32 EEDPBlockSize; /* 0x28 */
__le32 SecondaryReferenceTag; /* 0x2C */
__le16 SecondaryApplicationTag; /* 0x30 */
__le16 ApplicationTagTranslationMask; /* 0x32 */
u8 LUN[8]; /* 0x34 */
u32 Control; /* 0x3C */
__le32 Control; /* 0x3C */
union MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */
struct RAID_CONTEXT RaidContext; /* 0x60 */
union MPI2_SGE_IO_UNION SGL; /* 0x80 */
@ -315,45 +315,45 @@ struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR {
struct MPI2_DEFAULT_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 LMID; /* 0x04 */
u16 DescriptorTypeDependent; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 LMID; /* 0x04 */
__le16 DescriptorTypeDependent; /* 0x06 */
};
/* High Priority Request Descriptor */
struct MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 LMID; /* 0x04 */
u16 Reserved1; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 LMID; /* 0x04 */
__le16 Reserved1; /* 0x06 */
};
/* SCSI IO Request Descriptor */
struct MPI2_SCSI_IO_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 LMID; /* 0x04 */
u16 DevHandle; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 LMID; /* 0x04 */
__le16 DevHandle; /* 0x06 */
};
/* SCSI Target Request Descriptor */
struct MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 LMID; /* 0x04 */
u16 IoIndex; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 LMID; /* 0x04 */
__le16 IoIndex; /* 0x06 */
};
/* RAID Accelerator Request Descriptor */
struct MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
u8 RequestFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 LMID; /* 0x04 */
u16 Reserved; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 LMID; /* 0x04 */
__le16 Reserved; /* 0x06 */
};
/* union of Request Descriptors */
@ -366,10 +366,10 @@ union MEGASAS_REQUEST_DESCRIPTOR_UNION {
struct MEGASAS_RAID_MFA_IO_REQUEST_DESCRIPTOR MFAIo;
union {
struct {
u32 low;
u32 high;
__le32 low;
__le32 high;
} u;
u64 Words;
__le64 Words;
};
};
@ -377,35 +377,35 @@ union MEGASAS_REQUEST_DESCRIPTOR_UNION {
struct MPI2_DEFAULT_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 DescriptorTypeDependent1; /* 0x02 */
u32 DescriptorTypeDependent2; /* 0x04 */
__le16 DescriptorTypeDependent1; /* 0x02 */
__le32 DescriptorTypeDependent2; /* 0x04 */
};
/* Address Reply Descriptor */
struct MPI2_ADDRESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u32 ReplyFrameAddress; /* 0x04 */
__le16 SMID; /* 0x02 */
__le32 ReplyFrameAddress; /* 0x04 */
};
/* SCSI IO Success Reply Descriptor */
struct MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u16 TaskTag; /* 0x04 */
u16 Reserved1; /* 0x06 */
__le16 SMID; /* 0x02 */
__le16 TaskTag; /* 0x04 */
__le16 Reserved1; /* 0x06 */
};
/* TargetAssist Success Reply Descriptor */
struct MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
__le16 SMID; /* 0x02 */
u8 SequenceNumber; /* 0x04 */
u8 Reserved1; /* 0x05 */
u16 IoIndex; /* 0x06 */
__le16 IoIndex; /* 0x06 */
};
/* Target Command Buffer Reply Descriptor */
@ -414,16 +414,16 @@ struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR {
u8 MSIxIndex; /* 0x01 */
u8 VP_ID; /* 0x02 */
u8 Flags; /* 0x03 */
u16 InitiatorDevHandle; /* 0x04 */
u16 IoIndex; /* 0x06 */
__le16 InitiatorDevHandle; /* 0x04 */
__le16 IoIndex; /* 0x06 */
};
/* RAID Accelerator Success Reply Descriptor */
struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
u8 ReplyFlags; /* 0x00 */
u8 MSIxIndex; /* 0x01 */
u16 SMID; /* 0x02 */
u32 Reserved; /* 0x04 */
__le16 SMID; /* 0x02 */
__le32 Reserved; /* 0x04 */
};
/* union of Reply Descriptors */
@ -435,7 +435,7 @@ union MPI2_REPLY_DESCRIPTORS_UNION {
struct MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
struct MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR
RAIDAcceleratorSuccess;
u64 Words;
__le64 Words;
};
/* IOCInit Request message */
@ -444,28 +444,28 @@ struct MPI2_IOC_INIT_REQUEST {
u8 Reserved1; /* 0x01 */
u8 ChainOffset; /* 0x02 */
u8 Function; /* 0x03 */
u16 Reserved2; /* 0x04 */
__le16 Reserved2; /* 0x04 */
u8 Reserved3; /* 0x06 */
u8 MsgFlags; /* 0x07 */
u8 VP_ID; /* 0x08 */
u8 VF_ID; /* 0x09 */
u16 Reserved4; /* 0x0A */
u16 MsgVersion; /* 0x0C */
u16 HeaderVersion; /* 0x0E */
__le16 Reserved4; /* 0x0A */
__le16 MsgVersion; /* 0x0C */
__le16 HeaderVersion; /* 0x0E */
u32 Reserved5; /* 0x10 */
u16 Reserved6; /* 0x14 */
__le16 Reserved6; /* 0x14 */
u8 Reserved7; /* 0x16 */
u8 HostMSIxVectors; /* 0x17 */
u16 Reserved8; /* 0x18 */
u16 SystemRequestFrameSize; /* 0x1A */
u16 ReplyDescriptorPostQueueDepth; /* 0x1C */
u16 ReplyFreeQueueDepth; /* 0x1E */
u32 SenseBufferAddressHigh; /* 0x20 */
u32 SystemReplyAddressHigh; /* 0x24 */
u64 SystemRequestFrameBaseAddress; /* 0x28 */
u64 ReplyDescriptorPostQueueAddress;/* 0x30 */
u64 ReplyFreeQueueAddress; /* 0x38 */
u64 TimeStamp; /* 0x40 */
__le16 Reserved8; /* 0x18 */
__le16 SystemRequestFrameSize; /* 0x1A */
__le16 ReplyDescriptorPostQueueDepth; /* 0x1C */
__le16 ReplyFreeQueueDepth; /* 0x1E */
__le32 SenseBufferAddressHigh; /* 0x20 */
__le32 SystemReplyAddressHigh; /* 0x24 */
__le64 SystemRequestFrameBaseAddress; /* 0x28 */
__le64 ReplyDescriptorPostQueueAddress;/* 0x30 */
__le64 ReplyFreeQueueAddress; /* 0x38 */
__le64 TimeStamp; /* 0x40 */
};
/* mrpriv defines */
@ -491,41 +491,41 @@ struct MPI2_IOC_INIT_REQUEST {
#define MR_DCMD_LD_VF_MAP_GET_ALL_LDS 0x03150200
struct MR_DEV_HANDLE_INFO {
u16 curDevHdl;
__le16 curDevHdl;
u8 validHandles;
u8 reserved;
u16 devHandle[2];
__le16 devHandle[2];
};
struct MR_ARRAY_INFO {
u16 pd[MAX_RAIDMAP_ROW_SIZE];
__le16 pd[MAX_RAIDMAP_ROW_SIZE];
};
struct MR_QUAD_ELEMENT {
u64 logStart;
u64 logEnd;
u64 offsetInSpan;
u32 diff;
u32 reserved1;
__le64 logStart;
__le64 logEnd;
__le64 offsetInSpan;
__le32 diff;
__le32 reserved1;
};
struct MR_SPAN_INFO {
u32 noElements;
u32 reserved1;
__le32 noElements;
__le32 reserved1;
struct MR_QUAD_ELEMENT quad[MAX_RAIDMAP_SPAN_DEPTH];
};
struct MR_LD_SPAN {
u64 startBlk;
u64 numBlks;
u16 arrayRef;
__le64 startBlk;
__le64 numBlks;
__le16 arrayRef;
u8 spanRowSize;
u8 spanRowDataSize;
u8 reserved[4];
};
struct MR_SPAN_BLOCK_INFO {
u64 num_rows;
__le64 num_rows;
struct MR_LD_SPAN span;
struct MR_SPAN_INFO block_span_info;
};
@ -558,8 +558,8 @@ struct MR_LD_RAID {
u32 reserved4:7;
#endif
} capability;
u32 reserved6;
u64 size;
__le32 reserved6;
__le64 size;
u8 spanDepth;
u8 level;
u8 stripeShift;
@ -568,12 +568,12 @@ struct MR_LD_RAID {
u8 writeMode;
u8 PRL;
u8 SRL;
u16 targetId;
__le16 targetId;
u8 ldState;
u8 regTypeReqOnWrite;
u8 modFactor;
u8 regTypeReqOnRead;
u16 seqNum;
__le16 seqNum;
struct {
u32 ldSyncRequired:1;
@ -592,20 +592,20 @@ struct MR_LD_SPAN_MAP {
};
struct MR_FW_RAID_MAP {
u32 totalSize;
__le32 totalSize;
union {
struct {
u32 maxLd;
u32 maxSpanDepth;
u32 maxRowSize;
u32 maxPdCount;
u32 maxArrays;
__le32 maxLd;
__le32 maxSpanDepth;
__le32 maxRowSize;
__le32 maxPdCount;
__le32 maxArrays;
} validationInfo;
u32 version[5];
__le32 version[5];
};
u32 ldCount;
u32 Reserved1;
__le32 ldCount;
__le32 Reserved1;
u8 ldTgtIdToLd[MAX_RAIDMAP_LOGICAL_DRIVES+
MAX_RAIDMAP_VIEWS];
u8 fpPdIoTimeoutSec;
@ -620,7 +620,7 @@ struct IO_REQUEST_INFO {
u32 numBlocks;
u16 ldTgtId;
u8 isRead;
u16 devHandle;
__le16 devHandle;
u64 pdBlock;
u8 fpOkForIo;
u8 IoforUnevenSpan;
@ -634,7 +634,7 @@ struct IO_REQUEST_INFO {
struct MR_LD_TARGET_SYNC {
u8 targetId;
u8 reserved;
u16 seqNum;
__le16 seqNum;
};
#define IEEE_SGE_FLAGS_ADDR_MASK (0x03)
@ -679,7 +679,6 @@ struct megasas_cmd_fusion {
*/
u32 sync_cmd_idx;
u32 index;
u8 flags;
u8 pd_r1_lb;
};
@ -720,27 +719,27 @@ struct MR_DRV_RAID_MAP {
* This feild will be manupulated by driver for ext raid map,
* else pick the value from firmware raid map.
*/
u32 totalSize;
__le32 totalSize;
union {
struct {
u32 maxLd;
u32 maxSpanDepth;
u32 maxRowSize;
u32 maxPdCount;
u32 maxArrays;
__le32 maxLd;
__le32 maxSpanDepth;
__le32 maxRowSize;
__le32 maxPdCount;
__le32 maxArrays;
} validationInfo;
u32 version[5];
__le32 version[5];
};
/* timeout value used by driver in FP IOs*/
u8 fpPdIoTimeoutSec;
u8 reserved2[7];
u16 ldCount;
u16 arCount;
u16 spanCount;
u16 reserve3;
__le16 ldCount;
__le16 arCount;
__le16 spanCount;
__le16 reserve3;
struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
@ -779,10 +778,10 @@ struct MR_FW_RAID_MAP_EXT {
u8 fpPdIoTimeoutSec;
u8 reserved2[7];
u16 ldCount;
u16 arCount;
u16 spanCount;
u16 reserve3;
__le16 ldCount;
__le16 arCount;
__le16 spanCount;
__le16 reserve3;
struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
@ -792,10 +791,6 @@ struct MR_FW_RAID_MAP_EXT {
struct fusion_context {
struct megasas_cmd_fusion **cmd_list;
struct list_head cmd_pool;
spinlock_t mpt_pool_lock;
dma_addr_t req_frames_desc_phys;
u8 *req_frames_desc;
@ -839,10 +834,10 @@ struct fusion_context {
};
union desc_value {
u64 word;
__le64 word;
struct {
u32 low;
u32 high;
__le32 low;
__le32 high;
} u;
};

View file

@ -56,7 +56,6 @@ static struct scsi_host_template mvs_sht = {
.change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param,
.can_queue = 1,
.cmd_per_lun = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,

View file

@ -274,7 +274,6 @@ static struct scsi_host_template nsp32_template = {
.can_queue = 1,
.sg_tablesize = NSP32_SG_SIZE,
.max_sectors = 128,
.cmd_per_lun = 1,
.this_id = NSP32_HOST_SCSIID,
.use_clustering = DISABLE_CLUSTERING,
.eh_abort_handler = nsp32_eh_abort,

View file

@ -86,7 +86,6 @@ static struct scsi_host_template nsp_driver_template = {
.can_queue = 1,
.this_id = NSP_INITIATOR_ID,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};

View file

@ -72,7 +72,6 @@ static struct scsi_host_template qlogicfas_driver_template = {
.can_queue = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};

View file

@ -680,7 +680,6 @@ static struct scsi_host_template sym53c500_driver_template = {
.can_queue = 1,
.this_id = 7,
.sg_tablesize = 32,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = SYM53C500_shost_attrs
};

View file

@ -78,7 +78,6 @@ static struct scsi_host_template pm8001_sht = {
.change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param,
.can_queue = 1,
.cmd_per_lun = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,

View file

@ -974,7 +974,6 @@ static struct scsi_host_template ppa_template = {
.bios_param = ppa_biosparam,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
.can_queue = 1,
.slave_alloc = ppa_adjust_queue,

View file

@ -347,7 +347,6 @@ static struct scsi_host_template ps3rom_host_template = {
.can_queue = 1,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.emulated = 1, /* only sg driver uses this */
.max_sectors = PS3ROM_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,

View file

@ -4217,7 +4217,6 @@ static struct scsi_host_template qla1280_driver_template = {
.can_queue = 0xfffff,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -708,7 +708,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
if (rval != QLA_SUCCESS) {
ql_log(ql_log_warn, vha, 0x00d4,
"Unable to initialize ISP84XX.\n");
qla84xx_put_chip(vha);
qla84xx_put_chip(vha);
}
}

View file

@ -2797,10 +2797,10 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds) {

View file

@ -1580,7 +1580,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
ql_log(ql_log_warn, fcport->vha, 0x503c,
"Async-%s error - hdl=%x response(%x).\n",
type, sp->handle, sts->data[3]);
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
}
}
@ -1979,7 +1979,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
rval = EXT_STATUS_ERR;
break;
}
bsg_job->reply->reply_payload_rcv_len = 0;
bsg_job->reply->reply_payload_rcv_len = 0;
done:
/* Return the vendor specific reply to API */

View file

@ -1843,7 +1843,7 @@ qla82xx_set_product_offset(struct qla_hw_data *ha)
ptab_desc = qla82xx_get_table_desc(unirom,
QLA82XX_URI_DIR_SECT_PRODUCT_TBL);
if (!ptab_desc)
if (!ptab_desc)
return -1;
entries = cpu_to_le32(ptab_desc->num_entries);

View file

@ -397,11 +397,11 @@ qla8044_idc_lock(struct qla_hw_data *ha)
* has the lock, wait for 2secs
* and retry
*/
ql_dbg(ql_dbg_p3p, vha, 0xb08a,
"%s: IDC lock Recovery by %d "
"failed, Retrying timeout\n", __func__,
ha->portnum);
timeout = 0;
ql_dbg(ql_dbg_p3p, vha, 0xb08a,
"%s: IDC lock Recovery by %d "
"failed, Retrying timeout\n", __func__,
ha->portnum);
timeout = 0;
}
}
msleep(QLA8044_DRV_LOCK_MSLEEP);
@ -3141,8 +3141,7 @@ qla8044_minidump_process_rdmdio(struct scsi_qla_host *vha,
goto error;
addr7 = addr2 - (4 * stride1);
data = qla8044_ipmdio_rd_reg(vha, addr1, addr3,
mask, addr7);
data = qla8044_ipmdio_rd_reg(vha, addr1, addr3, mask, addr7);
if (data == -1)
goto error;

View file

@ -4418,7 +4418,10 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
void
qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
uint16_t options = (requester_id << 15) | BIT_7, retry;
#if 0
uint16_t options = (requester_id << 15) | BIT_7;
#endif
uint16_t retry;
uint32_t data;
struct qla_hw_data *ha = base_vha->hw;
@ -4454,6 +4457,7 @@ qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
return;
#if 0
/* XXX: IDC-unlock implementation using access-control mbx */
retry = 0;
retry_unlock2:
@ -4469,6 +4473,7 @@ qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
}
return;
#endif
}
int

View file

@ -3712,6 +3712,14 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
{
#if 1
/*
* FIXME: Reject non zero SRR relative offset until we can test
* this code properly.
*/
pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset);
return -1;
#else
struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL;
size_t first_offset = 0, rem_offset = offset, tmp = 0;
int i, sg_srr_cnt, bufflen = 0;
@ -3721,13 +3729,6 @@ static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
"cmd->sg_cnt: %u, direction: %d\n",
cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
/*
* FIXME: Reject non zero SRR relative offset until we can test
* this code properly.
*/
pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset);
return -1;
if (!cmd->sg || !cmd->sg_cnt) {
ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055,
"Missing cmd->sg or zero cmd->sg_cnt in"
@ -3810,6 +3811,7 @@ static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset)
BUG();
return 0;
#endif
}
static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd,

View file

@ -193,7 +193,6 @@ static struct scsi_host_template qlogicfas_driver_template = {
.can_queue = 1,
.this_id = -1,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};

View file

@ -1287,7 +1287,6 @@ static struct scsi_host_template qpti_template = {
.can_queue = QLOGICPTI_REQ_QUEUE_LEN,
.this_id = 7,
.sg_tablesize = QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN),
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};

View file

@ -98,52 +98,6 @@ EXPORT_SYMBOL(scsi_sd_probe_domain);
ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
EXPORT_SYMBOL(scsi_sd_pm_domain);
/* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
* You may not alter any existing entry (although adding new ones is
* encouraged once assigned by ANSI/INCITS T10
*/
static const char *const scsi_device_types[] = {
"Direct-Access ",
"Sequential-Access",
"Printer ",
"Processor ",
"WORM ",
"CD-ROM ",
"Scanner ",
"Optical Device ",
"Medium Changer ",
"Communications ",
"ASC IT8 ",
"ASC IT8 ",
"RAID ",
"Enclosure ",
"Direct-Access-RBC",
"Optical card ",
"Bridge controller",
"Object storage ",
"Automation/Drive ",
"Security Manager ",
"Direct-Access-ZBC",
};
/**
* scsi_device_type - Return 17 char string indicating device type.
* @type: type number to look up
*/
const char * scsi_device_type(unsigned type)
{
if (type == 0x1e)
return "Well-known LUN ";
if (type == 0x1f)
return "No Device ";
if (type >= ARRAY_SIZE(scsi_device_types))
return "Unknown ";
return scsi_device_types[type];
}
EXPORT_SYMBOL(scsi_device_type);
struct scsi_host_cmd_pool {
struct kmem_cache *cmd_slab;
struct kmem_cache *sense_slab;

178
drivers/scsi/scsi_common.c Normal file
View file

@ -0,0 +1,178 @@
/*
* SCSI functions used by both the initiator and the target code.
*/
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <scsi/scsi_common.h>
/* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
* You may not alter any existing entry (although adding new ones is
* encouraged once assigned by ANSI/INCITS T10
*/
static const char *const scsi_device_types[] = {
"Direct-Access ",
"Sequential-Access",
"Printer ",
"Processor ",
"WORM ",
"CD-ROM ",
"Scanner ",
"Optical Device ",
"Medium Changer ",
"Communications ",
"ASC IT8 ",
"ASC IT8 ",
"RAID ",
"Enclosure ",
"Direct-Access-RBC",
"Optical card ",
"Bridge controller",
"Object storage ",
"Automation/Drive ",
"Security Manager ",
"Direct-Access-ZBC",
};
/**
* scsi_device_type - Return 17 char string indicating device type.
* @type: type number to look up
*/
const char *scsi_device_type(unsigned type)
{
if (type == 0x1e)
return "Well-known LUN ";
if (type == 0x1f)
return "No Device ";
if (type >= ARRAY_SIZE(scsi_device_types))
return "Unknown ";
return scsi_device_types[type];
}
EXPORT_SYMBOL(scsi_device_type);
/**
* scsilun_to_int - convert a scsi_lun to an int
* @scsilun: struct scsi_lun to be converted.
*
* Description:
* Convert @scsilun from a struct scsi_lun to a four byte host byte-ordered
* integer, and return the result. The caller must check for
* truncation before using this function.
*
* Notes:
* For a description of the LUN format, post SCSI-3 see the SCSI
* Architecture Model, for SCSI-3 see the SCSI Controller Commands.
*
* Given a struct scsi_lun of: d2 04 0b 03 00 00 00 00, this function
* returns the integer: 0x0b03d204
*
* This encoding will return a standard integer LUN for LUNs smaller
* than 256, which typically use a single level LUN structure with
* addressing method 0.
*/
u64 scsilun_to_int(struct scsi_lun *scsilun)
{
int i;
u64 lun;
lun = 0;
for (i = 0; i < sizeof(lun); i += 2)
lun = lun | (((u64)scsilun->scsi_lun[i] << ((i + 1) * 8)) |
((u64)scsilun->scsi_lun[i + 1] << (i * 8)));
return lun;
}
EXPORT_SYMBOL(scsilun_to_int);
/**
* int_to_scsilun - reverts an int into a scsi_lun
* @lun: integer to be reverted
* @scsilun: struct scsi_lun to be set.
*
* Description:
* Reverts the functionality of the scsilun_to_int, which packed
* an 8-byte lun value into an int. This routine unpacks the int
* back into the lun value.
*
* Notes:
* Given an integer : 0x0b03d204, this function returns a
* struct scsi_lun of: d2 04 0b 03 00 00 00 00
*
*/
void int_to_scsilun(u64 lun, struct scsi_lun *scsilun)
{
int i;
memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
for (i = 0; i < sizeof(lun); i += 2) {
scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
scsilun->scsi_lun[i+1] = lun & 0xFF;
lun = lun >> 16;
}
}
EXPORT_SYMBOL(int_to_scsilun);
/**
* scsi_normalize_sense - normalize main elements from either fixed or
* descriptor sense data format into a common format.
*
* @sense_buffer: byte array containing sense data returned by device
* @sb_len: number of valid bytes in sense_buffer
* @sshdr: pointer to instance of structure that common
* elements are written to.
*
* Notes:
* The "main elements" from sense data are: response_code, sense_key,
* asc, ascq and additional_length (only for descriptor format).
*
* Typically this function can be called after a device has
* responded to a SCSI command with the CHECK_CONDITION status.
*
* Return value:
* true if valid sense data information found, else false;
*/
bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
struct scsi_sense_hdr *sshdr)
{
if (!sense_buffer || !sb_len)
return false;
memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
sshdr->response_code = (sense_buffer[0] & 0x7f);
if (!scsi_sense_valid(sshdr))
return false;
if (sshdr->response_code >= 0x72) {
/*
* descriptor format
*/
if (sb_len > 1)
sshdr->sense_key = (sense_buffer[1] & 0xf);
if (sb_len > 2)
sshdr->asc = sense_buffer[2];
if (sb_len > 3)
sshdr->ascq = sense_buffer[3];
if (sb_len > 7)
sshdr->additional_length = sense_buffer[7];
} else {
/*
* fixed format
*/
if (sb_len > 2)
sshdr->sense_key = (sense_buffer[2] & 0xf);
if (sb_len > 7) {
sb_len = (sb_len < (sense_buffer[7] + 8)) ?
sb_len : (sense_buffer[7] + 8);
if (sb_len > 12)
sshdr->asc = sense_buffer[12];
if (sb_len > 13)
sshdr->ascq = sense_buffer[13];
}
}
return true;
}
EXPORT_SYMBOL(scsi_normalize_sense);

View file

@ -2399,70 +2399,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
}
EXPORT_SYMBOL(scsi_ioctl_reset);
/**
* scsi_normalize_sense - normalize main elements from either fixed or
* descriptor sense data format into a common format.
*
* @sense_buffer: byte array containing sense data returned by device
* @sb_len: number of valid bytes in sense_buffer
* @sshdr: pointer to instance of structure that common
* elements are written to.
*
* Notes:
* The "main elements" from sense data are: response_code, sense_key,
* asc, ascq and additional_length (only for descriptor format).
*
* Typically this function can be called after a device has
* responded to a SCSI command with the CHECK_CONDITION status.
*
* Return value:
* true if valid sense data information found, else false;
*/
bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
struct scsi_sense_hdr *sshdr)
{
if (!sense_buffer || !sb_len)
return false;
memset(sshdr, 0, sizeof(struct scsi_sense_hdr));
sshdr->response_code = (sense_buffer[0] & 0x7f);
if (!scsi_sense_valid(sshdr))
return false;
if (sshdr->response_code >= 0x72) {
/*
* descriptor format
*/
if (sb_len > 1)
sshdr->sense_key = (sense_buffer[1] & 0xf);
if (sb_len > 2)
sshdr->asc = sense_buffer[2];
if (sb_len > 3)
sshdr->ascq = sense_buffer[3];
if (sb_len > 7)
sshdr->additional_length = sense_buffer[7];
} else {
/*
* fixed format
*/
if (sb_len > 2)
sshdr->sense_key = (sense_buffer[2] & 0xf);
if (sb_len > 7) {
sb_len = (sb_len < (sense_buffer[7] + 8)) ?
sb_len : (sense_buffer[7] + 8);
if (sb_len > 12)
sshdr->asc = sense_buffer[12];
if (sb_len > 13)
sshdr->ascq = sense_buffer[13];
}
}
return true;
}
EXPORT_SYMBOL(scsi_normalize_sense);
bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd,
struct scsi_sense_hdr *sshdr)
{

View file

@ -280,7 +280,8 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
sdev->host->cmd_per_lun, shost->bqt,
shost->hostt->tag_alloc_policy);
}
scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun);
scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun ?
sdev->host->cmd_per_lun : 1);
scsi_sysfs_device_initialize(sdev);
@ -1268,68 +1269,6 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
return;
}
/**
* scsilun_to_int - convert a scsi_lun to an int
* @scsilun: struct scsi_lun to be converted.
*
* Description:
* Convert @scsilun from a struct scsi_lun to a four byte host byte-ordered
* integer, and return the result. The caller must check for
* truncation before using this function.
*
* Notes:
* For a description of the LUN format, post SCSI-3 see the SCSI
* Architecture Model, for SCSI-3 see the SCSI Controller Commands.
*
* Given a struct scsi_lun of: d2 04 0b 03 00 00 00 00, this function
* returns the integer: 0x0b03d204
*
* This encoding will return a standard integer LUN for LUNs smaller
* than 256, which typically use a single level LUN structure with
* addressing method 0.
**/
u64 scsilun_to_int(struct scsi_lun *scsilun)
{
int i;
u64 lun;
lun = 0;
for (i = 0; i < sizeof(lun); i += 2)
lun = lun | (((u64)scsilun->scsi_lun[i] << ((i + 1) * 8)) |
((u64)scsilun->scsi_lun[i + 1] << (i * 8)));
return lun;
}
EXPORT_SYMBOL(scsilun_to_int);
/**
* int_to_scsilun - reverts an int into a scsi_lun
* @lun: integer to be reverted
* @scsilun: struct scsi_lun to be set.
*
* Description:
* Reverts the functionality of the scsilun_to_int, which packed
* an 8-byte lun value into an int. This routine unpacks the int
* back into the lun value.
*
* Notes:
* Given an integer : 0x0b03d204, this function returns a
* struct scsi_lun of: d2 04 0b 03 00 00 00 00
*
**/
void int_to_scsilun(u64 lun, struct scsi_lun *scsilun)
{
int i;
memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
for (i = 0; i < sizeof(lun); i += 2) {
scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
scsilun->scsi_lun[i+1] = lun & 0xFF;
lun = lun >> 16;
}
}
EXPORT_SYMBOL(int_to_scsilun);
/**
* scsi_report_lun_scan - Scan using SCSI REPORT LUN results
* @starget: which target

View file

@ -204,6 +204,8 @@ iscsi_create_endpoint(int dd_size)
iscsi_match_epid);
if (!dev)
break;
else
put_device(dev);
}
if (id == ISCSI_MAX_EPID) {
printk(KERN_ERR "Too many connections. Max supported %u\n",

View file

@ -2988,7 +2988,8 @@ static int sd_probe(struct device *dev)
sdkp->dev.class = &sd_disk_class;
dev_set_name(&sdkp->dev, "%s", dev_name(dev));
if (device_add(&sdkp->dev))
error = device_add(&sdkp->dev);
if (error)
goto out_free_index;
get_device(dev);

View file

@ -0,0 +1,17 @@
obj-$(CONFIG_SCSI_SNIC) += snic.o
snic-y := \
snic_attrs.o \
snic_main.o \
snic_res.o \
snic_isr.o \
snic_ctl.o \
snic_io.o \
snic_scsi.o \
snic_disc.o \
vnic_cq.o \
vnic_intr.o \
vnic_dev.o \
vnic_wq.o
snic-$(CONFIG_SCSI_SNIC_DEBUG_FS) += snic_debugfs.o snic_trc.o

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