Skip to content

Commit ad8a69f

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "16 small(ish) fixes all in drivers. The major fixes are in pm8001 (fixes MSI-X issue going back to its origin), the qla2xxx endianness fix, which fixes a bug on big endian and the lpfc ones which can cause an oops on module removal without them" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: lpfc: Prevent use-after-free during rmmod with mapped NVMe rports scsi: lpfc: Early return after marking final NLP_DROPPED flag in dev_loss_tmo scsi: lpfc: Fix the NULL vs IS_ERR() bug for debugfs_create_file() scsi: target: core: Fix target_cmd_counter leak scsi: pm8001: Setup IRQs on resume scsi: pm80xx: Avoid leaking tags when processing OPC_INB_SET_CONTROLLER_CONFIG command scsi: pm80xx: Use phy-specific SAS address when sending PHY_START command scsi: ufs: core: Poll HCS.UCRDY before issuing a UIC command scsi: ufs: core: Move __ufshcd_send_uic_cmd() outside host_lock scsi: qedf: Add synchronization between I/O completions and abort scsi: target: Replace strlcpy() with strscpy() scsi: qla2xxx: Fix NULL vs IS_ERR() bug for debugfs_create_dir() scsi: qla2xxx: Use raw_smp_processor_id() instead of smp_processor_id() scsi: qla2xxx: Correct endianness for rqstlen and rsplen scsi: ppa: Fix accidentally reversed conditions for 16-bit and 32-bit EPP scsi: megaraid_sas: Fix deadlock on firmware crashdump
2 parents cc3e5af + dae40be commit ad8a69f

21 files changed

+112
-107
lines changed

