usbdebug: Split endpoint buffers

Refactor the structure to better support receive and another
set of endpoints over usbdebug.

Change-Id: Ib0f76afdf4e638363ff30c67010920142c58f250
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/3726
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@google.com>
This commit is contained in:
Kyösti Mälkki 2013-07-08 18:11:44 +03:00
parent dcea700762
commit 026ff3e436
2 changed files with 72 additions and 54 deletions

View File

@ -40,31 +40,18 @@ void pci_ehci_read_resources(struct device *dev);
#endif #endif
#endif #endif
struct ehci_debug_info { struct dbgp_pipe;
void *ehci_caps;
void *ehci_regs;
void *ehci_debug;
u32 devnum;
u32 endpoint_out;
u32 endpoint_in;
char buf[8];
u8 bufidx;
u8 status;
};
#define DBGP_EP_VALID (1<<0)
#define DBGP_EP_ENABLED (1<<1)
#define DBGP_EP_STATMASK (DBGP_EP_VALID | DBGP_EP_ENABLED)
void enable_usbdebug(unsigned int port); void enable_usbdebug(unsigned int port);
int dbgp_bulk_write_x(struct ehci_debug_info *dbg_info, const char *bytes, int size);
int dbgp_bulk_read_x(struct ehci_debug_info *dbg_info, void *data, int size);
void set_debug_port(unsigned port); void set_debug_port(unsigned port);
int usbdebug_init(void); int usbdebug_init(void);
struct ehci_debug_info *dbgp_console_output(void);
struct ehci_debug_info *dbgp_console_input(void); struct dbgp_pipe *dbgp_console_output(void);
int dbgp_ep_is_active(struct ehci_debug_info *dbg_info); struct dbgp_pipe *dbgp_console_input(void);
void usbdebug_tx_byte(struct ehci_debug_info *info, unsigned char data); int dbgp_ep_is_active(struct dbgp_pipe *pipe);
void usbdebug_tx_flush(struct ehci_debug_info *info); int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size);
int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size);
void usbdebug_tx_byte(struct dbgp_pipe *pipe, unsigned char data);
void usbdebug_tx_flush(struct dbgp_pipe *pipe);
#endif #endif

View File

