Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "This is mostly updates of the usual suspects: lpfc, qla2xxx, bnx2fc, qedf, hpsa, hisi_sas, smartpqi, cxlflash, aacraid, csiostor along with a host of minor and miscellaneous changes" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (276 commits) qla2xxx: Fix NVMe entry_type for iocb packet on BE system scsi: qla2xxx: avoid unused-function warning scsi: snic: fix a couple of spelling mistakes/typos scsi: qla2xxx: fix a bunch of typos and spelling mistakes scsi: lpfc: don't double count abort errors scsi: lpfc: spin_lock_irq() is not nestable scsi: hisi_sas: optimise DMA slot memory scsi: ibmvfc: constify dev_pm_ops structures. scsi: ibmvscsi: constify dev_pm_ops structures. scsi: cxlflash: Update debug prints in reset handlers scsi: cxlflash: Update send_tmf() parameters scsi: cxlflash: Avoid double free of character device scsi: Add STARGET_CREATED_REMOVE state to scsi_target_state scsi: ses: do not add a device to an enclosure if enclosure_add_links() fails. scsi: ufs: flush eh_work when eh_work scheduled. scsi: qla2xxx: Protect access to qpair members with qpair->qp_lock scsi: sun_esp: fix device reference leaks scsi: fnic: changing queue command to return result DID_IMM_RETRY when rport is init scsi: fnic: correct speed display and add support for 25,40 and 100G scsi: fnic: added timestamp reporting in fnic debug stats ...
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* QLogic FCoE Offload Driver
|
||||
* Copyright (c) 2016 Cavium Inc.
|
||||
* Copyright (c) 2016-2017 Cavium Inc.
|
||||
*
|
||||
* This software is available under the terms of the GNU General Public License
|
||||
* (GPL) Version 2, available from the file COPYING in the main directory of
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/cpu.h>
|
||||
#include "qedf.h"
|
||||
#include <uapi/linux/pci_regs.h>
|
||||
|
||||
const struct qed_fcoe_ops *qed_ops;
|
||||
|
||||
@@ -94,7 +95,7 @@ module_param_named(dp_module, qedf_dp_module, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(dp_module, " bit flags control for verbose printk passed "
|
||||
"qed module during probe.");
|
||||
|
||||
static uint qedf_dp_level;
|
||||
static uint qedf_dp_level = QED_LEVEL_NOTICE;
|
||||
module_param_named(dp_level, qedf_dp_level, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(dp_level, " printk verbosity control passed to qed module "
|
||||
"during probe (0-3: 0 more verbose).");
|
||||
@@ -441,7 +442,8 @@ static void qedf_link_update(void *dev, struct qed_link_output *link)
|
||||
qedf_update_link_speed(qedf, link);
|
||||
|
||||
if (atomic_read(&qedf->dcbx) == QEDF_DCBX_DONE) {
|
||||
QEDF_ERR(&(qedf->dbg_ctx), "DCBx done.\n");
|
||||
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
|
||||
"DCBx done.\n");
|
||||
if (atomic_read(&qedf->link_down_tmo_valid) > 0)
|
||||
queue_delayed_work(qedf->link_update_wq,
|
||||
&qedf->link_recovery, 0);
|
||||
@@ -627,6 +629,16 @@ static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd)
|
||||
return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
|
||||
}
|
||||
|
||||
static int qedf_eh_bus_reset(struct scsi_cmnd *sc_cmd)
|
||||
{
|
||||
QEDF_ERR(NULL, "BUS RESET Issued...\n");
|
||||
/*
|
||||
* Essentially a no-op but return SUCCESS to prevent
|
||||
* unnecessary escalation to the host reset handler.
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void qedf_wait_for_upload(struct qedf_ctx *qedf)
|
||||
{
|
||||
while (1) {
|
||||
@@ -639,27 +651,17 @@ void qedf_wait_for_upload(struct qedf_ctx *qedf)
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the host by gracefully logging out and then logging back in */
|
||||
static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
|
||||
/* Performs soft reset of qedf_ctx by simulating a link down/up */
|
||||
static void qedf_ctx_soft_reset(struct fc_lport *lport)
|
||||
{
|
||||
struct fc_lport *lport;
|
||||
struct qedf_ctx *qedf;
|
||||
|
||||
lport = shost_priv(sc_cmd->device->host);
|
||||
|
||||
if (lport->vport) {
|
||||
QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n");
|
||||
return SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
qedf = (struct qedf_ctx *)lport_priv(lport);
|
||||
|
||||
if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN ||
|
||||
test_bit(QEDF_UNLOADING, &qedf->flags) ||
|
||||
test_bit(QEDF_DBG_STOP_IO, &qedf->flags))
|
||||
return FAILED;
|
||||
|
||||
QEDF_ERR(&(qedf->dbg_ctx), "HOST RESET Issued...");
|
||||
qedf = lport_priv(lport);
|
||||
|
||||
/* For host reset, essentially do a soft link up/down */
|
||||
atomic_set(&qedf->link_state, QEDF_LINK_DOWN);
|
||||
@@ -671,6 +673,24 @@ static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
|
||||
qedf->vlan_id = 0;
|
||||
queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
|
||||
0);
|
||||
}
|
||||
|
||||
/* Reset the host by gracefully logging out and then logging back in */
|
||||
static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
|
||||
{
|
||||
struct fc_lport *lport;
|
||||
struct qedf_ctx *qedf;
|
||||
|
||||
lport = shost_priv(sc_cmd->device->host);
|
||||
qedf = lport_priv(lport);
|
||||
|
||||
if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN ||
|
||||
test_bit(QEDF_UNLOADING, &qedf->flags))
|
||||
return FAILED;
|
||||
|
||||
QEDF_ERR(&(qedf->dbg_ctx), "HOST RESET Issued...");
|
||||
|
||||
qedf_ctx_soft_reset(lport);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -688,7 +708,7 @@ static struct scsi_host_template qedf_host_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = QEDF_MODULE_NAME,
|
||||
.this_id = -1,
|
||||
.cmd_per_lun = 3,
|
||||
.cmd_per_lun = 32,
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
.max_sectors = 0xffff,
|
||||
.queuecommand = qedf_queuecommand,
|
||||
@@ -696,11 +716,13 @@ static struct scsi_host_template qedf_host_template = {
|
||||
.eh_abort_handler = qedf_eh_abort,
|
||||
.eh_device_reset_handler = qedf_eh_device_reset, /* lun reset */
|
||||
.eh_target_reset_handler = qedf_eh_target_reset, /* target reset */
|
||||
.eh_bus_reset_handler = qedf_eh_bus_reset,
|
||||
.eh_host_reset_handler = qedf_eh_host_reset,
|
||||
.slave_configure = qedf_slave_configure,
|
||||
.dma_boundary = QED_HW_DMA_BOUNDARY,
|
||||
.sg_tablesize = QEDF_MAX_BDS_PER_CMD,
|
||||
.can_queue = FCOE_PARAMS_NUM_TASKS,
|
||||
.change_queue_depth = scsi_change_queue_depth,
|
||||
};
|
||||
|
||||
static int qedf_get_paged_crc_eof(struct sk_buff *skb, int tlen)
|
||||
@@ -950,25 +972,21 @@ static int qedf_alloc_sq(struct qedf_ctx *qedf, struct qedf_rport *fcport)
|
||||
sizeof(void *);
|
||||
fcport->sq_pbl_size = fcport->sq_pbl_size + QEDF_PAGE_SIZE;
|
||||
|
||||
fcport->sq = dma_alloc_coherent(&qedf->pdev->dev, fcport->sq_mem_size,
|
||||
&fcport->sq_dma, GFP_KERNEL);
|
||||
fcport->sq = dma_zalloc_coherent(&qedf->pdev->dev,
|
||||
fcport->sq_mem_size, &fcport->sq_dma, GFP_KERNEL);
|
||||
if (!fcport->sq) {
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send "
|
||||
"queue.\n");
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send queue.\n");
|
||||
rval = 1;
|
||||
goto out;
|
||||
}
|
||||
memset(fcport->sq, 0, fcport->sq_mem_size);
|
||||
|
||||
fcport->sq_pbl = dma_alloc_coherent(&qedf->pdev->dev,
|
||||
fcport->sq_pbl = dma_zalloc_coherent(&qedf->pdev->dev,
|
||||
fcport->sq_pbl_size, &fcport->sq_pbl_dma, GFP_KERNEL);
|
||||
if (!fcport->sq_pbl) {
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send "
|
||||
"queue PBL.\n");
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate send queue PBL.\n");
|
||||
rval = 1;
|
||||
goto out_free_sq;
|
||||
}
|
||||
memset(fcport->sq_pbl, 0, fcport->sq_pbl_size);
|
||||
|
||||
/* Create PBL */
|
||||
num_pages = fcport->sq_mem_size / QEDF_PAGE_SIZE;
|
||||
@@ -1334,6 +1352,59 @@ static void qedf_fcoe_ctlr_setup(struct qedf_ctx *qedf)
|
||||
ether_addr_copy(qedf->ctlr.ctl_src_addr, qedf->mac);
|
||||
}
|
||||
|
||||
static void qedf_setup_fdmi(struct qedf_ctx *qedf)
|
||||
{
|
||||
struct fc_lport *lport = qedf->lport;
|
||||
struct fc_host_attrs *fc_host = shost_to_fc_host(lport->host);
|
||||
u8 buf[8];
|
||||
int i, pos;
|
||||
|
||||
/*
|
||||
* fdmi_enabled needs to be set for libfc to execute FDMI registration.
|
||||
*/
|
||||
lport->fdmi_enabled = 1;
|
||||
|
||||
/*
|
||||
* Setup the necessary fc_host attributes to that will be used to fill
|
||||
* in the FDMI information.
|
||||
*/
|
||||
|
||||
/* Get the PCI-e Device Serial Number Capability */
|
||||
pos = pci_find_ext_capability(qedf->pdev, PCI_EXT_CAP_ID_DSN);
|
||||
if (pos) {
|
||||
pos += 4;
|
||||
for (i = 0; i < 8; i++)
|
||||
pci_read_config_byte(qedf->pdev, pos + i, &buf[i]);
|
||||
|
||||
snprintf(fc_host->serial_number,
|
||||
sizeof(fc_host->serial_number),
|
||||
"%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
buf[7], buf[6], buf[5], buf[4],
|
||||
buf[3], buf[2], buf[1], buf[0]);
|
||||
} else
|
||||
snprintf(fc_host->serial_number,
|
||||
sizeof(fc_host->serial_number), "Unknown");
|
||||
|
||||
snprintf(fc_host->manufacturer,
|
||||
sizeof(fc_host->manufacturer), "%s", "Cavium Inc.");
|
||||
|
||||
snprintf(fc_host->model, sizeof(fc_host->model), "%s", "QL41000");
|
||||
|
||||
snprintf(fc_host->model_description, sizeof(fc_host->model_description),
|
||||
"%s", "QLogic FastLinQ QL41000 Series 10/25/40/50GGbE Controller"
|
||||
"(FCoE)");
|
||||
|
||||
snprintf(fc_host->hardware_version, sizeof(fc_host->hardware_version),
|
||||
"Rev %d", qedf->pdev->revision);
|
||||
|
||||
snprintf(fc_host->driver_version, sizeof(fc_host->driver_version),
|
||||
"%s", QEDF_VERSION);
|
||||
|
||||
snprintf(fc_host->firmware_version, sizeof(fc_host->firmware_version),
|
||||
"%d.%d.%d.%d", FW_MAJOR_VERSION, FW_MINOR_VERSION,
|
||||
FW_REVISION_VERSION, FW_ENGINEERING_VERSION);
|
||||
}
|
||||
|
||||
static int qedf_lport_setup(struct qedf_ctx *qedf)
|
||||
{
|
||||
struct fc_lport *lport = qedf->lport;
|
||||
@@ -1377,6 +1448,8 @@ static int qedf_lport_setup(struct qedf_ctx *qedf)
|
||||
snprintf(fc_host_symbolic_name(lport->host), 256,
|
||||
"QLogic %s v%s", QEDF_MODULE_NAME, QEDF_VERSION);
|
||||
|
||||
qedf_setup_fdmi(qedf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1613,8 +1686,7 @@ static int qedf_fcoe_reset(struct Scsi_Host *shost)
|
||||
{
|
||||
struct fc_lport *lport = shost_priv(shost);
|
||||
|
||||
fc_fabric_logoff(lport);
|
||||
fc_fabric_login(lport);
|
||||
qedf_ctx_soft_reset(lport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1979,6 +2051,8 @@ static int qedf_setup_int(struct qedf_ctx *qedf)
|
||||
* Learn interrupt configuration
|
||||
*/
|
||||
rc = qed_ops->common->set_fp_int(qedf->cdev, num_online_cpus());
|
||||
if (rc <= 0)
|
||||
return 0;
|
||||
|
||||
rc = qed_ops->common->get_fp_int(qedf->cdev, &qedf->int_info);
|
||||
if (rc)
|
||||
@@ -2011,6 +2085,8 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
|
||||
u8 *dest_mac = NULL;
|
||||
struct fcoe_hdr *hp;
|
||||
struct qedf_rport *fcport;
|
||||
struct fc_lport *vn_port;
|
||||
u32 f_ctl;
|
||||
|
||||
lport = qedf->lport;
|
||||
if (lport == NULL || lport->state == LPORT_ST_DISABLED) {
|
||||
@@ -2047,6 +2123,10 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
|
||||
|
||||
fh = fc_frame_header_get(fp);
|
||||
|
||||
/*
|
||||
* Invalid frame filters.
|
||||
*/
|
||||
|
||||
if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
|
||||
fh->fh_type == FC_TYPE_FCP) {
|
||||
/* Drop FCP data. We dont this in L2 path */
|
||||
@@ -2072,6 +2152,45 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
|
||||
return;
|
||||
}
|
||||
|
||||
if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) {
|
||||
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
|
||||
"FC frame d_id mismatch with MAC %pM.\n", dest_mac);
|
||||
return;
|
||||
}
|
||||
|
||||
if (qedf->ctlr.state) {
|
||||
if (!ether_addr_equal(mac, qedf->ctlr.dest_addr)) {
|
||||
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
|
||||
"Wrong source address: mac:%pM dest_addr:%pM.\n",
|
||||
mac, qedf->ctlr.dest_addr);
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
|
||||
|
||||
/*
|
||||
* If the destination ID from the frame header does not match what we
|
||||
* have on record for lport and the search for a NPIV port came up
|
||||
* empty then this is not addressed to our port so simply drop it.
|
||||
*/
|
||||
if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) {
|
||||
QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
|
||||
"Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n",
|
||||
lport->port_id, ntoh24(fh->fh_d_id));
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
f_ctl = ntoh24(fh->fh_f_ctl);
|
||||
if ((fh->fh_type == FC_TYPE_BLS) && (f_ctl & FC_FC_SEQ_CTX) &&
|
||||
(f_ctl & FC_FC_EX_CTX)) {
|
||||
/* Drop incoming ABTS response that has both SEQ/EX CTX set */
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a connection is uploading, drop incoming FCoE frames as there
|
||||
* is a small window where we could try to return a frame while libfc
|
||||
@@ -2474,14 +2593,12 @@ static int qedf_alloc_bdq(struct qedf_ctx *qedf)
|
||||
}
|
||||
|
||||
/* Allocate list of PBL pages */
|
||||
qedf->bdq_pbl_list = dma_alloc_coherent(&qedf->pdev->dev,
|
||||
qedf->bdq_pbl_list = dma_zalloc_coherent(&qedf->pdev->dev,
|
||||
QEDF_PAGE_SIZE, &qedf->bdq_pbl_list_dma, GFP_KERNEL);
|
||||
if (!qedf->bdq_pbl_list) {
|
||||
QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate list of PBL "
|
||||
"pages.\n");
|
||||
QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate list of PBL pages.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(qedf->bdq_pbl_list, 0, QEDF_PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Now populate PBL list with pages that contain pointers to the
|
||||
@@ -2548,8 +2665,9 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf)
|
||||
qedf->global_queues[i] = kzalloc(sizeof(struct global_queue),
|
||||
GFP_KERNEL);
|
||||
if (!qedf->global_queues[i]) {
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Unable to allocation "
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Unable to allocate "
|
||||
"global queue %d.\n", i);
|
||||
status = -ENOMEM;
|
||||
goto mem_alloc_failure;
|
||||
}
|
||||
|
||||
@@ -2565,32 +2683,26 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf)
|
||||
ALIGN(qedf->global_queues[i]->cq_pbl_size, QEDF_PAGE_SIZE);
|
||||
|
||||
qedf->global_queues[i]->cq =
|
||||
dma_alloc_coherent(&qedf->pdev->dev,
|
||||
dma_zalloc_coherent(&qedf->pdev->dev,
|
||||
qedf->global_queues[i]->cq_mem_size,
|
||||
&qedf->global_queues[i]->cq_dma, GFP_KERNEL);
|
||||
|
||||
if (!qedf->global_queues[i]->cq) {
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate "
|
||||
"cq.\n");
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate cq.\n");
|
||||
status = -ENOMEM;
|
||||
goto mem_alloc_failure;
|
||||
}
|
||||
memset(qedf->global_queues[i]->cq, 0,
|
||||
qedf->global_queues[i]->cq_mem_size);
|
||||
|
||||
qedf->global_queues[i]->cq_pbl =
|
||||
dma_alloc_coherent(&qedf->pdev->dev,
|
||||
dma_zalloc_coherent(&qedf->pdev->dev,
|
||||
qedf->global_queues[i]->cq_pbl_size,
|
||||
&qedf->global_queues[i]->cq_pbl_dma, GFP_KERNEL);
|
||||
|
||||
if (!qedf->global_queues[i]->cq_pbl) {
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate "
|
||||
"cq PBL.\n");
|
||||
QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate cq PBL.\n");
|
||||
status = -ENOMEM;
|
||||
goto mem_alloc_failure;
|
||||
}
|
||||
memset(qedf->global_queues[i]->cq_pbl, 0,
|
||||
qedf->global_queues[i]->cq_pbl_size);
|
||||
|
||||
/* Create PBL */
|
||||
num_pages = qedf->global_queues[i]->cq_mem_size /
|
||||
@@ -2683,8 +2795,7 @@ static int qedf_set_fcoe_pf_param(struct qedf_ctx *qedf)
|
||||
cq_mem_size = ALIGN(cq_mem_size, QEDF_PAGE_SIZE);
|
||||
cq_num_entries = cq_mem_size / sizeof(struct fcoe_cqe);
|
||||
|
||||
memset(&(qedf->pf_params), 0,
|
||||
sizeof(qedf->pf_params));
|
||||
memset(&(qedf->pf_params), 0, sizeof(qedf->pf_params));
|
||||
|
||||
/* Setup the value for fcoe PF */
|
||||
qedf->pf_params.fcoe_pf_params.num_cons = QEDF_MAX_SESSIONS;
|
||||
|
Reference in New Issue
Block a user