drivers/scsi/lpfc/lpfc_debugfs.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6073,7 +6073,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
60736073
phba->hba_debugfs_root,
60746074
phba,
60756075
&lpfc_debugfs_op_multixripools);
6076-
if (!phba->debug_multixri_pools) {
6076+
if (IS_ERR(phba->debug_multixri_pools)) {
60776077
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
60786078
"0527 Cannot create debugfs multixripools\n");
60796079
goto debug_failed;
@@ -6085,7 +6085,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
60856085
debugfs_create_file(name, S_IFREG | 0644,
60866086
phba->hba_debugfs_root,
60876087
phba, &lpfc_cgn_buffer_op);
6088-
if (!phba->debug_cgn_buffer) {
6088+
if (IS_ERR(phba->debug_cgn_buffer)) {
60896089
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
60906090
"6527 Cannot create debugfs "
60916091
"cgn_buffer\n");
@@ -6098,7 +6098,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
60986098
debugfs_create_file(name, S_IFREG | 0644,
60996099
phba->hba_debugfs_root,
61006100
phba, &lpfc_rx_monitor_op);
6101-
if (!phba->debug_rx_monitor) {
6101+
if (IS_ERR(phba->debug_rx_monitor)) {
61026102
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
61036103
"6528 Cannot create debugfs "
61046104
"rx_monitor\n");
@@ -6111,7 +6111,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
61116111
debugfs_create_file(name, 0644,
61126112
phba->hba_debugfs_root,
61136113
phba, &lpfc_debugfs_ras_log);
6114-
if (!phba->debug_ras_log) {
6114+
if (IS_ERR(phba->debug_ras_log)) {
61156115
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
61166116
"6148 Cannot create debugfs"
61176117
" ras_log\n");
@@ -6132,7 +6132,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
61326132
debugfs_create_file(name, S_IFREG | 0644,
61336133
phba->hba_debugfs_root,
61346134
phba, &lpfc_debugfs_op_lockstat);
6135-
if (!phba->debug_lockstat) {
6135+
if (IS_ERR(phba->debug_lockstat)) {
61366136
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
61376137
"4610 Can't create debugfs lockstat\n");
61386138
goto debug_failed;
@@ -6358,7 +6358,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
63586358
debugfs_create_file(name, 0644,
63596359
vport->vport_debugfs_root,
63606360
vport, &lpfc_debugfs_op_scsistat);
6361-
if (!vport->debug_scsistat) {
6361+
if (IS_ERR(vport->debug_scsistat)) {
63626362
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
63636363
"4611 Cannot create debugfs scsistat\n");
63646364
goto debug_failed;
@@ -6369,7 +6369,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
63696369
debugfs_create_file(name, 0644,
63706370
vport->vport_debugfs_root,
63716371
vport, &lpfc_debugfs_op_ioktime);
6372-
if (!vport->debug_ioktime) {
6372+
if (IS_ERR(vport->debug_ioktime)) {
63736373
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
63746374
"0815 Cannot create debugfs ioktime\n");
63756375
goto debug_failed;

drivers/scsi/lpfc/lpfc_hbadisc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,12 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
199199
/* Only 1 thread can drop the initial node reference. If
200200
* another thread has set NLP_DROPPED, this thread is done.
201201
*/
202-
if (!(ndlp->nlp_flag & NLP_DROPPED)) {
202+
if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD) &&
203+
!(ndlp->nlp_flag & NLP_DROPPED)) {
203204
ndlp->nlp_flag |= NLP_DROPPED;
204205
spin_unlock_irqrestore(&ndlp->lock, iflags);
205206
lpfc_nlp_put(ndlp);
206-
spin_lock_irqsave(&ndlp->lock, iflags);
207+
return;
207208
}
208209

209210
spin_unlock_irqrestore(&ndlp->lock, iflags);

drivers/scsi/lpfc/lpfc_nvme.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport)
228228
spin_unlock_irq(&ndlp->lock);
229229

230230
/* On a devloss timeout event, one more put is executed provided the
231-
* NVME and SCSI rport unregister requests are complete. If the vport
232-
* is unloading, this extra put is executed by lpfc_drop_node.
231+
* NVME and SCSI rport unregister requests are complete.
233232
*/
234233
if (!(ndlp->fc4_xpt_flags & fc4_xpt_flags))
235234
lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
@@ -2567,11 +2566,7 @@ lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
25672566
* nvme_transport perspective. Loss of an rport just means IO cannot
25682567
* be sent and recovery is completely up to the initator.
25692568
* For now, the driver just unbinds the DID and port_role so that
2570-
* no further IO can be issued. Changes are planned for later.
2571-
*
2572-
* Notes - the ndlp reference count is not decremented here since
2573-
* since there is no nvme_transport api for devloss. Node ref count
2574-
* is only adjusted in driver unload.
2569+
* no further IO can be issued.
25752570
*/
25762571
void
25772572
lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
@@ -2646,6 +2641,21 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
26462641
"6167 NVME unregister failed %d "
26472642
"port_state x%x\n",
26482643
ret, remoteport->port_state);
2644+
2645+
if (vport->load_flag & FC_UNLOADING) {
2646+
/* Only 1 thread can drop the initial node
2647+
* reference. Check if another thread has set
2648+
* NLP_DROPPED.
2649+
*/
2650+
spin_lock_irq(&ndlp->lock);
2651+
if (!(ndlp->nlp_flag & NLP_DROPPED)) {
2652+
ndlp->nlp_flag |= NLP_DROPPED;
2653+
spin_unlock_irq(&ndlp->lock);
2654+
lpfc_nlp_put(ndlp);
2655+
return;
2656+
}
2657+
spin_unlock_irq(&ndlp->lock);
2658+
}
26492659
}
26502660
}
26512661
return;

drivers/scsi/megaraid/megaraid_sas.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,7 @@ struct megasas_instance {
23322332
u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */
23332333
bool use_seqnum_jbod_fp; /* Added for PD sequence */
23342334
bool smp_affinity_enable;
2335-
spinlock_t crashdump_lock;
2335+
struct mutex crashdump_lock;
23362336

23372337
struct megasas_register_set __iomem *reg_set;
23382338
u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY];

drivers/scsi/megaraid/megaraid_sas_base.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,14 +3271,13 @@ fw_crash_buffer_store(struct device *cdev,
32713271
struct megasas_instance *instance =
32723272
(struct megasas_instance *) shost->hostdata;
32733273
int val = 0;
3274-
unsigned long flags;
32753274

32763275
if (kstrtoint(buf, 0, &val) != 0)
32773276
return -EINVAL;
32783277

3279-
spin_lock_irqsave(&instance->crashdump_lock, flags);
3278+
mutex_lock(&instance->crashdump_lock);
32803279
instance->fw_crash_buffer_offset = val;
3281-
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3280+
mutex_unlock(&instance->crashdump_lock);
32823281
return strlen(buf);
32833282
}
32843283

@@ -3293,24 +3292,23 @@ fw_crash_buffer_show(struct device *cdev,
32933292
unsigned long dmachunk = CRASH_DMA_BUF_SIZE;
32943293
unsigned long chunk_left_bytes;
32953294
unsigned long src_addr;
3296-
unsigned long flags;
32973295
u32 buff_offset;
32983296

3299-
spin_lock_irqsave(&instance->crashdump_lock, flags);
3297+
mutex_lock(&instance->crashdump_lock);
33003298
buff_offset = instance->fw_crash_buffer_offset;
33013299
if (!instance->crash_dump_buf ||
33023300
!((instance->fw_crash_state == AVAILABLE) ||
33033301
(instance->fw_crash_state == COPYING))) {
33043302
dev_err(&instance->pdev->dev,
33053303
"Firmware crash dump is not available\n");
3306-
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3304+
mutex_unlock(&instance->crashdump_lock);
33073305
return -EINVAL;
33083306
}
33093307

33103308
if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) {
33113309
dev_err(&instance->pdev->dev,
33123310
"Firmware crash dump offset is out of range\n");
3313-
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3311+
mutex_unlock(&instance->crashdump_lock);
33143312
return 0;
33153313
}
33163314

@@ -3322,7 +3320,7 @@ fw_crash_buffer_show(struct device *cdev,
33223320
src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] +
33233321
(buff_offset % dmachunk);
33243322
memcpy(buf, (void *)src_addr, size);
3325-
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3323+
mutex_unlock(&instance->crashdump_lock);
33263324

33273325
return size;
33283326
}
@@ -3347,7 +3345,6 @@ fw_crash_state_store(struct device *cdev,
33473345
struct megasas_instance *instance =
33483346
(struct megasas_instance *) shost->hostdata;
33493347
int val = 0;
3350-
unsigned long flags;
33513348

33523349
if (kstrtoint(buf, 0, &val) != 0)
33533350
return -EINVAL;
@@ -3361,9 +3358,9 @@ fw_crash_state_store(struct device *cdev,
33613358
instance->fw_crash_state = val;
33623359

33633360
if ((val == COPIED) || (val == COPY_ERROR)) {
3364-
spin_lock_irqsave(&instance->crashdump_lock, flags);
3361+
mutex_lock(&instance->crashdump_lock);
33653362
megasas_free_host_crash_buffer(instance);
3366-
spin_unlock_irqrestore(&instance->crashdump_lock, flags);
3363+
mutex_unlock(&instance->crashdump_lock);
33673364
if (val == COPY_ERROR)
33683365
dev_info(&instance->pdev->dev, "application failed to "
33693366
"copy Firmware crash dump\n");
@@ -7422,7 +7419,7 @@ static inline void megasas_init_ctrl_params(struct megasas_instance *instance)
74227419
init_waitqueue_head(&instance->int_cmd_wait_q);
74237420
init_waitqueue_head(&instance->abort_cmd_wait_q);
74247421

7425-
spin_lock_init(&instance->crashdump_lock);
7422+
mutex_init(&instance->crashdump_lock);
74267423
spin_lock_init(&instance->mfi_pool_lock);
74277424
spin_lock_init(&instance->hba_lock);
74287425
spin_lock_init(&instance->stream_lock);

drivers/scsi/pm8001/pm8001_hwi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4180,7 +4180,7 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
41804180
payload.sas_identify.dev_type = SAS_END_DEVICE;
41814181
payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
41824182
memcpy(payload.sas_identify.sas_addr,
4183-
pm8001_ha->sas_addr, SAS_ADDR_SIZE);
4183+
&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
41844184
payload.sas_identify.phy_id = phy_id;
41854185

41864186
return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,

drivers/scsi/pm8001/pm8001_init.c

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id)
273273
return ret;
274274
}
275275

276-
static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha);
277276
static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha);
278277

