[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH 1/5] usb: Extend interface for interrupt transfers



+ Add a way to make the HCD start transactions as interrupt transfers
+ Add a way to make the bus driver start an interrupt transfer
+ Add a way to make the bus driver cancel and destroy and asynchronous
  transmission (such as an interrupt transfer)

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
 include/cdi/usb.h     | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/cdi/usb_hcd.h | 29 +++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/include/cdi/usb.h b/include/cdi/usb.h
index c7fa751..894be0d 100644
--- a/include/cdi/usb.h
+++ b/include/cdi/usb.h
@@ -51,6 +51,21 @@ typedef uint32_t cdi_usb_port_status_t;
 #define CDI_USB_PORT_SPEED_MASK (0x7)
 #define CDI_USB_PORT_CONNECTED  (1 << 3)
 
+/**
+ * Callback function pointer type for asynchronous transmissions.
+ */
+typedef void (*cdi_usb_async_cb_t)(void* opaque);
+
+/**
+ * Callback function pointer type for interrupt transfers.
+ */
+typedef cdi_usb_async_cb_t cdi_usb_interrupt_cb_t;
+
+/**
+ * Type of asynchronous transmissions.
+ */
+typedef void* cdi_usb_async_transmission_t;
+
 struct cdi_usb_hub;
 
 /**
@@ -158,6 +173,27 @@ struct cdi_usb_driver {
     cdi_usb_transmission_result_t (*bulk_transfer)(struct cdi_usb_device* dev,
                                                    int ep, void* data,
                                                    size_t size);
+
+    /**
+     * Enqueues an interrupt transfer to endpoint @ep (0 up until
+     * dev->endpoint_count - 1) of device @dev, trying to transfer @size bytes
+     * to @data every polling interval as specified by the given endpoint's
+     * descriptor. Each time a transfer is successful, the @cb is invoked.
+     *
+     * This function will return immediately. Use destroy_async_transfer()
+     * to dequeue and release its resources.
+     *
+     * Returns NULL on error.
+     */
+    cdi_usb_async_transmission_t
+        (*interrupt_transfer)(struct cdi_usb_device* dev, int ep,
+                              void* data, size_t size,
+                              cdi_usb_interrupt_cb_t cb, void* opaque);
+
+    /**
+     * Cancels the given asynchronous transmission and releases its resources.
+     */
+    void (*destroy_async_transfer)(cdi_usb_async_transmission_t transmission);
 };
 
 /**
@@ -212,6 +248,27 @@ cdi_usb_transmission_result_t cdi_usb_bulk_transfer(struct cdi_usb_device* dev,
                                                     int ep, void* data,
                                                     size_t size);
 
+/**
+ * Enqueues an interrupt transfer to endpoint @ep (0 up until
+ * dev->endpoint_count - 1) of device @dev, trying to transfer @size bytes to
+ * @data every polling interval as specified by the given endpoint's descriptor.
+ * Each time a transfer is successful, the @cb is invoked.
+ *
+ * This function will return immediately. Use destroy_async_transfer() to
+ * dequeue and release its resources.
+ *
+ * Returns NULL on error.
+ */
+cdi_usb_async_transmission_t
+    cdi_usb_interrupt_transfer(struct cdi_usb_device* dev, int ep,
+                               void* data, size_t size,
+                               cdi_usb_interrupt_cb_t cb, void* opaque);
+
+/**
+ * Cancels the given asynchronous transmission and releases its resources.
+ */
+void cdi_usb_destroy_async_transfer(cdi_usb_async_transmission_t transmission);
+
 #ifdef __cplusplus
 }; // extern "C"
 #endif
diff --git a/include/cdi/usb_hcd.h b/include/cdi/usb_hcd.h
index 842ae73..37f0400 100644
--- a/include/cdi/usb_hcd.h
+++ b/include/cdi/usb_hcd.h
@@ -20,6 +20,11 @@
  */
 typedef void* cdi_usb_hc_transaction_t;
 
+/**
+ * Callback function pointer type for interrupt transactions.
+ */
+typedef void (*cdi_usb_hc_interrupt_cb_t)(void* opaque);
+
 typedef enum {
     CDI_USB_IN,
     CDI_USB_OUT,
@@ -139,7 +144,7 @@ struct cdi_usb_hcd {
                     const struct cdi_usb_hc_transmission* trans);
 
     /**
-     * Starts asynchronous execution of a transaction.
+     * Starts asynchronous execution of a control or bulk transaction.
      */
     void (*start_transaction)(struct cdi_usb_hc* hc,
                               cdi_usb_hc_transaction_t ta);
@@ -155,6 +160,28 @@ struct cdi_usb_hcd {
                              cdi_usb_hc_transaction_t ta);
 
     /**
+     * Starts periodic execution of an interrupt transaction.
+     *
+     * The unit of @interval depends on the transmission speed. For low and
+     * full speed devices, it is one frame (= 1 ms); for high speed devices, it
+     * is one microframe (= 1/8 ms).
+     *
+     * @interval must be a positive power of two. Depending on the host
+     * controller, there may be an upper limit; values greater than that limit
+     * will be capped accordingly.
+     *
+     * Whenever data is received, the @cb is invoked.
+     *
+     * All transmissions enqueued in this transaction must be CDI_USB_IN
+     * transmissions.
+     */
+    void (*start_interrupt_transaction)(struct cdi_usb_hc* hc,
+                                        cdi_usb_hc_transaction_t ta,
+                                        int interval,
+                                        cdi_usb_hc_interrupt_cb_t cb,
+                                        void* cb_opaque);
+
+    /**
      * Destroys a transaction. Transmissions which have not been waited on may
      * or may not have been executed by the time this function returns. The
      * values of the variables pointed to by the @result field of unwaited-for
-- 
2.6.4