usbdebug: Dump low-level protocol details
Dumping these EHCI host controller registers is useful to solve problems with debug devices. Change-Id: I0610cecca57b1b952d4f87211dd00c8c0bc398b9 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: http://review.coreboot.org/3866 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@google.com>
This commit is contained in:
parent
5c87d2f17e
commit
e53cece07b
|
@ -63,10 +63,12 @@ struct ehci_debug_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_DEBUG_USBDEBUG
|
#if CONFIG_DEBUG_USBDEBUG
|
||||||
|
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug);
|
||||||
static int dbgp_enabled(void);
|
static int dbgp_enabled(void);
|
||||||
# define dprintk(LEVEL, args...) \
|
# define dprintk(LEVEL, args...) \
|
||||||
do { if (!dbgp_enabled()) printk(LEVEL, ##args); } while (0)
|
do { if (!dbgp_enabled()) printk(LEVEL, ##args); } while (0)
|
||||||
#else
|
#else
|
||||||
|
# define dbgp_print_data(x) do {} while(0)
|
||||||
# define dprintk(LEVEL, args...) do {} while(0)
|
# define dprintk(LEVEL, args...) do {} while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -136,8 +138,10 @@ static int dbgp_wait_until_complete(struct ehci_dbg_port *ehci_debug)
|
||||||
break;
|
break;
|
||||||
} while (++loop < DBGP_MICROFRAME_TIMEOUT_LOOPS);
|
} while (++loop < DBGP_MICROFRAME_TIMEOUT_LOOPS);
|
||||||
|
|
||||||
if (! (ctrl & DBGP_DONE))
|
if (! (ctrl & DBGP_DONE)) {
|
||||||
|
dprintk(BIOS_ERR, "dbgp_wait_until_complete: retry timeout.\n");
|
||||||
return -DBGP_ERR_SIGNAL;
|
return -DBGP_ERR_SIGNAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now that we have observed the completed transaction,
|
/* Now that we have observed the completed transaction,
|
||||||
* clear the done bit.
|
* clear the done bit.
|
||||||
|
@ -155,6 +159,7 @@ static int dbgp_wait_until_done(struct ehci_dbg_port *ehci_debug, struct dbgp_pi
|
||||||
unsigned ctrl, const int timeout)
|
unsigned ctrl, const int timeout)
|
||||||
{
|
{
|
||||||
u32 rd_ctrl, rd_pids;
|
u32 rd_ctrl, rd_pids;
|
||||||
|
u32 ctrl_prev = 0, pids_prev = 0;
|
||||||
u8 lpid;
|
u8 lpid;
|
||||||
int ret, host_retries;
|
int ret, host_retries;
|
||||||
int loop;
|
int loop;
|
||||||
|
@ -168,11 +173,21 @@ device_retry:
|
||||||
host_retry:
|
host_retry:
|
||||||
if (host_retries++ >= DBGP_MICROFRAME_RETRIES)
|
if (host_retries++ >= DBGP_MICROFRAME_RETRIES)
|
||||||
return -DBGP_ERR_BAD;
|
return -DBGP_ERR_BAD;
|
||||||
|
if (loop == 1 || host_retries > 1)
|
||||||
|
dprintk(BIOS_SPEW, "dbgp: start (@ %3d,%d) ctrl=%08x\n",
|
||||||
|
loop, host_retries, ctrl | DBGP_GO);
|
||||||
write32((unsigned long)&ehci_debug->control, ctrl | DBGP_GO);
|
write32((unsigned long)&ehci_debug->control, ctrl | DBGP_GO);
|
||||||
ret = dbgp_wait_until_complete(ehci_debug);
|
ret = dbgp_wait_until_complete(ehci_debug);
|
||||||
rd_ctrl = read32((unsigned long)&ehci_debug->control);
|
rd_ctrl = read32((unsigned long)&ehci_debug->control);
|
||||||
rd_pids = read32((unsigned long)&ehci_debug->pids);
|
rd_pids = read32((unsigned long)&ehci_debug->pids);
|
||||||
|
|
||||||
|
if (rd_ctrl != ctrl_prev || rd_pids != pids_prev || (ret<0)) {
|
||||||
|
ctrl_prev = rd_ctrl;
|
||||||
|
pids_prev = rd_pids;
|
||||||
|
dprintk(BIOS_SPEW, "dbgp: status (@ %3d,%d) ctrl=%08x pids=%08x ret=%d\n",
|
||||||
|
loop, host_retries, rd_ctrl, rd_pids, ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* Controller hardware failure. */
|
/* Controller hardware failure. */
|
||||||
if (ret == -DBGP_ERR_SIGNAL) {
|
if (ret == -DBGP_ERR_SIGNAL) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -208,6 +223,8 @@ host_retry:
|
||||||
ret = -DBGP_ERR_BAD;
|
ret = -DBGP_ERR_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbgp_print_data(ehci_debug);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +257,25 @@ static void dbgp_get_data(struct ehci_dbg_port *ehci_debug, void *buf, int size)
|
||||||
bytes[i] = (hi >> (8*(i - 4))) & 0xff;
|
bytes[i] = (hi >> (8*(i - 4))) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_DEBUG_USBDEBUG
|
||||||
|
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug)
|
||||||
|
{
|
||||||
|
u32 ctrl = read32((unsigned long)&ehci_debug->control);
|
||||||
|
u32 lo = read32((unsigned long)&ehci_debug->data03);
|
||||||
|
u32 hi = read32((unsigned long)&ehci_debug->data47);
|
||||||
|
int len = DBGP_LEN(ctrl);
|
||||||
|
if (len) {
|
||||||
|
int i;
|
||||||
|
dprintk(BIOS_SPEW, "dbgp: buf:");
|
||||||
|
for (i = 0; i < 4 && i < len; i++)
|
||||||
|
dprintk(BIOS_SPEW, " %02x", (lo >> (8*i)) & 0xff);
|
||||||
|
for (; i < 8 && i < len; i++)
|
||||||
|
dprintk(BIOS_SPEW, " %02x", (hi >> (8*(i - 4))) & 0xff);
|
||||||
|
dprintk(BIOS_SPEW, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
|
static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
|
||||||
const char *bytes, int size)
|
const char *bytes, int size)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue