Modify source files

This commit is contained in:
xj 2024-06-11 22:58:17 -07:00
parent 9469217fe6
commit 6039856cd2
4 changed files with 421 additions and 3 deletions

View File

@ -1,6 +1,124 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_HUB_H_
#define USB_HUB_H_
#include <stdint.h>
/* HUB Class Descriptor Types */
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
#define HUB_DESCRIPTOR_TYPE_HUB3 0x2a
/* Hub class requests */
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
#define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE
#define HUB_REQUEST_SET_FEATURE USB_REQUEST_SET_FEATURE
#define HUB_REQUEST_GET_DESCRIPTOR USB_REQUEST_GET_DESCRIPTOR
#define HUB_REQUEST_SET_DESCRIPTOR USB_REQUEST_SET_DESCRIPTOR
#define HUB_REQUEST_CLEAR_TT_BUFFER (0x08)
#define HUB_REQUEST_RESET_TT (0x09)
#define HUB_REQUEST_GET_TT_STATE (0x0a)
#define HUB_REQUEST_STOP_TT (0x0b)
#define HUB_REQUEST_SET_HUB_DEPTH (0x0C)
/* Hub class features */
#define HUB_FEATURE_HUB_C_LOCALPOWER (0x0)
#define HUB_FEATURE_HUB_C_OVERCURRENT (0x1)
/* Port features */
#define HUB_PORT_FEATURE_CONNECTION (0x00)
#define HUB_PORT_FEATURE_ENABLE (0x01)
#define HUB_PORT_FEATURE_SUSPEND (0x02)
#define HUB_PORT_FEATURE_OVERCURRENT (0x03)
#define HUB_PORT_FEATURE_RESET (0x04)
#define HUB_PORT_FEATURE_L1 (0x05)
#define HUB_PORT_FEATURE_POWER (0x08)
#define HUB_PORT_FEATURE_LOWSPEED (0x09)
#define HUB_PORT_FEATURE_HIGHSPEED (0x0a)
#define HUB_PORT_FEATURE_C_CONNECTION (0x10)
#define HUB_PORT_FEATURE_C_ENABLE (0x11)
#define HUB_PORT_FEATURE_C_SUSPEND (0x12)
#define HUB_PORT_FEATURE_C_OVER_CURREN (0x13)
#define HUB_PORT_FEATURE_C_RESET (0x14)
#define HUB_PORT_FEATURE_TEST (0x15)
#define HUB_PORT_FEATURE_INDICATOR (0x16)
#define HUB_PORT_FEATURE_C_PORTL1 (0x17)
/* Hub status */
#define HUB_STATUS_LOCALPOWER (1 << 0)
#define HUB_STATUS_OVERCURRENT (1 << 1)
/* Hub status change */
#define HUB_STATUS_C_LOCALPOWER (1 << 0)
#define HUB_STATUS_C_OVERCURRENT (1 << 1)
/* Hub port status */
#define HUB_PORT_STATUS_CONNECTION (1 << 0)
#define HUB_PORT_STATUS_ENABLE (1 << 1)
#define HUB_PORT_STATUS_SUSPEND (1 << 2)
#define HUB_PORT_STATUS_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_RESET (1 << 4)
#define HUB_PORT_STATUS_L1 (1 << 5)
#define HUB_PORT_STATUS_POWER (1 << 8)
#define HUB_PORT_STATUS_LOW_SPEED (1 << 9)
#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10)
#define HUB_PORT_STATUS_TEST (1 << 11)
#define HUB_PORT_STATUS_INDICATOR (1 << 12)
/* Hub port status change */
#define HUB_PORT_STATUS_C_CONNECTION (1 << 0)
#define HUB_PORT_STATUS_C_ENABLE (1 << 1)
#define HUB_PORT_STATUS_C_SUSPEND (1 << 2)
#define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3)
#define HUB_PORT_STATUS_C_RESET (1 << 4)
#define HUB_PORT_STATUS_C_L1 (1 << 5)
/* Hub characteristics */
#define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */
#define HUB_CHAR_LPSM_MASK (3 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_LPSM_GANGED (0 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_LPSM_INDIVIDUAL (1 << HUB_CHAR_LPSM_SHIFT)
#define HUB_CHAR_COMPOUND (1 << 2) /* Bit 2: Compound device */
#define HUB_CHAR_OCPM_SHIFT (3) /* Bits 3-4: Over-current Protection Mode */
#define HUB_CHAR_OCPM_MASK (3 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_OCPM_GLOBAL (0 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_OCPM_INDIVIDUAL (1 << HUB_CHAR_OCPM_SHIFT)
#define HUB_CHAR_TTTT_SHIFT (5) /* Bits 5-6: TT Think Time */
#define HUB_CHAR_TTTT_MASK (3 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_8_BITS (0 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_16_BITS (1 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_24_BITS (2 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_TTTT_32_BITS (3 << HUB_CHAR_TTTT_SHIFT)
#define HUB_CHAR_PORTIND (1 << 7) /* Bit 7: Port Indicators Supported */
/* Hub descriptor */
struct usb_hub_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bNbrPorts;
uint16_t wHubCharacteristics;
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
uint8_t DeviceRemovable;
uint8_t PortPwrCtrlMask;
} __PACKED;
#define USB_SIZEOF_HUB_DESC 9
/* Hub status */
struct hub_status {
uint16_t wPortStatus;
uint16_t wPortChange;
};
/* Hub port status */
struct hub_port_status {
uint16_t wPortStatus;
uint16_t wPortChange;
};

