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 aec4146757da..9097b3b30385 100644
--- a/drivers/uwb/i1480/dfu/dfu.c
+++ b/drivers/uwb/i1480/dfu/dfu.c
@@ -37,29 +37,45 @@
37#define D_LOCAL 0 37#define D_LOCAL 0
38#include <linux/uwb/debug.h> 38#include <linux/uwb/debug.h>
39 39
40/** @return 0 if If @evt is a valid reply event; otherwise complain */ 40/**
41 * i1480_rceb_check - Check RCEB for expected field values
42 * @i1480: pointer to device for which RCEB is being checked
43 * @rceb: RCEB being checked
44 * @cmd: which command the RCEB is related to
45 * @context: expected context
46 * @expected_type: expected event type
47 * @expected_event: expected event
48 *
49 * If @cmd is NULL, do not print error messages, but still return an error
50 * code.
51 *
52 * Return 0 if @rceb matches the expected values, -EINVAL otherwise.
53 */
41int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb, 54int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb,
42 const char *cmd, u8 context, 55 const char *cmd, u8 context, u8 expected_type,
43 unsigned expected_type, unsigned expected_event) 56 unsigned expected_event)
44{ 57{
45 int result = 0; 58 int result = 0;
46 struct device *dev = i1480->dev; 59 struct device *dev = i1480->dev;
47 if (rceb->bEventContext != context) { 60 if (rceb->bEventContext != context) {
48 dev_err(dev, "%s: " 61 if (cmd)
49 "unexpected context id 0x%02x (expected 0x%02x)\n", 62 dev_err(dev, "%s: unexpected context id 0x%02x "
50 cmd, rceb->bEventContext, context); 63 "(expected 0x%02x)\n", cmd,
64 rceb->bEventContext, context);
51 result = -EINVAL; 65 result = -EINVAL;
52 } 66 }
53 if (rceb->bEventType != expected_type) { 67 if (rceb->bEventType != expected_type) {
54 dev_err(dev, "%s: " 68 if (cmd)
55 "unexpected event type 0x%02x (expected 0x%02x)\n", 69 dev_err(dev, "%s: unexpected event type 0x%02x "
56 cmd, rceb->bEventType, expected_type); 70 "(expected 0x%02x)\n", cmd,
71 rceb->bEventType, expected_type);
57 result = -EINVAL; 72 result = -EINVAL;
58 } 73 }
59 if (le16_to_cpu(rceb->wEvent) != expected_event) { 74 if (le16_to_cpu(rceb->wEvent) != expected_event) {
60 dev_err(dev, "%s: " 75 if (cmd)
61 "unexpected event 0x%04x (expected 0x%04x)\n", 76 dev_err(dev, "%s: unexpected event 0x%04x "
62 cmd, le16_to_cpu(rceb->wEvent), expected_event); 77 "(expected 0x%04x)\n", cmd,
78 le16_to_cpu(rceb->wEvent), expected_event);
63 result = -EINVAL; 79 result = -EINVAL;
64 } 80 }
65 return result; 81 return result;
@@ -110,6 +126,20 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size,
110 cmd_name, result); 126 cmd_name, result);
111 goto error; 127 goto error;
112 } 128 }
129 /*
130 * Firmware versions >= 1.4.12224 for IOGear GUWA100U generate a
131 * spurious notification after firmware is downloaded. So check whether
132 * the receibed RCEB is such notification before assuming that the
133 * command has failed.
134 */
135 if (i1480_rceb_check(i1480, i1480->evt_buf, NULL,
136 0, 0xfd, 0x0022) == 0) {
137 /* Now wait for the actual RCEB for this command. */
138 result = i1480->wait_init_done(i1480);
139 if (result < 0)
140 goto error;
141 result = i1480->evt_result;
142 }
113 if (result != reply_size) { 143 if (result != reply_size) {
114 dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n", 144 dev_err(i1480->dev, "%s returned only %zu bytes, %zu expected\n",
115 cmd_name, result, reply_size); 145 cmd_name, result, reply_size);
diff --git a/drivers/uwb/i1480/dfu/i1480-dfu.h b/drivers/uwb/i1480/dfu/i1480-dfu.h
index 8035418de132..46f45e800f36 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 *);
145extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t); 145extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t);
146extern int i1480_rceb_check(const struct i1480 *, 146extern int i1480_rceb_check(const struct i1480 *,
147 const struct uwb_rceb *, const char *, u8, 147 const struct uwb_rceb *, const char *, u8,
148 unsigned, unsigned); 148 u8, unsigned);
149 149
150enum { 150enum {
151 /* Vendor specific command type */ 151 /* Vendor specific command type */
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c
index 3d445541e8e9..8d069907a3b5 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)
507 goto error_size; 507 goto error_size;
508 } 508 }
509 result = -EIO; 509 result = -EIO;
510 if (rcebe->rceb.bEventType != i1480_CET_VS1 510 if (i1480_rceb_check(i1480, &rcebe->rceb, NULL, 0, i1480_CET_VS1,
511 || le16_to_cpu(rcebe->rceb.wEvent) != i1480_EVT_RM_INIT_DONE) { 511 i1480_EVT_RM_INIT_DONE) < 0) {
512 dev_err(i1480->dev, "wrong initialization event 0x%02x/%04x/%02x " 512 dev_err(i1480->dev, "wrong initialization event 0x%02x/%04x/%02x "
513 "received; expected 0x%02x/%04x/00\n", 513 "received; expected 0x%02x/%04x/00\n",
514 rcebe->rceb.bEventType, le16_to_cpu(rcebe->rceb.wEvent), 514 rcebe->rceb.bEventType, le16_to_cpu(rcebe->rceb.wEvent),