Skip to content

Commit 9afc116

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: "Ten updates: one non code maintainer update for vmw_pvscsi, five code updates for ibmvfc and four for UFS. All are either trivial patches or bug fixes" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: vmw_pvscsi: MAINTAINERS: Update maintainer scsi: ufs: Convert sysfs sprintf/snprintf family to sysfs_emit scsi: ufs: Remove redundant checks of !hba in suspend/resume callbacks scsi: ufs: ufs-qcom: Disable interrupt in reset path scsi: ufs: Minor adjustments to error handling scsi: ibmvfc: Reinitialize sub-CRQs and perform channel enquiry after LPM scsi: ibmvfc: Store return code of H_FREE_SUB_CRQ during cleanup scsi: ibmvfc: Treat H_CLOSED as success during sub-CRQ registration scsi: ibmvfc: Fix invalid sub-CRQ handles after hard reset scsi: ibmvfc: Simplify handling of sub-CRQ initialization
2 parents ce30708 + 1112963 commit 9afc116

6 files changed

Lines changed: 60 additions & 59 deletions

File tree

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19166,7 +19166,7 @@ S: Maintained
1916619166
F: drivers/infiniband/hw/vmw_pvrdma/
1916719167

1916819168
VMware PVSCSI driver
19169-
M: Jim Gill <jgill@vmware.com>
19169+
M: Vishal Bhakta <vbhakta@vmware.com>
1917019170
M: VMware PV-Drivers <pv-drivers@vmware.com>
1917119171
L: linux-scsi@vger.kernel.org
1917219172
S: Maintained

drivers/scsi/ibmvscsi/ibmvfc.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/bsg-lib.h>
2222
#include <asm/firmware.h>
2323
#include <asm/irq.h>
24+
#include <asm/rtas.h>
2425
#include <asm/vio.h>
2526
#include <scsi/scsi.h>
2627
#include <scsi/scsi_cmnd.h>
@@ -158,6 +159,9 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *);
158159
static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *);
159160
static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
160161

162+
static void ibmvfc_release_sub_crqs(struct ibmvfc_host *);
163+
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *);
164+
161165
static const char *unknown_error = "unknown error";
162166

163167
static long h_reg_sub_crq(unsigned long unit_address, unsigned long ioba,
@@ -899,6 +903,9 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
899903
{
900904
int rc = 0;
901905
struct vio_dev *vdev = to_vio_dev(vhost->dev);
906+
unsigned long flags;
907+
908+
ibmvfc_release_sub_crqs(vhost);
902909

903910
/* Re-enable the CRQ */
904911
do {
@@ -910,6 +917,15 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
910917
if (rc)
911918
dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc);
912919

920+
spin_lock_irqsave(vhost->host->host_lock, flags);
921+
spin_lock(vhost->crq.q_lock);
922+
vhost->do_enquiry = 1;
923+
vhost->using_channels = 0;
924+
spin_unlock(vhost->crq.q_lock);
925+
spin_unlock_irqrestore(vhost->host->host_lock, flags);
926+
927+
ibmvfc_init_sub_crqs(vhost);
928+
913929
return rc;
914930
}
915931

@@ -926,8 +942,8 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
926942
unsigned long flags;
927943
struct vio_dev *vdev = to_vio_dev(vhost->dev);
928944
struct ibmvfc_queue *crq = &vhost->crq;
929-
struct ibmvfc_queue *scrq;
930-
int i;
945+
946+
ibmvfc_release_sub_crqs(vhost);
931947

932948
/* Close the CRQ */
933949
do {
@@ -947,16 +963,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
947963
memset(crq->msgs.crq, 0, PAGE_SIZE);
948964
crq->cur = 0;
949965

950-
if (vhost->scsi_scrqs.scrqs) {
951-
for (i = 0; i < nr_scsi_hw_queues; i++) {
952-
scrq = &vhost->scsi_scrqs.scrqs[i];
953-
spin_lock(scrq->q_lock);
954-
memset(scrq->msgs.scrq, 0, PAGE_SIZE);
955-
scrq->cur = 0;
956-
spin_unlock(scrq->q_lock);
957-
}
958-
}
959-
960966
/* And re-open it again */
961967
rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address,
962968
crq->msg_token, PAGE_SIZE);
@@ -966,9 +972,12 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
966972
dev_warn(vhost->dev, "Partner adapter not ready\n");
967973
else if (rc != 0)
968974
dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc);
975+
969976
spin_unlock(vhost->crq.q_lock);
970977
spin_unlock_irqrestore(vhost->host->host_lock, flags);
971978

979+
ibmvfc_init_sub_crqs(vhost);
980+
972981
return rc;
973982
}
974983

@@ -5642,7 +5651,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
56425651
rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE,
56435652
&scrq->cookie, &scrq->hw_irq);
56445653

