summaryrefslogtreecommitdiff
path: root/chip/stm32/usb-stream.c
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2015-04-06 14:15:08 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-04-13 16:32:14 +0000
commit0f6335451dba025328fd0a6ad3da79d57405135b (patch)
tree4d7285c736561f52ca8bc749a19d8f993c46d11e /chip/stm32/usb-stream.c
parent676a995cb3e940b1c9e727ec8a97bef2a14c4ca5 (diff)
downloadchrome-ec-0f6335451dba025328fd0a6ad3da79d57405135b.tar.gz
USB-Stream: Switch to handling packets in a deferred hook
Previously the TX and RX queues were being accessed from two different locations without locking, which is wrong. This moves the access to a single location in a deffered hook and calls that hook from the old locations. The result is correct, simpler, and not much slower. It also reduces time in the USB interrupt handler by moving the memcpy from packet to queue out to the deferred hook. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Verify that USB streams still work on Ryu and discovery-stm32f072 Change-Id: I6ea53d7c40b42c6112e86a7886f3b888408f72b7 Reviewed-on: https://chromium-review.googlesource.com/264763 Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org> Trybot-Ready: Anton Staaf <robotboy@chromium.org>
Diffstat (limited to 'chip/stm32/usb-stream.c')
-rw-r--r--chip/stm32/usb-stream.c63
1 files changed, 27 insertions, 36 deletions
diff --git a/chip/stm32/usb-stream.c b/chip/stm32/usb-stream.c
index 05351a8ca3..f5487372bb 100644
--- a/chip/stm32/usb-stream.c
+++ b/chip/stm32/usb-stream.c
@@ -44,21 +44,22 @@ static size_t tx_write(struct usb_stream_config const *config)
return count;
}
-static void usb_read(struct producer const *producer, size_t count)
+static int tx_valid(struct usb_stream_config const *config)
{
- struct usb_stream_config const *config =
- DOWNCAST(producer, struct usb_stream_config, producer);
-
- if (config->state->rx_waiting && rx_read(config)) {
- config->state->rx_waiting = 0;
+ return (STM32_USB_EP(config->endpoint) & EP_TX_MASK) == EP_TX_VALID;
+}
- STM32_TOGGLE_EP(config->endpoint, EP_RX_MASK, EP_RX_VALID, 0);
- }
+static int rx_valid(struct usb_stream_config const *config)
+{
+ return (STM32_USB_EP(config->endpoint) & EP_RX_MASK) == EP_RX_VALID;
}
-static int tx_valid(struct usb_stream_config const *config)
+static void usb_read(struct producer const *producer, size_t count)
{
- return (STM32_USB_EP(config->endpoint) & EP_TX_MASK) == EP_TX_VALID;
+ struct usb_stream_config const *config =
+ DOWNCAST(producer, struct usb_stream_config, producer);
+
+ hook_call_deferred(config->deferred, 0);
}
static void usb_written(struct consumer const *consumer, size_t count)
@@ -66,12 +67,7 @@ static void usb_written(struct consumer const *consumer, size_t count)
struct usb_stream_config const *config =
DOWNCAST(consumer, struct usb_stream_config, consumer);
- /*
- * If we are not currently in a valid transmission state and we had
- * something for the TX buffer, then mark the TX endpoint as valid.
- */
- if (!tx_valid(config) && tx_write(config))
- STM32_TOGGLE_EP(config->endpoint, EP_TX_MASK, EP_TX_VALID, 0);
+ hook_call_deferred(config->deferred, 0);
}
static void usb_flush(struct consumer const *consumer)
@@ -92,32 +88,27 @@ struct consumer_ops const usb_stream_consumer_ops = {
.flush = usb_flush,
};
-void usb_stream_tx(struct usb_stream_config const *config)
+void usb_stream_deferred(struct usb_stream_config const *config)
{
- if (tx_write(config))
+ if (!tx_valid(config) && tx_write(config))
STM32_TOGGLE_EP(config->endpoint, EP_TX_MASK, EP_TX_VALID, 0);
- else
- STM32_TOGGLE_EP(config->endpoint, 0, 0, 0);
+
+ if (!rx_valid(config) && rx_read(config))
+ STM32_TOGGLE_EP(config->endpoint, EP_RX_MASK, EP_RX_VALID, 0);
+}
+
+void usb_stream_tx(struct usb_stream_config const *config)
+{
+ STM32_TOGGLE_EP(config->endpoint, 0, 0, 0);
+
+ hook_call_deferred(config->deferred, 0);
}
void usb_stream_rx(struct usb_stream_config const *config)
{
- if (rx_read(config)) {
- /*
- * RX packet consumed, mark the packet as VALID.
- */
- STM32_TOGGLE_EP(config->endpoint, EP_RX_MASK, EP_RX_VALID, 0);
- } else {
- /*
- * There is not enough space in the RX queue to receive this
- * packet. Leave the RX endpoint in a NAK state, clear the
- * interrupt, and indicate to the usb_read function that when
- * there is enough space in the queue to hold it there is an
- * RX packet waiting.
- */
- config->state->rx_waiting = 1;
- STM32_TOGGLE_EP(config->endpoint, 0, 0, 0);
- }
+ STM32_TOGGLE_EP(config->endpoint, 0, 0, 0);
+
+ hook_call_deferred(config->deferred, 0);
}
static usb_uint usb_ep_rx_size(size_t bytes)