@ -29,6 +29,33 @@
#include <ehci.h> #include <ehci.h>
#include <usbdebug.h> #include <usbdebug.h>
#define DBGP_EP_VALID (1<<0)
#define DBGP_EP_ENABLED (1<<1)
#define DBGP_EP_STATMASK (DBGP_EP_VALID | DBGP_EP_ENABLED)
struct dbgp_pipe
{
u8 endpoint;
u8 status;
u8 bufidx;
char buf[8];
};
#define DBGP_MAX_ENDPOINTS 4
#define DBGP_CONSOLE_EPOUT 0
#define DBGP_CONSOLE_EPIN 1
struct ehci_debug_info {
u8 devnum;
void *ehci_caps;
void *ehci_regs;
void *ehci_debug;
struct dbgp_pipe ep_pipe[DBGP_MAX_ENDPOINTS];
};
/* Set this to 1 to debug the start-up of EHCI debug port hardware. You need /* Set this to 1 to debug the start-up of EHCI debug port hardware. You need
* to modify console_init() to initialise some other console before usbdebug * to modify console_init() to initialise some other console before usbdebug
* to receive the printk lines from here. * to receive the printk lines from here.
@ -215,10 +242,11 @@ static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug,
return ret; return ret;
} }
int dbgp_bulk_write_x(struct ehci_debug_info *dbg_info, const char *bytes, int size) int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size)
{ {
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
return dbgp_bulk_write(dbg_info->ehci_debug, dbg_info->devnum, return dbgp_bulk_write(dbg_info->ehci_debug, dbg_info->devnum,
dbg_info->endpoint_out, bytes, size); pipe->endpoint, bytes, size);
} }
static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, unsigned devnum, static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, unsigned devnum,
@ -252,10 +280,11 @@ static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, unsigned devnum,
return ret; return ret;
} }
int dbgp_bulk_read_x(struct ehci_debug_info *dbg_info, void *data, int size) int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size)
{ {
struct ehci_debug_info *dbg_info = dbgp_ehci_info();
return dbgp_bulk_read(dbg_info->ehci_debug, dbg_info->devnum, return dbgp_bulk_read(dbg_info->ehci_debug, dbg_info->devnum,
dbg_info->endpoint_in, data, size, DBGP_LOOPS); pipe->endpoint, data, size, DBGP_LOOPS);
} }
static void dbgp_mdelay(int ms) static void dbgp_mdelay(int ms)
@ -379,8 +408,6 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_
struct ehci_caps *ehci_caps; struct ehci_caps *ehci_caps;
struct ehci_regs *ehci_regs; struct ehci_regs *ehci_regs;
struct ehci_dbg_port *ehci_debug; struct ehci_dbg_port *ehci_debug;
unsigned dbgp_endpoint_out;
unsigned dbgp_endpoint_in;
struct usb_debug_descriptor dbgp_desc; struct usb_debug_descriptor dbgp_desc;
u32 cmd, ctrl, status, portsc, hcs_params; u32 cmd, ctrl, status, portsc, hcs_params;
@ -396,8 +423,8 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_
HC_LENGTH(read32((unsigned long)&ehci_caps->hc_capbase))); HC_LENGTH(read32((unsigned long)&ehci_caps->hc_capbase)));
ehci_debug = (struct ehci_dbg_port *)(ehci_bar + offset); ehci_debug = (struct ehci_dbg_port *)(ehci_bar + offset);
info->ehci_debug = (void *)0; info->ehci_debug = (void *)0;
info->bufidx = 0;
info->status = 0; memset(&info->ep_pipe, 0, sizeof (info->ep_pipe));
try_next_time: try_next_time:
port_map_tried = 0; port_map_tried = 0;
@ -516,8 +543,6 @@ try_next_port:
ret = -6; ret = -6;
goto err; goto err;
} }
dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint;
/* Move the device to 127 if it isn't already there */ /* Move the device to 127 if it isn't already there */
if (devnum != USB_DEBUG_DEVNUM) { if (devnum != USB_DEBUG_DEVNUM) {
@ -546,7 +571,7 @@ try_next_port:
dbgp_printk("EHCI debug interface enabled.\n"); dbgp_printk("EHCI debug interface enabled.\n");
/* Perform a small write to get the even/odd data state in sync */ /* Perform a small write to get the even/odd data state in sync */
ret = dbgp_bulk_write(ehci_debug, USB_DEBUG_DEVNUM, dbgp_endpoint_out, "USB\r\n",5); ret = dbgp_bulk_write(ehci_debug, USB_DEBUG_DEVNUM, dbgp_desc.bDebugOutEndpoint, "USB\r\n",5);
if (ret < 0) { if (ret < 0) {
dbgp_printk("dbgp_bulk_write failed: %d\n", ret); dbgp_printk("dbgp_bulk_write failed: %d\n", ret);
ret = -9; ret = -9;
@ -558,10 +583,11 @@ try_next_port:
info->ehci_regs = ehci_regs; info->ehci_regs = ehci_regs;
info->ehci_debug = ehci_debug; info->ehci_debug = ehci_debug;
info->devnum = devnum; info->devnum = devnum;
info->endpoint_out = dbgp_endpoint_out;
info->endpoint_in = dbgp_endpoint_in;
info->status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
info->ep_pipe[DBGP_CONSOLE_EPOUT].endpoint = dbgp_desc.bDebugOutEndpoint;
info->ep_pipe[DBGP_CONSOLE_EPIN].endpoint = dbgp_desc.bDebugInEndpoint;
info->ep_pipe[DBGP_CONSOLE_EPOUT].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
info->ep_pipe[DBGP_CONSOLE_EPIN].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
return 0; return 0;
err: err:
/* Things didn't work so remove my claim */ /* Things didn't work so remove my claim */
@ -586,22 +612,22 @@ next_debug_port:
return -10; return -10;
} }
void usbdebug_tx_byte(struct ehci_debug_info *dbg_info, unsigned char data) void usbdebug_tx_byte(struct dbgp_pipe *pipe, unsigned char data)
{ {
if (dbgp_is_ep_active(dbg_info)) { if (dbgp_ep_is_active(pipe)) {
dbg_info->buf[dbg_info->bufidx++] = data; pipe->buf[pipe->bufidx++] = data;
if (dbg_info->bufidx >= 8) { if (pipe->bufidx >= 8) {
dbgp_bulk_write_x(dbg_info, dbg_info->buf, dbg_info->bufidx); dbgp_bulk_write_x(pipe, pipe->buf, pipe->bufidx);
dbg_info->bufidx = 0; pipe->bufidx = 0;
} }
} }
} }
void usbdebug_tx_flush(struct ehci_debug_info *dbg_info) void usbdebug_tx_flush(struct dbgp_pipe *pipe)
{ {
if (dbgp_is_ep_active(dbg_info) && dbg_info->bufidx > 0) { if (dbgp_ep_is_active(pipe) && pipe->bufidx > 0) {
dbgp_bulk_write_x(dbg_info, dbg_info->buf, dbg_info->bufidx); dbgp_bulk_write_x(pipe, pipe->buf, pipe->bufidx);
dbg_info->bufidx = 0; pipe->bufidx = 0;
} }
} }
@ -610,6 +636,7 @@ static void usbdebug_re_enable(unsigned ehci_base)
{ {
struct ehci_debug_info *dbg_info = dbgp_ehci_info(); struct ehci_debug_info *dbg_info = dbgp_ehci_info();
unsigned diff; unsigned diff;
int i;
if (!dbg_info->ehci_debug) if (!dbg_info->ehci_debug)
return; return;
@ -618,13 +645,17 @@ static void usbdebug_re_enable(unsigned ehci_base)
dbg_info->ehci_regs -= diff; dbg_info->ehci_regs -= diff;
dbg_info->ehci_debug -= diff; dbg_info->ehci_debug -= diff;
dbg_info->ehci_caps = (void*)ehci_base; dbg_info->ehci_caps = (void*)ehci_base;
dbg_info->status |= DBGP_EP_ENABLED;
for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
dbg_info->ep_pipe[i].status |= DBGP_EP_ENABLED;
} }
static void usbdebug_disable(void) static void usbdebug_disable(void)
{ {
struct ehci_debug_info *dbg_info = dbgp_ehci_info(); struct ehci_debug_info *dbg_info = dbgp_ehci_info();
dbg_info->status &= ~DBGP_EP_ENABLED; int i;
for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
dbg_info->ep_pipe[i].status &= ~DBGP_EP_ENABLED;
} }
static void pci_ehci_set_resources(struct device *dev) static void pci_ehci_set_resources(struct device *dev)
@ -661,19 +692,19 @@ void pci_ehci_read_resources(struct device *dev)
} }
#endif #endif
int dbgp_ep_is_active(struct ehci_debug_info *dbg_info) int dbgp_ep_is_active(struct dbgp_pipe *pipe)
{ {
return (dbg_info->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED); return (pipe->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);
} }
struct ehci_debug_info *dbgp_console_input(void) struct dbgp_pipe *dbgp_console_output(void)
{ {
return dbgp_ehci_info(); return &dbgp_ehci_info()->ep_pipe[DBGP_CONSOLE_EPOUT];
} }
struct ehci_debug_info *dbgp_console_input(void) struct dbgp_pipe *dbgp_console_input(void)
{ {
return dbgp_ehci_info(); return &dbgp_ehci_info()->ep_pipe[DBGP_CONSOLE_EPIN];
} }
int usbdebug_init(void) int usbdebug_init(void)