5645-
if (rc) {
5654+
/* H_CLOSED indicates successful register, but no CRQ partner */
5655+
if (rc && rc != H_CLOSED) {
56465656
dev_warn(dev, "Error registering sub-crq: %d\n", rc);
56475657
if (rc == H_PARAMETER)
56485658
dev_warn_once(dev, "Firmware may not support MQ\n");
@@ -5675,8 +5685,8 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
56755685

56765686
irq_failed:
56775687
do {
5678-
plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
5679-
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
5688+
rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
5689+
} while (rtas_busy_delay(rc));
56805690
reg_failed:
56815691
ibmvfc_free_queue(vhost, scrq);
56825692
LEAVE;
@@ -5694,6 +5704,7 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)
56945704

56955705
free_irq(scrq->irq, scrq);
56965706
irq_dispose_mapping(scrq->irq);
5707+
scrq->irq = 0;
56975708

56985709
do {
56995710
rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address,
@@ -5707,17 +5718,21 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)
57075718
LEAVE;
57085719
}
57095720

5710-
static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
5721+
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
57115722
{
57125723
int i, j;
57135724

57145725
ENTER;
5726+
if (!vhost->mq_enabled)
5727+
return;
57155728

57165729
vhost->scsi_scrqs.scrqs = kcalloc(nr_scsi_hw_queues,
57175730
sizeof(*vhost->scsi_scrqs.scrqs),
57185731
GFP_KERNEL);
5719-
if (!vhost->scsi_scrqs.scrqs)
5720-
return -1;
5732+
if (!vhost->scsi_scrqs.scrqs) {
5733+
vhost->do_enquiry = 0;
5734+
return;
5735+
}
57215736

57225737
for (i = 0; i < nr_scsi_hw_queues; i++) {
57235738
if (ibmvfc_register_scsi_channel(vhost, i)) {
@@ -5726,13 +5741,12 @@ static int ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
57265741
kfree(vhost->scsi_scrqs.scrqs);
57275742
vhost->scsi_scrqs.scrqs = NULL;
57285743
vhost->scsi_scrqs.active_queues = 0;
5729-
LEAVE;
5730-
return -1;
5744+
vhost->do_enquiry = 0;
5745+
break;
57315746
}
57325747
}
57335748

57345749
LEAVE;
5735-
return 0;
57365750
}
57375751

57385752
static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost)
@@ -5999,11 +6013,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
59996013
goto remove_shost;
60006014
}
60016015

6002-
if (vhost->mq_enabled) {
6003-
rc = ibmvfc_init_sub_crqs(vhost);
6004-
if (rc)
6005-
dev_warn(dev, "Failed to allocate Sub-CRQs. rc=%d\n", rc);
6006-
}
6016+
ibmvfc_init_sub_crqs(vhost);
60076017

60086018
if (shost_to_fc_host(shost)->rqst_q)
60096019
blk_queue_max_segments(shost_to_fc_host(shost)->rqst_q, 1);

drivers/scsi/ufs/ufs-qcom.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,17 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba)
253253
{
254254
int ret = 0;
255255
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
256+
bool reenable_intr = false;
256257

257258
if (!host->core_reset) {
258259
dev_warn(hba->dev, "%s: reset control not set\n", __func__);
259260
goto out;
260261
}
261262

263+
reenable_intr = hba->is_irq_enabled;
264+
disable_irq(hba->irq);
265+
hba->is_irq_enabled = false;
266+
262267
ret = reset_control_assert(host->core_reset);
263268
if (ret) {
264269
dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n",
@@ -280,6 +285,11 @@ static int ufs_qcom_host_reset(struct ufs_hba *hba)
280285

281286
usleep_range(1000, 1100);
282287

288+
if (reenable_intr) {
289+
enable_irq(hba->irq);
290+
hba->is_irq_enabled = true;
291+
}
292+
283293
out:
284294
return ret;
285295
}

drivers/scsi/ufs/ufshcd.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@
9595
16, 4, buf, __len, false); \
9696
} while (0)
9797

