summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@chromium.org>2019-04-18 17:49:18 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-27 03:44:52 +0000
commita1886cee8aa429b350246548fe1c719f54c1dc5c (patch)
tree1acbf9604b752b31d4394c2cbc1b89069873fcc5
parente0075d54e65cd1f3f9379a8ef9568734a383d033 (diff)
downloadchrome-ec-a1886cee8aa429b350246548fe1c719f54c1dc5c.tar.gz
g: set up USB TX in USB endpoint interrupt handler
USB TX used to be set up in a deferred function. This patch makes USB endpoint interrupt handler to setup USB TX to speed up sending data to host USB. It reduces Flash usage by 100 bytes, and RAM usage by 40 bytes. BUG=b:38448364 BRANCH=cr50, cr50-mp TEST=(1) Flashed EC FW on fleex (uut), atlas (npcx_int_spi), ampton (it83xx), bob (npcx_spi), coral (npcx_spi), and scarlet(stm32). (2) Flashed AP FW on fleex. (3) Ran firmware_Cr50DeviceState on Coral. (4) Uart Stress Tester on fleex. [ before applying this CL ] $ uart_stress_tester.sh --pty="/dev/ttyUSB2 /dev/ttyUSB1" --min_char 200000 ........................... ERROR : /dev/ttyUSB2: 1953 lost / 330330 : .5 % ERROR : /dev/ttyUSB1: 451 lost / 200655 : .2 % [ after applying this CL ] $ uart_stress_tester.sh --pty="/dev/ttyUSB2 /dev/ttyUSB1" --min_char 200000 ........................... INFO : /dev/ttyUSB2: 0 lost / 334425 : 0 % INFO : /dev/ttyUSB1: 0 lost / 200655 : 0 % Change-Id: Ic966486f034a199b601ca002f6ed76a73b2b9dd8 Signed-off-by: Namyoon Woo <namyoon@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1574661 Tested-by: Vadim Bendebury <vbendeb@chromium.org> Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--chip/g/usb-stream.c47
-rw-r--r--chip/g/usb-stream.h14
2 files changed, 36 insertions, 25 deletions
diff --git a/chip/g/usb-stream.c b/chip/g/usb-stream.c
index 8241eaf43c..7ab28c37a6 100644
--- a/chip/g/usb-stream.c
+++ b/chip/g/usb-stream.c
@@ -120,7 +120,7 @@ static inline int tx_fifo_is_ready(struct usb_stream_config const *config)
uint32_t status;
struct g_usb_desc *in_desc = config->in_desc;
- if (!(in_desc->flags & DOEPDMA_LAST))
+ if (!(in_desc->flags & DIEPDMA_LAST))
++in_desc;
status = in_desc->flags & DIEPDMA_BS_MASK;
@@ -133,12 +133,6 @@ void tx_stream_handler(struct usb_stream_config const *config)
size_t count;
struct queue const *tx_q = config->consumer.queue;
- if (!*config->is_reset)
- return;
-
- if (!tx_fifo_is_ready(config))
- return;
-
/* handle the completion of the previous transfer, if there was any. */
count = *(config->tx_handled);
if (count > 0) {
@@ -194,21 +188,30 @@ void tx_stream_handler(struct usb_stream_config const *config)
* descriptor as well if it is needed.
*/
usb_enable_tx(config, len);
+ } else {
+ /* USB TX transfer is not active. */
+ *config->tx_in_progress = 0;
}
}
/* Tx/IN interrupt handler */
void usb_stream_tx(struct usb_stream_config const *config)
{
- /* Wake up the Tx FIFO handler */
- hook_call_deferred(config->deferred_tx, 0);
-
- /* clear the Tx/IN interrupts */
+ /* Clear the Tx/IN interrupts */
GR_USB_DIEPINT(config->endpoint) = 0xffffffff;
+
+ /* Call the Tx FIFO handler */
+ tx_stream_handler(config);
}
void usb_stream_reset(struct usb_stream_config const *config)
{
+ /*
+ * Mark USB TX transfer is in progress, because it shall be so at
+ * the end of this function to flush any queued data.
+ */
+ *config->tx_in_progress = 1;
+
config->out_desc->flags = DOEPDMA_RXBYTES(config->rx_size) |
DOEPDMA_LAST | DOEPDMA_BS_HOST_RDY |
DOEPDMA_IOC;
@@ -235,10 +238,8 @@ void usb_stream_reset(struct usb_stream_config const *config)
GR_USB_DAINTMSK |= DAINT_INEP(config->endpoint) |
DAINT_OUTEP(config->endpoint);
- *config->is_reset = 1;
-
/* Flush any queued data */
- hook_call_deferred(config->deferred_tx, 0);
+ tx_stream_handler(config);
hook_call_deferred(config->deferred_rx, 0);
}
@@ -250,12 +251,28 @@ static void usb_read(struct producer const *producer, size_t count)
hook_call_deferred(config->deferred_rx, 0);
}
+/*
+ * NOTE: usb_written() should be called by IRQ handlers, so that
+ * it can be non-preemptive.
+ */
static void usb_written(struct consumer const *consumer, size_t count)
{
struct usb_stream_config const *config =
DOWNCAST(consumer, struct usb_stream_config, consumer);
- hook_call_deferred(config->deferred_tx, 0);
+ /* USB TX transfer is active. No need to activate it. */
+ if (*config->tx_in_progress)
+ return;
+
+ /*
+ * if USB Endpoint has not been initialized nor in ready status,
+ * then return.
+ */
+ if (!tx_fifo_is_ready(config))
+ return;
+
+ *config->tx_in_progress = 1;
+ tx_stream_handler(config);
}
struct producer_ops const usb_stream_producer_ops = {
diff --git a/chip/g/usb-stream.h b/chip/g/usb-stream.h
index 020f6995c5..a0c580acea 100644
--- a/chip/g/usb-stream.h
+++ b/chip/g/usb-stream.h
@@ -29,12 +29,12 @@ struct usb_stream_config {
*/
int endpoint;
- int *is_reset;
+ /* USB TX transfer is in progress */
+ uint8_t *tx_in_progress;
/*
* Deferred function to call to handle USB and Queue request.
*/
- const struct deferred_data *deferred_tx;
const struct deferred_data *deferred_rx;
int tx_size;
@@ -114,19 +114,16 @@ extern struct producer_ops const usb_stream_producer_ops;
static struct g_usb_desc CONCAT2(NAME, _out_desc_); \
static struct g_usb_desc CONCAT2(NAME, _in_desc_)[MAX_IN_DESC]; \
static uint8_t CONCAT2(NAME, _buf_rx_)[RX_SIZE]; \
- static int CONCAT2(NAME, _is_reset_); \
- static void CONCAT2(NAME, _deferred_tx_)(void); \
- DECLARE_DEFERRED(CONCAT2(NAME, _deferred_tx_)); \
+ static uint8_t CONCAT2(NAME, _tx_in_progress_); \
static void CONCAT2(NAME, _deferred_rx_)(void); \
DECLARE_DEFERRED(CONCAT2(NAME, _deferred_rx_)); \
static int CONCAT2(NAME, _rx_handled); \
static size_t CONCAT2(NAME, _tx_handled); \
struct usb_stream_config const NAME = { \
.endpoint = ENDPOINT, \
- .is_reset = &CONCAT2(NAME, _is_reset_), \
+ .tx_in_progress = &CONCAT2(NAME, _tx_in_progress_), \
.in_desc = &CONCAT2(NAME, _in_desc_)[0], \
.out_desc = &CONCAT2(NAME, _out_desc_), \
- .deferred_tx = &CONCAT2(NAME, _deferred_tx__data), \
.deferred_rx = &CONCAT2(NAME, _deferred_rx__data), \
.tx_size = TX_SIZE, \
.rx_size = RX_SIZE, \
@@ -172,8 +169,6 @@ extern struct producer_ops const usb_stream_producer_ops;
.wMaxPacketSize = RX_SIZE, \
.bInterval = 0, \
}; \
- static void CONCAT2(NAME, _deferred_tx_)(void) \
- { tx_stream_handler(&NAME); } \
static void CONCAT2(NAME, _deferred_rx_)(void) \
{ rx_stream_handler(&NAME); } \
static void CONCAT2(NAME, _ep_tx)(void) \
@@ -218,7 +213,6 @@ extern struct producer_ops const usb_stream_producer_ops;
* Handle USB and Queue request in a deferred callback.
*/
void rx_stream_handler(struct usb_stream_config const *config);
-void tx_stream_handler(struct usb_stream_config const *config);
/*
* These functions are used by the trampoline functions defined above to