aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAnderson Lizardo <anderson.lizardo@indt.org.br>2008-09-17 11:34:38 -0400
committerDavid Vrabel <dv02@dv02pc01.europe.root.pri>2008-09-17 11:54:34 -0400
commitb5784f10d559b3c7b25874b21702ad0907b6fcb7 (patch)
treec3e678d182a8c928cbb3660895458ed98e6c9b03 /drivers
parent8c7e8cb85557cc500122f3e489936582b7d11a7c (diff)
uwb: i1480/GUWA100U: fix firmware download issues
IOGear firmware versions >= 1.4.12224 fail to be downloaded because of a spurious (and harmless) RCEB received after the download notification. This patch handles this RCEB and keeps compatibility with future versions that might not emit this RCEB. i1480_rceb_check() is reused to check for the RCEB. It is also refactored with improved comments and reused in another place in mac.c where the checking was being duplicated. This patch was tested on both i1480 and GUWA100U HWAs, with all firmware versions currently available. Signed-off-by: Anderson Lizardo <anderson.lizardo@indt.org.br>
Diffstat (limited to 'drivers')
-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),