diff options
author | Cindy H Kao <cindy.h.kao@intel.com> | 2010-04-07 22:42:42 -0400 |
---|---|---|
committer | Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 2010-05-11 17:05:30 -0400 |
commit | f4e413458104210bc29aa5c437882c68b4b20100 (patch) | |
tree | 72508e9a5d3620986120304db7fe78f0326b0743 /drivers/net/wimax/i2400m/i2400m.h | |
parent | 49d72df3f6cd63b49528306a2577ae7a6a0e9d6b (diff) |
wimax/i2400m: fix for missed reset events if triggered by dev_reset_handle()
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>
Diffstat (limited to 'drivers/net/wimax/i2400m/i2400m.h')
-rw-r--r-- | drivers/net/wimax/i2400m/i2400m.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index da218b98e27f..ad8e6a3be1e3 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h | |||
@@ -177,6 +177,11 @@ enum { | |||
177 | I2400M_BM_ACK_BUF_SIZE = 256, | 177 | I2400M_BM_ACK_BUF_SIZE = 256, |
178 | }; | 178 | }; |
179 | 179 | ||
180 | enum { | ||
181 | /* Maximum number of bus reset can be retried */ | ||
182 | I2400M_BUS_RESET_RETRIES = 3, | ||
183 | }; | ||
184 | |||
180 | /** | 185 | /** |
181 | * struct i2400m_poke_table - Hardware poke table for the Intel 2400m | 186 | * struct i2400m_poke_table - Hardware poke table for the Intel 2400m |
182 | * | 187 | * |
@@ -517,6 +522,29 @@ struct i2400m_barker_db; | |||
517 | * same. | 522 | * same. |
518 | * | 523 | * |
519 | * @pm_notifier: used to register for PM events | 524 | * @pm_notifier: used to register for PM events |
525 | * | ||
526 | * @bus_reset_retries: counter for the number of bus resets attempted for | ||
527 | * this boot. It's not for tracking the number of bus resets during | ||
528 | * the whole driver life cycle (from insmod to rmmod) but for the | ||
529 | * number of dev_start() executed until dev_start() returns a success | ||
530 | * (ie: a good boot means a dev_stop() followed by a successful | ||
531 | * dev_start()). dev_reset_handler() increments this counter whenever | ||
532 | * it is triggering a bus reset. It checks this counter to decide if a | ||
533 | * subsequent bus reset should be retried. dev_reset_handler() retries | ||
534 | * the bus reset until dev_start() succeeds or the counter reaches | ||
535 | * I2400M_BUS_RESET_RETRIES. The counter is cleared to 0 in | ||
536 | * dev_reset_handle() when dev_start() returns a success, | ||
537 | * ie: a successul boot is completed. | ||
538 | * | ||
539 | * @alive: flag to denote if the device *should* be alive. This flag is | ||
540 | * everything like @updown (see doc for @updown) except reflecting | ||
541 | * the device state *we expect* rather than the actual state as denoted | ||
542 | * by @updown. It is set 1 whenever @updown is set 1 in dev_start(). | ||
543 | * Then the device is expected to be alive all the time | ||
544 | * (i2400m->alive remains 1) until the driver is removed. Therefore | ||
545 | * all the device reboot events detected can be still handled properly | ||
546 | * by either dev_reset_handle() or .pre_reset/.post_reset as long as | ||
547 | * the driver presents. It is set 0 along with @updown in dev_stop(). | ||
520 | */ | 548 | */ |
521 | struct i2400m { | 549 | struct i2400m { |
522 | struct wimax_dev wimax_dev; /* FIRST! See doc */ | 550 | struct wimax_dev wimax_dev; /* FIRST! See doc */ |
@@ -591,6 +619,12 @@ struct i2400m { | |||
591 | struct i2400m_barker_db *barker; | 619 | struct i2400m_barker_db *barker; |
592 | 620 | ||
593 | struct notifier_block pm_notifier; | 621 | struct notifier_block pm_notifier; |
622 | |||
623 | /* counting bus reset retries in this boot */ | ||
624 | atomic_t bus_reset_retries; | ||
625 | |||
626 | /* if the device is expected to be alive */ | ||
627 | unsigned alive; | ||
594 | }; | 628 | }; |
595 | 629 | ||
596 | 630 | ||