add usbh_deinitialize api

This commit is contained in:
sakumisu
2023-12-24 23:37:47 +08:00
parent 8a831cdaa5
commit f68a86ea89
12 changed files with 179 additions and 0 deletions

View File

@@ -647,6 +647,8 @@ static void usbh_hub_thread(void *argument)
static void usbh_roothub_register(void)
{
usb_slist_init(&hub_class_head);
memset(&roothub, 0, sizeof(struct usbh_hub));
roothub.connected = true;
@@ -680,6 +682,36 @@ int usbh_hub_initialize(void)
}
return 0;
}
int usbh_hub_deinitialize(void)
{
usb_slist_t *i;
struct usbh_hubport *hport;
size_t flags;
flags = usb_osal_enter_critical_section();
usb_slist_for_each(i, &hub_class_head)
{
struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
hport = &hub->child[port];
usbh_hubport_release(hport);
}
}
usb_hc_deinit();
usb_osal_leave_critical_section(flags);
usb_osal_mq_delete(hub_mq);
usb_osal_thread_delete(hub_thread);
return 0;
}
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
const struct usbh_class_driver hub_class_driver = {
.driver_name = "hub",

View File

@@ -23,7 +23,10 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
void usbh_roothub_thread_wakeup(uint8_t port);
int usbh_hub_initialize(void);
int usbh_hub_deinitialize(void);
#ifdef __cplusplus
}
#endif

View File

@@ -61,6 +61,13 @@ struct usbh_urb {
*/
int usb_hc_init(void);
/**
* @brief usb host controller hardware deinit.
*
* @return On success will return 0, and others indicate fail.
*/
int usb_hc_deinit(void);
/**
* @brief Get frame number.
*

View File

@@ -35,6 +35,7 @@ int usb_osal_mutex_take(usb_osal_mutex_t mutex);
int usb_osal_mutex_give(usb_osal_mutex_t mutex);
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs);
void usb_osal_mq_delete(usb_osal_mq_t mq);
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr);
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout);

View File

@@ -666,6 +666,11 @@ int usbh_initialize(void)
return 0;
}
int usbh_deinitialize(void)
{
return usbh_hub_deinitialize();
}
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
{
struct usbh_urb *urb;

View File

@@ -226,6 +226,7 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
int usbh_initialize(void);
int usbh_deinitialize(void);
void *usbh_find_class_instance(const char *devname);
int lsusb(int argc, char **argv);

View File

@@ -89,6 +89,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
return (usb_osal_mq_t)xQueueCreate(max_msgs, sizeof(uintptr_t));
}
void usb_osal_mq_delete(usb_osal_mq_t mq)
{
vQueueDelete((QueueHandle_t)mq);
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;

View File

@@ -91,6 +91,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
return (usb_osal_mq_t)rt_mq_create("usbh_mq", sizeof(uintptr_t), max_msgs, RT_IPC_FLAG_FIFO);
}
void usb_osal_mq_delete(usb_osal_mq_t mq)
{
rt_mq_delete((rt_mq_t)mq);
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
return rt_mq_send((rt_mq_t)mq, &addr, sizeof(uintptr_t));

View File

@@ -89,6 +89,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
return (usb_osal_mq_t)queue;
}
void usb_osal_mq_delete(usb_osal_mq_t mq)
{
aos_queue_free((aos_queue_t)mq);
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
return aos_queue_send((aos_queue_t *)&mq, &addr, sizeof(uintptr_t));

View File

@@ -525,6 +525,57 @@ int usb_hc_init(void)
return 0;
}
int usb_hc_deinit(void)
{
volatile uint32_t count = 0U;
uint32_t value;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
dwc2_flush_txfifo(0x10U);
dwc2_flush_rxfifo();
/* Flush out any leftover queued requests. */
for (uint32_t i = 0U; i <= 15U; i++) {
value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS;
value &= ~USB_OTG_HCCHAR_CHENA;
value &= ~USB_OTG_HCCHAR_EPDIR;
USB_OTG_HC(i)->HCCHAR = value;
}
/* Halt all channels to put them into a known state. */
for (uint32_t i = 0U; i <= 15U; i++) {
value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS;
value |= USB_OTG_HCCHAR_CHENA;
value &= ~USB_OTG_HCCHAR_EPDIR;
USB_OTG_HC(i)->HCCHAR = value;
do {
if (++count > 1000U) {
return -USB_ERR_TIMEOUT;
}
} while ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
}
/* Disable all interrupts. */
USB_OTG_GLB->GINTMSK = 0U;
/* Clear any pending Host interrupts */
USB_OTG_HOST->HAINT = 0xFFFFFFFFU;
USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
dwc2_drivebus(0);
usb_osal_msleep(200);
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
usb_osal_sem_delete(g_dwc2_hcd.chan_pool[chidx].waitsem);
}
return 0;
}
uint16_t usbh_get_frame_number(void)
{
return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);

View File

@@ -906,6 +906,51 @@ int usb_hc_init(void)
return 0;
}
int usb_hc_deinit(void)
{
struct ehci_qh_hw *qh;
volatile uint32_t timeout = 0;
uint32_t regval;
EHCI_HCOR->usbintr = 0;
regval = EHCI_HCOR->usbcmd;
regval &= ~EHCI_USBCMD_ASEN;
regval &= ~EHCI_USBCMD_PSEN;
regval &= ~EHCI_USBCMD_RUN;
EHCI_HCOR->usbcmd = regval;
while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS))) {
usb_osal_msleep(1);
timeout++;
if (timeout > 100) {
return -USB_ERR_TIMEOUT;
}
}
#ifdef CONFIG_USB_EHCI_PORT_POWER
for (uint8_t port = 0; port < CONFIG_USBHOST_MAX_RHPORTS; port++) {
regval = EHCI_HCOR->portsc[port];
regval &= ~EHCI_PORTSC_PP;
EHCI_HCOR->portsc[port] = regval;
}
#endif
#ifdef CONFIG_USB_EHCI_CONFIGFLAG
EHCI_HCOR->configflag = 0;
#endif
EHCI_HCOR->usbsts = EHCI_HCOR->usbsts;
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
qh = &ehci_qh_pool[index];
usb_osal_sem_delete(qh->waitsem);
}
return 0;
}
uint16_t usbh_get_frame_number(void)
{
return (((EHCI_HCOR->frindex & EHCI_FRINDEX_MASK) >> 3) & 0x3ff);
@@ -1199,6 +1244,9 @@ int usbh_kill_urb(struct usbh_urb *urb)
} else {
#ifdef CONFIG_USB_EHCI_ISO
ehci_remove_itd_urb(urb);
EHCI_HCOR->usbcmd |= (EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
usb_osal_leave_critical_section(flags);
return 0;
#endif
}

View File

@@ -470,6 +470,22 @@ int usb_hc_init(void)
return 0;
}
int usb_hc_deinit(void)
{
HWREGB(USB_BASE + MUSB_IE_OFFSET) = 0;
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = 0;
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) &= ~USB_DEVCTL_SESSION;
for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
usb_osal_sem_delete(g_musb_hcd.pipe_pool[i].waitsem);
}
return 0;
}
int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
{
uint8_t nports;