279278
/**
@@ -294,13 +293,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
294293
pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n",
295294
pm8001_ha->chip->n_phy);
296295

297-
/* Setup Interrupt */
298-
rc = pm8001_setup_irq(pm8001_ha);
299-
if (rc) {
300-
pm8001_dbg(pm8001_ha, FAIL,
301-
"pm8001_setup_irq failed [ret: %d]\n", rc);
302-
goto err_out;
303-
}
304296
/* Request Interrupt */
305297
rc = pm8001_request_irq(pm8001_ha);
306298
if (rc)
@@ -1031,47 +1023,38 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha)
10311023
}
10321024
#endif
10331025

1034-
static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha)
1035-
{
1036-
struct pci_dev *pdev;
1037-
1038-
pdev = pm8001_ha->pdev;
1039-
1040-
#ifdef PM8001_USE_MSIX
1041-
if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
1042-
return pm8001_setup_msix(pm8001_ha);
1043-
pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
1044-
#endif
1045-
return 0;
1046-
}
1047-
10481026
/**
10491027
* pm8001_request_irq - register interrupt
10501028
* @pm8001_ha: our ha struct.
10511029
*/
10521030
static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
10531031
{
1054-
struct pci_dev *pdev;
1032+
struct pci_dev *pdev = pm8001_ha->pdev;
1033+
#ifdef PM8001_USE_MSIX
10551034
int rc;
10561035

1057-
pdev = pm8001_ha->pdev;
1036+
if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
1037+
rc = pm8001_setup_msix(pm8001_ha);
1038+
if (rc) {
1039+
pm8001_dbg(pm8001_ha, FAIL,
1040+
"pm8001_setup_irq failed [ret: %d]\n", rc);
1041+
return rc;
1042+
}
10581043

1059-
#ifdef PM8001_USE_MSIX
1060-
if (pdev->msix_cap && pci_msi_enabled())
1061-
return pm8001_request_msix(pm8001_ha);
1062-
else {
1063-
pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
1064-
goto intx;
1044+
if (pdev->msix_cap && pci_msi_enabled())
1045+
return pm8001_request_msix(pm8001_ha);
10651046
}
1047+
1048+
pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n");
10661049
#endif
10671050

1068-
intx:
10691051
/* initialize the INT-X interrupt */
10701052
pm8001_ha->irq_vector[0].irq_id = 0;
10711053
pm8001_ha->irq_vector[0].drv_inst = pm8001_ha;
1072-
rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED,
1073-
pm8001_ha->name, SHOST_TO_SAS_HA(pm8001_ha->shost));
1074-
return rc;
1054+
1055+
return request_irq(pdev->irq, pm8001_interrupt_handler_intx,
1056+
IRQF_SHARED, pm8001_ha->name,
1057+
SHOST_TO_SAS_HA(pm8001_ha->shost));
10751058
}
10761059

