greybus: fw-download: Introduce timeouts for firmware downloads
authorViresh Kumar <viresh.kumar@linaro.org>
Thu, 5 May 2016 10:03:20 +0000 (15:33 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 May 2016 20:52:06 +0000 (13:52 -0700)
commit69c8763eb883a331832b58e842fa0b01321ed9d6
treeea00c5bed96be250fa8b44c00c0c1a58bc4b81d1
parentf63a896e532b12f9104749b13861080981b64bad
greybus: fw-download: Introduce timeouts for firmware downloads

As per greybus specification, the AP can apply, implementation
dependent, timeouts for:

- The time interval between the Find Firmware Response and the first
  Fetch Firmware Request.
- The time interval between a Fetch Firmware Response and the next Fetch
  Firmware Request.
- The time interval between a Fetch Firmware Response and the Release
  Firmware Request.
- The time interval between the Find Firmware Response and the Release
  Firmware Request.

This patch implements those timeouts.

The timeout period for the first three cases is fixed to one-second and
the timeout for the last one is finalized at runtime, dependent on the
total size of the firmware.

There can be two possible paths now, which may race for freeing or
getting the 'struct fw_request'. They are:
- Request handler: initiated from the Module side.
- Timeout handler: initiated on timeout of the programmed timer.

And so a mutex is added to avoid races.

Every caller which needs to access the 'struct fw_request' increments
the reference count, so that the structure doesn't get freed in
parallel. Once the structure is freed and reference is put by all the
users, the structure is freed.

If we timeout while waiting for a request from the Module, the AP frees
the 'struct fw_request', but does *not* free the request-id. This is
done to guarantee that a delayed request from the Module for the expired
id, doesn't get access to a new 'struct fw_request' allocated later with
the same id.

Tested with gbsim by hacking its code to delay the release request and
indefinitely fetch the same section of the firmware package. Both timed
out on the AP side and the 'struct fw_request' is free properly. Further
requests work fine after few are timed out. And rmmod (followed by more
similar testing) works just fine.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/fw-download.c