diff options
-rw-r--r-- | drivers/uwb/i1480/dfu/dfu.c | 54 | ||||
-rw-r--r-- | drivers/uwb/i1480/dfu/i1480-dfu.h | 2 | ||||
-rw-r--r-- | drivers/uwb/i1480/dfu/mac.c | 4 |
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 | */ | ||
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); |
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 *); | |||
145 | extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t); | 145 | extern ssize_t i1480_cmd(struct i1480 *, const char *, size_t, size_t); |
146 | extern int i1480_rceb_check(const struct i1480 *, | 146 | extern 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 | ||
150 | enum { | 150 | enum { |
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), |