View File

@ -1,9 +1,25 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBH_HUB_H_
#define USBH_HUB_H_
#include "usbh_core.h"
#include "usb_hub.h"
#ifdef __cplusplus
extern "C" {
#endif
void usbh_roothub_thread_wakeup(uint32_t usb_id, uint8_t port);
int usbh_hub_initialize(struct usbh_bus *usb);
struct usbh_hubport *usbh_get_roothub_port (struct usbh_bus *bus, unsigned int port);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,7 +1,291 @@
#ifndef USBH_CORE_H_
#define USBH_CORE_H_
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "usb_config.h"
#include "usb_util.h"
#include "usb_errno.h"
#include "usb_def.h"
#include "usb_list.h"
#include "usb_mem.h"
#include "usb_log.h"
#include "usb_hc.h"
#include "usb_osal.h"
#include "usb_hub.h"
#ifdef __cplusplus
extern "C" {
#endif
#define USB_CLASS_MATCH_VENDOR 0x0001
#define USB_CLASS_MATCH_PRODUCT 0x0002
#define USB_CLASS_MATCH_INTF_CLASS 0x0004
#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))
#ifdef __ARMCC_VERSION /* ARM C Compiler */
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
#elif defined(__GNUC__)
#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
#elif defined(__ICCARM__) || defined(__ICCRX__)
#pragma section = "usbh_class_info"
#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;
}
struct usbh_class_info {
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
uint8_t class; /* Base device class code */
uint8_t subclass; /* Sub-class, depends on base class. Eg. */
uint8_t protocol; /* Protocol, depends on base class. Eg. */
uint16_t vid; /* Vendor ID (for vendor/product specific devices) */
uint16_t pid; /* Product ID (for vendor/product specific devices) */
const struct usbh_class_driver *class_driver;
};
struct usbh_hubport;
struct usbh_class_driver {
const char *driver_name;
int (*connect)(struct usbh_hubport *hport, uint8_t intf);
int (*disconnect)(struct usbh_hubport *hport, uint8_t intf);
};
struct usbh_endpoint {
struct usb_endpoint_descriptor ep_desc;
};
struct usbh_interface_altsetting {
struct usb_interface_descriptor intf_desc;
struct usbh_endpoint ep[CONFIG_USBHOST_MAX_ENDPOINTS];
};
struct usbh_interface {
char devname[CONFIG_USBHOST_DEV_NAMELEN];
struct usbh_class_driver *class_driver;
void *priv;
struct usbh_interface_altsetting altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
uint8_t altsetting_num;
};
struct usbh_configuration {
struct usb_configuration_descriptor config_desc;
struct usbh_interface intf[CONFIG_USBHOST_MAX_INTERFACES];
};
struct usbh_hub;
struct usbh_hubport {
/** Name */
char name[32];
bool connected; /* True: device connected; false: disconnected */
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_device_descriptor device_desc;
struct usbh_configuration config;
const char *iManufacturer;
const char *iProduct;
const char *iSerialNumber;
uint8_t *raw_config_desc;
struct usb_setup_packet *setup;
struct usbh_hub *parent;
#ifdef CONFIG_USBHOST_XHCI
uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */
#endif
};
struct usbh_bus;
struct usbh_hub {
usb_slist_t list;
bool connected;
bool is_roothub;
uint8_t index;
uint8_t hub_addr;
usbh_pipe_t intin;
uint8_t *int_buffer;
struct usbh_urb intin_urb;
struct usb_hub_descriptor hub_desc;
struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS];
struct usbh_hubport *parent;
usb_slist_t hub_event_list;
struct usbh_bus *usb;
uint32_t ports; /* num of ports */
USB_MEM_ALIGNX uint8_t g_hub_buf[32];
USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1];
};
int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc);
/**
* @brief Submit an control transfer to an endpoint.
* This is a blocking method; this method will not return until the transfer has completed.
* Default timeout is 500ms.
*
* @param pipe The control endpoint to send/receive the control request.
* @param setup Setup packet to be sent.
* @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);
struct usbh_devaddr_map {
/**
* alloctab[0]:addr from 0~31
* alloctab[1]:addr from 32~63
* alloctab[2]:addr from 64~95
* alloctab[3]:addr from 96~127
*
*/
uint8_t next; /* Next device address */
uint32_t alloctab[4]; /* Bit allocation table */
};
struct usbh_bus {
usb_slist_t list;
uint8_t id;
/** Largest transfer allowed on the bus */
size_t mtu;
struct usbh_devaddr_map devgen;
struct usbh_hub roothub;
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS];
#endif
struct usbh_hubport roothub_parent_port;
usb_slist_t hub_event_head;
usb_slist_t hub_class_head;
usb_osal_sem_t hub_event_wait;
usb_osal_thread_t hub_thread;
usb_osal_mq_t hub_mq;
void *priv; /* private data, usb host */
int (*hub_open)(struct usbh_hub *hub);
void (*hub_close)(struct usbh_hub *hub);
int (*root_open)(struct usbh_hub *hub);
USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN];
USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
};
/**
* Get USB transaction translator
*
* @v hport Hub port of USB device
* @ret port Transaction translator port, or NULL
*/
struct usbh_hubport *usbh_transaction_translator ( struct usbh_hubport *hport );
/**
* Get USB route string
*
* @v hport Hub Port of USB device
* @ret route USB route string
*/
unsigned int usbh_route_string ( struct usbh_hubport *hport );
static inline struct usbh_bus* usbh_get_bus_of_port(struct usbh_hubport *hport)
{
USB_ASSERT(hport && hport->parent);
return hport->parent->usb;
}
static inline struct usbh_hub *usbh_get_roothub_of_port(struct usbh_hubport *hport)
{
return &(usbh_get_bus_of_port(hport)->roothub);
}
struct usbh_bus* usbh_get_bus_of_index(uint8_t usb);
/**
* Get USB root hub port
*
* @v hport Hub port of USB device
* @ret port Root hub port
*/
struct usbh_hubport * usbh_root_hub_port ( struct usbh_hubport *hport );
int usbh_initialize(uint32_t id, struct usbh_bus *usb);
struct usbh_hubport *usbh_find_hubport(uint32_t id, uint8_t dev_addr);
void *usbh_find_class_instance(const char *devname);
int lsusb(int argc, char **argv);
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,6 @@
#include "usb_osal.h"
int usb_wait_until(int msec){
return 0;
}
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args){
return NULL;
}