f4e4134581
The problem is only seen on SDIO interface since on USB, a bus reset would really re-probe the driver, but on SDIO interface, a bus reset will not re-enumerate the SDIO bus, so no driver re-probe is happening. Therefore, on SDIO interface, the reset event should be still detected and handled by dev_reset_handle(). Problem description: Whenever a reboot barker is received during operational mode (i2400m->boot_mode == 0), dev_reset_handle() is invoked to handle that function reset event. dev_reset_handle() then sets the flag i2400m->boot_mode to 1 indicating the device is back to bootmode before proceeding to dev_stop() and dev_start(). If dev_start() returns failure, a bus reset is triggered by dev_reset_handle(). The flag i2400m->boot_mode then remains 1 when the second reboot barker arrives. However the interrupt service routine i2400ms_rx() instead of invoking dev_reset_handle() to handle that reset event, it filters out that boot event to bootmode because it sees the flag i2400m->boot_mode equal to 1. The fix: Maintain the flag i2400m->boot_mode within dev_reset_handle() and set the flag i2400m->boot_mode to 1 when entering dev_reset_handle(). It remains 1 until the dev_reset_handle() issues a bus reset. ie: the bus reset is taking place just like it happens for the first time during operational mode. To denote the actual device state and the state we expect, a flag i2400m->alive is introduced in addition to the existing flag i2400m->updown. It's maintained with the same way for i2400m->updown but instead of reflecting the actual state like i2400m->updown does, i2400m->alive maintains the state we expect. i2400m->alive is set 1 just like whenever i2400m->updown is set 1. Yet i2400m->alive remains 1 since we expect the device to be up all the time until the driver is removed. See the doc for @alive in i2400m.h. An enumeration I2400M_BUS_RESET_RETRIES is added to define the maximum number of bus resets that a device reboot can retry. A counter i2400m->bus_reset_retries is added to track how many bus resets have been retried in one device reboot. If I2400M_BUS_RESET_RETRIES bus resets were retried in this boot, we give up any further retrying so the device would enter low power state. The counter i2400m->bus_reset_retries is incremented whenever dev_reset_handle() is issuing a bus reset and is cleared to 0 when dev_start() is successfully done, ie: a successful reboot. Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com> |
||
---|---|---|
.. | ||
control.c | ||
debug-levels.h | ||
debugfs.c | ||
driver.c | ||
fw.c | ||
i2400m-sdio.h | ||
i2400m-usb.h | ||
i2400m.h | ||
Kconfig | ||
Makefile | ||
netdev.c | ||
op-rfkill.c | ||
rx.c | ||
sdio-debug-levels.h | ||
sdio-fw.c | ||
sdio-rx.c | ||
sdio-tx.c | ||
sdio.c | ||
sysfs.c | ||
tx.c | ||
usb-debug-levels.h | ||
usb-fw.c | ||
usb-notif.c | ||
usb-rx.c | ||
usb-tx.c | ||
usb.c |