Commit ed02bfa4aaf7fa015cbb8444d83a98f9f263c5df
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "This is a set of ten fixes: 8 for UFS including four static checker warnings, a potential null deref in the voltage regulator code, a race on module unload, a ref counting fix on the well known LUNs which made it impossible to remove the ufs module and fix to correct the information in pwr_info. In addition to UFS, there's a blacklist for the Intel Multi-Flex array which chokes on report supported operation codes and a fix to an oops in bnx2fc caused by shared skbs" [ For us non-SCSI people: "UFS" here is "Universal Flash Storage" not the filesystem. - Linus ] * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: ufs: fix NULL dereference when no regulators are defined ufs: ensure clk gating work is finished before module unloading scsi: ufs: fix static checker warning in ufshcd_parse_clock_info scsi: ufs: fix static checker warning in __ufshcd_setup_clocks scsi: ufs: fix static checker warning in ufshcd_populate_vreg scsi: ufs: fix static checker errors in ufshcd_system_suspend ufs: fix power info after link start-up ufs: fix reference counting of W-LUs scsi: add Intel Multi-Flex to scsi scan blacklist bnx2fc: do not add shared skbs to the fcoe_rx_list
Showing 5 changed files Side-by-side Diff
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
... | ... | @@ -412,6 +412,7 @@ |
412 | 412 | struct fc_frame_header *fh; |
413 | 413 | struct fcoe_rcv_info *fr; |
414 | 414 | struct fcoe_percpu_s *bg; |
415 | + struct sk_buff *tmp_skb; | |
415 | 416 | unsigned short oxid; |
416 | 417 | |
417 | 418 | interface = container_of(ptype, struct bnx2fc_interface, |
... | ... | @@ -423,6 +424,12 @@ |
423 | 424 | printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n"); |
424 | 425 | goto err; |
425 | 426 | } |
427 | + | |
428 | + tmp_skb = skb_share_check(skb, GFP_ATOMIC); | |
429 | + if (!tmp_skb) | |
430 | + goto err; | |
431 | + | |
432 | + skb = tmp_skb; | |
426 | 433 | |
427 | 434 | if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { |
428 | 435 | printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); |
drivers/scsi/scsi_devinfo.c
... | ... | @@ -202,6 +202,7 @@ |
202 | 202 | {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, |
203 | 203 | {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, |
204 | 204 | {"INSITE", "I325VM", NULL, BLIST_KEY}, |
205 | + {"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC}, | |
205 | 206 | {"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36}, |
206 | 207 | {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN}, |
207 | 208 | {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, |
drivers/scsi/ufs/ufshcd-pltfrm.c
... | ... | @@ -102,7 +102,6 @@ |
102 | 102 | clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq), |
103 | 103 | GFP_KERNEL); |
104 | 104 | if (!clkfreq) { |
105 | - dev_err(dev, "%s: no memory\n", "freq-table-hz"); | |
106 | 105 | ret = -ENOMEM; |
107 | 106 | goto out; |
108 | 107 | } |
109 | 108 | |
110 | 109 | |
... | ... | @@ -112,19 +111,19 @@ |
112 | 111 | if (ret && (ret != -EINVAL)) { |
113 | 112 | dev_err(dev, "%s: error reading array %d\n", |
114 | 113 | "freq-table-hz", ret); |
115 | - goto free_clkfreq; | |
114 | + return ret; | |
116 | 115 | } |
117 | 116 | |
118 | 117 | for (i = 0; i < sz; i += 2) { |
119 | 118 | ret = of_property_read_string_index(np, |
120 | 119 | "clock-names", i/2, (const char **)&name); |
121 | 120 | if (ret) |
122 | - goto free_clkfreq; | |
121 | + goto out; | |
123 | 122 | |
124 | 123 | clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); |
125 | 124 | if (!clki) { |
126 | 125 | ret = -ENOMEM; |
127 | - goto free_clkfreq; | |
126 | + goto out; | |
128 | 127 | } |
129 | 128 | |
130 | 129 | clki->min_freq = clkfreq[i]; |
... | ... | @@ -134,8 +133,6 @@ |
134 | 133 | clki->min_freq, clki->max_freq, clki->name); |
135 | 134 | list_add_tail(&clki->list, &hba->clk_list_head); |
136 | 135 | } |
137 | -free_clkfreq: | |
138 | - kfree(clkfreq); | |
139 | 136 | out: |
140 | 137 | return ret; |
141 | 138 | } |
... | ... | @@ -162,10 +159,8 @@ |
162 | 159 | } |
163 | 160 | |
164 | 161 | vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); |
165 | - if (!vreg) { | |
166 | - dev_err(dev, "No memory for %s regulator\n", name); | |
167 | - goto out; | |
168 | - } | |
162 | + if (!vreg) | |
163 | + return -ENOMEM; | |
169 | 164 | |
170 | 165 | vreg->name = kstrdup(name, GFP_KERNEL); |
171 | 166 |
drivers/scsi/ufs/ufshcd.c
... | ... | @@ -744,6 +744,8 @@ |
744 | 744 | if (!ufshcd_is_clkgating_allowed(hba)) |
745 | 745 | return; |
746 | 746 | device_remove_file(hba->dev, &hba->clk_gating.delay_attr); |
747 | + cancel_work_sync(&hba->clk_gating.ungate_work); | |
748 | + cancel_delayed_work_sync(&hba->clk_gating.gate_work); | |
747 | 749 | } |
748 | 750 | |
749 | 751 | /* Must be called with host lock acquired */ |
... | ... | @@ -2246,6 +2248,22 @@ |
2246 | 2248 | return ret; |
2247 | 2249 | } |
2248 | 2250 | |
2251 | + /** | |
2252 | + * ufshcd_init_pwr_info - setting the POR (power on reset) | |
2253 | + * values in hba power info | |
2254 | + * @hba: per-adapter instance | |
2255 | + */ | |
2256 | +static void ufshcd_init_pwr_info(struct ufs_hba *hba) | |
2257 | +{ | |
2258 | + hba->pwr_info.gear_rx = UFS_PWM_G1; | |
2259 | + hba->pwr_info.gear_tx = UFS_PWM_G1; | |
2260 | + hba->pwr_info.lane_rx = 1; | |
2261 | + hba->pwr_info.lane_tx = 1; | |
2262 | + hba->pwr_info.pwr_rx = SLOWAUTO_MODE; | |
2263 | + hba->pwr_info.pwr_tx = SLOWAUTO_MODE; | |
2264 | + hba->pwr_info.hs_rate = 0; | |
2265 | +} | |
2266 | + | |
2249 | 2267 | /** |
2250 | 2268 | * ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device |
2251 | 2269 | * @hba: per-adapter instance |
2252 | 2270 | |
... | ... | @@ -2844,8 +2862,13 @@ |
2844 | 2862 | hba = shost_priv(sdev->host); |
2845 | 2863 | scsi_deactivate_tcq(sdev, hba->nutrs); |
2846 | 2864 | /* Drop the reference as it won't be needed anymore */ |
2847 | - if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) | |
2865 | + if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { | |
2866 | + unsigned long flags; | |
2867 | + | |
2868 | + spin_lock_irqsave(hba->host->host_lock, flags); | |
2848 | 2869 | hba->sdev_ufs_device = NULL; |
2870 | + spin_unlock_irqrestore(hba->host->host_lock, flags); | |
2871 | + } | |
2849 | 2872 | } |
2850 | 2873 | |
2851 | 2874 | /** |
... | ... | @@ -4062,6 +4085,8 @@ |
4062 | 4085 | static int ufshcd_scsi_add_wlus(struct ufs_hba *hba) |
4063 | 4086 | { |
4064 | 4087 | int ret = 0; |
4088 | + struct scsi_device *sdev_rpmb; | |
4089 | + struct scsi_device *sdev_boot; | |
4065 | 4090 | |
4066 | 4091 | hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0, |
4067 | 4092 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL); |
4068 | 4093 | |
4069 | 4094 | |
4070 | 4095 | |
4071 | 4096 | |
4072 | 4097 | |
4073 | 4098 | |
4074 | 4099 | |
... | ... | @@ -4070,26 +4095,27 @@ |
4070 | 4095 | hba->sdev_ufs_device = NULL; |
4071 | 4096 | goto out; |
4072 | 4097 | } |
4098 | + scsi_device_put(hba->sdev_ufs_device); | |
4073 | 4099 | |
4074 | - hba->sdev_boot = __scsi_add_device(hba->host, 0, 0, | |
4100 | + sdev_boot = __scsi_add_device(hba->host, 0, 0, | |
4075 | 4101 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_BOOT_WLUN), NULL); |
4076 | - if (IS_ERR(hba->sdev_boot)) { | |
4077 | - ret = PTR_ERR(hba->sdev_boot); | |
4078 | - hba->sdev_boot = NULL; | |
4102 | + if (IS_ERR(sdev_boot)) { | |
4103 | + ret = PTR_ERR(sdev_boot); | |
4079 | 4104 | goto remove_sdev_ufs_device; |
4080 | 4105 | } |
4106 | + scsi_device_put(sdev_boot); | |
4081 | 4107 | |
4082 | - hba->sdev_rpmb = __scsi_add_device(hba->host, 0, 0, | |
4108 | + sdev_rpmb = __scsi_add_device(hba->host, 0, 0, | |
4083 | 4109 | ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_RPMB_WLUN), NULL); |
4084 | - if (IS_ERR(hba->sdev_rpmb)) { | |
4085 | - ret = PTR_ERR(hba->sdev_rpmb); | |
4086 | - hba->sdev_rpmb = NULL; | |
4110 | + if (IS_ERR(sdev_rpmb)) { | |
4111 | + ret = PTR_ERR(sdev_rpmb); | |
4087 | 4112 | goto remove_sdev_boot; |
4088 | 4113 | } |
4114 | + scsi_device_put(sdev_rpmb); | |
4089 | 4115 | goto out; |
4090 | 4116 | |
4091 | 4117 | remove_sdev_boot: |
4092 | - scsi_remove_device(hba->sdev_boot); | |
4118 | + scsi_remove_device(sdev_boot); | |
4093 | 4119 | remove_sdev_ufs_device: |
4094 | 4120 | scsi_remove_device(hba->sdev_ufs_device); |
4095 | 4121 | out: |
... | ... | @@ -4097,30 +4123,6 @@ |
4097 | 4123 | } |
4098 | 4124 | |
4099 | 4125 | /** |
4100 | - * ufshcd_scsi_remove_wlus - Removes the W-LUs which were added by | |
4101 | - * ufshcd_scsi_add_wlus() | |
4102 | - * @hba: per-adapter instance | |
4103 | - * | |
4104 | - */ | |
4105 | -static void ufshcd_scsi_remove_wlus(struct ufs_hba *hba) | |
4106 | -{ | |
4107 | - if (hba->sdev_ufs_device) { | |
4108 | - scsi_remove_device(hba->sdev_ufs_device); | |
4109 | - hba->sdev_ufs_device = NULL; | |
4110 | - } | |
4111 | - | |
4112 | - if (hba->sdev_boot) { | |
4113 | - scsi_remove_device(hba->sdev_boot); | |
4114 | - hba->sdev_boot = NULL; | |
4115 | - } | |
4116 | - | |
4117 | - if (hba->sdev_rpmb) { | |
4118 | - scsi_remove_device(hba->sdev_rpmb); | |
4119 | - hba->sdev_rpmb = NULL; | |
4120 | - } | |
4121 | -} | |
4122 | - | |
4123 | -/** | |
4124 | 4126 | * ufshcd_probe_hba - probe hba to detect device and initialize |
4125 | 4127 | * @hba: per-adapter instance |
4126 | 4128 | * |
... | ... | @@ -4134,6 +4136,8 @@ |
4134 | 4136 | if (ret) |
4135 | 4137 | goto out; |
4136 | 4138 | |
4139 | + ufshcd_init_pwr_info(hba); | |
4140 | + | |
4137 | 4141 | /* UniPro link is active now */ |
4138 | 4142 | ufshcd_set_link_active(hba); |
4139 | 4143 | |
4140 | 4144 | |
... | ... | @@ -4264,12 +4268,18 @@ |
4264 | 4268 | static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba, |
4265 | 4269 | struct ufs_vreg *vreg) |
4266 | 4270 | { |
4271 | + if (!vreg) | |
4272 | + return 0; | |
4273 | + | |
4267 | 4274 | return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA); |
4268 | 4275 | } |
4269 | 4276 | |
4270 | 4277 | static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, |
4271 | 4278 | struct ufs_vreg *vreg) |
4272 | 4279 | { |
4280 | + if (!vreg) | |
4281 | + return 0; | |
4282 | + | |
4273 | 4283 | return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA); |
4274 | 4284 | } |
4275 | 4285 | |
... | ... | @@ -4471,7 +4481,7 @@ |
4471 | 4481 | if (!IS_ERR_OR_NULL(clki->clk) && clki->enabled) |
4472 | 4482 | clk_disable_unprepare(clki->clk); |
4473 | 4483 | } |
4474 | - } else if (!ret && on) { | |
4484 | + } else if (on) { | |
4475 | 4485 | spin_lock_irqsave(hba->host->host_lock, flags); |
4476 | 4486 | hba->clk_gating.state = CLKS_ON; |
4477 | 4487 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
4478 | 4488 | |
4479 | 4489 | |
... | ... | @@ -4675,12 +4685,26 @@ |
4675 | 4685 | { |
4676 | 4686 | unsigned char cmd[6] = { START_STOP }; |
4677 | 4687 | struct scsi_sense_hdr sshdr; |
4678 | - struct scsi_device *sdp = hba->sdev_ufs_device; | |
4688 | + struct scsi_device *sdp; | |
4689 | + unsigned long flags; | |
4679 | 4690 | int ret; |
4680 | 4691 | |
4681 | - if (!sdp || !scsi_device_online(sdp)) | |
4682 | - return -ENODEV; | |
4692 | + spin_lock_irqsave(hba->host->host_lock, flags); | |
4693 | + sdp = hba->sdev_ufs_device; | |
4694 | + if (sdp) { | |
4695 | + ret = scsi_device_get(sdp); | |
4696 | + if (!ret && !scsi_device_online(sdp)) { | |
4697 | + ret = -ENODEV; | |
4698 | + scsi_device_put(sdp); | |
4699 | + } | |
4700 | + } else { | |
4701 | + ret = -ENODEV; | |
4702 | + } | |
4703 | + spin_unlock_irqrestore(hba->host->host_lock, flags); | |
4683 | 4704 | |
4705 | + if (ret) | |
4706 | + return ret; | |
4707 | + | |
4684 | 4708 | /* |
4685 | 4709 | * If scsi commands fail, the scsi mid-layer schedules scsi error- |
4686 | 4710 | * handling, which would wait for host to be resumed. Since we know |
... | ... | @@ -4718,6 +4742,7 @@ |
4718 | 4742 | if (!ret) |
4719 | 4743 | hba->curr_dev_pwr_mode = pwr_mode; |
4720 | 4744 | out: |
4745 | + scsi_device_put(sdp); | |
4721 | 4746 | hba->host->eh_noresume = 0; |
4722 | 4747 | return ret; |
4723 | 4748 | } |
... | ... | @@ -5087,7 +5112,7 @@ |
5087 | 5112 | int ret = 0; |
5088 | 5113 | |
5089 | 5114 | if (!hba || !hba->is_powered) |
5090 | - goto out; | |
5115 | + return 0; | |
5091 | 5116 | |
5092 | 5117 | if (pm_runtime_suspended(hba->dev)) { |
5093 | 5118 | if (hba->rpm_lvl == hba->spm_lvl) |
... | ... | @@ -5231,7 +5256,6 @@ |
5231 | 5256 | void ufshcd_remove(struct ufs_hba *hba) |
5232 | 5257 | { |
5233 | 5258 | scsi_remove_host(hba->host); |
5234 | - ufshcd_scsi_remove_wlus(hba); | |
5235 | 5259 | /* disable interrupts */ |
5236 | 5260 | ufshcd_disable_intr(hba, hba->intr_mask); |
5237 | 5261 | ufshcd_hba_stop(hba); |
drivers/scsi/ufs/ufshcd.h