Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"Three small fixes, all in the embedded ufs driver subsystem"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: ufshcd: Fix missing destroy_workqueue()
scsi: ufs: Try to save power mode change and UIC cmd completion timeout
scsi: ufs: Fix unbalanced scsi_block_reqs_cnt caused by ufshcd_hold()

+31 -5
+29 -5
drivers/scsi/ufs/ufshcd.c
··· 1627 1627 */ 1628 1628 fallthrough; 1629 1629 case CLKS_OFF: 1630 - ufshcd_scsi_block_requests(hba); 1631 1630 hba->clk_gating.state = REQ_CLKS_ON; 1632 1631 trace_ufshcd_clk_gating(dev_name(hba->dev), 1633 1632 hba->clk_gating.state); 1634 - queue_work(hba->clk_gating.clk_gating_workq, 1635 - &hba->clk_gating.ungate_work); 1633 + if (queue_work(hba->clk_gating.clk_gating_workq, 1634 + &hba->clk_gating.ungate_work)) 1635 + ufshcd_scsi_block_requests(hba); 1636 1636 /* 1637 1637 * fall through to check if we should wait for this 1638 1638 * work to be done or not. ··· 2115 2115 unsigned long flags; 2116 2116 2117 2117 if (wait_for_completion_timeout(&uic_cmd->done, 2118 - msecs_to_jiffies(UIC_CMD_TIMEOUT))) 2118 + msecs_to_jiffies(UIC_CMD_TIMEOUT))) { 2119 2119 ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; 2120 - else 2120 + } else { 2121 2121 ret = -ETIMEDOUT; 2122 + dev_err(hba->dev, 2123 + "uic cmd 0x%x with arg3 0x%x completion timeout\n", 2124 + uic_cmd->command, uic_cmd->argument3); 2125 + 2126 + if (!uic_cmd->cmd_active) { 2127 + dev_err(hba->dev, "%s: UIC cmd has been completed, return the result\n", 2128 + __func__); 2129 + ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; 2130 + } 2131 + } 2122 2132 2123 2133 spin_lock_irqsave(hba->host->host_lock, flags); 2124 2134 hba->active_uic_cmd = NULL; ··· 2160 2150 if (completion) 2161 2151 init_completion(&uic_cmd->done); 2162 2152 2153 + uic_cmd->cmd_active = 1; 2163 2154 ufshcd_dispatch_uic_cmd(hba, uic_cmd); 2164 2155 2165 2156 return 0; ··· 3818 3807 dev_err(hba->dev, 3819 3808 "pwr ctrl cmd 0x%x with mode 0x%x completion timeout\n", 3820 3809 cmd->command, cmd->argument3); 3810 + 3811 + if (!cmd->cmd_active) { 3812 + dev_err(hba->dev, "%s: Power Mode Change operation has been completed, go check UPMCRS\n", 3813 + __func__); 3814 + goto check_upmcrs; 3815 + } 3816 + 3821 3817 ret = -ETIMEDOUT; 3822 3818 goto out; 3823 3819 } 3824 3820 3821 + check_upmcrs: 3825 3822 status = ufshcd_get_upmcrs(hba); 3826 3823 if (status != PWR_LOCAL) { 3827 3824 dev_err(hba->dev, ··· 4921 4902 ufshcd_get_uic_cmd_result(hba); 4922 4903 hba->active_uic_cmd->argument3 = 4923 4904 ufshcd_get_dme_attr_val(hba); 4905 + if (!hba->uic_async_done) 4906 + hba->active_uic_cmd->cmd_active = 0; 4924 4907 complete(&hba->active_uic_cmd->done); 4925 4908 retval = IRQ_HANDLED; 4926 4909 } 4927 4910 4928 4911 if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) { 4912 + hba->active_uic_cmd->cmd_active = 0; 4929 4913 complete(hba->uic_async_done); 4930 4914 retval = IRQ_HANDLED; 4931 4915 } ··· 8928 8906 blk_mq_free_tag_set(&hba->tmf_tag_set); 8929 8907 blk_cleanup_queue(hba->cmd_queue); 8930 8908 scsi_remove_host(hba->host); 8909 + destroy_workqueue(hba->eh_wq); 8931 8910 /* disable interrupts */ 8932 8911 ufshcd_disable_intr(hba, hba->intr_mask); 8933 8912 ufshcd_hba_stop(hba); ··· 9229 9206 exit_gating: 9230 9207 ufshcd_exit_clk_scaling(hba); 9231 9208 ufshcd_exit_clk_gating(hba); 9209 + destroy_workqueue(hba->eh_wq); 9232 9210 out_disable: 9233 9211 hba->is_irq_enabled = false; 9234 9212 ufshcd_hba_exit(hba);
+2
drivers/scsi/ufs/ufshcd.h
··· 64 64 * @argument1: UIC command argument 1 65 65 * @argument2: UIC command argument 2 66 66 * @argument3: UIC command argument 3 67 + * @cmd_active: Indicate if UIC command is outstanding 67 68 * @done: UIC command completion 68 69 */ 69 70 struct uic_command { ··· 72 71 u32 argument1; 73 72 u32 argument2; 74 73 u32 argument3; 74 + int cmd_active; 75 75 struct completion done; 76 76 }; 77 77