summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@chromium.org>2019-04-18 17:49:18 -0700
committerVadim Bendebury <vbendeb@chromium.org>2019-09-21 19:11:25 -0700
commitd9119aed99f15b0460834be421aa6ea0c9de217c (patch)
tree9b5a40cea06cfac2b4d1c7edae6f8619a0346228
parentd48a71b49f11bd8738e4c1fc4bc15a431319da38 (diff)
downloadchrome-ec-d9119aed99f15b0460834be421aa6ea0c9de217c.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> (cherry picked from commit a1886cee8aa429b350246548fe1c719f54c1dc5c) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1684050 (cherry picked from commit 28ff10b561247f02fd8221754e08aca78f79efc5) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1705739 (cherry picked from commit 61896a76c5a8eb64f188a6f58551ceec469312fb)
-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