10771060
/**

drivers/scsi/pm8001/pm80xx_hwi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3671,10 +3671,12 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha,
36713671
(struct set_ctrl_cfg_resp *)(piomb + 4);
36723672
u32 status = le32_to_cpu(pPayload->status);
36733673
u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd);
3674+
u32 tag = le32_to_cpu(pPayload->tag);
36743675

36753676
pm8001_dbg(pm8001_ha, MSG,
36763677
"SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n",
36773678
status, err_qlfr_pgcd);
3679+
pm8001_tag_free(pm8001_ha, tag);
36783680

36793681
return 0;
36803682
}
@@ -4671,7 +4673,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
46714673
payload.sas_identify.dev_type = SAS_END_DEVICE;
46724674
payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
46734675
memcpy(payload.sas_identify.sas_addr,
4674-
&pm8001_ha->sas_addr, SAS_ADDR_SIZE);
4676+
&pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE);
46754677
payload.sas_identify.phy_id = phy_id;
46764678

46774679
return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload,

drivers/scsi/ppa.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,9 @@ static int ppa_out(ppa_struct *dev, char *buffer, int len)
307307
case PPA_EPP_8:
308308
epp_reset(ppb);
309309
w_ctr(ppb, 0x4);
310-
if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x01))
310+
if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x03))
311311
outsl(ppb + 4, buffer, len >> 2);
312-
else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x03))
312+
else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x01))
313313
outsw(ppb + 4, buffer, len >> 1);
314314
else
315315
outsb(ppb + 4, buffer, len);

drivers/scsi/qedf/qedf_io.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,24 +1904,28 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
19041904
goto drop_rdata_kref;
19051905
}
19061906

1907+
spin_lock_irqsave(&fcport->rport_lock, flags);
19071908
if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
19081909
test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) ||
19091910
test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) {
19101911
QEDF_ERR(&qedf->dbg_ctx,
19111912
"io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n",
19121913
io_req->xid, io_req->sc_cmd);
19131914
rc = 1;
1915+
spin_unlock_irqrestore(&fcport->rport_lock, flags);
19141916
goto drop_rdata_kref;
19151917
}
19161918

1919+
/* Set the command type to abort */
1920+
io_req->cmd_type = QEDF_ABTS;
1921+
spin_unlock_irqrestore(&fcport->rport_lock, flags);
1922+
19171923
kref_get(&io_req->refcount);
19181924

19191925
xid = io_req->xid;
19201926
qedf->control_requests++;
19211927
qedf->packet_aborts++;
19221928

1923-
/* Set the command type to abort */
1924-
io_req->cmd_type = QEDF_ABTS;
19251929
io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
19261930

19271931
set_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
@@ -2210,7 +2214,9 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req,
22102214
refcount, fcport, fcport->rdata->ids.port_id);
22112215

22122216
/* Cleanup cmds re-use the same TID as the original I/O */
2217+
spin_lock_irqsave(&fcport->rport_lock, flags);
22132218
io_req->cmd_type = QEDF_CLEANUP;
2219+
spin_unlock_irqrestore(&fcport->rport_lock, flags);
22142220
io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
22152221

22162222
init_completion(&io_req->cleanup_done);

0 commit comments

Comments
 (0)