This patch adds interfaces for bulk out and bulk in ops. These
interfaces could be used to implement early printk bootconsole
or hook to various system debuggers.
Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
---
drivers/usb/early/xhci-dbc.c | 373 +++++++++++++++++++++++++++++++++++++++++++
include/linux/usb/xhci-dbc.h | 30 ++++
2 files changed, 403 insertions(+)
+
+/*
+ * Check and dispatch events in event ring. It also checks status
+ * of hardware. This function will be called from multiple threads.
+ * An atomic lock is applied to protect the access of event ring.
+ */
+static int xdbc_check_event(void)
+{
+ /* event ring is under checking by other thread? */
+ if (!test_bit(XDBC_ATOMIC_EVENT, &xdbcp->atomic_flags) &&
+ !test_and_set_bit(XDBC_ATOMIC_EVENT,
+ &xdbcp->atomic_flags))
+ return 0;
+
+ xdbc_handle_events();
+
+ test_and_clear_bit(XDBC_ATOMIC_EVENT, &xdbcp->atomic_flags);
+
+ return 0;
+}
+
+#define BULK_IN_COMPLETED(p) ((xdbcp->in_pending == (p)) && \
+ xdbcp->in_complete)
+#define BULK_OUT_COMPLETED(p) ((xdbcp->out_pending == (p)) && \
+ xdbcp->out_complete)
+
+}
+
+int xdbc_bulk_read(void *data, int size, int loops)
+{
+ int ret;
+
+ do {
+ if (!test_bit(XDBC_ATOMIC_BULKIN, &xdbcp->atomic_flags) &&
+ !test_and_set_bit(XDBC_ATOMIC_BULKIN,
+ &xdbcp->atomic_flags))
+ break;
+ } while (1);
+
+ ret = xdbc_bulk_transfer(data, size, loops, true);
+
+ test_and_clear_bit(XDBC_ATOMIC_BULKIN, &xdbcp->atomic_flags);
+
+ return ret;
+}
+
+int xdbc_bulk_write(const char *bytes, int size)
+{
+ int ret;
+
+ do {
+ if (!test_bit(XDBC_ATOMIC_BULKOUT, &xdbcp->atomic_flags) &&
+ !test_and_set_bit(XDBC_ATOMIC_BULKOUT,
+ &xdbcp->atomic_flags))
+ break;
+ } while (1);