usb_host: Run formatting script

This commit is contained in:
Darian Leung
2023-05-09 00:53:27 +08:00
parent a3e4e9c772
commit ff8c4f79d2
13 changed files with 1604 additions and 1604 deletions

View File

@@ -52,19 +52,19 @@ typedef struct interface_s interface_t;
typedef struct client_s client_t;
struct ep_wrapper_s {
//Dynamic members require a critical section
// Dynamic members require a critical section
struct {
TAILQ_ENTRY(ep_wrapper_s) tailq_entry;
union {
struct {
uint32_t pending: 1;
uint32_t reserved31:31;
uint32_t reserved31: 31;
};
} flags;
uint32_t num_urb_inflight;
usbh_ep_event_t last_event;
} dynamic;
//Constant members do no change after claiming the interface thus do not require a critical section
// Constant members do no change after claiming the interface thus do not require a critical section
struct {
usbh_ep_handle_t ep_hdl;
interface_t *intf_obj;
@@ -72,11 +72,11 @@ struct ep_wrapper_s {
};
struct interface_s {
//Dynamic members require a critical section
// Dynamic members require a critical section
struct {
TAILQ_ENTRY(interface_s) tailq_entry;
} mux_protected;
//Constant members do no change after claiming the interface thus do not require a critical section
// Constant members do no change after claiming the interface thus do not require a critical section
struct {
const usb_intf_desc_t *intf_desc;
usb_device_handle_t dev_hdl;
@@ -86,7 +86,7 @@ struct interface_s {
};
struct client_s {
//Dynamic members require a critical section
// Dynamic members require a critical section
struct {
TAILQ_ENTRY(client_s) tailq_entry;
TAILQ_HEAD(tailhead_pending_ep, ep_wrapper_s) pending_ep_tailq;
@@ -107,11 +107,11 @@ struct client_s {
uint32_t num_done_ctrl_xfer;
uint32_t opened_dev_addr_map;
} dynamic;
//Mux protected members must be protected by host library the mux_lock when accessed
// Mux protected members must be protected by host library the mux_lock when accessed
struct {
TAILQ_HEAD(tailhead_interfaces, interface_s) interface_tailq;
} mux_protected;
//Constant members do no change after registration thus do not require a critical section
// Constant members do no change after registration thus do not require a critical section
struct {
SemaphoreHandle_t event_sem;
usb_host_client_event_cb_t event_callback;
@@ -121,9 +121,9 @@ struct client_s {
};
typedef struct {
//Dynamic members require a critical section
// Dynamic members require a critical section
struct {
//Access to these should be done in a critical section
// Access to these should be done in a critical section
uint32_t process_pending_flags;
uint32_t lib_event_flags;
union {
@@ -138,15 +138,15 @@ typedef struct {
uint32_t val;
} flags;
} dynamic;
//Mux protected members must be protected by host library the mux_lock when accessed
// Mux protected members must be protected by host library the mux_lock when accessed
struct {
TAILQ_HEAD(tailhead_clients, client_s) client_tailq; //List of all clients registered
TAILQ_HEAD(tailhead_clients, client_s) client_tailq; // List of all clients registered
} mux_protected;
//Constant members do no change after installation thus do not require a critical section
// Constant members do no change after installation thus do not require a critical section
struct {
SemaphoreHandle_t event_sem;
SemaphoreHandle_t mux_lock;
usb_phy_handle_t phy_handle; //Will be NULL if host library is installed with skip_phy_setup
usb_phy_handle_t phy_handle; // Will be NULL if host library is installed with skip_phy_setup
} constant;
} host_lib_t;
@@ -228,13 +228,13 @@ static bool _unblock_lib(bool in_isr)
static void send_event_msg_to_clients(const usb_host_client_event_msg_t *event_msg, bool send_to_all, uint8_t opened_dev_addr)
{
//Lock client list
// Lock client list
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
//Send event message to relevant or all clients
// Send event message to relevant or all clients
client_t *client_obj;
TAILQ_FOREACH(client_obj, &p_host_lib_obj->mux_protected.client_tailq, dynamic.tailq_entry) {
if (!send_to_all) {
//Check if client opened the device
// Check if client opened the device
HOST_ENTER_CRITICAL();
bool send = _check_client_opened_device(client_obj, opened_dev_addr);
HOST_EXIT_CRITICAL();
@@ -242,7 +242,7 @@ static void send_event_msg_to_clients(const usb_host_client_event_msg_t *event_m
continue;
}
}
//Send the event message
// Send the event message
if (xQueueSend(client_obj->constant.event_msg_queue, event_msg, 0) == pdTRUE) {
HOST_ENTER_CRITICAL();
_unblock_client(client_obj, false);
@@ -251,7 +251,7 @@ static void send_event_msg_to_clients(const usb_host_client_event_msg_t *event_m
ESP_LOGE(USB_HOST_TAG, "Client event message queue full");
}
}
//Unlock client list
// Unlock client list
xSemaphoreGive(p_host_lib_obj->constant.mux_lock);
}
@@ -262,14 +262,14 @@ static void send_event_msg_to_clients(const usb_host_client_event_msg_t *event_m
static bool proc_req_callback(usb_proc_req_source_t source, bool in_isr, void *arg)
{
HOST_ENTER_CRITICAL_SAFE();
//Store the processing request source
// Store the processing request source
switch (source) {
case USB_PROC_REQ_SOURCE_USBH:
p_host_lib_obj->dynamic.process_pending_flags |= PROCESS_REQUEST_PENDING_FLAG_USBH;
break;
case USB_PROC_REQ_SOURCE_HUB:
p_host_lib_obj->dynamic.process_pending_flags |= PROCESS_REQUEST_PENDING_FLAG_HUB;
break;
case USB_PROC_REQ_SOURCE_USBH:
p_host_lib_obj->dynamic.process_pending_flags |= PROCESS_REQUEST_PENDING_FLAG_USBH;
break;
case USB_PROC_REQ_SOURCE_HUB:
p_host_lib_obj->dynamic.process_pending_flags |= PROCESS_REQUEST_PENDING_FLAG_HUB;
break;
}
bool yield = _unblock_lib(in_isr);
HOST_EXIT_CRITICAL_SAFE();
@@ -280,7 +280,7 @@ static bool proc_req_callback(usb_proc_req_source_t source, bool in_isr, void *a
static void ctrl_xfer_callback(usb_device_handle_t dev_hdl, urb_t *urb, void *arg)
{
assert(urb->usb_host_client != NULL);
//Redistribute done control transfer to the clients that submitted them
// Redistribute done control transfer to the clients that submitted them
client_t *client_obj = (client_t *)urb->usb_host_client;
HOST_ENTER_CRITICAL();
@@ -292,41 +292,41 @@ static void ctrl_xfer_callback(usb_device_handle_t dev_hdl, urb_t *urb, void *ar
static void dev_event_callback(usb_device_handle_t dev_hdl, usbh_event_t usbh_event, void *arg)
{
//Check usbh_event. The data type of event_arg depends on the type of event
// Check usbh_event. The data type of event_arg depends on the type of event
switch (usbh_event) {
case USBH_EVENT_DEV_NEW: {
//Prepare a NEW_DEV client event message, the send it to all clients
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
usb_host_client_event_msg_t event_msg = {
.event = USB_HOST_CLIENT_EVENT_NEW_DEV,
.new_dev.address = dev_addr,
};
send_event_msg_to_clients(&event_msg, true, 0);
break;
}
case USBH_EVENT_DEV_GONE: {
//Prepare event msg, send only to clients that have opened the device
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
usb_host_client_event_msg_t event_msg = {
.event = USB_HOST_CLIENT_EVENT_DEV_GONE,
.dev_gone.dev_hdl = dev_hdl,
};
send_event_msg_to_clients(&event_msg, false, dev_addr);
break;
}
case USBH_EVENT_DEV_ALL_FREE: {
//Notify the lib handler that all devices are free
HOST_ENTER_CRITICAL();
p_host_lib_obj->dynamic.lib_event_flags |= USB_HOST_LIB_EVENT_FLAGS_ALL_FREE;
_unblock_lib(false);
HOST_EXIT_CRITICAL();
break;
}
default:
abort(); //Should never occur
break;
case USBH_EVENT_DEV_NEW: {
// Prepare a NEW_DEV client event message, the send it to all clients
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
usb_host_client_event_msg_t event_msg = {
.event = USB_HOST_CLIENT_EVENT_NEW_DEV,
.new_dev.address = dev_addr,
};
send_event_msg_to_clients(&event_msg, true, 0);
break;
}
case USBH_EVENT_DEV_GONE: {
// Prepare event msg, send only to clients that have opened the device
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
usb_host_client_event_msg_t event_msg = {
.event = USB_HOST_CLIENT_EVENT_DEV_GONE,
.dev_gone.dev_hdl = dev_hdl,
};
send_event_msg_to_clients(&event_msg, false, dev_addr);
break;
}
case USBH_EVENT_DEV_ALL_FREE: {
// Notify the lib handler that all devices are free
HOST_ENTER_CRITICAL();
p_host_lib_obj->dynamic.lib_event_flags |= USB_HOST_LIB_EVENT_FLAGS_ALL_FREE;
_unblock_lib(false);
HOST_EXIT_CRITICAL();
break;
}
default:
abort(); // Should never occur
break;
}
}
@@ -338,9 +338,9 @@ static bool endpoint_callback(usbh_ep_handle_t ep_hdl, usbh_ep_event_t ep_event,
client_t *client_obj = (client_t *)ep_wrap->constant.intf_obj->constant.client_obj;
HOST_ENTER_CRITICAL_SAFE();
//Store the event to be handled later. Note that we allow overwriting of events because more severe will halt the pipe prevent any further events.
// Store the event to be handled later. Note that we allow overwriting of events because more severe will halt the pipe prevent any further events.
ep_wrap->dynamic.last_event = ep_event;
//Add the EP to the client's pending list if it's not in the list already
// Add the EP to the client's pending list if it's not in the list already
if (!ep_wrap->dynamic.flags.pending) {
ep_wrap->dynamic.flags.pending = 1;
TAILQ_REMOVE(&client_obj->dynamic.idle_ep_tailq, ep_wrap, dynamic.tailq_entry);
@@ -371,7 +371,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
ret = ESP_ERR_NO_MEM;
goto alloc_err;
}
//Initialize host library object
// Initialize host library object
TAILQ_INIT(&host_lib_obj->mux_protected.client_tailq);
host_lib_obj->constant.event_sem = event_sem;
host_lib_obj->constant.mux_lock = mux_lock;
@@ -384,24 +384,24 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
- Hub
*/
//Install USB PHY (if necessary). USB PHY driver will also enable the underlying Host Controller
// Install USB PHY (if necessary). USB PHY driver will also enable the underlying Host Controller
if (!config->skip_phy_setup) {
//Host Library defaults to internal PHY
// Host Library defaults to internal PHY
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.target = USB_PHY_TARGET_INT,
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED, //In Host mode, the speed is determined by the connected device
.otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
ret = usb_new_phy(&phy_config, &host_lib_obj->constant.phy_handle);
if (ret != ESP_OK) {
goto phy_err;
}
if (ret != ESP_OK) {
goto phy_err;
}
}
//Install HCD
// Install HCD
hcd_config_t hcd_config = {
.intr_flags = config->intr_flags
};
@@ -410,7 +410,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
goto hcd_err;
}
//Install USBH
// Install USBH
usbh_config_t usbh_config = {
.proc_req_cb = proc_req_callback,
.proc_req_cb_arg = NULL,
@@ -424,7 +424,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
goto usbh_err;
}
//Install Hub
// Install Hub
hub_config_t hub_config = {
.proc_req_cb = proc_req_callback,
.proc_req_cb_arg = NULL,
@@ -434,7 +434,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
goto hub_err;
}
//Assign host library object
// Assign host library object
HOST_ENTER_CRITICAL();
if (p_host_lib_obj != NULL) {
HOST_EXIT_CRITICAL();
@@ -444,7 +444,7 @@ esp_err_t usb_host_install(const usb_host_config_t *config)
p_host_lib_obj = host_lib_obj;
HOST_EXIT_CRITICAL();
//Start the root hub
// Start the root hub
ESP_ERROR_CHECK(hub_root_start());
ret = ESP_OK;
return ret;
@@ -473,7 +473,7 @@ alloc_err:
esp_err_t usb_host_uninstall(void)
{
//All devices must have been freed at this point
// All devices must have been freed at this point
HOST_ENTER_CRITICAL();
HOST_CHECK_FROM_CRIT(p_host_lib_obj != NULL, ESP_ERR_INVALID_STATE);
HOST_CHECK_FROM_CRIT(p_host_lib_obj->dynamic.process_pending_flags == 0 &&
@@ -482,10 +482,10 @@ esp_err_t usb_host_uninstall(void)
ESP_ERR_INVALID_STATE);
HOST_EXIT_CRITICAL();
//Stop the root hub
// Stop the root hub
ESP_ERROR_CHECK(hub_root_stop());
//Unassign the host library object
// Unassign the host library object
HOST_ENTER_CRITICAL();
host_lib_t *host_lib_obj = p_host_lib_obj;
p_host_lib_obj = NULL;
@@ -501,12 +501,12 @@ esp_err_t usb_host_uninstall(void)
ESP_ERROR_CHECK(hub_uninstall());
ESP_ERROR_CHECK(usbh_uninstall());
ESP_ERROR_CHECK(hcd_uninstall());
//If the USB PHY was setup, then delete it
// If the USB PHY was setup, then delete it
if (host_lib_obj->constant.phy_handle) {
ESP_ERROR_CHECK(usb_del_phy(host_lib_obj->constant.phy_handle));
}
//Free memory objects
// Free memory objects
vSemaphoreDelete(host_lib_obj->constant.mux_lock);
vSemaphoreDelete(host_lib_obj->constant.event_sem);
heap_caps_free(host_lib_obj);
@@ -520,7 +520,7 @@ esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_f
HOST_ENTER_CRITICAL();
if (!p_host_lib_obj->dynamic.flags.process_pending) {
//There is currently processing that needs to be done. Wait for some processing
// There is currently processing that needs to be done. Wait for some processing
HOST_EXIT_CRITICAL();
BaseType_t sem_ret = xSemaphoreTake(p_host_lib_obj->constant.event_sem, timeout_ticks);
if (sem_ret == pdFALSE) {
@@ -529,7 +529,7 @@ esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_f
}
HOST_ENTER_CRITICAL();
}
//Read and clear process pending flags
// Read and clear process pending flags
uint32_t process_pending_flags = p_host_lib_obj->dynamic.process_pending_flags;
p_host_lib_obj->dynamic.process_pending_flags = 0;
p_host_lib_obj->dynamic.flags.handling_events = 1;
@@ -542,7 +542,7 @@ esp_err_t usb_host_lib_handle_events(TickType_t timeout_ticks, uint32_t *event_f
ESP_ERROR_CHECK(hub_process());
}
HOST_ENTER_CRITICAL();
//Read and clear process pending flags again, and loop back if there is more to process
// Read and clear process pending flags again, and loop back if there is more to process
process_pending_flags = p_host_lib_obj->dynamic.process_pending_flags;
p_host_lib_obj->dynamic.process_pending_flags = 0;
}
@@ -562,7 +562,7 @@ exit:
esp_err_t usb_host_lib_unblock(void)
{
//All devices must have been freed at this point
// All devices must have been freed at this point
HOST_ENTER_CRITICAL();
HOST_CHECK_FROM_CRIT(p_host_lib_obj != NULL, ESP_ERR_INVALID_STATE);
_unblock_lib(false);
@@ -581,7 +581,7 @@ esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret)
HOST_EXIT_CRITICAL();
usbh_num_devs(&num_devs_temp);
//Write back return values
// Write back return values
info_ret->num_devices = num_devs_temp;
info_ret->num_clients = num_clients_temp;
return ESP_OK;
@@ -593,9 +593,9 @@ esp_err_t usb_host_lib_info(usb_host_lib_info_t *info_ret)
static void _handle_pending_ep(client_t *client_obj)
{
//Handle each EP on the pending list
// Handle each EP on the pending list
while (!TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq)) {
//Get the next pending EP.
// Get the next pending EP.
ep_wrapper_t *ep_wrap = TAILQ_FIRST(&client_obj->dynamic.pending_ep_tailq);
TAILQ_REMOVE(&client_obj->dynamic.pending_ep_tailq, ep_wrap, dynamic.tailq_entry);
TAILQ_INSERT_TAIL(&client_obj->dynamic.idle_ep_tailq, ep_wrap, dynamic.tailq_entry);
@@ -604,36 +604,36 @@ static void _handle_pending_ep(client_t *client_obj)
uint32_t num_urb_dequeued = 0;
HOST_EXIT_CRITICAL();
//Handle pipe event
// Handle pipe event
switch (last_event) {
case USBH_EP_EVENT_ERROR_XFER:
case USBH_EP_EVENT_ERROR_URB_NOT_AVAIL:
case USBH_EP_EVENT_ERROR_OVERFLOW:
case USBH_EP_EVENT_ERROR_STALL:
//The endpoint is now stalled. Flush all pending URBs
ESP_ERROR_CHECK(usbh_ep_command(ep_wrap->constant.ep_hdl, USBH_EP_CMD_FLUSH));
//All URBs in this pipe are now retired waiting to be dequeued. Fall through to dequeue them
__attribute__((fallthrough));
case USBH_EP_EVENT_URB_DONE: {
//Dequeue all URBs and run their transfer callback
urb_t *urb;
case USBH_EP_EVENT_ERROR_XFER:
case USBH_EP_EVENT_ERROR_URB_NOT_AVAIL:
case USBH_EP_EVENT_ERROR_OVERFLOW:
case USBH_EP_EVENT_ERROR_STALL:
// The endpoint is now stalled. Flush all pending URBs
ESP_ERROR_CHECK(usbh_ep_command(ep_wrap->constant.ep_hdl, USBH_EP_CMD_FLUSH));
// All URBs in this pipe are now retired waiting to be dequeued. Fall through to dequeue them
__attribute__((fallthrough));
case USBH_EP_EVENT_URB_DONE: {
// Dequeue all URBs and run their transfer callback
urb_t *urb;
usbh_ep_dequeue_urb(ep_wrap->constant.ep_hdl, &urb);
while (urb != NULL) {
// Clear the transfer's in-flight flag to indicate the transfer is no longer in-flight
urb->usb_host_inflight = false;
urb->transfer.callback(&urb->transfer);
num_urb_dequeued++;
usbh_ep_dequeue_urb(ep_wrap->constant.ep_hdl, &urb);
while (urb != NULL) {
//Clear the transfer's in-flight flag to indicate the transfer is no longer in-flight
urb->usb_host_inflight = false;
urb->transfer.callback(&urb->transfer);
num_urb_dequeued++;
usbh_ep_dequeue_urb(ep_wrap->constant.ep_hdl, &urb);
}
break;
}
default:
abort(); //Should never occur
break;
break;
}
default:
abort(); // Should never occur
break;
}
HOST_ENTER_CRITICAL();
//Update the endpoint's number of URB's in-flight
// Update the endpoint's number of URB's in-flight
assert(num_urb_dequeued <= ep_wrap->dynamic.num_urb_inflight);
ep_wrap->dynamic.num_urb_inflight -= num_urb_dequeued;
}
@@ -647,12 +647,12 @@ esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config
HOST_CHECK(client_config != NULL && client_hdl_ret != NULL, ESP_ERR_INVALID_ARG);
HOST_CHECK(client_config->max_num_event_msg > 0, ESP_ERR_INVALID_ARG);
if (!client_config->is_synchronous) {
//Asynchronous clients must provide a
// Asynchronous clients must provide a
HOST_CHECK(client_config->async.client_event_callback != NULL, ESP_ERR_INVALID_ARG);
}
esp_err_t ret;
//Create client object
// Create client object
client_t *client_obj = heap_caps_calloc(1, sizeof(client_t), MALLOC_CAP_DEFAULT);
SemaphoreHandle_t event_sem = xSemaphoreCreateBinary();
QueueHandle_t event_msg_queue = xQueueCreate(client_config->max_num_event_msg, sizeof(usb_host_client_event_msg_t));
@@ -660,7 +660,7 @@ esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config
ret = ESP_ERR_NO_MEM;
goto alloc_err;
}
//Initialize client object
// Initialize client object
TAILQ_INIT(&client_obj->dynamic.pending_ep_tailq);
TAILQ_INIT(&client_obj->dynamic.idle_ep_tailq);
TAILQ_INIT(&client_obj->mux_protected.interface_tailq);
@@ -670,7 +670,7 @@ esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config
client_obj->constant.callback_arg = client_config->async.callback_arg;
client_obj->constant.event_msg_queue = event_msg_queue;
//Add client to the host library's list of clients
// Add client to the host library's list of clients
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
HOST_ENTER_CRITICAL();
p_host_lib_obj->dynamic.flags.num_clients++;
@@ -678,7 +678,7 @@ esp_err_t usb_host_client_register(const usb_host_client_config_t *client_config
TAILQ_INSERT_TAIL(&p_host_lib_obj->mux_protected.client_tailq, client_obj, dynamic.tailq_entry);
xSemaphoreGive(p_host_lib_obj->constant.mux_lock);
//Write back client handle
// Write back client handle
*client_hdl_ret = (usb_host_client_handle_t)client_obj;
ret = ESP_OK;
return ret;
@@ -700,41 +700,41 @@ esp_err_t usb_host_client_deregister(usb_host_client_handle_t client_hdl)
client_t *client_obj = (client_t *)client_hdl;
esp_err_t ret;
//We take the mux_lock because we need to access the host library's client_tailq
// We take the mux_lock because we need to access the host library's client_tailq
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
HOST_ENTER_CRITICAL();
//Check that client can currently deregistered
// Check that client can currently deregistered
bool can_deregister;
if (!TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq) ||
!TAILQ_EMPTY(&client_obj->dynamic.idle_ep_tailq) ||
!TAILQ_EMPTY(&client_obj->dynamic.done_ctrl_xfer_tailq) ||
client_obj->dynamic.flags.handling_events ||
client_obj->dynamic.flags.blocked ||
client_obj->dynamic.flags.taking_mux ||
client_obj->dynamic.flags.num_intf_claimed != 0 ||
client_obj->dynamic.num_done_ctrl_xfer != 0 ||
client_obj->dynamic.opened_dev_addr_map != 0) {
can_deregister = false;
} else {
can_deregister = true;
}
!TAILQ_EMPTY(&client_obj->dynamic.idle_ep_tailq) ||
!TAILQ_EMPTY(&client_obj->dynamic.done_ctrl_xfer_tailq) ||
client_obj->dynamic.flags.handling_events ||
client_obj->dynamic.flags.blocked ||
client_obj->dynamic.flags.taking_mux ||
client_obj->dynamic.flags.num_intf_claimed != 0 ||
client_obj->dynamic.num_done_ctrl_xfer != 0 ||
client_obj->dynamic.opened_dev_addr_map != 0) {
can_deregister = false;
} else {
can_deregister = true;
}
HOST_EXIT_CRITICAL();
if (!can_deregister) {
ret = ESP_ERR_INVALID_STATE;
goto exit;
}
//Remove client object from the library's list of clients
// Remove client object from the library's list of clients
TAILQ_REMOVE(&p_host_lib_obj->mux_protected.client_tailq, client_obj, dynamic.tailq_entry);
HOST_ENTER_CRITICAL();
p_host_lib_obj->dynamic.flags.num_clients--;
if (p_host_lib_obj->dynamic.flags.num_clients == 0) {
//This is the last client being deregistered. Notify the lib handler
// This is the last client being deregistered. Notify the lib handler
p_host_lib_obj->dynamic.lib_event_flags |= USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS;
_unblock_lib(false);
}
HOST_EXIT_CRITICAL();
//Free client object
// Free client object
vQueueDelete(client_obj->constant.event_msg_queue);
vSemaphoreDelete(client_obj->constant.event_sem);
heap_caps_free(client_obj);
@@ -752,7 +752,7 @@ esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, Tic
HOST_ENTER_CRITICAL();
if (!client_obj->dynamic.flags.events_pending) {
//There are currently no events, wait for one to occur
// There are currently no events, wait for one to occur
client_obj->dynamic.flags.blocked = 1;
HOST_EXIT_CRITICAL();
BaseType_t sem_ret = xSemaphoreTake(client_obj->constant.event_sem, timeout_ticks);
@@ -760,45 +760,45 @@ esp_err_t usb_host_client_handle_events(usb_host_client_handle_t client_hdl, Tic
client_obj->dynamic.flags.blocked = 0;
if (sem_ret == pdFALSE) {
HOST_EXIT_CRITICAL();
//Timed out waiting for semaphore
// Timed out waiting for semaphore
ret = ESP_ERR_TIMEOUT;
goto exit;
}
}
//Mark that we're processing events
// Mark that we're processing events
client_obj->dynamic.flags.handling_events = 1;
while (client_obj->dynamic.flags.handling_events) {
//Handle pending endpoints
// Handle pending endpoints
if (!TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq)) {
_handle_pending_ep(client_obj);
}
//Handle any done control transfers
// Handle any done control transfers
while (client_obj->dynamic.num_done_ctrl_xfer > 0) {
urb_t *urb = TAILQ_FIRST(&client_obj->dynamic.done_ctrl_xfer_tailq);
TAILQ_REMOVE(&client_obj->dynamic.done_ctrl_xfer_tailq, urb, tailq_entry);
client_obj->dynamic.num_done_ctrl_xfer--;
HOST_EXIT_CRITICAL();
//Clear the transfer's in-flight flag to indicate the transfer is no longer in-flight
// Clear the transfer's in-flight flag to indicate the transfer is no longer in-flight
urb->usb_host_inflight = false;
//Call the transfer's callback
// Call the transfer's callback
urb->transfer.callback(&urb->transfer);
HOST_ENTER_CRITICAL();
}
//Handle event messages
// Handle event messages
while (uxQueueMessagesWaiting(client_obj->constant.event_msg_queue) > 0) {
HOST_EXIT_CRITICAL();
//Dequeue the event message and call the client event callback
// Dequeue the event message and call the client event callback
usb_host_client_event_msg_t event_msg;
BaseType_t queue_ret = xQueueReceive(client_obj->constant.event_msg_queue, &event_msg, 0);
assert(queue_ret == pdTRUE);
client_obj->constant.event_callback(&event_msg, client_obj->constant.callback_arg);
HOST_ENTER_CRITICAL();
}
//Check each event again to see any new events occurred
// Check each event again to see any new events occurred
if (TAILQ_EMPTY(&client_obj->dynamic.pending_ep_tailq) &&
client_obj->dynamic.num_done_ctrl_xfer == 0 &&
uxQueueMessagesWaiting(client_obj->constant.event_msg_queue) == 0) {
//All pending endpoints and event messages handled
client_obj->dynamic.num_done_ctrl_xfer == 0 &&
uxQueueMessagesWaiting(client_obj->constant.event_msg_queue) == 0) {
// All pending endpoints and event messages handled
client_obj->dynamic.flags.events_pending = 0;
client_obj->dynamic.flags.handling_events = 0;
}
@@ -838,12 +838,12 @@ esp_err_t usb_host_device_open(usb_host_client_handle_t client_hdl, uint8_t dev_
HOST_ENTER_CRITICAL();
if (_check_client_opened_device(client_obj, dev_addr)) {
//Client has already opened the device. Close it and return an error
// Client has already opened the device. Close it and return an error
ret = ESP_ERR_INVALID_STATE;
HOST_EXIT_CRITICAL();
goto already_opened;
}
//Record in client object that we have opened the device of this address
// Record in client object that we have opened the device of this address
_record_client_opened_device(client_obj, dev_addr);
HOST_EXIT_CRITICAL();
@@ -862,10 +862,10 @@ esp_err_t usb_host_device_close(usb_host_client_handle_t client_hdl, usb_device_
HOST_CHECK(dev_hdl != NULL && client_hdl != NULL, ESP_ERR_INVALID_ARG);
client_t *client_obj = (client_t *)client_hdl;
//We take the lock because we need to walk the interface list
// We take the lock because we need to walk the interface list
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
esp_err_t ret;
//Check that all interfaces claimed by this client do not belong to this device
// Check that all interfaces claimed by this client do not belong to this device
bool all_released = true;
interface_t *intf_obj;
TAILQ_FOREACH(intf_obj, &client_obj->mux_protected.interface_tailq, mux_protected.tailq_entry) {
@@ -879,18 +879,18 @@ esp_err_t usb_host_device_close(usb_host_client_handle_t client_hdl, usb_device_
goto exit;
}
//Check that client actually opened the device in the first place
// Check that client actually opened the device in the first place
HOST_ENTER_CRITICAL();
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
HOST_CHECK_FROM_CRIT(_check_client_opened_device(client_obj, dev_addr), ESP_ERR_NOT_FOUND);
if (!_check_client_opened_device(client_obj, dev_addr)) {
//Client never opened this device
// Client never opened this device
ret = ESP_ERR_INVALID_STATE;
HOST_EXIT_CRITICAL();
goto exit;
}
//Proceed to clear the record of the device form the client
// Proceed to clear the record of the device form the client
_clear_client_opened_device(client_obj, dev_addr);
HOST_EXIT_CRITICAL();
@@ -904,11 +904,11 @@ exit:
esp_err_t usb_host_device_free_all(void)
{
HOST_ENTER_CRITICAL();
HOST_CHECK_FROM_CRIT(p_host_lib_obj->dynamic.flags.num_clients == 0, ESP_ERR_INVALID_STATE); //All clients must have been deregistered
HOST_CHECK_FROM_CRIT(p_host_lib_obj->dynamic.flags.num_clients == 0, ESP_ERR_INVALID_STATE); // All clients must have been deregistered
HOST_EXIT_CRITICAL();
esp_err_t ret;
ret = usbh_dev_mark_all_free();
//If ESP_ERR_NOT_FINISHED is returned, caller must wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE to confirm all devices are free
// If ESP_ERR_NOT_FINISHED is returned, caller must wait for USB_HOST_LIB_EVENT_FLAGS_ALL_FREE to confirm all devices are free
return ret;
}
@@ -968,10 +968,10 @@ static esp_err_t ep_wrapper_alloc(usb_device_handle_t dev_hdl, const usb_ep_desc
if (ret != ESP_OK) {
goto alloc_err;
}
//Initialize endpoint wrapper item
// Initialize endpoint wrapper item
ep_wrap->constant.ep_hdl = ep_hdl;
ep_wrap->constant.intf_obj = intf_obj;
//Write back result
// Write back result
*ep_wrap_ret = ep_wrap;
ret = ESP_OK;
return ret;
@@ -986,9 +986,9 @@ static void ep_wrapper_free(usb_device_handle_t dev_hdl, ep_wrapper_t *ep_wrap)
if (ep_wrap == NULL) {
return;
}
//Free the underlying endpoint
// Free the underlying endpoint
ESP_ERROR_CHECK(usbh_ep_free(ep_wrap->constant.ep_hdl));
//Free the endpoint wrapper item
// Free the endpoint wrapper item
heap_caps_free(ep_wrap);
}
@@ -1018,21 +1018,21 @@ static void interface_free(interface_t *intf_obj)
static esp_err_t interface_claim(client_t *client_obj, usb_device_handle_t dev_hdl, const usb_config_desc_t *config_desc, uint8_t bInterfaceNumber, uint8_t bAlternateSetting, interface_t **intf_obj_ret)
{
esp_err_t ret;
//We need to walk to configuration descriptor to find the correct interface descriptor, and each of its constituent endpoint descriptors
//Find the interface descriptor and allocate the interface object
// We need to walk to configuration descriptor to find the correct interface descriptor, and each of its constituent endpoint descriptors
// Find the interface descriptor and allocate the interface object
int offset_intf;
const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, bInterfaceNumber, bAlternateSetting, &offset_intf);
if (intf_desc == NULL) {
ret = ESP_ERR_NOT_FOUND;
goto exit;
}
//Allocate interface object
// Allocate interface object
interface_t *intf_obj = interface_alloc(client_obj, dev_hdl, intf_desc);
if (intf_obj == NULL) {
ret = ESP_ERR_NO_MEM;
goto exit;
}
//Find each endpoint descriptor in the interface by index, and allocate those endpoints
// Find each endpoint descriptor in the interface by index, and allocate those endpoints
for (int i = 0; i < intf_desc->bNumEndpoints; i++) {
int offset_ep = offset_intf;
const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, i, config_desc->wTotalLength, &offset_ep);
@@ -1040,24 +1040,24 @@ static esp_err_t interface_claim(client_t *client_obj, usb_device_handle_t dev_h
ret = ESP_ERR_NOT_FOUND;
goto ep_alloc_err;
}
//Allocate the endpoint wrapper item
// Allocate the endpoint wrapper item
ep_wrapper_t *ep_wrap;
ret = ep_wrapper_alloc(dev_hdl, ep_desc, intf_obj, &ep_wrap);
if (ret != ESP_OK) {
goto ep_alloc_err;
}
//Fill the interface object with the allocated endpoints
// Fill the interface object with the allocated endpoints
intf_obj->constant.endpoints[i] = ep_wrap;
}
//Add interface object to client (safe because we have already taken the mutex)
// Add interface object to client (safe because we have already taken the mutex)
TAILQ_INSERT_TAIL(&client_obj->mux_protected.interface_tailq, intf_obj, mux_protected.tailq_entry);
//Add each endpoint wrapper item to the client's endpoint list
// Add each endpoint wrapper item to the client's endpoint list
HOST_ENTER_CRITICAL();
for (int i = 0; i < intf_desc->bNumEndpoints; i++) {
TAILQ_INSERT_TAIL(&client_obj->dynamic.idle_ep_tailq, intf_obj->constant.endpoints[i], dynamic.tailq_entry);
}
HOST_EXIT_CRITICAL();
//Write back result
// Write back result
*intf_obj_ret = intf_obj;
ret = ESP_OK;
return ret;
@@ -1075,7 +1075,7 @@ exit:
static esp_err_t interface_release(client_t *client_obj, usb_device_handle_t dev_hdl, uint8_t bInterfaceNumber)
{
esp_err_t ret;
//Find the interface object
// Find the interface object
interface_t *intf_obj_iter;
interface_t *intf_obj = NULL;
TAILQ_FOREACH(intf_obj_iter, &client_obj->mux_protected.interface_tailq, mux_protected.tailq_entry) {
@@ -1089,13 +1089,13 @@ static esp_err_t interface_release(client_t *client_obj, usb_device_handle_t dev
goto exit;
}
//Check that all endpoints in the interface are in a state to be freed
//Todo: Check that each EP is halted before allowing them to be freed (IDF-7273)
// Check that all endpoints in the interface are in a state to be freed
// Todo: Check that each EP is halted before allowing them to be freed (IDF-7273)
HOST_ENTER_CRITICAL();
bool can_free = true;
for (int i = 0; i < intf_obj->constant.intf_desc->bNumEndpoints; i++) {
ep_wrapper_t *ep_wrap = intf_obj->constant.endpoints[i];
//Endpoint must not be on the pending list and must not have in-flight URBs
// Endpoint must not be on the pending list and must not have in-flight URBs
if (ep_wrap->dynamic.num_urb_inflight != 0 || ep_wrap->dynamic.flags.pending) {
can_free = false;
break;
@@ -1106,21 +1106,21 @@ static esp_err_t interface_release(client_t *client_obj, usb_device_handle_t dev
ret = ESP_ERR_INVALID_STATE;
goto exit;
}
//Proceed to remove all endpoint wrapper items from the list
// Proceed to remove all endpoint wrapper items from the list
for (int i = 0; i < intf_obj->constant.intf_desc->bNumEndpoints; i++) {
TAILQ_REMOVE(&client_obj->dynamic.idle_ep_tailq, intf_obj->constant.endpoints[i], dynamic.tailq_entry);
}
HOST_EXIT_CRITICAL();
//Remove the interface object from the list (safe because we have already taken the mutex)
// Remove the interface object from the list (safe because we have already taken the mutex)
TAILQ_REMOVE(&client_obj->mux_protected.interface_tailq, intf_obj, mux_protected.tailq_entry);
//Free each endpoint in the interface
for (int i = 0; i < intf_obj->constant.intf_desc->bNumEndpoints; i++) {
// Free each endpoint in the interface
for (int i = 0; i < intf_obj->constant.intf_desc->bNumEndpoints; i++) {
ep_wrapper_free(dev_hdl, intf_obj->constant.endpoints[i]);
intf_obj->constant.endpoints[i] = NULL;
}
//Free the interface object itself
// Free the interface object itself
interface_free(intf_obj);
ret = ESP_OK;
exit:
@@ -1137,18 +1137,18 @@ esp_err_t usb_host_interface_claim(usb_host_client_handle_t client_hdl, usb_devi
HOST_ENTER_CRITICAL();
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
//Check if client actually opened device
// Check if client actually opened device
HOST_CHECK_FROM_CRIT(_check_client_opened_device(client_obj, dev_addr), ESP_ERR_INVALID_STATE);
client_obj->dynamic.flags.taking_mux = 1;
HOST_EXIT_CRITICAL();
//Take mux lock. This protects the client being released or other clients from claiming interfaces
// Take mux lock. This protects the client being released or other clients from claiming interfaces
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
esp_err_t ret;
const usb_config_desc_t *config_desc;
ESP_ERROR_CHECK(usbh_dev_get_config_desc(dev_hdl, &config_desc));
interface_t *intf_obj;
//Claim interface
// Claim interface
ret = interface_claim(client_obj, dev_hdl, config_desc, bInterfaceNumber, bAlternateSetting, &intf_obj);
if (ret != ESP_OK) {
goto exit;
@@ -1174,12 +1174,12 @@ esp_err_t usb_host_interface_release(usb_host_client_handle_t client_hdl, usb_de
HOST_ENTER_CRITICAL();
uint8_t dev_addr;
ESP_ERROR_CHECK(usbh_dev_get_addr(dev_hdl, &dev_addr));
//Check if client actually opened device
// Check if client actually opened device
HOST_CHECK_FROM_CRIT(_check_client_opened_device(client_obj, dev_addr), ESP_ERR_INVALID_STATE);
client_obj->dynamic.flags.taking_mux = 1;
HOST_EXIT_CRITICAL();
//Take mux lock. This protects the client being released or other clients from claiming interfaces
// Take mux lock. This protects the client being released or other clients from claiming interfaces
xSemaphoreTake(p_host_lib_obj->constant.mux_lock, portMAX_DELAY);
esp_err_t ret = interface_release(client_obj, dev_hdl, bInterfaceNumber);
xSemaphoreGive(p_host_lib_obj->constant.mux_lock);
@@ -1266,8 +1266,8 @@ esp_err_t usb_host_transfer_free(usb_transfer_t *transfer)
esp_err_t usb_host_transfer_submit(usb_transfer_t *transfer)
{
HOST_CHECK(transfer != NULL, ESP_ERR_INVALID_ARG);
//Check that transfer and target endpoint are valid
HOST_CHECK(transfer->device_handle != NULL, ESP_ERR_INVALID_ARG); //Target device must be set
// Check that transfer and target endpoint are valid
HOST_CHECK(transfer->device_handle != NULL, ESP_ERR_INVALID_ARG); // Target device must be set
HOST_CHECK((transfer->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK) != 0, ESP_ERR_INVALID_ARG);
usbh_ep_handle_t ep_hdl;
@@ -1281,7 +1281,7 @@ esp_err_t usb_host_transfer_submit(usb_transfer_t *transfer)
}
ep_wrap = usbh_ep_get_context(ep_hdl);
assert(ep_wrap != NULL);
//Check that we are not submitting a transfer already in-flight
// Check that we are not submitting a transfer already in-flight
HOST_CHECK(!urb_obj->usb_host_inflight, ESP_ERR_NOT_FINISHED);
urb_obj->usb_host_inflight = true;
HOST_ENTER_CRITICAL();
@@ -1306,17 +1306,17 @@ err:
esp_err_t usb_host_transfer_submit_control(usb_host_client_handle_t client_hdl, usb_transfer_t *transfer)
{
HOST_CHECK(client_hdl != NULL && transfer != NULL, ESP_ERR_INVALID_ARG);
//Check that control transfer is valid
HOST_CHECK(transfer->device_handle != NULL, ESP_ERR_INVALID_ARG); //Target device must be set
//Control transfers must be targeted at EP 0
// Check that control transfer is valid
HOST_CHECK(transfer->device_handle != NULL, ESP_ERR_INVALID_ARG); // Target device must be set
// Control transfers must be targeted at EP 0
HOST_CHECK((transfer->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_NUM_MASK) == 0, ESP_ERR_INVALID_ARG);
usb_device_handle_t dev_hdl = transfer->device_handle;
urb_t *urb_obj = __containerof(transfer, urb_t, transfer);
//Check that we are not submitting a transfer already in-flight
// Check that we are not submitting a transfer already in-flight
HOST_CHECK(!urb_obj->usb_host_inflight, ESP_ERR_NOT_FINISHED);
urb_obj->usb_host_inflight = true;
//Save client handle into URB
// Save client handle into URB
urb_obj->usb_host_client = (void *)client_hdl;
esp_err_t ret;