Skip to content

Commit ed02bfa

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: "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
2 parents 8891063 + 3e660fb commit ed02bfa

File tree

5 files changed

+77
-52
lines changed

5 files changed

+77
-52
lines changed

drivers/scsi/bnx2fc/bnx2fc_fcoe.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
412412
struct fc_frame_header *fh;
413413
struct fcoe_rcv_info *fr;
414414
struct fcoe_percpu_s *bg;
415+
struct sk_buff *tmp_skb;
415416
unsigned short oxid;
416417

417418
interface = container_of(ptype, struct bnx2fc_interface,
@@ -424,6 +425,12 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
424425
goto err;
425426
}
426427

428+
tmp_skb = skb_share_check(skb, GFP_ATOMIC);
429+
if (!tmp_skb)
430+
goto err;
431+
432+
skb = tmp_skb;
433+
427434
if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
428435
printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n");
429436
goto err;

drivers/scsi/scsi_devinfo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ static struct {
202202
{"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
203203
{"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
204204
{"INSITE", "I325VM", NULL, BLIST_KEY},
205+
{"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
205206
{"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
206207
{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
207208
{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},

drivers/scsi/ufs/ufshcd-pltfrm.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
102102
clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq),
103103
GFP_KERNEL);
104104
if (!clkfreq) {
105-
dev_err(dev, "%s: no memory\n", "freq-table-hz");
106105
ret = -ENOMEM;
107106
goto out;
108107
}
@@ -112,19 +111,19 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
112111
if (ret && (ret != -EINVAL)) {
113112
dev_err(dev, "%s: error reading array %d\n",
114113
"freq-table-hz", ret);
115-
goto free_clkfreq;
114+
return ret;
116115
}
117116

118117
for (i = 0; i < sz; i += 2) {
119118
ret = of_property_read_string_index(np,
120119
"clock-names", i/2, (const char **)&name);
121120
if (ret)
122-
goto free_clkfreq;
121+
goto out;
123122

124123
clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL);
125124
if (!clki) {
126125
ret = -ENOMEM;
127-
goto free_clkfreq;
126+
goto out;
128127
}
129128

130129
clki->min_freq = clkfreq[i];
@@ -134,8 +133,6 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
134133
clki->min_freq, clki->max_freq, clki->name);
135134
list_add_tail(&clki->list, &hba->clk_list_head);
136135
}
137-
free_clkfreq:
138-
kfree(clkfreq);
139136
out:
140137
return ret;
141138
}
@@ -162,10 +159,8 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
162159
}
163160

164161
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;
169164

170165
vreg->name = kstrdup(name, GFP_KERNEL);
171166

drivers/scsi/ufs/ufshcd.c

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,8 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba)
744744
if (!ufshcd_is_clkgating_allowed(hba))
745745
return;
746746
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);
747749
}
748750

749751
/* Must be called with host lock acquired */
@@ -2246,6 +2248,22 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
22462248
return ret;
22472249
}
22482250

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+
22492267
/**
22502268
* ufshcd_get_max_pwr_mode - reads the max power mode negotiated with device
22512269
* @hba: per-adapter instance
@@ -2844,8 +2862,13 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev)
28442862
hba = shost_priv(sdev->host);
28452863
scsi_deactivate_tcq(sdev, hba->nutrs);
28462864
/* 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);
28482869
hba->sdev_ufs_device = NULL;
2870+
spin_unlock_irqrestore(hba->host->host_lock, flags);
2871+
}
28492872
}
28502873

28512874
/**
@@ -4062,6 +4085,8 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
40624085
static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
40634086
{
40644087
int ret = 0;
4088+
struct scsi_device *sdev_rpmb;
4089+
struct scsi_device *sdev_boot;
40654090

40664091
hba->sdev_ufs_device = __scsi_add_device(hba->host, 0, 0,
40674092
ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN), NULL);
@@ -4070,56 +4095,33 @@ static int ufshcd_scsi_add_wlus(struct ufs_hba *hba)
40704095
hba->sdev_ufs_device = NULL;
40714096
goto out;
40724097
}
4098+
scsi_device_put(hba->sdev_ufs_device);
40734099

4074-
hba->sdev_boot = __scsi_add_device(hba->host, 0, 0,
4100+
sdev_boot = __scsi_add_device(hba->host, 0, 0,
40754101
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);
40794104
goto remove_sdev_ufs_device;
40804105
}
4106+
scsi_device_put(sdev_boot);
40814107

4082-
hba->sdev_rpmb = __scsi_add_device(hba->host, 0, 0,
4108+
sdev_rpmb = __scsi_add_device(hba->host, 0, 0,
40834109
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);
40874112
goto remove_sdev_boot;
40884113
}
4114+
scsi_device_put(sdev_rpmb);
40894115
goto out;
40904116

40914117
remove_sdev_boot:
4092-
scsi_remove_device(hba->sdev_boot);
4118+
scsi_remove_device(sdev_boot);
40934119
remove_sdev_ufs_device:
40944120
scsi_remove_device(hba->sdev_ufs_device);
40954121
out:
40964122
return ret;
40974123
}
40984124

4099-
/**
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-
41234125
/**
41244126
* ufshcd_probe_hba - probe hba to detect device and initialize
41254127
* @hba: per-adapter instance
@@ -4134,6 +4136,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
41344136
if (ret)
41354137
goto out;
41364138

4139+
ufshcd_init_pwr_info(hba);
4140+
41374141
/* UniPro link is active now */
41384142
ufshcd_set_link_active(hba);
41394143

