refactor urb, add ep & hport in urb to make hardware pipe more reusable
This commit is contained in:
127
core/usbh_core.c
127
core/usbh_core.c
@@ -64,7 +64,7 @@ static int usbh_allocate_devaddr(struct usbh_devaddr_map *devgen)
|
||||
}
|
||||
}
|
||||
|
||||
static int usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
|
||||
static int __usbh_free_devaddr(struct usbh_devaddr_map *devgen, uint8_t devaddr)
|
||||
{
|
||||
int index;
|
||||
int bitno;
|
||||
@@ -340,57 +340,18 @@ static int usbh_get_default_mps(int speed)
|
||||
}
|
||||
}
|
||||
|
||||
int usbh_hport_activate_ep0(struct usbh_hubport *hport)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep0_cfg = { 0 };
|
||||
|
||||
ep0_cfg.ep_addr = 0x00;
|
||||
ep0_cfg.ep_interval = 0x00;
|
||||
ep0_cfg.ep_mps = usbh_get_default_mps(hport->speed);
|
||||
ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
|
||||
ep0_cfg.hport = hport;
|
||||
|
||||
usbh_pipe_alloc(&hport->ep0, &ep0_cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_hport_deactivate_ep0(struct usbh_hubport *hport)
|
||||
int usbh_free_devaddr(struct usbh_hubport *hport)
|
||||
{
|
||||
#ifndef CONFIG_USBHOST_XHCI
|
||||
if (hport->dev_addr > 0) {
|
||||
usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
|
||||
__usbh_free_devaddr(&g_usbh_bus.devgen, hport->dev_addr);
|
||||
}
|
||||
#endif
|
||||
if (hport->ep0) {
|
||||
usbh_pipe_free(hport->ep0);
|
||||
}
|
||||
|
||||
hport->ep0 = NULL;
|
||||
hport->dev_addr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep_cfg = { 0 };
|
||||
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
|
||||
ep_cfg.hport = hport;
|
||||
|
||||
USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n",
|
||||
ep_cfg.ep_addr,
|
||||
ep_desc->bmAttributes,
|
||||
ep_cfg.ep_mps,
|
||||
ep_cfg.ep_interval,
|
||||
ep_cfg.mult);
|
||||
|
||||
return usbh_pipe_alloc(pipe, &ep_cfg);
|
||||
}
|
||||
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
@@ -408,7 +369,7 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
|
||||
setup->wIndex = 0x0409;
|
||||
setup->wLength = 255;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -436,7 +397,7 @@ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsett
|
||||
setup->wIndex = altsetting;
|
||||
setup->wLength = 0;
|
||||
|
||||
return usbh_control_transfer(hport->ep0, setup, NULL);
|
||||
return usbh_control_transfer(hport, setup, NULL);
|
||||
}
|
||||
|
||||
int usbh_enumerate(struct usbh_hubport *hport)
|
||||
@@ -444,12 +405,25 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
struct usb_interface_descriptor *intf_desc;
|
||||
struct usb_setup_packet *setup;
|
||||
struct usb_device_descriptor *dev_desc;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
int dev_addr;
|
||||
uint16_t ep_mps;
|
||||
int ret;
|
||||
|
||||
hport->setup = &g_setup[hport->parent->index - 1][hport->port - 1];
|
||||
setup = hport->setup;
|
||||
ep = &hport->ep0;
|
||||
|
||||
/* Config EP0 mps from speed */
|
||||
ep->bEndpointAddress = 0x00;
|
||||
ep->bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT;
|
||||
ep->bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
|
||||
ep->wMaxPacketSize = usbh_get_default_mps(hport->speed);
|
||||
ep->bInterval = 0;
|
||||
ep->bLength = 7;
|
||||
|
||||
/* Configure EP0 with zero address */
|
||||
hport->dev_addr = 0;
|
||||
|
||||
/* Read the first 8 bytes of the device descriptor */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -458,7 +432,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 8;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get device descriptor,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -479,7 +453,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
dev_desc->bDeviceProtocol, ep_mps);
|
||||
|
||||
/* Reconfigure EP0 with the correct maximum packet size */
|
||||
usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0);
|
||||
ep->wMaxPacketSize = ep_mps;
|
||||
|
||||
#ifdef CONFIG_USBHOST_XHCI
|
||||
extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe);
|
||||
@@ -506,7 +480,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 0;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, NULL);
|
||||
ret = usbh_control_transfer(hport, setup, NULL);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to set devaddr,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -515,12 +489,9 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
/* Wait device set address completely */
|
||||
usb_osal_msleep(2);
|
||||
|
||||
/* Assign the function address to the port */
|
||||
/*Reconfigure EP0 with the correct address */
|
||||
hport->dev_addr = dev_addr;
|
||||
|
||||
/* And reconfigure EP0 with the correct address */
|
||||
usbh_ep_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, 0);
|
||||
|
||||
/* Read the full device descriptor */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
@@ -528,7 +499,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = USB_SIZEOF_DEVICE_DESC;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get full device descriptor,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -547,7 +518,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = USB_SIZEOF_CONFIG_DESC;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get config descriptor,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -564,7 +535,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = wTotalLength;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get full config descriptor,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -623,7 +594,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 0;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, NULL);
|
||||
ret = usbh_control_transfer(hport, setup, NULL);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to set configuration,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
@@ -670,27 +641,6 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *usbh_find_class_instance(const char *devname)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
usb_slist_t *hub_list;
|
||||
|
||||
usb_slist_for_each(hub_list, &hub_class_head)
|
||||
{
|
||||
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
|
||||
if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
|
||||
return hport->config.intf[itf].priv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int usbh_initialize(void)
|
||||
{
|
||||
memset(&g_usbh_bus, 0, sizeof(struct usbh_bus));
|
||||
@@ -717,7 +667,7 @@ int usbh_initialize(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer)
|
||||
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
|
||||
{
|
||||
struct usbh_urb *urb;
|
||||
int ret;
|
||||
@@ -725,7 +675,7 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint
|
||||
urb = usb_malloc(sizeof(struct usbh_urb));
|
||||
memset(urb, 0, sizeof(struct usbh_urb));
|
||||
|
||||
usbh_control_urb_fill(urb, pipe, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
|
||||
usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
|
||||
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
@@ -735,6 +685,27 @@ int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *usbh_find_class_instance(const char *devname)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
usb_slist_t *hub_list;
|
||||
|
||||
usb_slist_for_each(hub_list, &hub_class_head)
|
||||
{
|
||||
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) {
|
||||
if ((strncmp(hport->config.intf[itf].devname, devname, CONFIG_USBHOST_DEV_NAMELEN) == 0) && hport->config.intf[itf].priv)
|
||||
return hport->config.intf[itf].priv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int lsusb(int argc, char **argv)
|
||||
{
|
||||
usb_slist_t *i;
|
||||
|
||||
138
core/usbh_core.h
138
core/usbh_core.h
@@ -32,8 +32,8 @@ extern "C" {
|
||||
#define USB_CLASS_MATCH_INTF_SUBCLASS 0x0008
|
||||
#define USB_CLASS_MATCH_INTF_PROTOCOL 0x0010
|
||||
|
||||
#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
|
||||
#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
|
||||
#define CLASS_CONNECT(hport, i) ((hport)->config.intf[i].class_driver->connect(hport, i))
|
||||
#define CLASS_DISCONNECT(hport, i) ((hport)->config.intf[i].class_driver->disconnect(hport, i))
|
||||
|
||||
#ifdef __ARMCC_VERSION /* ARM C Compiler */
|
||||
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
|
||||
@@ -44,57 +44,16 @@ extern "C" {
|
||||
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
|
||||
#endif
|
||||
|
||||
static inline void usbh_control_urb_fill(struct usbh_urb *urb,
|
||||
usbh_pipe_t pipe,
|
||||
struct usb_setup_packet *setup,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->pipe = pipe;
|
||||
urb->setup = setup;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
|
||||
static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
|
||||
usbh_pipe_t pipe,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->pipe = pipe;
|
||||
urb->setup = NULL;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
|
||||
static inline void usbh_int_urb_fill(struct usbh_urb *urb,
|
||||
usbh_pipe_t pipe,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->pipe = pipe;
|
||||
urb->setup = NULL;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
#define USBH_EP_INIT(ep, ep_desc) \
|
||||
do { \
|
||||
ep = ep_desc; \
|
||||
USB_LOG_INFO("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", \
|
||||
ep_desc->bEndpointAddress, \
|
||||
USB_GET_ENDPOINT_TYPE(ep_desc->bmAttributes), \
|
||||
USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), \
|
||||
ep_desc->bInterval, \
|
||||
USB_GET_MULT(ep_desc->bmAttributes)); \
|
||||
} while (0)
|
||||
|
||||
struct usbh_class_info {
|
||||
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
|
||||
@@ -140,7 +99,7 @@ struct usbh_hubport {
|
||||
uint8_t port; /* Hub port index */
|
||||
uint8_t dev_addr; /* device address */
|
||||
uint8_t speed; /* device speed */
|
||||
usbh_pipe_t ep0; /* control ep pipe info */
|
||||
struct usb_endpoint_descriptor ep0;
|
||||
struct usb_device_descriptor device_desc;
|
||||
struct usbh_configuration config;
|
||||
const char *iManufacturer;
|
||||
@@ -161,7 +120,7 @@ struct usbh_hub {
|
||||
bool is_roothub;
|
||||
uint8_t index;
|
||||
uint8_t hub_addr;
|
||||
usbh_pipe_t intin;
|
||||
struct usb_endpoint_descriptor *intin;
|
||||
uint8_t *int_buffer;
|
||||
struct usbh_urb intin_urb;
|
||||
struct usb_hub_descriptor hub_desc;
|
||||
@@ -169,17 +128,62 @@ struct usbh_hub {
|
||||
struct usbh_hubport *parent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Activates an endpoint for a USB host pipe on a specific hub port.
|
||||
*
|
||||
* This function is responsible for activating the specified endpoint
|
||||
* described by the given endpoint descriptor on the USB host pipe.
|
||||
* @param pipe Pointer to the USB host pipe structure.
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param ep_desc Pointer to the USB endpoint descriptor.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc);
|
||||
static inline void usbh_control_urb_fill(struct usbh_urb *urb,
|
||||
struct usbh_hubport *hport,
|
||||
struct usb_setup_packet *setup,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->hport = hport;
|
||||
urb->ep = &hport->ep0;
|
||||
urb->setup = setup;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
|
||||
static inline void usbh_bulk_urb_fill(struct usbh_urb *urb,
|
||||
struct usbh_hubport *hport,
|
||||
struct usb_endpoint_descriptor *ep,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->hport = hport;
|
||||
urb->ep = ep;
|
||||
urb->setup = NULL;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
|
||||
static inline void usbh_int_urb_fill(struct usbh_urb *urb,
|
||||
struct usbh_hubport *hport,
|
||||
struct usb_endpoint_descriptor *ep,
|
||||
uint8_t *transfer_buffer,
|
||||
uint32_t transfer_buffer_length,
|
||||
uint32_t timeout,
|
||||
usbh_complete_callback_t complete,
|
||||
void *arg)
|
||||
{
|
||||
urb->hport = hport;
|
||||
urb->ep = ep;
|
||||
urb->setup = NULL;
|
||||
urb->transfer_buffer = transfer_buffer;
|
||||
urb->transfer_buffer_length = transfer_buffer_length;
|
||||
urb->timeout = timeout;
|
||||
urb->complete = complete;
|
||||
urb->arg = arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Submit an control transfer to an endpoint.
|
||||
@@ -191,7 +195,7 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc
|
||||
* @param buffer buffer used for sending the request and for returning any responses.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer);
|
||||
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Retrieves a USB string descriptor from a specific hub port.
|
||||
|
||||
Reference in New Issue
Block a user