diff options
Diffstat (limited to 'drivers/uwb/i1480/dfu/dfu.c')
-rw-r--r-- | drivers/uwb/i1480/dfu/dfu.c | 54 |
1 files changed, 42 insertions, 12 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 | */ | ||
41 | int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb, | 54 | int 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); |