98-
static bool early_suspend;
99-
10098
int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
10199
const char *prefix)
102100
{
@@ -1535,7 +1533,7 @@ static ssize_t ufshcd_clkscale_enable_show(struct device *dev,
15351533
{
15361534
struct ufs_hba *hba = dev_get_drvdata(dev);
15371535

1538-
return snprintf(buf, PAGE_SIZE, "%d\n", hba->clk_scaling.is_enabled);
1536+
return sysfs_emit(buf, "%d\n", hba->clk_scaling.is_enabled);
15391537
}
15401538

15411539
static ssize_t ufshcd_clkscale_enable_store(struct device *dev,
@@ -4987,6 +4985,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
49874985
* UFS device needs urgent BKOPs.
49884986
*/
49894987
if (!hba->pm_op_in_progress &&
4988+
!ufshcd_eh_in_progress(hba) &&
49904989
ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) &&
49914990
schedule_work(&hba->eeh_work)) {
49924991
/*
@@ -5784,13 +5783,20 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
57845783
ufshcd_suspend_clkscaling(hba);
57855784
ufshcd_clk_scaling_allow(hba, false);
57865785
}
5786+
ufshcd_scsi_block_requests(hba);
5787+
/* Drain ufshcd_queuecommand() */
5788+
down_write(&hba->clk_scaling_lock);
5789+
up_write(&hba->clk_scaling_lock);
5790+
cancel_work_sync(&hba->eeh_work);
57875791
}
57885792

57895793
static void ufshcd_err_handling_unprepare(struct ufs_hba *hba)
57905794
{
5795+
ufshcd_scsi_unblock_requests(hba);
57915796
ufshcd_release(hba);
57925797
if (ufshcd_is_clkscaling_supported(hba))
57935798
ufshcd_clk_scaling_suspend(hba, false);
5799+
ufshcd_clear_ua_wluns(hba);
57945800
pm_runtime_put(hba->dev);
57955801
}
57965802

@@ -5882,8 +5888,8 @@ static void ufshcd_err_handler(struct work_struct *work)
58825888
spin_unlock_irqrestore(hba->host->host_lock, flags);
58835889
ufshcd_err_handling_prepare(hba);
58845890
spin_lock_irqsave(hba->host->host_lock, flags);
5885-
ufshcd_scsi_block_requests(hba);
5886-
hba->ufshcd_state = UFSHCD_STATE_RESET;
5891+
if (hba->ufshcd_state != UFSHCD_STATE_ERROR)
5892+
hba->ufshcd_state = UFSHCD_STATE_RESET;
58875893

58885894
/* Complete requests that have door-bell cleared by h/w */
58895895
ufshcd_complete_requests(hba);
@@ -6042,12 +6048,8 @@ static void ufshcd_err_handler(struct work_struct *work)
60426048
}
60436049
ufshcd_clear_eh_in_progress(hba);
60446050
spin_unlock_irqrestore(hba->host->host_lock, flags);
6045-
ufshcd_scsi_unblock_requests(hba);
60466051
ufshcd_err_handling_unprepare(hba);
60476052
up(&hba->host_sem);
6048-
6049-
if (!err && needs_reset)
6050-
ufshcd_clear_ua_wluns(hba);
60516053
}
60526054

60536055
/**
@@ -7858,6 +7860,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
78587860
unsigned long flags;
78597861
ktime_t start = ktime_get();
78607862

7863+
hba->ufshcd_state = UFSHCD_STATE_RESET;
7864+
78617865
ret = ufshcd_link_startup(hba);
78627866
if (ret)
78637867
goto out;
@@ -8972,11 +8976,6 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
89728976
int ret = 0;
89738977
ktime_t start = ktime_get();
89748978

8975-
if (!hba) {
8976-
early_suspend = true;
8977-
return 0;
8978-
}
8979-
89808979
down(&hba->host_sem);
89818980

89828981
if (!hba->is_powered)
@@ -9028,14 +9027,6 @@ int ufshcd_system_resume(struct ufs_hba *hba)
90289027
int ret = 0;
90299028
ktime_t start = ktime_get();
90309029

9031-
if (!hba)
9032-
return -EINVAL;
9033-
9034-
if (unlikely(early_suspend)) {
9035-
early_suspend = false;
9036-
down(&hba->host_sem);
9037-
}
9038-
90399030
if (!hba->is_powered || pm_runtime_suspended(hba->dev))
90409031
/*
90419032
* Let the runtime resume take care of resuming
@@ -9068,9 +9059,6 @@ int ufshcd_runtime_suspend(struct ufs_hba *hba)
90689059
int ret = 0;
90699060
ktime_t start = ktime_get();
90709061

9071-
if (!hba)
9072-
return -EINVAL;
9073-
90749062
if (!hba->is_powered)
90759063
goto out;
90769064
else
@@ -9109,9 +9097,6 @@ int ufshcd_runtime_resume(struct ufs_hba *hba)
91099097
int ret = 0;
91109098
ktime_t start = ktime_get();
91119099

9112-
if (!hba)
9113-
return -EINVAL;
9114-
91159100
if (!hba->is_powered)
91169101
goto out;
91179102
else

drivers/scsi/vmw_pvscsi.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* along with this program; if not, write to the Free Software
1818
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1919
*
20-
* Maintained by: Jim Gill <jgill@vmware.com>
21-
*
2220
*/
2321

2422
#include <linux/kernel.h>

drivers/scsi/vmw_pvscsi.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
* along with this program; if not, write to the Free Software
1818
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1919
*
20-
* Maintained by: Jim Gill <jgill@vmware.com>
21-
*
2220
*/
2321

2422
#ifndef _VMW_PVSCSI_H_

0 commit comments

Comments
 (0)