aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/uwb/i1480/dfu/dfu.c54
-rw-r--r--drivers/uwb/i1480/dfu/i1480-dfu.h2
-rw-r--r--drivers/uwb/i1480/dfu/mac.c4
3 files changed, 45 insertions, 15 deletions
diff --git a/drivers/uwb/i1480/dfu/dfu.c b/drivers/uwb/i1480/dfu/dfu.c
index aec4146..9097b3b 100644
--- a/drivers/uwb/i1480/dfu/dfu.c
+++ b/drivers/uwb/i1480/dfu/dfu.c
@@ -37,29 +37,45 @@
#define D_LOCAL 0
#include <linux/uwb/debug.h>
-/** @return 0 if If @evt is a valid reply event; otherwise complain */
+/**
+ * i1480_rceb_check - Check RCEB for expected field values
+ * @i1480: pointer to device for which RCEB is being checked
+ * @rceb: RCEB being checked
+ * @cmd: which command the RCEB is related to
+ * @context: expected context
+ * @expected_type: expected event type
+ * @expected_event: expected event
+ *
+ * If @cmd is NULL, do not print error messages, but still return an error
+ * code.
+ *
+ * Return 0 if @rceb matches the expected values, -EINVAL otherwise.
+ */
int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb,
- const char *cmd, u8 context,
- unsigned expected_type, unsigned expected_event)
+ const char *cmd, u8 context, u8 expected_type,
+ unsigned expected_event)
{
int result = 0;
struct device *dev = i1480->dev;
if (rceb->bEventContext != context) {
- dev_err(dev, "%s: "
- "unexpected context id 0x%02x (expected 0x%02x)\n",
- cmd, rceb->bEventContext, context);
+ if (cmd)
+ dev_err(dev, "%s: unexpected context id 0x%02x "
+ "(expected 0x%02x)\n", cmd,
+ rceb->bEventContext, context);
result = -EINVAL;
}
if (rceb->bEventType != expected_type) {
- dev_err(dev, "%s: "
- "unexpected event type 0x%02x (expected 0x%02x)\n",
- cmd, rceb->bEventType, expected_type);
+ if (cmd)
+ dev_err(dev, "%s: unexpected event type 0x%02x "
+ "(expected 0x%02x)\n", cmd,
+ rceb->bEventType, expected_type);
result = -EINVAL;
}
if (le16_to_cpu(rceb->wEvent) != expected_event) {
- dev_err(dev, "%s: "
- "unexpected event 0x%04x (expected 0x%04x)\n",
- cmd, le16_to_cpu(rceb->wEvent), expected_event);
+ if (cmd)
+ dev_err(dev, "%s: unexpected event 0x%04x "
+ "(expected 0x%04x)\n", cmd,
+ le16_to_cpu(rceb->wEvent), expected_event);
result = -EINVAL;
}
return result;
@@ -110,6 +126,20 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
cmd_name, result);
goto error;
}
+ /*
+ * Firmware versions >= 1.4.12224 for IOGear GUWA100U generate a
+ * spurious notification after firmware is downloaded. So check whether
+ * the receibed RCEB is such notification before assuming that the
+ * command has failed.
+ */
+ if (i1480_rceb_check(i1480, i1480->evt_buf, NULL,
+ 0, 0xfd, 0x0022) == 0) {
+ /* Now wait for the actual RCEB for this command. */
+ result = i1480->wait_init_done(i1480);
+ if (result < 0)
+ goto error;
+ result = i1480->evt_result;
+ }
if (result != reply_size) {
dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n",
cmd_name, result, reply_size);
diff --git a/drivers/uwb/i1480/dfu/i1480-dfu.h b/drivers/uwb/i1480/dfu/i1480-dfu.h
index 8035418..46f45e8 100644
--- a/drivers/uwb/i1480/dfu/i1480-dfu.h
+++ b/drivers/uwb/i1480/dfu/i1480-dfu.h
@@ -145,7 +145,7 @@ extern int i1480_phy_fw_upload(struct i1480 *);
extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
extern int i1480_rceb_check(const struct i1480 *,
const struct uwb_rceb *, const char *, u8,
- unsigned, unsigned);
+ u8, unsigned);
enum {
/* Vendor specific command type */
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c
index 3d44554..8d06990 100644
--- a/drivers/uwb/i1480/dfu/mac.c
+++ b/drivers/uwb/i1480/dfu/mac.c
@@ -507,8 +507,8 @@ int i1480_mac_fw_upload(struct i1480 *i1480)
goto error_size;
}
result = -EIO;
- if (rcebe->rceb.bEventType != i1480_CET_VS1
- || le16_to_cpu(rcebe->rceb.wEvent) != i1480_EVT_RM_INIT_DONE) {
+ if (i1480_rceb_check(i1480, &rcebe->rceb, NULL, 0, i1480_CET_VS1,
+ i1480_EVT_RM_INIT_DONE) < 0) {
dev_err(i1480->dev, "wrong initialization event 0x%02x/%04x/%02x "
"received; expected 0x%02x/%04x/00\n",
rcebe->rceb.bEventType, le16_to_cpu(rcebe->rceb.wEvent),