summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 13:34:31 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-16 13:34:31 -0800
commit60f7c503d971a731ee3c4f884a9f2e80d476730d (patch)
tree30e23c822306b0e407f6218135feb5b2e847665d /drivers/scsi/qla2xxx
parent69f637c33560b02ae7313e0c142d847361cc723a (diff)
parentbe1b500212541a70006887bae558ff834d7365d0 (diff)
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "This consists of the usual driver updates (ufs, qla2xxx, smartpqi, target, zfcp, fnic, mpt3sas, ibmvfc) plus a load of cleanups, a major power management rework and a load of assorted minor updates. There are a few core updates (formatting fixes being the big one) but nothing major this cycle" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (279 commits) scsi: mpt3sas: Update driver version to 36.100.00.00 scsi: mpt3sas: Handle trigger page after firmware update scsi: mpt3sas: Add persistent MPI trigger page scsi: mpt3sas: Add persistent SCSI sense trigger page scsi: mpt3sas: Add persistent Event trigger page scsi: mpt3sas: Add persistent Master trigger page scsi: mpt3sas: Add persistent trigger pages support scsi: mpt3sas: Sync time periodically between driver and firmware scsi: qla2xxx: Update version to 10.02.00.104-k scsi: qla2xxx: Fix device loss on 4G and older HBAs scsi: qla2xxx: If fcport is undergoing deletion complete I/O with retry scsi: qla2xxx: Fix the call trace for flush workqueue scsi: qla2xxx: Fix flash update in 28XX adapters on big endian machines scsi: qla2xxx: Handle aborts correctly for port undergoing deletion scsi: qla2xxx: Fix N2N and NVMe connect retry failure scsi: qla2xxx: Fix FW initialization error on big endian machines scsi: qla2xxx: Fix crash during driver load on big endian machines scsi: qla2xxx: Fix compilation issue in PPC systems scsi: qla2xxx: Don't check for fw_started while posting NVMe command scsi: qla2xxx: Tear down session if FW say it is down ...
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_gs.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c77
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c34
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_nvme.c14
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c27
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c53
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c24
-rw-r--r--drivers/scsi/qla2xxx/qla_target.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_tmpl.c9
-rw-r--r--drivers/scsi/qla2xxx/qla_tmpl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qla2xxx/tcm_qla2xxx.c72
16 files changed, 212 insertions, 147 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 4f0486fe30dd..30c7e5e63851 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2493,6 +2493,8 @@ typedef struct fc_port {
int generation;
struct se_session *se_sess;
+ struct list_head sess_cmd_list;
+ spinlock_t sess_cmd_lock;
struct kref sess_kref;
struct qla_tgt *tgt;
unsigned long expires;
@@ -3294,8 +3296,10 @@ struct isp_operations {
void (*fw_dump)(struct scsi_qla_host *vha);
void (*mpi_fw_dump)(struct scsi_qla_host *, int);
+ /* Context: task, might sleep */
int (*beacon_on) (struct scsi_qla_host *);
int (*beacon_off) (struct scsi_qla_host *);
+
void (*beacon_blink) (struct scsi_qla_host *);
void *(*read_optrom)(struct scsi_qla_host *, void *,
@@ -3306,7 +3310,10 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
int (*start_scsi_mq) (srb_t *);
+
+ /* Context: task, might sleep */
int (*abort_isp) (struct scsi_qla_host *);
+
int (*iospace_config)(struct qla_hw_data *);
int (*initialize_adapter)(struct scsi_qla_host *);
};
@@ -4968,8 +4975,7 @@ struct secure_flash_update_block_pk {
} while (0)
#define QLA_QPAIR_MARK_NOT_BUSY(__qpair) \
- atomic_dec(&__qpair->ref_count); \
-
+ atomic_dec(&__qpair->ref_count)
#define QLA_ENA_CONF(_ha) {\
int i;\
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index e28c4b7ec55f..391ac75e3de3 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3558,10 +3558,10 @@ login_logout:
if (fcport->flags & FCF_FCP2_DEVICE)
fcport->logout_on_delete = 0;
- ql_dbg(ql_dbg_disc, vha, 0x20f0,
- "%s %d %8phC post del sess\n",
- __func__, __LINE__,
- fcport->port_name);
+ ql_log(ql_log_warn, vha, 0x20f0,
+ "%s %d %8phC post del sess\n",
+ __func__, __LINE__,
+ fcport->port_name);
qlt_schedule_sess_for_deletion(fcport);
continue;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 898c70b8ebbf..dcc0f0d823db 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1268,9 +1268,10 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
ql_dbg(ql_dbg_disc, vha, 0x211b,
- "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
+ "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
- fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
+ fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
+ NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
@@ -1932,26 +1933,58 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
break;
}
- /*
- * Retry PRLI with other FC-4 type if failure occurred on dual
- * FCP/NVMe port
- */
- if (NVME_FCP_TARGET(ea->fcport)) {
- ql_dbg(ql_dbg_disc, vha, 0x2118,
- "%s %d %8phC post %s prli\n",
- __func__, __LINE__, ea->fcport->port_name,
- (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
- "NVMe" : "FCP");
- if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+ "%s %d %8phC priority %s, fc4type %x\n",
+ __func__, __LINE__, ea->fcport->port_name,
+ vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
+ "FCP" : "NVMe", ea->fcport->fc4_type);
+
+ if (N2N_TOPO(vha->hw)) {
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
- else
+ ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
+ } else {
ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
- }
+ ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
+ }
- ea->fcport->flags &= ~FCF_ASYNC_SENT;
- ea->fcport->keep_nport_handle = 0;
- ea->fcport->logout_on_delete = 1;
- qlt_schedule_sess_for_deletion(ea->fcport);
+ if (ea->fcport->n2n_link_reset_cnt < 3) {
+ ea->fcport->n2n_link_reset_cnt++;
+ vha->relogin_jif = jiffies + 2 * HZ;
+ /*
+ * PRLI failed. Reset link to kick start
+ * state machine
+ */
+ set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+ } else {
+ ql_log(ql_log_warn, vha, 0x2119,
+ "%s %d %8phC Unable to reconnect\n",
+ __func__, __LINE__,
+ ea->fcport->port_name);
+ }
+ } else {
+ /*
+ * switch connect. login failed. Take connection down
+ * and allow relogin to retrigger
+ */
+ if (NVME_FCP_TARGET(ea->fcport)) {
+ ql_dbg(ql_dbg_disc, vha, 0x2118,
+ "%s %d %8phC post %s prli\n",
+ __func__, __LINE__,
+ ea->fcport->port_name,
+ (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
+ ? "NVMe" : "FCP");
+ if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
+ else
+ ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
+ }
+
+ ea->fcport->flags &= ~FCF_ASYNC_SENT;
+ ea->fcport->keep_nport_handle = 0;
+ ea->fcport->logout_on_delete = 1;
+ qlt_schedule_sess_for_deletion(ea->fcport);
+ }
break;
}
}
@@ -4974,6 +5007,9 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
INIT_LIST_HEAD(&fcport->gnl_entry);
INIT_LIST_HEAD(&fcport->list);
+ INIT_LIST_HEAD(&fcport->sess_cmd_list);
+ spin_lock_init(&fcport->sess_cmd_lock);
+
return fcport;
}
@@ -5946,6 +5982,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
break;
}
+ if (fcport->login_retry == 0)
+ fcport->login_retry =
+ vha->hw->login_retry_count;
/*
* If device was not a fabric device before.
*/
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a24b82de4aab..f9142dbec112 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2226,11 +2226,13 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
srb_t *sp;
struct srb_iocb *iocb;
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
+ u16 comp_status;
sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
if (!sp)
return;
+ comp_status = le16_to_cpu(sts->comp_status);
iocb = &sp->u.iocb_cmd;
type = sp->name;
fcport = sp->fcport;
@@ -2244,7 +2246,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
} else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
ql_log(ql_log_warn, fcport->vha, 0x5039,
"Async-%s error - hdl=%x completion status(%x).\n",
- type, sp->handle, sts->comp_status);
+ type, sp->handle, comp_status);
iocb->u.tmf.data = QLA_FUNCTION_FAILED;
} else if ((le16_to_cpu(sts->scsi_status) &
SS_RESPONSE_INFO_LEN_VALID)) {
@@ -2260,6 +2262,30 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk)
}
}
+ switch (comp_status) {
+ case CS_PORT_LOGGED_OUT:
+ case CS_PORT_CONFIG_CHG:
+ case CS_PORT_BUSY:
+ case CS_INCOMPLETE:
+ case CS_PORT_UNAVAILABLE:
+ case CS_TIMEOUT:
+ case CS_RESET:
+ if (atomic_read(&fcport->state) == FCS_ONLINE) {
+ ql_dbg(ql_dbg_disc, fcport->vha, 0x3021,
+ "-Port to be marked lost on fcport=%02x%02x%02x, current port state= %s comp_status %x.\n",
+ fcport->d_id.b.domain, fcport->d_id.b.area,
+ fcport->d_id.b.al_pa,
+ port_state_str[FCS_ONLINE],
+ comp_status);
+
+ qlt_schedule_sess_for_deletion(fcport);
+ }
+ break;
+
+ default:
+ break;
+ }
+
if (iocb->u.tmf.data != QLA_SUCCESS)
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, sp->vha, 0x5055,
sts, sizeof(*sts));
@@ -3952,10 +3978,12 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
if (USER_CTRL_IRQ(ha) || !ha->mqiobase) {
/* user wants to control IRQ setting for target mode */
ret = pci_alloc_irq_vectors(ha->pdev, min_vecs,
- ha->msix_count, PCI_IRQ_MSIX);
+ min((u16)ha->msix_count, (u16)num_online_cpus()),
+ PCI_IRQ_MSIX);
} else
ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs,
- ha->msix_count, PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
+ min((u16)ha->msix_count, (u16)num_online_cpus()),
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
&desc);
if (ret < 0) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 07afd0d8a8f3..d7d4ab65009c 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1129,7 +1129,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (ha->flags.scm_supported_a &&
(ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) {
ha->flags.scm_supported_f = 1;
- ha->sf_init_cb->flags |= BIT_13;
+ ha->sf_init_cb->flags |= cpu_to_le16(BIT_13);
}
ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n",
(ha->flags.scm_supported_f) ? "Supported" :
@@ -1137,9 +1137,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
if (vha->flags.nvme2_enabled) {
/* set BIT_15 of special feature control block for SLER */
- ha->sf_init_cb->flags |= BIT_15;
+ ha->sf_init_cb->flags |= cpu_to_le16(BIT_15);
/* set BIT_14 of special feature control block for PI CTRL*/
- ha->sf_init_cb->flags |= BIT_14;
+ ha->sf_init_cb->flags |= cpu_to_le16(BIT_14);
}
}
@@ -3998,9 +3998,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->n2n_flag = 1;
fcport->keep_nport_handle = 1;
- fcport->fc4_type = FS_FC4TYPE_FCP;
- if (vha->flags.nvme_enabled)
- fcport->fc4_type |= FS_FC4TYPE_NVME;
if (wwn_to_u64(vha->port_name) >
wwn_to_u64(fcport->port_name)) {
@@ -4030,7 +4027,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
return;
- break;
case TOPO_FL:
ha->current_topology = ISP_CFG_FL;
break;
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
index b7a1dc24db38..eab559b3b257 100644
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -227,7 +227,7 @@ static void qla_nvme_abort_work(struct work_struct *work)
"%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n",
__func__, sp, sp->handle, fcport, fcport->deleted);
- if (!ha->flags.fw_started && fcport->deleted)
+ if (!ha->flags.fw_started || fcport->deleted)
goto out;
if (ha->flags.host_shutting_down) {
@@ -554,19 +554,15 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
fcport = qla_rport->fcport;
- if (!qpair || !fcport)
- return -ENODEV;
-
- if (!qpair->fw_started || fcport->deleted)
+ if (unlikely(!qpair || !fcport || fcport->deleted))
return -EBUSY;
- vha = fcport->vha;
-
if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
return -ENODEV;
- if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- (qpair && !qpair->fw_started) || fcport->deleted)
+ vha = fcport->vha;
+
+ if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
return -EBUSY;
/*
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index b3ba0de5d4fb..0677295957bc 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -489,29 +489,26 @@ qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in)
return data;
}
-#define IDC_LOCK_TIMEOUT 100000000
+/*
+ * Context: task, might sleep
+ */
int qla82xx_idc_lock(struct qla_hw_data *ha)
{
- int i;
- int done = 0, timeout = 0;
+ const int delay_ms = 100, timeout_ms = 2000;
+ int done, total = 0;
- while (!done) {
+ might_sleep();
+
+ while (true) {
/* acquire semaphore5 from PCI HW block */
done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));
if (done == 1)
break;
- if (timeout >= IDC_LOCK_TIMEOUT)
+ if (WARN_ON_ONCE(total >= timeout_ms))
return -1;
- timeout++;
-
- /* Yield CPU */
- if (!in_interrupt())
- schedule();
- else {
- for (i = 0; i < 20; i++)
- cpu_relax();
- }
+ total += delay_ms;
+ msleep(delay_ms);
}
return 0;
@@ -965,7 +962,7 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)
static int
qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)
{
- uint32_t val;
+ uint32_t val = 0;
int i, ret;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
index 01ccd4526707..68a16c95dcb7 100644
--- a/drivers/scsi/qla2xxx/qla_nx2.c
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -139,7 +139,7 @@ qla8044_poll_wait_for_ready(struct scsi_qla_host *vha, uint32_t addr1,
uint32_t mask)
{
unsigned long timeout;
- uint32_t temp;
+ uint32_t temp = 0;
/* jiffies after 100ms */
timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS);
@@ -2594,7 +2594,7 @@ qla8044_minidump_process_rdmux(struct scsi_qla_host *vha,
struct qla8044_minidump_entry_hdr *entry_hdr,
uint32_t **d_ptr)
{
- uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
+ uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value = 0;
struct qla8044_minidump_entry_mux *mux_hdr;
uint32_t *data_ptr = *d_ptr;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f9c8ae9d669e..f80abe28f35a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -884,8 +884,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto qc24_fail_command;
}
- if (!fcport) {
- cmd->result = DID_NO_CONNECT << 16;
+ if (!fcport || fcport->deleted) {
+ cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}
@@ -966,8 +966,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
goto qc24_fail_command;
}
- if (!fcport) {
- cmd->result = DID_NO_CONNECT << 16;
+ if (!fcport || fcport->deleted) {
+ cmd->result = DID_IMM_RETRY << 16;
goto qc24_fail_command;
}
@@ -3265,7 +3265,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
"req->req_q_in=%p req->req_q_out=%p rsp->rsp_q_in=%p rsp->rsp_q_out=%p.\n",
req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out);
- ha->wq = alloc_workqueue("qla2xxx_wq", 0, 0);
+ ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 0);
if (unlikely(!ha->wq)) {
ret = -ENOMEM;
goto probe_failed;
@@ -5619,25 +5619,10 @@ qla83xx_service_idc_aen(struct work_struct *work)
}
}
-static void
-qla83xx_wait_logic(void)
-{
- int i;
-
- /* Yield CPU */
- if (!in_interrupt()) {
- /*
- * Wait about 200ms before retrying again.
- * This controls the number of retries for single
- * lock operation.
- */
- msleep(100);
- schedule();
- } else {
- for (i = 0; i < 20; i++)
- cpu_relax(); /* This a nop instr on i386 */
- }
-}
+/*
+ * Control the frequency of IDC lock retries
+ */
+#define QLA83XX_WAIT_LOGIC_MS 100
static int
qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
@@ -5727,7 +5712,7 @@ retry_lockid:
goto exit;
if (o_drv_lockid == n_drv_lockid) {
- qla83xx_wait_logic();
+ msleep(QLA83XX_WAIT_LOGIC_MS);
goto retry_lockid;
} else
return QLA_SUCCESS;
@@ -5736,6 +5721,9 @@ exit:
return rval;
}
+/*
+ * Context: task, can sleep
+ */
void
qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
@@ -5743,6 +5731,8 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
uint32_t lock_owner;
struct qla_hw_data *ha = base_vha->hw;
+ might_sleep();
+
/* IDC-lock implementation using driver-lock/lock-id remote registers */
retry_lock:
if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data)
@@ -5761,7 +5751,7 @@ retry_lock:
/* Retry/Perform IDC-Lock recovery */
if (qla83xx_idc_lock_recovery(base_vha)
== QLA_SUCCESS) {
- qla83xx_wait_logic();
+ msleep(QLA83XX_WAIT_LOGIC_MS);
goto retry_lock;
} else
ql_log(ql_log_warn, base_vha, 0xb075,
@@ -6259,6 +6249,9 @@ void qla24xx_process_purex_list(struct purex_list *list)
}
}
+/*
+ * Context: task, can sleep
+ */
void
qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
{
@@ -6269,6 +6262,8 @@ qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
uint32_t data;
struct qla_hw_data *ha = base_vha->hw;
+ might_sleep();
+
/* IDC-unlock implementation using driver-unlock/lock-id
* remote registers
*/
@@ -6284,7 +6279,7 @@ retry_unlock:
/* SV: XXX: IDC unlock retrying needed here? */
/* Retry for IDC-unlock */
- qla83xx_wait_logic();
+ msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb064,
"Failed to release IDC lock, retrying=%d\n", retry);
@@ -6292,7 +6287,7 @@ retry_unlock:
}
} else if (retry < 10) {
/* Retry for IDC-unlock */
- qla83xx_wait_logic();
+ msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb065,
"Failed to read drv-lockid, retrying=%d\n", retry);
@@ -6308,7 +6303,7 @@ retry_unlock2:
if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
if (retry < 10) {
/* Retry for IDC-unlock */
- qla83xx_wait_logic();
+ msleep(QLA83XX_WAIT_LOGIC_MS);
retry++;
ql_dbg(ql_dbg_p3p, base_vha, 0xb066,
"Failed to release IDC lock, retrying=%d\n", retry);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 0f92e9a044dc..f771fabcba59 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -2634,14 +2634,14 @@ qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf,
sizeof(struct secure_flash_update_block));
for (i = 0; i < (sizeof(struct secure_flash_update_block) >> 2); i++)
- check_sum += p[i];
+ check_sum += le32_to_cpu(p[i]);
check_sum = (~check_sum) + 1;
- if (check_sum != p[i]) {
+ if (check_sum != le32_to_cpu(p[i])) {
ql_log(ql_log_warn, vha, 0x7097,
"SFUB checksum failed, 0x%x, 0x%x\n",
- check_sum, p[i]);
+ check_sum, le32_to_cpu(p[i]));
return QLA_COMMAND_ERROR;
}
@@ -2721,7 +2721,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
if (ha->flags.secure_adapter && region.attribute) {
ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff,
- "Region %x is secure\n", region.code);
+ "Region %x is secure\n", le16_to_cpu(region.code));
switch (le16_to_cpu(region.code)) {
case FLT_REG_FW:
@@ -2775,7 +2775,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
default:
ql_log(ql_log_warn + ql_dbg_verbose, vha,
0xffff, "Secure region %x not supported\n",
- region.code);
+ le16_to_cpu(region.code));
rval = QLA_COMMAND_ERROR;
goto done;
}
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index a27a625839e6..0d09480b66cd 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1273,7 +1273,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
qla24xx_chk_fcp_state(sess);
- ql_dbg(ql_dbg_disc, sess->vha, 0xe001,
+ ql_dbg(ql_log_warn, sess->vha, 0xe001,
"Scheduling sess %p for deletion %8phC\n",
sess, sess->port_name);
@@ -2083,6 +2083,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw;
struct qla_tgt_mgmt_cmd *mcmd;
struct qla_qpair_hint *h = &vha->vha_tgt.qla_tgt->qphints[0];
+ struct qla_tgt_cmd *abort_cmd;
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
"qla_target(%d): task abort (tag=%d)\n",
@@ -2110,17 +2111,17 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
*/
mcmd->se_cmd.cpuid = h->cpuid;
- if (ha->tgt.tgt_ops->find_cmd_by_tag) {
- struct qla_tgt_cmd *abort_cmd;
-
- abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
+ abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess,
le32_to_cpu(abts->exchange_addr_to_abort));
- if (abort_cmd && abort_cmd->qpair) {
- mcmd->qpair = abort_cmd->qpair;
- mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid;
- mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr;
- mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID;
- }
+ if (!abort_cmd)
+ return -EIO;
+ mcmd->unpacked_lun = abort_cmd->se_cmd.orig_fe_lun;
+
+ if (abort_cmd->qpair) {
+ mcmd->qpair = abort_cmd->qpair;
+ mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid;
+ mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr;
+ mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID;
}
INIT_WORK(&mcmd->work, qlt_do_tmr_work);
@@ -4291,6 +4292,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
cmd->cmd_type = TYPE_TGT_CMD;
memcpy(&cmd->atio, atio, sizeof(*atio));
+ INIT_LIST_HEAD(&cmd->sess_cmd_list);
cmd->state = QLA_TGT_STATE_NEW;
cmd->tgt = vha->vha_tgt.qla_tgt;
qlt_incr_num_pend_cmds(vha);
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 1cff7c69d448..10e5e6c8087d 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -856,6 +856,7 @@ struct qla_tgt_cmd {
uint8_t cmd_type;
uint8_t pad[7];
struct se_cmd se_cmd;
+ struct list_head sess_cmd_list;
struct fc_port *sess;
struct qla_qpair *qpair;
uint32_t reset_count;
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index bd8623ee156a..26c13a953b97 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -928,7 +928,8 @@ qla27xx_template_checksum(void *p, ulong size)
static inline int
qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp)
{
- return qla27xx_template_checksum(tmp, tmp->template_size) == 0;
+ return qla27xx_template_checksum(tmp,
+ le32_to_cpu(tmp->template_size)) == 0;
}
static inline int
@@ -944,7 +945,7 @@ qla27xx_execute_fwdt_template(struct scsi_qla_host *vha,
ulong len = 0;
if (qla27xx_fwdt_template_valid(tmp)) {
- len = tmp->template_size;
+ len = le32_to_cpu(tmp->template_size);
tmp = memcpy(buf, tmp, len);
ql27xx_edit_template(vha, tmp);
qla27xx_walk_template(vha, tmp, buf, &len);
@@ -960,7 +961,7 @@ qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p)
ulong len = 0;
if (qla27xx_fwdt_template_valid(tmp)) {
- len = tmp->template_size;
+ len = le32_to_cpu(tmp->template_size);
qla27xx_walk_template(vha, tmp, NULL, &len);
}
@@ -972,7 +973,7 @@ qla27xx_fwdt_template_size(void *p)
{
struct qla27xx_fwdt_template *tmp = p;
- return tmp->template_size;
+ return le32_to_cpu(tmp->template_size);
}
int
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.h b/drivers/scsi/qla2xxx/qla_tmpl.h
index c47184db5081..6e0987edfceb 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.h
+++ b/drivers/scsi/qla2xxx/qla_tmpl.h
@@ -12,7 +12,7 @@
struct __packed qla27xx_fwdt_template {
__le32 template_type;
__le32 entry_offset;
- uint32_t template_size;
+ __le32 template_size;
uint32_t count; /* borrow field for running/residual count */
__le32 entry_count;
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index c2d4da52f4a9..ccec858875dd 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -6,9 +6,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "10.02.00.103-k"
+#define QLA2XXX_VERSION "10.02.00.104-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 2
#define QLA_DRIVER_PATCH_VER 0
-#define QLA_DRIVER_BETA_VER 103
+#define QLA_DRIVER_BETA_VER 104
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 61017acd3458..b55fc768a2a7 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -255,6 +255,7 @@ static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd)
static void tcm_qla2xxx_complete_free(struct work_struct *work)
{
struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
+ unsigned long flags;
cmd->cmd_in_wq = 0;
@@ -265,6 +266,10 @@ static void tcm_qla2xxx_complete_free(struct work_struct *work)
cmd->trc_flags |= TRC_CMD_FREE;
cmd->cmd_sent_to_fw = 0;
+ spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
+ list_del_init(&cmd->sess_cmd_list);
+ spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
+
transport_generic_free_cmd(&cmd->se_cmd, 0);
}
@@ -363,15 +368,10 @@ static void tcm_qla2xxx_put_sess(struct fc_port *sess)
static void tcm_qla2xxx_close_session(struct se_session *se_sess)
{
struct fc_port *sess = se_sess->fabric_sess_ptr;
- struct scsi_qla_host *vha;
- unsigned long flags;
BUG_ON(!sess);
- vha = sess->vha;
- spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
- target_sess_cmd_list_set_waiting(se_sess);
- spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+ target_stop_session(se_sess);
sess->explicit_logout = 1;
tcm_qla2xxx_put_sess(sess);
@@ -451,13 +451,14 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
struct se_portal_group *se_tpg;
struct tcm_qla2xxx_tpg *tpg;
#endif
- int flags = TARGET_SCF_ACK_KREF;
+ int target_flags = TARGET_SCF_ACK_KREF;
+ unsigned long flags;
if (bidi)
- flags |= TARGET_SCF_BIDI_OP;
+ target_flags |= TARGET_SCF_BIDI_OP;
if (se_cmd->cpuid != WORK_CPU_UNBOUND)
- flags |= TARGET_SCF_USE_CPUID;
+ target_flags |= TARGET_SCF_USE_CPUID;
sess = cmd->sess;
if (!sess) {
@@ -479,11 +480,15 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd,
return 0;
}
#endif
-
cmd->qpair->tgt_counters.qla_core_sbt_cmd++;
+
+ spin_lock_irqsave(&sess->sess_cmd_lock, flags);
+ list_add_tail(&cmd->sess_cmd_list, &sess->sess_cmd_list);
+ spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
+
return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0],
- cmd->unpacked_lun, data_length, fcp_task_attr,
- data_dir, flags);
+ cmd->unpacked_lun, data_length, fcp_task_attr,
+ data_dir, target_flags);
}
static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
@@ -574,13 +579,11 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
struct fc_port *sess = mcmd->sess;
struct se_cmd *se_cmd = &mcmd->se_cmd;
int transl_tmr_func = 0;
- int flags = TARGET_SCF_ACK_KREF;
switch (tmr_func) {
case QLA_TGT_ABTS:
pr_debug("%ld: ABTS received\n", sess->vha->host_no);
transl_tmr_func = TMR_ABORT_TASK;
- flags |= TARGET_SCF_LOOKUP_LUN_FROM_TAG;
break;
case QLA_TGT_2G_ABORT_TASK:
pr_debug("%ld: 2G Abort Task received\n", sess->vha->host_no);
@@ -613,31 +616,26 @@ static int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, u64 lun,
}
return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd,
- transl_tmr_func, GFP_ATOMIC, tag, flags);
+ transl_tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF);
}
static struct qla_tgt_cmd *tcm_qla2xxx_find_cmd_by_tag(struct fc_port *sess,
uint64_t tag)
{
- struct qla_tgt_cmd *cmd = NULL;
- struct se_cmd *secmd;
+ struct qla_tgt_cmd *cmd;
unsigned long flags;
if (!sess->se_sess)
return NULL;
- spin_lock_irqsave(&sess->se_sess->sess_cmd_lock, flags);
- list_for_each_entry(secmd, &sess->se_sess->sess_cmd_list, se_cmd_list) {
- /* skip task management functions, including tmr->task_cmd */
- if (secmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
- continue;
-
- if (secmd->tag == tag) {
- cmd = container_of(secmd, struct qla_tgt_cmd, se_cmd);
- break;
- }
+ spin_lock_irqsave(&sess->sess_cmd_lock, flags);
+ list_for_each_entry(cmd, &sess->sess_cmd_list, sess_cmd_list) {
+ if (cmd->se_cmd.tag == tag)
+ goto done;
}
- spin_unlock_irqrestore(&sess->se_sess->sess_cmd_lock, flags);
+ cmd = NULL;
+done:
+ spin_unlock_irqrestore(&sess->sess_cmd_lock, flags);
return cmd;
}
@@ -767,11 +765,19 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
- struct qla_tgt_cmd *cmd = container_of(se_cmd,
- struct qla_tgt_cmd, se_cmd);
+ struct qla_tgt_cmd *cmd;
+ unsigned long flags;
- if (qlt_abort_cmd(cmd))
+ if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
return;
+
+ cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
+
+ spin_lock_irqsave(&cmd->sess->sess_cmd_lock, flags);
+ list_del_init(&cmd->sess_cmd_list);
+ spin_unlock_irqrestore(&cmd->sess->sess_cmd_lock, flags);
+
+ qlt_abort_cmd(cmd);
}
static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
@@ -820,7 +826,7 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct fc_port *sess)
static void tcm_qla2xxx_shutdown_sess(struct fc_port *sess)
{
- target_sess_cmd_list_set_waiting(sess->se_sess);
+ target_stop_session(sess->se_sess);
}
static int tcm_qla2xxx_init_nodeacl(struct se_node_acl *se_nacl,
@@ -1394,8 +1400,6 @@ static void tcm_qla2xxx_free_session(struct fc_port *sess)
struct se_session *se_sess;
struct tcm_qla2xxx_lport *lport;
- BUG_ON(in_interrupt());
-
se_sess = sess->se_sess;
if (!se_sess) {
pr_err("struct fc_port->se_sess is NULL\n");