[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