summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bfa/bfad_im.c1
-rw-r--r--drivers/scsi/elx/efct/efct_lio.c2
-rw-r--r--drivers/scsi/fcoe/fcoe.c22
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c6
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c6
-rw-r--r--drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c2
-rw-r--r--drivers/scsi/ibmvscsi_tgt/libsrp.c6
-rw-r--r--drivers/scsi/isci/request.c2
-rw-r--r--drivers/scsi/libiscsi.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c28
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h20
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c84
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr.h10
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr_app.c10
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr_fw.c17
-rw-r--r--drivers/scsi/mpi3mr/mpi3mr_os.c22
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_ctl.c3
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_scsih.c19
-rw-r--r--drivers/scsi/mvsas/mv_sas.c4
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h10
-rw-r--r--drivers/scsi/pm8001/pm80xx_hwi.c60
-rw-r--r--drivers/scsi/qla2xxx/Kconfig6
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c20
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c48
-rw-r--r--drivers/scsi/scsi.c15
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_devinfo.c11
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/scsi_transport_fc.c72
-rw-r--r--drivers/scsi/sd.c13
40 files changed, 372 insertions, 233 deletions
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index a719a18f0fbc..f56e008ee52b 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -706,6 +706,7 @@ bfad_im_probe(struct bfad_s *bfad)
if (bfad_thread_workq(bfad) != BFA_STATUS_OK) {
kfree(im);
+ bfad->im = NULL;
return BFA_STATUS_FAILED;
}
diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c
index 9ac69356b13e..bd3d489e56ae 100644
--- a/drivers/scsi/elx/efct/efct_lio.c
+++ b/drivers/scsi/elx/efct/efct_lio.c
@@ -382,7 +382,7 @@ efct_lio_sg_unmap(struct efct_io *io)
return;
dma_unmap_sg(&io->efct->pci->dev, cmd->t_data_sg,
- ocp->seg_map_cnt, cmd->data_direction);
+ cmd->t_data_nents, cmd->data_direction);
ocp->seg_map_cnt = 0;
}
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index b911fdb387f3..4912087de10d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1300,26 +1300,6 @@ static void fcoe_thread_cleanup_local(unsigned int cpu)
}
/**
- * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming
- * command.
- *
- * This routine selects next CPU based on cpumask to distribute
- * incoming requests in round robin.
- *
- * Returns: int CPU number
- */
-static inline unsigned int fcoe_select_cpu(void)
-{
- static unsigned int selected_cpu;
-
- selected_cpu = cpumask_next(selected_cpu, cpu_online_mask);
- if (selected_cpu >= nr_cpu_ids)
- selected_cpu = cpumask_first(cpu_online_mask);
-
- return selected_cpu;
-}
-
-/**
* fcoe_rcv() - Receive packets from a net device
* @skb: The received packet
* @netdev: The net device that the packet was received on
@@ -1405,7 +1385,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask;
else {
if (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)
- cpu = fcoe_select_cpu();
+ cpu = skb->alloc_cpu;
else
cpu = ntohs(fh->fh_rx_id) & fc_cpu_mask;
}
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 24cd172905f3..4431698a5d78 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -2401,7 +2401,7 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
slot_err_v2_hw(hisi_hba, task, slot, 2);
if (ts->stat != SAS_DATA_UNDERRUN)
- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
+ dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
slot->idx, task, sas_dev->device_id,
complete_hdr->dw0, complete_hdr->dw1,
complete_hdr->act, complete_hdr->dw3,
@@ -2467,7 +2467,7 @@ out:
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
- dev_info(dev, "slot complete: task(%pK) aborted\n", task);
+ dev_info(dev, "slot complete: task(%p) aborted\n", task);
return;
}
task->task_state_flags |= SAS_TASK_STATE_DONE;
@@ -2478,7 +2478,7 @@ out:
spin_lock_irqsave(&device->done_lock, flags);
if (test_bit(SAS_HA_FROZEN, &ha->state)) {
spin_unlock_irqrestore(&device->done_lock, flags);
- dev_info(dev, "slot complete: task(%pK) ignored\n",
+ dev_info(dev, "slot complete: task(%p) ignored\n",
task);
return;
}
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index bc5d5356dd00..2f3d61abab3a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2409,7 +2409,7 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
if (slot_err_v3_hw(hisi_hba, task, slot)) {
if (ts->stat != SAS_DATA_UNDERRUN)
- dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
+ dev_info(dev, "erroneous completion iptt=%d task=%p dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n",
slot->idx, task, sas_dev->device_id,
SAS_ADDR(device->sas_addr),
dw0, dw1, complete_hdr->act, dw3,
@@ -2470,7 +2470,7 @@ out:
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
- dev_info(dev, "slot complete: task(%pK) aborted\n", task);
+ dev_info(dev, "slot complete: task(%p) aborted\n", task);
return;
}
task->task_state_flags |= SAS_TASK_STATE_DONE;
@@ -2481,7 +2481,7 @@ out:
spin_lock_irqsave(&device->done_lock, flags);
if (test_bit(SAS_HA_FROZEN, &ha->state)) {
spin_unlock_irqrestore(&device->done_lock, flags);
- dev_info(dev, "slot complete: task(%pK) ignored\n",
+ dev_info(dev, "slot complete: task(%p) ignored\n",
task);
return;
}
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index 9e42230e42b8..5a3787f27369 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -425,7 +425,7 @@ static void ibmvscsis_disconnect(struct work_struct *work)
/*
* check which state we are in and see if we
- * should transitition to the new state
+ * should transition to the new state
*/
switch (vscsi->state) {
/* Should never be called while in this state. */
diff --git a/drivers/scsi/ibmvscsi_tgt/libsrp.c b/drivers/scsi/ibmvscsi_tgt/libsrp.c
index 8a0e28aec928..0ecad398ed3d 100644
--- a/drivers/scsi/ibmvscsi_tgt/libsrp.c
+++ b/drivers/scsi/ibmvscsi_tgt/libsrp.c
@@ -184,7 +184,8 @@ static int srp_direct_data(struct ibmvscsis_cmd *cmd, struct srp_direct_buf *md,
err = rdma_io(cmd, sg, nsg, md, 1, dir, len);
if (dma_map)
- dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents,
+ DMA_BIDIRECTIONAL);
return err;
}
@@ -256,7 +257,8 @@ rdma:
err = rdma_io(cmd, sg, nsg, md, nmd, dir, len);
if (dma_map)
- dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(iue->target->dev, sg, cmd->se_cmd.t_data_nents,
+ DMA_BIDIRECTIONAL);
free_mem:
if (token && dma_map) {
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 355a0bc0828e..bb89a2e33eb4 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -2904,7 +2904,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
task->total_xfer_len, task->data_dir);
else /* unmap the sgl dma addresses */
dma_unmap_sg(&ihost->pdev->dev, task->scatter,
- request->num_sg_entries, task->data_dir);
+ task->num_scatter, task->data_dir);
break;
case SAS_PROTOCOL_SMP: {
struct scatterlist *sg = &task->smp_task.smp_req;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 392d57e054db..c9f410c50978 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -3185,7 +3185,8 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
return NULL;
conn = cls_conn->dd_data;
- conn->dd_data = cls_conn->dd_data + sizeof(*conn);
+ if (dd_size)
+ conn->dd_data = cls_conn->dd_data + sizeof(*conn);
conn->session = session;
conn->cls_conn = cls_conn;
conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 530dddd39bab..f93f8dca65bd 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -264,9 +264,9 @@ ct_free_mpvirt:
ct_free_mp:
kfree(mp);
ct_exit:
- lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
- "6440 Unsol CT: Rsp err %d Data: x%lx\n",
- rc, vport->fc_flag);
+ lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
+ "6440 Unsol CT: Rsp err %d Data: x%lx\n",
+ rc, vport->fc_flag);
}
/**
@@ -313,7 +313,7 @@ lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)
mi_cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp);
lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,
- "6442 MI Cmd : x%x Not Supported\n", mi_cmd);
+ "6442 MI Cmd: x%x Not Supported\n", mi_cmd);
lpfc_ct_reject_event(ndlp, ct_req,
bf_get(wqe_ctxt_tag,
&ctiocbq->wqe.xmit_els_rsp.wqe_com),
@@ -2229,21 +2229,6 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* Look for a retryable error */
if (ulp_status == IOSTAT_LOCAL_REJECT) {
switch ((ulp_word4 & IOERR_PARAM_MASK)) {
- case IOERR_SLI_ABORTED:
- case IOERR_SLI_DOWN:
- /* Driver aborted this IO. No retry as error
- * is likely Offline->Online or some adapter
- * error. Recovery will try again, but if port
- * is not active there's no point to continue
- * issuing follow up FDMI commands.
- */
- if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) {
- free_ndlp = cmdiocb->ndlp;
- lpfc_ct_free_iocb(phba, cmdiocb);
- lpfc_nlp_put(free_ndlp);
- return;
- }
- break;
case IOERR_ABORT_IN_PROGRESS:
case IOERR_SEQUENCE_TIMEOUT:
case IOERR_ILLEGAL_FRAME:
@@ -2269,6 +2254,9 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_ct_free_iocb(phba, cmdiocb);
lpfc_nlp_put(free_ndlp);
+ if (ulp_status != IOSTAT_SUCCESS)
+ return;
+
ndlp = lpfc_findnode_did(vport, FDMI_DID);
if (!ndlp)
return;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 42d138ec11b4..2db8d9529b8f 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2007-2015 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -6218,8 +6218,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
i++;
}
lpfc_debugfs_max_slow_ring_trc = (1 << i);
- pr_err("lpfc_debugfs_max_disc_trc changed to "
- "%d\n", lpfc_debugfs_max_disc_trc);
+ pr_info("lpfc_debugfs_max_slow_ring_trc "
+ "changed to %d\n",
+ lpfc_debugfs_max_slow_ring_trc);
}
}
@@ -6251,7 +6252,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
atomic_set(&phba->nvmeio_trc_cnt, 0);
if (lpfc_debugfs_max_nvmeio_trc) {
num = lpfc_debugfs_max_nvmeio_trc - 1;
- if (num & lpfc_debugfs_max_disc_trc) {
+ if (num & lpfc_debugfs_max_nvmeio_trc) {
/* Change to be a power of 2 */
num = lpfc_debugfs_max_nvmeio_trc;
i = 0;
@@ -6260,10 +6261,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
i++;
}
lpfc_debugfs_max_nvmeio_trc = (1 << i);
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0575 lpfc_debugfs_max_nvmeio_trc "
- "changed to %d\n",
- lpfc_debugfs_max_nvmeio_trc);
+ pr_info("lpfc_debugfs_max_nvmeio_trc changed "
+ "to %d\n",
+ lpfc_debugfs_max_nvmeio_trc);
}
phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc;
@@ -6308,8 +6308,8 @@ nvmeio_off:
i++;
}
lpfc_debugfs_max_disc_trc = (1 << i);
- pr_err("lpfc_debugfs_max_disc_trc changed to %d\n",
- lpfc_debugfs_max_disc_trc);
+ pr_info("lpfc_debugfs_max_disc_trc changed to %d\n",
+ lpfc_debugfs_max_disc_trc);
}
}
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index b1a61eca8295..fca81e0c7c2e 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -7861,6 +7861,13 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
/* Move all affected nodes by pending RSCNs to NPR state. */
list_for_each_entry_safe(ndlp, n, &vport->fc_nodes, nlp_listp) {
+ if (test_bit(FC_UNLOADING, &vport->load_flag)) {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "1000 %s Unloading set\n",
+ __func__);
+ return 0;
+ }
+
if ((ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
!lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
continue;
@@ -8369,9 +8376,9 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
clear_bit(FC_PUBLIC_LOOP, &vport->fc_flag);
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
"3311 Rcv Flogi PS x%x new PS x%x "
- "fc_flag x%lx new fc_flag x%lx\n",
+ "fc_flag x%lx new fc_flag x%lx, hba_flag x%lx\n",
port_state, vport->port_state,
- fc_flag, vport->fc_flag);
+ fc_flag, vport->fc_flag, phba->hba_flag);
/*
* We temporarily set fc_myDID to make it look like we are
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index b88e54a7e65c..43d246c5c049 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -183,7 +183,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
/* Don't schedule a worker thread event if the vport is going down. */
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
- !test_bit(HBA_SETUP, &phba->hba_flag)) {
+ (phba->sli_rev == LPFC_SLI_REV4 &&
+ !test_bit(HBA_SETUP, &phba->hba_flag))) {
spin_lock_irqsave(&ndlp->lock, iflags);
ndlp->rport = NULL;
@@ -1266,6 +1267,10 @@ lpfc_linkdown(struct lpfc_hba *phba)
}
phba->defer_flogi_acc.flag = false;
+ /* reinitialize initial HBA flag */
+ clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag);
+ clear_bit(HBA_RHBA_CMPL, &phba->hba_flag);
+
/* Clear external loopback plug detected flag */
phba->link_flag &= ~LS_EXTERNAL_LOOPBACK;
@@ -1436,10 +1441,6 @@ lpfc_linkup(struct lpfc_hba *phba)
phba->pport->rcv_flogi_cnt = 0;
spin_unlock_irq(shost->host_lock);
- /* reinitialize initial HBA flag */
- clear_bit(HBA_FLOGI_ISSUED, &phba->hba_flag);
- clear_bit(HBA_RHBA_CMPL, &phba->hba_flag);
-
return 0;
}
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 2dedb273b091..bc709786e6af 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -1328,6 +1328,9 @@ struct cq_context {
#define LPFC_CQ_CNT_512 0x1
#define LPFC_CQ_CNT_1024 0x2
#define LPFC_CQ_CNT_WORD7 0x3
+#define lpfc_cq_context_cqe_sz_SHIFT 25
+#define lpfc_cq_context_cqe_sz_MASK 0x00000003
+#define lpfc_cq_context_cqe_sz_WORD word0
#define lpfc_cq_context_autovalid_SHIFT 15
#define lpfc_cq_context_autovalid_MASK 0x00000001
#define lpfc_cq_context_autovalid_WORD word0
@@ -1383,9 +1386,9 @@ struct lpfc_mbx_cq_create_set {
#define lpfc_mbx_cq_create_set_valid_SHIFT 29
#define lpfc_mbx_cq_create_set_valid_MASK 0x00000001
#define lpfc_mbx_cq_create_set_valid_WORD word1
-#define lpfc_mbx_cq_create_set_cqe_cnt_SHIFT 27
-#define lpfc_mbx_cq_create_set_cqe_cnt_MASK 0x00000003
-#define lpfc_mbx_cq_create_set_cqe_cnt_WORD word1
+#define lpfc_mbx_cq_create_set_cqecnt_SHIFT 27
+#define lpfc_mbx_cq_create_set_cqecnt_MASK 0x00000003
+#define lpfc_mbx_cq_create_set_cqecnt_WORD word1
#define lpfc_mbx_cq_create_set_cqe_size_SHIFT 25
#define lpfc_mbx_cq_create_set_cqe_size_MASK 0x00000003
#define lpfc_mbx_cq_create_set_cqe_size_WORD word1
@@ -1398,13 +1401,16 @@ struct lpfc_mbx_cq_create_set {
#define lpfc_mbx_cq_create_set_clswm_SHIFT 12
#define lpfc_mbx_cq_create_set_clswm_MASK 0x00000003
#define lpfc_mbx_cq_create_set_clswm_WORD word1
+#define lpfc_mbx_cq_create_set_cqe_cnt_hi_SHIFT 0
+#define lpfc_mbx_cq_create_set_cqe_cnt_hi_MASK 0x0000001F
+#define lpfc_mbx_cq_create_set_cqe_cnt_hi_WORD word1
uint32_t word2;
#define lpfc_mbx_cq_create_set_arm_SHIFT 31
#define lpfc_mbx_cq_create_set_arm_MASK 0x00000001
#define lpfc_mbx_cq_create_set_arm_WORD word2
-#define lpfc_mbx_cq_create_set_cq_cnt_SHIFT 16
-#define lpfc_mbx_cq_create_set_cq_cnt_MASK 0x00007FFF
-#define lpfc_mbx_cq_create_set_cq_cnt_WORD word2
+#define lpfc_mbx_cq_create_set_cqe_cnt_lo_SHIFT 16
+#define lpfc_mbx_cq_create_set_cqe_cnt_lo_MASK 0x00007FFF
+#define lpfc_mbx_cq_create_set_cqe_cnt_lo_WORD word2
#define lpfc_mbx_cq_create_set_num_cq_SHIFT 0
#define lpfc_mbx_cq_create_set_num_cq_MASK 0x0000FFFF
#define lpfc_mbx_cq_create_set_num_cq_WORD word2
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 20fa450def03..4081d2a358ee 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2627,27 +2627,33 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
"Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_BMID:
- m = (typeof(m)){"LP1150", "PCI-X2", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LP1150", "PCI-X2",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_BSMB:
m = (typeof(m)){"LP111", "PCI-X2",
"Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_ZEPHYR:
- m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe11000", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_ZEPHYR_SCSP:
- m = (typeof(m)){"LPe11000", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe11000", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_ZEPHYR_DCSP:
- m = (typeof(m)){"LP2105", "PCIe", "FCoE Adapter"};
+ m = (typeof(m)){"LP2105", "PCIe",
+ "Obsolete, Unsupported FCoE Adapter"};
GE = 1;
break;
case PCI_DEVICE_ID_ZMID:
- m = (typeof(m)){"LPe1150", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe1150", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_ZSMB:
- m = (typeof(m)){"LPe111", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe111", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_LP101:
m = (typeof(m)){"LP101", "PCI-X",
@@ -2666,22 +2672,28 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
"Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT:
- m = (typeof(m)){"LPe12000", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe12000", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT_MID:
- m = (typeof(m)){"LPe1250", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe1250", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT_SMB:
- m = (typeof(m)){"LPe121", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe121", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT_DCSP:
- m = (typeof(m)){"LPe12002-SP", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe12002-SP", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT_SCSP:
- m = (typeof(m)){"LPe12000-SP", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe12000-SP", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_SAT_S:
- m = (typeof(m)){"LPe12000-S", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe12000-S", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_PROTEUS_VF:
m = (typeof(m)){"LPev12000", "PCIe IOV",
@@ -2697,22 +2709,25 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
break;
case PCI_DEVICE_ID_TIGERSHARK:
oneConnect = 1;
- m = (typeof(m)){"OCe10100", "PCIe", "FCoE"};
+ m = (typeof(m)){"OCe10100", "PCIe",
+ "Obsolete, Unsupported FCoE Adapter"};
break;
case PCI_DEVICE_ID_TOMCAT:
oneConnect = 1;
- m = (typeof(m)){"OCe11100", "PCIe", "FCoE"};
+ m = (typeof(m)){"OCe11100", "PCIe",
+ "Obsolete, Unsupported FCoE Adapter"};
break;
case PCI_DEVICE_ID_FALCON:
m = (typeof(m)){"LPSe12002-ML1-E", "PCIe",
- "EmulexSecure Fibre"};
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_BALIUS:
m = (typeof(m)){"LPVe12002", "PCIe Shared I/O",
"Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_LANCER_FC:
- m = (typeof(m)){"LPe16000", "PCIe", "Fibre Channel Adapter"};
+ m = (typeof(m)){"LPe16000", "PCIe",
+ "Obsolete, Unsupported Fibre Channel Adapter"};
break;
case PCI_DEVICE_ID_LANCER_FC_VF:
m = (typeof(m)){"LPe16000", "PCIe",
@@ -2720,12 +2735,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
break;
case PCI_DEVICE_ID_LANCER_FCOE:
oneConnect = 1;
- m = (typeof(m)){"OCe15100", "PCIe", "FCoE"};
+ m = (typeof(m)){"OCe15100", "PCIe",
+ "Obsolete, Unsupported FCoE Adapter"};
break;
case PCI_DEVICE_ID_LANCER_FCOE_VF:
oneConnect = 1;
m = (typeof(m)){"OCe15100", "PCIe",
- "Obsolete, Unsupported FCoE"};
+ "Obsolete, Unsupported FCoE Adapter"};
break;
case PCI_DEVICE_ID_LANCER_G6_FC:
m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"};
@@ -2739,7 +2755,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
case PCI_DEVICE_ID_SKYHAWK:
case PCI_DEVICE_ID_SKYHAWK_VF:
oneConnect = 1;
- m = (typeof(m)){"OCe14000", "PCIe", "FCoE"};
+ m = (typeof(m)){"OCe14000", "PCIe",
+ "Obsolete, Unsupported FCoE Adapter"};
break;
default:
m = (typeof(m)){"Unknown", "", ""};
@@ -7919,8 +7936,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
int longs;
int extra;
uint64_t wwn;
- u32 if_type;
- u32 if_fam;
phba->sli4_hba.num_present_cpu = lpfc_present_cpu;
phba->sli4_hba.num_possible_cpu = cpumask_last(cpu_possible_mask) + 1;
@@ -8180,28 +8195,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
*/
rc = lpfc_get_sli4_parameters(phba, mboxq);
if (rc) {
- if_type = bf_get(lpfc_sli_intf_if_type,
- &phba->sli4_hba.sli_intf);
- if_fam = bf_get(lpfc_sli_intf_sli_family,
- &phba->sli4_hba.sli_intf);
- if (phba->sli4_hba.extents_in_use &&
- phba->sli4_hba.rpi_hdrs_in_use) {
- lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
- "2999 Unsupported SLI4 Parameters "
- "Extents and RPI headers enabled.\n");
- if (if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
- if_fam == LPFC_SLI_INTF_FAMILY_BE2) {
- mempool_free(mboxq, phba->mbox_mem_pool);
- rc = -EIO;
- goto out_free_bsmbx;
- }
- }
- if (!(if_type == LPFC_SLI_INTF_IF_TYPE_0 &&
- if_fam == LPFC_SLI_INTF_FAMILY_BE2)) {
- mempool_free(mboxq, phba->mbox_mem_pool);
- rc = -EIO;
- goto out_free_bsmbx;
- }
+ lpfc_log_msg(phba, KERN_WARNING, LOG_INIT,
+ "2999 Could not get SLI4 parameters\n");
+ rc = -EIO;
+ mempool_free(mboxq, phba->mbox_mem_pool);
+ goto out_free_bsmbx;
}
/*
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 8acb744febcd..508ceeecf2d9 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -390,6 +390,10 @@ lpfc_sli4_vport_delete_fcp_xri_aborted(struct lpfc_vport *vport)
if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
return;
+ /* may be called before queues established if hba_setup fails */
+ if (!phba->sli4_hba.hdwq)
+ return;
+
spin_lock_irqsave(&phba->hbalock, iflag);
for (idx = 0; idx < phba->cfg_hdw_queue; idx++) {
qp = &phba->sli4_hba.hdwq[idx];
@@ -532,7 +536,8 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba,
psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
psb->flags &= ~LPFC_SBUF_XBUSY;
spin_unlock_irqrestore(&phba->hbalock, iflag);
- if (!list_empty(&pring->txq))
+ if (test_bit(HBA_SETUP, &phba->hba_flag) &&
+ !list_empty(&pring->txq))
lpfc_worker_wake_up(phba);
return;
}
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 47bbcb78fb4d..a8fbdf7119d8 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -5167,7 +5167,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
phba->link_events = 0;
phba->pport->fc_myDID = 0;
phba->pport->fc_prevDID = 0;
- clear_bit(HBA_SETUP, &phba->hba_flag);
spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~(LPFC_PROCESS_LA);
@@ -5284,6 +5283,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
"0296 Restart HBA Data: x%x x%x\n",
phba->pport->port_state, psli->sli_flag);
+ clear_bit(HBA_SETUP, &phba->hba_flag);
lpfc_sli4_queue_unset(phba);
rc = lpfc_sli4_brdreset(phba);
@@ -16477,10 +16477,10 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
case 4096:
if (phba->sli4_hba.pc_sli4_params.cqv ==
LPFC_Q_CREATE_VERSION_2) {
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
+ bf_set(lpfc_mbx_cq_create_set_cqe_cnt_lo,
&cq_set->u.request,
- cq->entry_count);
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
+ cq->entry_count);
+ bf_set(lpfc_mbx_cq_create_set_cqecnt,
&cq_set->u.request,
LPFC_CQ_CNT_WORD7);
break;
@@ -16496,15 +16496,15 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp,
}
fallthrough; /* otherwise default to smallest */
case 256:
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
+ bf_set(lpfc_mbx_cq_create_set_cqecnt,
&cq_set->u.request, LPFC_CQ_CNT_256);
break;
case 512:
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
+ bf_set(lpfc_mbx_cq_create_set_cqecnt,
&cq_set->u.request, LPFC_CQ_CNT_512);
break;
case 1024:
- bf_set(lpfc_mbx_cq_create_set_cqe_cnt,
+ bf_set(lpfc_mbx_cq_create_set_cqecnt,
&cq_set->u.request, LPFC_CQ_CNT_1024);
break;
}
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 9be3da91c923..fd6dab157887 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -575,8 +575,10 @@ struct lpfc_pc_sli4_params {
#define LPFC_CQ_4K_PAGE_SZ 0x1
#define LPFC_CQ_16K_PAGE_SZ 0x4
+#define LPFC_CQ_32K_PAGE_SZ 0x8
#define LPFC_WQ_4K_PAGE_SZ 0x1
#define LPFC_WQ_16K_PAGE_SZ 0x4
+#define LPFC_WQ_32K_PAGE_SZ 0x8
struct lpfc_iov {
uint32_t pf_number;
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 749688aa8a82..9ee3a3a4ec4d 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "14.4.0.9"
+#define LPFC_DRIVER_VERSION "14.4.0.10"
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 9bbc7cb98ca3..8d4ef49e04d1 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -56,8 +56,8 @@ extern struct list_head mrioc_list;
extern int prot_mask;
extern atomic64_t event_counter;
-#define MPI3MR_DRIVER_VERSION "8.13.0.5.50"
-#define MPI3MR_DRIVER_RELDATE "20-February-2025"
+#define MPI3MR_DRIVER_VERSION "8.14.0.5.50"
+#define MPI3MR_DRIVER_RELDATE "27-June-2025"
#define MPI3MR_DRIVER_NAME "mpi3mr"
#define MPI3MR_DRIVER_LICENSE "GPL"
@@ -1137,6 +1137,8 @@ struct scmd_priv {
* @logdata_buf: Circular buffer to store log data entries
* @logdata_buf_idx: Index of entry in buffer to store
* @logdata_entry_sz: log data entry size
+ * @adm_req_q_bar_writeq_lock: Admin request queue lock
+ * @adm_reply_q_bar_writeq_lock: Admin reply queue lock
* @pend_large_data_sz: Counter to track pending large data
* @io_throttle_data_length: I/O size to track in 512b blocks
* @io_throttle_high: I/O size to start throttle in 512b blocks
@@ -1185,7 +1187,7 @@ struct mpi3mr_ioc {
char name[MPI3MR_NAME_LENGTH];
char driver_name[MPI3MR_NAME_LENGTH];
- volatile struct mpi3_sysif_registers __iomem *sysif_regs;
+ struct mpi3_sysif_registers __iomem *sysif_regs;
resource_size_t sysif_regs_phys;
int bars;
u64 dma_mask;
@@ -1339,6 +1341,8 @@ struct mpi3mr_ioc {
u8 *logdata_buf;
u16 logdata_buf_idx;
u16 logdata_entry_sz;
+ spinlock_t adm_req_q_bar_writeq_lock;
+ spinlock_t adm_reply_q_bar_writeq_lock;
atomic_t pend_large_data_sz;
u32 io_throttle_data_length;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index f36663613950..0e5478d62580 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -795,9 +795,8 @@ void mpi3mr_release_diag_bufs(struct mpi3mr_ioc *mrioc, u8 skip_rel_action)
*
* @hdb: HDB pointer
* @type: Trigger type
- * @data: Trigger data
- * @force: Trigger overwrite flag
* @trigger_data: Pointer to trigger data information
+ * @force: Trigger overwrite flag
*
* Updates trigger type and trigger data based on parameter
* passed to this function
@@ -822,9 +821,8 @@ void mpi3mr_set_trigger_data_in_hdb(struct diag_buffer_desc *hdb,
*
* @mrioc: Adapter instance reference
* @type: Trigger type
- * @data: Trigger data
- * @force: Trigger overwrite flag
* @trigger_data: Pointer to trigger data information
+ * @force: Trigger overwrite flag
*
* Updates trigger type and trigger data based on parameter
* passed to this function
@@ -3388,6 +3386,8 @@ static DEVICE_ATTR_RO(persistent_id);
* @buf: the buffer returned
*
* A sysfs 'read-only' sdev attribute, only works with SATA devices
+ *
+ * Returns: the number of characters written to @buf
*/
static ssize_t
sas_ncq_prio_supported_show(struct device *dev,
@@ -3406,6 +3406,8 @@ static DEVICE_ATTR_RO(sas_ncq_prio_supported);
* @buf: the buffer returned
*
* A sysfs 'read/write' sdev attribute, only works with SATA devices
+ *
+ * Returns: the number of characters written to @buf
*/
static ssize_t
sas_ncq_prio_enable_show(struct device *dev,
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 1d7901a8f0e4..0152d31d430a 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -23,17 +23,22 @@ module_param(poll_queues, int, 0444);
MODULE_PARM_DESC(poll_queues, "Number of queues for io_uring poll mode. (Range 1 - 126)");
#if defined(writeq) && defined(CONFIG_64BIT)
-static inline void mpi3mr_writeq(__u64 b, volatile void __iomem *addr)
+static inline void mpi3mr_writeq(__u64 b, void __iomem *addr,
+ spinlock_t *write_queue_lock)
{
writeq(b, addr);
}
#else
-static inline void mpi3mr_writeq(__u64 b, volatile void __iomem *addr)
+static inline void mpi3mr_writeq(__u64 b, void __iomem *addr,
+ spinlock_t *write_queue_lock)
{
__u64 data_out = b;
+ unsigned long flags;
+ spin_lock_irqsave(write_queue_lock, flags);
writel((u32)(data_out), addr);
writel((u32)(data_out >> 32), (addr + 4));
+ spin_unlock_irqrestore(write_queue_lock, flags);
}
#endif
@@ -428,8 +433,8 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,
MPI3MR_SENSE_BUF_SZ);
}
if (cmdptr->is_waiting) {
- complete(&cmdptr->done);
cmdptr->is_waiting = 0;
+ complete(&cmdptr->done);
} else if (cmdptr->callback)
cmdptr->callback(mrioc, cmdptr);
}
@@ -2954,9 +2959,11 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc)
(mrioc->num_admin_req);
writel(num_admin_entries, &mrioc->sysif_regs->admin_queue_num_entries);
mpi3mr_writeq(mrioc->admin_req_dma,
- &mrioc->sysif_regs->admin_request_queue_address);
+ &mrioc->sysif_regs->admin_request_queue_address,
+ &mrioc->adm_req_q_bar_writeq_lock);
mpi3mr_writeq(mrioc->admin_reply_dma,
- &mrioc->sysif_regs->admin_reply_queue_address);
+ &mrioc->sysif_regs->admin_reply_queue_address,
+ &mrioc->adm_reply_q_bar_writeq_lock);
writel(mrioc->admin_req_pi, &mrioc->sysif_regs->admin_request_queue_pi);
writel(mrioc->admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);
return retval;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index ce444efd859e..e467b56949e9 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -49,6 +49,13 @@ static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
#define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH (0xFFFE)
+/*
+ * SAS Log info code for a NCQ collateral abort after an NCQ error:
+ * IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR
+ * See: drivers/message/fusion/lsi/mpi_log_sas.h
+ */
+#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR 0x31080000
+
/**
* mpi3mr_host_tag_for_scmd - Get host tag for a scmd
* @mrioc: Adapter instance reference
@@ -3430,7 +3437,18 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,
scmd->result = DID_NO_CONNECT << 16;
break;
case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED:
- scmd->result = DID_SOFT_ERROR << 16;
+ if (ioc_loginfo == IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR) {
+ /*
+ * This is a ATA NCQ command aborted due to another NCQ
+ * command failure. We must retry this command
+ * immediately but without incrementing its retry
+ * counter.
+ */
+ WARN_ON_ONCE(xfer_count != 0);
+ scmd->result = DID_IMM_RETRY << 16;
+ } else {
+ scmd->result = DID_SOFT_ERROR << 16;
+ }
break;
case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED:
case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED:
@@ -5365,6 +5383,8 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&mrioc->tgtdev_lock);
spin_lock_init(&mrioc->watchdog_lock);
spin_lock_init(&mrioc->chain_buf_lock);
+ spin_lock_init(&mrioc->adm_req_q_bar_writeq_lock);
+ spin_lock_init(&mrioc->adm_reply_q_bar_writeq_lock);
spin_lock_init(&mrioc->sas_node_lock);
spin_lock_init(&mrioc->trigger_lock);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 02fc204b9bf7..3b951589feeb 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -2914,7 +2914,6 @@ int mpt3sas_send_mctp_passthru_req(struct mpt3_passthru_command *command)
{
struct MPT3SAS_ADAPTER *ioc;
MPI2RequestHeader_t *mpi_request = NULL, *request;
- MPI2DefaultReply_t *mpi_reply;
Mpi26MctpPassthroughRequest_t *mctp_passthru_req;
u16 smid;
unsigned long timeout;
@@ -3022,8 +3021,6 @@ int mpt3sas_send_mctp_passthru_req(struct mpt3_passthru_command *command)
goto issue_host_reset;
}
- mpi_reply = ioc->ctl_cmds.reply;
-
/* copy out xdata to user */
if (data_in_sz)
memcpy(command->data_in_buf_ptr, data_in, data_in_sz);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 508861e88d9f..d7d8244dfedc 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -195,6 +195,14 @@ struct sense_info {
#define MPT3SAS_PORT_ENABLE_COMPLETE (0xFFFD)
#define MPT3SAS_ABRT_TASK_SET (0xFFFE)
#define MPT3SAS_REMOVE_UNRESPONDING_DEVICES (0xFFFF)
+
+/*
+ * SAS Log info code for a NCQ collateral abort after an NCQ error:
+ * IOC_LOGINFO_PREFIX_PL | PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR
+ * See: drivers/message/fusion/lsi/mpi_log_sas.h
+ */
+#define IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR 0x31080000
+
/**
* struct fw_event_work - firmware event struct
* @list: link list framework
@@ -5814,6 +5822,17 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
scmd->result = DID_TRANSPORT_DISRUPTED << 16;
goto out;
}
+ if (log_info == IOC_LOGINFO_SATA_NCQ_FAIL_AFTER_ERR) {
+ /*
+ * This is a ATA NCQ command aborted due to another NCQ
+ * command failure. We must retry this command
+ * immediately but without incrementing its retry
+ * counter.
+ */
+ WARN_ON_ONCE(xfer_cnt != 0);
+ scmd->result = DID_IMM_RETRY << 16;
+ break;
+ }
if (log_info == 0x31110630) {
if (scmd->retries > 2) {
scmd->result = DID_NO_CONNECT << 16;
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 6c46654b9cd9..15b3d9d55a4b 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -818,7 +818,7 @@ err_out:
dev_printk(KERN_ERR, mvi->dev, "mvsas prep failed[%d]!\n", rc);
if (!sas_protocol_ata(task->task_proto))
if (n_elem)
- dma_unmap_sg(mvi->dev, task->scatter, n_elem,
+ dma_unmap_sg(mvi->dev, task->scatter, task->num_scatter,
task->data_dir);
prep_out:
return rc;
@@ -864,7 +864,7 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task,
if (!sas_protocol_ata(task->task_proto))
if (slot->n_elem)
dma_unmap_sg(mvi->dev, task->scatter,
- slot->n_elem, task->data_dir);
+ task->num_scatter, task->data_dir);
switch (task->task_proto) {
case SAS_PROTOCOL_SMP:
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 315f6a7523f0..334485bb2c12 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -170,6 +170,14 @@ struct forensic_data {
#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80
#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD 0x28) */
+/**
+ * enum fatal_error_reporter: Indicates the originator of the fatal error
+ */
+enum fatal_error_reporter {
+ REPORTER_DRIVER,
+ REPORTER_FIRMWARE,
+};
+
struct pm8001_dispatch {
char *name;
int (*chip_init)(struct pm8001_hba_info *pm8001_ha);
@@ -715,6 +723,8 @@ ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
struct device_attribute *attr, char *buf);
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha);
+void pm80xx_fatal_error_uevent_emit(struct pm8001_hba_info *pm8001_ha,
+ enum fatal_error_reporter error_reporter);
void pm8001_free_dev(struct pm8001_device *pm8001_dev);
/* ctl shared API */
extern const struct attribute_group *pm8001_host_groups[];
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 5b373c53c036..c1bae995a412 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1552,6 +1552,52 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
}
/**
+ * pm80xx_fatal_error_uevent_emit - emits a single fatal error uevent
+ * @pm8001_ha: our hba card information
+ * @error_reporter: reporter of fatal error
+ */
+void pm80xx_fatal_error_uevent_emit(struct pm8001_hba_info *pm8001_ha,
+ enum fatal_error_reporter error_reporter)
+{
+ struct kobj_uevent_env *env;
+
+ pm8001_dbg(pm8001_ha, FAIL, "emitting fatal error uevent");
+
+ env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
+ if (!env)
+ return;
+
+ if (add_uevent_var(env, "DRIVER=%s", DRV_NAME))
+ goto exit;
+
+ if (add_uevent_var(env, "HBA_NUM=%u", pm8001_ha->id))
+ goto exit;
+
+ if (add_uevent_var(env, "EVENT_TYPE=FATAL_ERROR"))
+ goto exit;
+
+ switch (error_reporter) {
+ case REPORTER_DRIVER:
+ if (add_uevent_var(env, "REPORTED_BY=DRIVER"))
+ goto exit;
+ break;
+ case REPORTER_FIRMWARE:
+ if (add_uevent_var(env, "REPORTED_BY=FIRMWARE"))
+ goto exit;
+ break;
+ default:
+ if (add_uevent_var(env, "REPORTED_BY=OTHER"))
+ goto exit;
+ break;
+ }
+
+ kobject_uevent_env(&pm8001_ha->shost->shost_dev.kobj, KOBJ_CHANGE, env->envp);
+
+exit:
+ kfree(env);
+}
+
+/**
* pm80xx_fatal_errors - returns non-zero *ONLY* when fatal errors
* @pm8001_ha: our hba card information
*
@@ -1580,6 +1626,7 @@ pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)
"Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n",
scratch_pad1, scratch_pad2, scratch_pad3,
scratch_pad_rsvd0, scratch_pad_rsvd1);
+ pm80xx_fatal_error_uevent_emit(pm8001_ha, REPORTER_DRIVER);
ret = 1;
}
@@ -4039,6 +4086,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec)
pm8001_dbg(pm8001_ha, FAIL,
"Firmware Fatal error! Regval:0x%x\n",
regval);
+ pm80xx_fatal_error_uevent_emit(pm8001_ha, REPORTER_FIRMWARE);
pm8001_handle_event(pm8001_ha, NULL, IO_FATAL_ERROR);
print_scratchpad_registers(pm8001_ha);
return ret;
@@ -4677,8 +4725,12 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
payload.sas_identify.phy_id = phy_id;
- return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+ ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
sizeof(payload), 0);
+ if (ret < 0)
+ pm8001_tag_free(pm8001_ha, tag);
+
+ return ret;
}
/**
@@ -4704,8 +4756,12 @@ static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,
payload.tag = cpu_to_le32(tag);
payload.phy_id = cpu_to_le32(phy_id);
- return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
+ ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,
sizeof(payload), 0);
+ if (ret < 0)
+ pm8001_tag_free(pm8001_ha, tag);
+
+ return ret;
}
/*
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index a8b4314bfd6e..6946d7155bc2 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -25,11 +25,7 @@ config SCSI_QLA_FC
Upon request, the driver caches the firmware image until
the driver is unloaded.
- Firmware images can be retrieved from:
-
- http://ldriver.qlogic.com/firmware/
-
- They are also included in the linux-firmware tree as well.
+ Firmware images are included in the linux-firmware tree.
config TCM_QLA2XXX
tristate "TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs"
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 08273520c777..43970caca7b3 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -179,10 +179,9 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
struct qla_hw_data *ha = vha->hw;
struct gid_list_info *gid_list;
dma_addr_t gid_list_dma;
- fc_port_t fc_port;
char *id_iter;
int rc, i;
- uint16_t entries, loop_id;
+ uint16_t entries;
seq_printf(s, "%s\n", vha->host_str);
gid_list = dma_alloc_coherent(&ha->pdev->dev,
@@ -205,18 +204,11 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused)
seq_puts(s, "Port Name Port ID Loop ID\n");
for (i = 0; i < entries; i++) {
- struct gid_list_info *gid =
- (struct gid_list_info *)id_iter;
- loop_id = le16_to_cpu(gid->loop_id);
- memset(&fc_port, 0, sizeof(fc_port_t));
-
- fc_port.loop_id = loop_id;
-
- rc = qla24xx_gpdb_wait(vha, &fc_port, 0);
- seq_printf(s, "%8phC %02x%02x%02x %d\n",
- fc_port.port_name, fc_port.d_id.b.domain,
- fc_port.d_id.b.area, fc_port.d_id.b.al_pa,
- fc_port.loop_id);
+ struct gid_list_info *gid = (struct gid_list_info *)id_iter;
+
+ rc = qla24xx_print_fc_port_id(vha, s, le16_to_cpu(gid->loop_id));
+ if (rc != QLA_SUCCESS)
+ break;
id_iter += ha->gid_list_info_size;
}
out_free_id_list:
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 03e50e8fc08d..145defc420f2 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -557,6 +557,7 @@ qla26xx_dport_diagnostics_v2(scsi_qla_host_t *,
int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *);
int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8);
+int qla24xx_print_fc_port_id(struct scsi_qla_host *, struct seq_file *, u16);
int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t,
uint16_t *);
int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 514934dd6f80..be211ff22acb 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -8603,8 +8603,6 @@ failed:
return QLA_SUCCESS;
}
-#define QLA_FW_URL "http://ldriver.qlogic.com/firmware/"
-
int
qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
{
@@ -8622,8 +8620,6 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
if (!blob) {
ql_log(ql_log_info, vha, 0x0083,
"Firmware image unavailable.\n");
- ql_log(ql_log_info, vha, 0x0084,
- "Firmware images can be retrieved from: "QLA_FW_URL ".\n");
return QLA_FUNCTION_FAILED;
}
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 13b6cb1b93ac..32eb0ce8b170 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -6597,6 +6597,54 @@ done:
return rval;
}
+int qla24xx_print_fc_port_id(struct scsi_qla_host *vha, struct seq_file *s, u16 loop_id)
+{
+ int rval = QLA_FUNCTION_FAILED;
+ dma_addr_t pd_dma;
+ struct port_database_24xx *pd;
+ struct qla_hw_data *ha = vha->hw;
+ mbx_cmd_t mc;
+
+ if (!vha->hw->flags.fw_started)
+ goto done;
+
+ pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
+ if (pd == NULL) {
+ ql_log(ql_log_warn, vha, 0xd047,
+ "Failed to allocate port database structure.\n");
+ goto done;
+ }
+
+ memset(&mc, 0, sizeof(mc));
+ mc.mb[0] = MBC_GET_PORT_DATABASE;
+ mc.mb[1] = loop_id;
+ mc.mb[2] = MSW(pd_dma);
+ mc.mb[3] = LSW(pd_dma);
+ mc.mb[6] = MSW(MSD(pd_dma));
+ mc.mb[7] = LSW(MSD(pd_dma));
+ mc.mb[9] = vha->vp_idx;
+
+ rval = qla24xx_send_mb_cmd(vha, &mc);
+ if (rval != QLA_SUCCESS) {
+ ql_dbg(ql_dbg_mbx, vha, 0x1193, "%s: fail\n", __func__);
+ goto done_free_sp;
+ }
+
+ ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",
+ __func__, pd->port_name);
+
+ seq_printf(s, "%8phC %02x%02x%02x %d\n",
+ pd->port_name, pd->port_id[0],
+ pd->port_id[1], pd->port_id[2],
+ loop_id);
+
+done_free_sp:
+ if (pd)
+ dma_pool_free(ha->s_dma_pool, pd, pd_dma);
+done:
+ return rval;
+}
+
/*
* qla24xx_gpdb_wait
* NOTE: Do not call this routine from DPC thread
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 518a252eb6aa..9a0f467264b3 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -242,9 +242,11 @@ EXPORT_SYMBOL(scsi_change_queue_depth);
* specific SCSI device to determine if and when there is a
* need to adjust the queue depth on the device.
*
- * Returns: 0 - No change needed, >0 - Adjust queue depth to this new depth,
- * -1 - Drop back to untagged operation using host->cmd_per_lun
- * as the untagged command depth
+ * Returns:
+ * * 0 - No change needed
+ * * >0 - Adjust queue depth to this new depth,
+ * * -1 - Drop back to untagged operation using host->cmd_per_lun as the
+ * untagged command depth
*
* Lock Status: None held on entry
*
@@ -708,20 +710,15 @@ void scsi_cdl_check(struct scsi_device *sdev)
int scsi_cdl_enable(struct scsi_device *sdev, bool enable)
{
char buf[64];
- bool is_ata;
int ret;
if (!sdev->cdl_supported)
return -EOPNOTSUPP;
- rcu_read_lock();
- is_ata = rcu_dereference(sdev->vpd_pg89);
- rcu_read_unlock();
-
/*
* For ATA devices, CDL needs to be enabled with a SET FEATURES command.
*/
- if (is_ata) {
+ if (sdev->is_ata) {
struct scsi_mode_data data;
struct scsi_sense_hdr sshdr;
char *buf_data;
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index aef33d1e346a..0847767d4d43 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -8770,7 +8770,7 @@ static int sdebug_add_store(void)
dif_size = sdebug_store_sectors * sizeof(struct t10_pi_tuple);
sip->dif_storep = vmalloc(dif_size);
- pr_info("dif_storep %u bytes @ %pK\n", dif_size,
+ pr_info("dif_storep %u bytes @ %p\n", dif_size,
sip->dif_storep);
if (!sip->dif_storep) {
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 8ff679e67bbf..78346b2b69c9 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -269,17 +269,12 @@ static struct {
static struct scsi_dev_info_list_table *scsi_devinfo_lookup_by_key(int key)
{
struct scsi_dev_info_list_table *devinfo_table;
- int found = 0;
list_for_each_entry(devinfo_table, &scsi_dev_info_list, node)
- if (devinfo_table->key == key) {
- found = 1;
- break;
- }
- if (!found)
- return ERR_PTR(-EINVAL);
+ if (devinfo_table->key == key)
+ return devinfo_table;
- return devinfo_table;
+ return ERR_PTR(-EINVAL);
}
/*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 144c72f0737a..0c65ecfedfbd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1843,7 +1843,7 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
* a function to initialize that data.
*/
if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv)
- memset(cmd + 1, 0, shost->hostt->cmd_size);
+ memset(scsi_cmd_priv(cmd), 0, shost->hostt->cmd_size);
if (!(req->rq_flags & RQF_DONTPREP)) {
ret = scsi_prepare_cmd(req);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 4833b8fe251b..160c2f74c7e7 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -909,7 +909,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
sdev->model = (char *) (sdev->inquiry + 16);
sdev->rev = (char *) (sdev->inquiry + 32);
- if (strncmp(sdev->vendor, "ATA ", 8) == 0) {
+ sdev->is_ata = strncmp(sdev->vendor, "ATA ", 8) == 0;
+ if (sdev->is_ata) {
/*
* sata emulation layer device. This is a hack to work around
* the SATL power management specifications which state that
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 6b165a3ec6de..3a821afee9bc 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -446,13 +446,6 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
return -ENOMEM;
fc_host->dev_loss_tmo = fc_dev_loss_tmo;
- fc_host->devloss_work_q = alloc_workqueue("fc_dl_%d", 0, 0,
- shost->host_no);
- if (!fc_host->devloss_work_q) {
- destroy_workqueue(fc_host->work_q);
- fc_host->work_q = NULL;
- return -ENOMEM;
- }
fc_bsg_hostadd(shost, fc_host);
/* ignore any bsg add error - we just can't do sgio */
@@ -2814,6 +2807,7 @@ fc_flush_work(struct Scsi_Host *shost)
/**
* fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue.
* @shost: Pointer to Scsi_Host bound to fc_host.
+ * @rport: rport associated with the devloss work
* @work: Work to queue for execution.
* @delay: jiffies to delay the work queuing
*
@@ -2821,10 +2815,10 @@ fc_flush_work(struct Scsi_Host *shost)
* 1 on success / 0 already queued / < 0 for error
*/
static int
-fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
- unsigned long delay)
+fc_queue_devloss_work(struct Scsi_Host *shost, struct fc_rport *rport,
+ struct delayed_work *work, unsigned long delay)
{
- if (unlikely(!fc_host_devloss_work_q(shost))) {
+ if (unlikely(!rport->devloss_work_q)) {
printk(KERN_ERR
"ERROR: FC host '%s' attempted to queue work, "
"when no workqueue created.\n", shost->hostt->name);
@@ -2833,17 +2827,18 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
return -EINVAL;
}
- return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
+ return queue_delayed_work(rport->devloss_work_q, work, delay);
}
/**
* fc_flush_devloss - Flush a fc_host's devloss workqueue.
* @shost: Pointer to Scsi_Host bound to fc_host.
+ * @rport: rport associated with the devloss work
*/
static void
-fc_flush_devloss(struct Scsi_Host *shost)
+fc_flush_devloss(struct Scsi_Host *shost, struct fc_rport *rport)
{
- if (!fc_host_devloss_work_q(shost)) {
+ if (unlikely(!rport->devloss_work_q)) {
printk(KERN_ERR
"ERROR: FC host '%s' attempted to flush work, "
"when no workqueue created.\n", shost->hostt->name);
@@ -2851,7 +2846,7 @@ fc_flush_devloss(struct Scsi_Host *shost)
return;
}
- flush_workqueue(fc_host_devloss_work_q(shost));
+ flush_workqueue(rport->devloss_work_q);
}
@@ -2913,13 +2908,6 @@ fc_remove_host(struct Scsi_Host *shost)
fc_host->work_q = NULL;
destroy_workqueue(work_q);
}
-
- /* flush all devloss work items, then kill it */
- if (fc_host->devloss_work_q) {
- work_q = fc_host->devloss_work_q;
- fc_host->devloss_work_q = NULL;
- destroy_workqueue(work_q);
- }
}
EXPORT_SYMBOL(fc_remove_host);
@@ -2967,6 +2955,7 @@ fc_rport_final_delete(struct work_struct *work)
struct device *dev = &rport->dev;
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);
+ struct workqueue_struct *work_q;
unsigned long flags;
int do_callback = 0;
@@ -2988,9 +2977,9 @@ fc_rport_final_delete(struct work_struct *work)
if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
spin_unlock_irqrestore(shost->host_lock, flags);
if (!cancel_delayed_work(&rport->fail_io_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
if (!cancel_delayed_work(&rport->dev_loss_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
cancel_work_sync(&rport->scan_work);
spin_lock_irqsave(shost->host_lock, flags);
rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
@@ -3021,6 +3010,12 @@ fc_rport_final_delete(struct work_struct *work)
fc_bsg_remove(rport->rqst_q);
+ if (rport->devloss_work_q) {
+ work_q = rport->devloss_work_q;
+ rport->devloss_work_q = NULL;
+ destroy_workqueue(work_q);
+ }
+
transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
@@ -3093,6 +3088,22 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel,
spin_unlock_irqrestore(shost->host_lock, flags);
+ rport->devloss_work_q = alloc_workqueue("fc_dl_%d_%d", 0, 0,
+ shost->host_no, rport->number);
+ if (!rport->devloss_work_q) {
+ printk(KERN_ERR "FC Remote Port alloc_workqueue failed\n");
+/*
+ * Note that we have not yet called device_initialize() / get_device()
+ * Cannot reclaim incremented rport->number because we released host_lock
+ */
+ spin_lock_irqsave(shost->host_lock, flags);
+ list_del(&rport->peers);
+ scsi_host_put(shost); /* for fc_host->rport list */
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ kfree(rport);
+ return NULL;
+ }
+
dev = &rport->dev;
device_initialize(dev); /* takes self reference */
dev->parent = get_device(&shost->shost_gendev); /* parent reference */
@@ -3255,9 +3266,9 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
* be checked and will NOOP the function.
*/
if (!cancel_delayed_work(&rport->fail_io_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
if (!cancel_delayed_work(&rport->dev_loss_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
spin_lock_irqsave(shost->host_lock, flags);
@@ -3451,11 +3462,12 @@ fc_remote_port_delete(struct fc_rport *rport)
/* see if we need to kill io faster than waiting for device loss */
if ((rport->fast_io_fail_tmo != -1) &&
(rport->fast_io_fail_tmo < timeout))
- fc_queue_devloss_work(shost, &rport->fail_io_work,
- rport->fast_io_fail_tmo * HZ);
+ fc_queue_devloss_work(shost, rport, &rport->fail_io_work,
+ rport->fast_io_fail_tmo * HZ);
/* cap the length the devices can be blocked until they are deleted */
- fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
+ fc_queue_devloss_work(shost, rport, &rport->dev_loss_work,
+ timeout * HZ);
}
EXPORT_SYMBOL(fc_remote_port_delete);
@@ -3514,9 +3526,9 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
* transaction.
*/
if (!cancel_delayed_work(&rport->fail_io_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
if (!cancel_delayed_work(&rport->dev_loss_work))
- fc_flush_devloss(shost);
+ fc_flush_devloss(shost, rport);
spin_lock_irqsave(shost->host_lock, flags);
rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7ce49d8f21c9..4a68b2ab2804 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3464,19 +3464,14 @@ static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer)
}
if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, INQUIRY, 0) < 0) {
- struct scsi_vpd *vpd;
-
sdev->no_report_opcodes = 1;
- /* Disable WRITE SAME if REPORT SUPPORTED OPERATION
- * CODES is unsupported and the device has an ATA
- * Information VPD page (SAT).
+ /*
+ * Disable WRITE SAME if REPORT SUPPORTED OPERATION CODES is
+ * unsupported and this is an ATA device.
*/
- rcu_read_lock();
- vpd = rcu_dereference(sdev->vpd_pg89);
- if (vpd)
+ if (sdev->is_ata)
sdev->no_write_same = 1;
- rcu_read_unlock();
}
if (scsi_report_opcode(sdev, buffer, SD_BUF_SIZE, WRITE_SAME_16, 0) == 1)