@@ -4264,12 +4268,18 @@ static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg,
42644268
static inline int ufshcd_config_vreg_lpm(struct ufs_hba *hba,
42654269
struct ufs_vreg *vreg)
42664270
{
4271+
if (!vreg)
4272+
return 0;
4273+
42674274
return ufshcd_config_vreg_load(hba->dev, vreg, UFS_VREG_LPM_LOAD_UA);
42684275
}
42694276

42704277
static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba,
42714278
struct ufs_vreg *vreg)
42724279
{
4280+
if (!vreg)
4281+
return 0;
4282+
42734283
return ufshcd_config_vreg_load(hba->dev, vreg, vreg->max_uA);
42744284
}
42754285

@@ -4471,7 +4481,7 @@ static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
44714481
if (!IS_ERR_OR_NULL(clki->clk) && clki->enabled)
44724482
clk_disable_unprepare(clki->clk);
44734483
}
4474-
} else if (!ret && on) {
4484+
} else if (on) {
44754485
spin_lock_irqsave(hba->host->host_lock, flags);
44764486
hba->clk_gating.state = CLKS_ON;
44774487
spin_unlock_irqrestore(hba->host->host_lock, flags);
@@ -4675,11 +4685,25 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
46754685
{
46764686
unsigned char cmd[6] = { START_STOP };
46774687
struct scsi_sense_hdr sshdr;
4678-
struct scsi_device *sdp = hba->sdev_ufs_device;
4688+
struct scsi_device *sdp;
4689+
unsigned long flags;
46794690
int ret;
46804691

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);
4704+
4705+
if (ret)
4706+
return ret;
46834707

46844708
/*
46854709
* If scsi commands fail, the scsi mid-layer schedules scsi error-
@@ -4718,6 +4742,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
47184742
if (!ret)
47194743
hba->curr_dev_pwr_mode = pwr_mode;
47204744
out:
4745+
scsi_device_put(sdp);
47214746
hba->host->eh_noresume = 0;
47224747
return ret;
47234748
}
@@ -5087,7 +5112,7 @@ int ufshcd_system_suspend(struct ufs_hba *hba)
50875112
int ret = 0;
50885113

50895114
if (!hba || !hba->is_powered)
5090-
goto out;
5115+
return 0;
50915116

50925117
if (pm_runtime_suspended(hba->dev)) {
50935118
if (hba->rpm_lvl == hba->spm_lvl)
@@ -5231,7 +5256,6 @@ EXPORT_SYMBOL(ufshcd_shutdown);
52315256
void ufshcd_remove(struct ufs_hba *hba)
52325257
{
52335258
scsi_remove_host(hba->host);
5234-
ufshcd_scsi_remove_wlus(hba);
52355259
/* disable interrupts */
52365260
ufshcd_disable_intr(hba, hba->intr_mask);
52375261
ufshcd_hba_stop(hba);

drivers/scsi/ufs/ufshcd.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,6 @@ struct ufs_hba {
392392
* "UFS device" W-LU.
393393
*/
394394
struct scsi_device *sdev_ufs_device;
395-
struct scsi_device *sdev_rpmb;
396-
struct scsi_device *sdev_boot;
397395

398396
enum ufs_dev_pwr_mode curr_dev_pwr_mode;
399397
enum uic_link_state uic_link_state;

0 commit comments

Comments
 (0)