浏览代码

wimax/i2400m: if a device reboot happens during probe, handle it

When a device reboot happens when we are under probe, with init_mutex
taken, make sure we can recover. Have dev_reset_handle set boot mode
and i2400m_msg_to_dev() will see it and fail gracefully instead of
timing out.

Found and diagnosed by Cindy H. Kao.

Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Inaky Perez-Gonzalez 16 年之前
父节点
当前提交
b4013f91cd
共有 3 个文件被更改,包括 5 次插入0 次删除
  1. 1 0
      drivers/net/wimax/i2400m/control.c
  2. 2 0
      drivers/net/wimax/i2400m/driver.c
  3. 2 0
      drivers/net/wimax/i2400m/fw.c

+ 1 - 0
drivers/net/wimax/i2400m/control.c

@@ -695,6 +695,7 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
 	d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
 	d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
 		  i2400m, buf, buf_len);
 		  i2400m, buf, buf_len);
 
 
+	rmb();		/* Make sure we see what i2400m_dev_reset_handle() */
 	if (i2400m->boot_mode)
 	if (i2400m->boot_mode)
 		return ERR_PTR(-ENODEV);
 		return ERR_PTR(-ENODEV);
 
 

+ 2 - 0
drivers/net/wimax/i2400m/driver.c

@@ -610,6 +610,8 @@ out:
  */
  */
 int i2400m_dev_reset_handle(struct i2400m *i2400m)
 int i2400m_dev_reset_handle(struct i2400m *i2400m)
 {
 {
+	i2400m->boot_mode = 1;
+	wmb();		/* Make sure i2400m_msg_to_dev() sees boot_mode */
 	return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
 	return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
 				    GFP_ATOMIC);
 				    GFP_ATOMIC);
 }
 }

+ 2 - 0
drivers/net/wimax/i2400m/fw.c

@@ -985,6 +985,7 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
 	d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
 	d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
 		  i2400m, bcf, bcf_size);
 		  i2400m, bcf, bcf_size);
 	i2400m->boot_mode = 1;
 	i2400m->boot_mode = 1;
+	wmb();		/* Make sure other readers see it */
 hw_reboot:
 hw_reboot:
 	if (count-- == 0) {
 	if (count-- == 0) {
 		ret = -ERESTARTSYS;
 		ret = -ERESTARTSYS;
@@ -1033,6 +1034,7 @@ hw_reboot:
 	d_printf(2, dev, "fw %s successfully uploaded\n",
 	d_printf(2, dev, "fw %s successfully uploaded\n",
 		 i2400m->fw_name);
 		 i2400m->fw_name);
 	i2400m->boot_mode = 0;
 	i2400m->boot_mode = 0;
+	wmb();		/* Make sure i2400m_msg_to_dev() sees boot_mode */
 error_dnload_finalize:
 error_dnload_finalize:
 error_dnload_bcf:
 error_dnload_bcf:
 error_dnload_init:
 error_dnload_init: