Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171233
b: refs/heads/master
c: b9ee950
h: refs/heads/master
i:
  171231: 8b7418b
v: v3
  • Loading branch information
Inaky Perez-Gonzalez committed Oct 19, 2009
1 parent 64eeec0 commit c073944
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5eeae35b9a2e304fc4ae3d9eed63afeea23b482c
refs/heads/master: b9ee95010bee6c0e17d18bc9d9c0cfab6e8cb73a
10 changes: 7 additions & 3 deletions trunk/drivers/net/wimax/i2400m/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,16 +765,20 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
wmb(); /* see i2400m->updown's documentation */
dev_err(dev, "%s: cannot start the device: %d\n",
reason, result);
result = i2400m->bus_reset(i2400m, I2400M_RT_BUS);
if (result >= 0)
result = -ENODEV;
result = -EUCLEAN;
}
out_unlock:
if (i2400m->reset_ctx) {
ctx->result = result;
complete(&ctx->completion);
}
mutex_unlock(&i2400m->init_mutex);
if (result == -EUCLEAN) {
/* ops, need to clean up [w/ init_mutex not held] */
result = i2400m->bus_reset(i2400m, I2400M_RT_BUS);
if (result >= 0)
result = -ENODEV;
}
out:
i2400m_put(i2400m);
kfree(iw);
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/wimax/i2400m/i2400m.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ struct i2400m_barker_db;
* process, so it cannot rely on common infrastructure being laid
* out.
*
* IMPORTANT: don't call reset on RT_BUS with i2400m->init_mutex
* held, as the .pre/.post reset handlers will deadlock.
*
* @bus_bm_retries: [fill] How many times shall a firmware upload /
* device initialization be retried? Different models of the same
* device might need different values, hence it is set by the
Expand Down
14 changes: 10 additions & 4 deletions trunk/drivers/net/wimax/i2400m/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,15 +254,14 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
sizeof(i2400m_COLD_BOOT_BARKER),
i2400mu->endpoint_cfg.reset_cold);
else if (rt == I2400M_RT_BUS) {
do_bus_reset:
result = usb_reset_device(i2400mu->usb_dev);
switch (result) {
case 0:
case -EINVAL: /* device is gone */
case -ENODEV:
case -ENOENT:
case -ESHUTDOWN:
result = rt == I2400M_RT_WARM ? -ENODEV : 0;
result = 0;
break; /* We assume the device is disconnected */
default:
dev_err(dev, "USB reset failed (%d), giving up!\n",
Expand All @@ -275,10 +274,17 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
if (result < 0
&& result != -EINVAL /* device is gone */
&& rt != I2400M_RT_BUS) {
/*
* Things failed -- resort to lower level reset, that
* we queue in another context; the reason for this is
* that the pre and post reset functionality requires
* the i2400m->init_mutex; RT_WARM and RT_COLD can
* come from areas where i2400m->init_mutex is taken.
*/
dev_err(dev, "%s reset failed (%d); trying USB reset\n",
rt == I2400M_RT_WARM ? "warm" : "cold", result);
rt = I2400M_RT_BUS;
goto do_bus_reset;
usb_queue_reset_device(i2400mu->usb_iface);
result = -ENODEV;
}
d_fnend(3, dev, "(i2400m %p rt %u) = %d\n", i2400m, rt, result);
return result;
Expand Down

0 comments on commit c073944

Please sign in to comment.