summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjzlv <[email protected]>2022-03-23 17:15:57 +0800
committerjzlv <[email protected]>2022-03-23 17:30:53 +0800
commit563888ec147a3d0d188991d7b9b61a6cc4702c17 (patch)
treed1339fecc64b332523b928aa23a9959f4e6509f4
parentc44a26d69f686f2aba3212aed9dbcb7682918bdb (diff)
update class driver info,support class driver export
-rw-r--r--class/cdc/usbh_cdc_acm.c10
-rw-r--r--class/cdc/usbh_cdc_acm.h2
-rw-r--r--class/hid/usbh_hid.c20
-rw-r--r--class/hid/usbh_hid.h3
-rw-r--r--class/hub/usbh_hub.c10
-rw-r--r--class/hub/usbh_hub.h4
-rw-r--r--class/msc/usbh_msc.c11
-rw-r--r--class/msc/usbh_msc.h4
-rw-r--r--core/usbh_core.c95
-rw-r--r--core/usbh_core.h10
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. */