diff options
| author | jzlv <[email protected]> | 2022-03-23 17:15:57 +0800 |
|---|---|---|
| committer | jzlv <[email protected]> | 2022-03-23 17:30:53 +0800 |
| commit | 563888ec147a3d0d188991d7b9b61a6cc4702c17 (patch) | |
| tree | d1339fecc64b332523b928aa23a9959f4e6509f4 | |
| parent | c44a26d69f686f2aba3212aed9dbcb7682918bdb (diff) | |
update class driver info,support class driver export
| -rw-r--r-- | class/cdc/usbh_cdc_acm.c | 10 | ||||
| -rw-r--r-- | class/cdc/usbh_cdc_acm.h | 2 | ||||
| -rw-r--r-- | class/hid/usbh_hid.c | 20 | ||||
| -rw-r--r-- | class/hid/usbh_hid.h | 3 | ||||
| -rw-r--r-- | class/hub/usbh_hub.c | 10 | ||||
| -rw-r--r-- | class/hub/usbh_hub.h | 4 | ||||
| -rw-r--r-- | class/msc/usbh_msc.c | 11 | ||||
| -rw-r--r-- | class/msc/usbh_msc.h | 4 | ||||
| -rw-r--r-- | core/usbh_core.c | 95 | ||||
| -rw-r--r-- | core/usbh_core.h | 10 |
10 files changed, 108 insertions, 61 deletions
diff --git a/class/cdc/usbh_cdc_acm.c b/class/cdc/usbh_cdc_acm.c index 5eb0489f..0a4ef400 100644 --- a/class/cdc/usbh_cdc_acm.c +++ b/class/cdc/usbh_cdc_acm.c @@ -273,3 +273,13 @@ const struct usbh_class_driver cdc_acm_class_driver = { .connect = usbh_cdc_acm_connect, .disconnect = usbh_cdc_acm_disconnect }; + +CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .class = USB_DEVICE_CLASS_CDC, + .subclass = CDC_ABSTRACT_CONTROL_MODEL, + .protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS, + .vid = 0x00, + .pid = 0x00, + .class_driver = &cdc_acm_class_driver +};
\ No newline at end of file diff --git a/class/cdc/usbh_cdc_acm.h b/class/cdc/usbh_cdc_acm.h index 4e9ea8a4..6e5c8a10 100644 --- a/class/cdc/usbh_cdc_acm.h +++ b/class/cdc/usbh_cdc_acm.h @@ -41,7 +41,7 @@ struct usbh_cdc_acm { #endif }; -extern const struct usbh_class_driver cdc_acm_class_driver; +extern const struct usbh_class_info cdc_acm_class_info; #ifdef __cplusplus extern "C" { diff --git a/class/hid/usbh_hid.c b/class/hid/usbh_hid.c index 64582041..ab5541b8 100644 --- a/class/hid/usbh_hid.c +++ b/class/hid/usbh_hid.c @@ -240,3 +240,23 @@ const struct usbh_class_driver hid_class_driver = { .connect = usbh_hid_connect, .disconnect = usbh_hid_disconnect }; + +CLASS_INFO_DEFINE const struct usbh_class_info hid_keyboard_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .class = USB_DEVICE_CLASS_HID, + .subclass = HID_SUBCLASS_BOOTIF, + .protocol = HID_PROTOCOL_KEYBOARD, + .vid = 0x00, + .pid = 0x00, + .class_driver = &hid_class_driver +}; + +CLASS_INFO_DEFINE const struct usbh_class_info hid_mouse_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .class = USB_DEVICE_CLASS_HID, + .subclass = HID_SUBCLASS_BOOTIF, + .protocol = HID_PROTOCOL_MOUSE, + .vid = 0x00, + .pid = 0x00, + .class_driver = &hid_class_driver +};
\ No newline at end of file diff --git a/class/hid/usbh_hid.h b/class/hid/usbh_hid.h index ccc051de..6c03b75e 100644 --- a/class/hid/usbh_hid.h +++ b/class/hid/usbh_hid.h @@ -34,7 +34,8 @@ struct usbh_hid { usbh_epinfo_t intout; /* INTR OUT endpoint */ }; -extern const struct usbh_class_driver hid_class_driver; +extern const struct usbh_class_info hid_keyboard_class_info; +extern const struct usbh_class_info hid_mouse_class_info; #ifdef __cplusplus extern "C" { diff --git a/class/hub/usbh_hub.c b/class/hub/usbh_hub.c index 69b75dd2..9eede10e 100644 --- a/class/hub/usbh_hub.c +++ b/class/hub/usbh_hub.c @@ -506,4 +506,14 @@ const struct usbh_class_driver hub_class_driver = { .driver_name = "hub", .connect = usbh_hub_connect, .disconnect = usbh_hub_disconnect +}; + +CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS, + .class = USB_DEVICE_CLASS_HUB, + .subclass = 0, + .protocol = 0, + .vid = 0x00, + .pid = 0x00, + .class_driver = &hub_class_driver };
\ No newline at end of file diff --git a/class/hub/usbh_hub.h b/class/hub/usbh_hub.h index 82bf1701..152eb376 100644 --- a/class/hub/usbh_hub.h +++ b/class/hub/usbh_hub.h @@ -29,9 +29,9 @@ /* Maximum size of an interrupt IN transfer */ #define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3) -extern const struct usbh_class_driver hub_class_driver; +extern const struct usbh_class_info hub_class_info; extern usb_slist_t hub_class_head; -extern usb_osal_thread_t hub_thread; + #ifdef __cplusplus extern "C" { #endif diff --git a/class/msc/usbh_msc.c b/class/msc/usbh_msc.c index f78b4662..1b4992e8 100644 --- a/class/msc/usbh_msc.c +++ b/class/msc/usbh_msc.c @@ -338,6 +338,7 @@ int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) } memset(msc_class, 0, sizeof(struct usbh_msc)); + msc_class->hport = hport; usbh_msc_devno_alloc(msc_class); snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); @@ -428,3 +429,13 @@ const struct usbh_class_driver msc_class_driver = { .connect = usbh_msc_connect, .disconnect = usbh_msc_disconnect }; + +CLASS_INFO_DEFINE const struct usbh_class_info msc_class_info = { + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .class = USB_DEVICE_CLASS_MASS_STORAGE, + .subclass = MSC_SUBCLASS_SCSI, + .protocol = MSC_PROTOCOL_BULK_ONLY, + .vid = 0x00, + .pid = 0x00, + .class_driver = &msc_class_driver +};
\ No newline at end of file diff --git a/class/msc/usbh_msc.h b/class/msc/usbh_msc.h index c37b7bf8..b7ef0d3a 100644 --- a/class/msc/usbh_msc.h +++ b/class/msc/usbh_msc.h @@ -38,7 +38,7 @@ struct usbh_msc { uint16_t blocksize; /* Block size of USB mass storage device */ }; -extern const struct usbh_class_driver msc_class_driver; +extern const struct usbh_class_info msc_class_info; int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors); int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors); @@ -51,4 +51,4 @@ extern "C" { } #endif -#endif +#endif
\ No newline at end of file diff --git a/core/usbh_core.c b/core/usbh_core.c index 74454b42..28b4d468 100644 --- a/core/usbh_core.c +++ b/core/usbh_core.c @@ -25,6 +25,12 @@ #include "usbh_hid.h" #include "usbh_msc.h" +extern uint32_t _usbh_class_info_start; +extern uint32_t _usbh_class_info_end; + +struct usbh_class_info *usbh_class_info_table_begin = NULL; +struct usbh_class_info *usbh_class_info_table_end = NULL; + static const char *speed_table[] = { "error speed", "low speed", "full speed", "high speed" }; static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subcalss, uint8_t protocol, uint16_t vid, uint16_t pid); @@ -808,6 +814,9 @@ int usbh_initialize(void) usb_osal_thread_t usb_thread; memset(&usbh_core_cfg, 0, sizeof(struct usbh_core_priv)); + + usbh_class_info_table_begin = (struct usbh_class_info *)&_usbh_class_info_start; + usbh_class_info_table_end = (struct usbh_class_info *)&_usbh_class_info_end; #ifdef CONFIG_USBHOST_HUB usbh_workq_initialize(); #endif @@ -922,6 +931,7 @@ struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr) } } } +#ifdef CONFIG_USBHOST_HUB usb_slist_for_each(hub_list, &hub_class_head) { usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list); @@ -934,6 +944,7 @@ struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr) } } } +#endif return NULL; } @@ -952,6 +963,7 @@ void *usbh_find_class_instance(const char *devname) } } } +#ifdef CONFIG_USBHOST_HUB usb_slist_for_each(hub_list, &hub_class_head) { usbh_hub_t *hub_class = usb_slist_entry(hub_list, struct usbh_hub, list); @@ -966,67 +978,44 @@ void *usbh_find_class_instance(const char *devname) } } } +#endif return NULL; } -const struct usbh_class_info class_info_table[] = { - - { .class = USB_DEVICE_CLASS_CDC, - .subclass = CDC_ABSTRACT_CONTROL_MODEL, - .protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS, - .vid = 0x00, - .pid = 0x00, - .class_driver = &cdc_acm_class_driver }, - { .class = USB_DEVICE_CLASS_HID, - .subclass = HID_SUBCLASS_BOOTIF, - .protocol = HID_PROTOCOL_KEYBOARD, - .vid = 0x00, - .pid = 0x00, - .class_driver = &hid_class_driver }, - { .class = USB_DEVICE_CLASS_HID, - .subclass = HID_SUBCLASS_BOOTIF, - .protocol = HID_PROTOCOL_MOUSE, - .vid = 0x00, - .pid = 0x00, - .class_driver = &hid_class_driver }, - { .class = USB_DEVICE_CLASS_MASS_STORAGE, - .subclass = MSC_SUBCLASS_SCSI, - .protocol = MSC_PROTOCOL_BULK_ONLY, - .vid = 0x00, - .pid = 0x00, - .class_driver = &msc_class_driver }, -#ifdef CONFIG_USBHOST_HUB - { .class = USB_DEVICE_CLASS_HUB, - .subclass = 0, - .protocol = 0, - .vid = 0x00, - .pid = 0x00, - .class_driver = &hub_class_driver }, - { .class = USB_DEVICE_CLASS_HUB, - .subclass = 0, - .protocol = 1, - .vid = 0x00, - .pid = 0x00, - .class_driver = &hub_class_driver }, -#endif +const struct usbh_class_info *class_info_table[] = { + &cdc_acm_class_info, + &hid_keyboard_class_info, + &hid_mouse_class_info, + &msc_class_info, + &hub_class_info, }; -static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subcalss, uint8_t protocol, uint16_t vid, uint16_t pid) +static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uint8_t subclass, uint8_t protocol, uint16_t vid, uint16_t pid) { - for (uint8_t i = 0; i < sizeof(class_info_table) / sizeof(class_info_table[0]); i++) { - if (class == class_info_table[i].class && - subcalss == class_info_table[i].subclass && - protocol == class_info_table[i].protocol) { - /* If this is a vendor-specific class ID, then the VID and PID have to match as well. */ - if (class == USB_DEVICE_CLASS_VEND_SPECIFIC) { - if (vid == class_info_table[i].vid && - pid == class_info_table[i].pid) { - return class_info_table[i].class_driver; - } + struct usbh_class_info *index = NULL; + + for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) { + if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) == + (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) { + if (index->vid == vid && index->pid == pid && + index->class == class && index->subclass == subclass && index->protocol == protocol) { + return index->class_driver; + } + } else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) == + (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL)) { + if (index->class == class && index->subclass == subclass && index->protocol == protocol) { + return index->class_driver; + } + } else if ((index->match_flags & (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) == + (USB_CLASS_MATCH_VENDOR | USB_CLASS_MATCH_PRODUCT | USB_CLASS_MATCH_INTF_CLASS)) { + if (index->vid == vid && index->pid == pid && index->class == class) { + return index->class_driver; + } + } else if (index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) { + if (index->class == class) { + return index->class_driver; } - return class_info_table[i].class_driver; } } - return NULL; } diff --git a/core/usbh_core.h b/core/usbh_core.h index dd46b17d..89010c8d 100644 --- a/core/usbh_core.h +++ b/core/usbh_core.h @@ -1,6 +1,5 @@ /** * @file usbh_core.h - * @brief * * Copyright (c) 2022 sakumisu * @@ -47,8 +46,15 @@ extern "C" { #define ROOTHUB(hport) true #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)) +#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1) enum usbh_event_type { USBH_EVENT_CONNECTED = (1 << 0), @@ -56,7 +62,7 @@ enum usbh_event_type { }; struct usbh_class_info { - uint8_t match_flags; + 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. */ |
