Skip to content

Commit cad9ff3

Browse files
author
Josuah Demangeon
committed
usb: host: introduce wrappers to access the class function pointers
Add API wrappers around the function pointers in struct usbh_class_api, while also documenting the USB host class internal API. Signed-off-by: Josuah Demangeon <[email protected]>
1 parent 90fad56 commit cad9ff3

File tree

3 files changed

+230
-13
lines changed

3 files changed

+230
-13
lines changed

include/zephyr/usb/usbh.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,18 @@ struct usbh_class_data;
9090
* @brief USB host class instance API
9191
*/
9292
struct usbh_class_api {
93-
/** Initialization of the class implementation */
94-
int (*init)(struct usbh_class_data *const c_data);
93+
/** Host init handler, before any device is connected */
94+
int (*init)(struct usbh_class_data *const c_data,
95+
struct usbh_context *const uhs_ctx);
9596
/** Request completion event handler */
96-
int (*request)(struct usbh_class_data *const c_data,
97-
struct uhc_transfer *const xfer, int err);
98-
/** Device connected handler */
99-
int (*connected)(struct usbh_class_data *const c_data,
100-
void *const desc_start_addr,
101-
void *const desc_end_addr);
102-
/** Device removed handler */
97+
int (*completion_cb)(struct usbh_class_data *const c_data,
98+
struct uhc_transfer *const xfer);
99+
/** Device connection handler */
100+
int (*probe)(struct usbh_class_data *const c_data,
101+
struct usb_device *const udev,
102+
const uint8_t iface);
103+
/** Device removal handler */
103104
int (*removed)(struct usbh_class_data *const c_data);
104-
/** Bus remote wakeup handler */
105-
int (*rwup)(struct usbh_class_data *const c_data);
106105
/** Bus suspended handler */
107106
int (*suspended)(struct usbh_class_data *const c_data);
108107
/** Bus resumed handler */
@@ -117,8 +116,10 @@ struct usbh_class_data {
117116
const char *name;
118117
/** Pointer to USB host stack context structure */
119118
struct usbh_context *uhs_ctx;
120-
/** Class code supported by this instance */
121-
struct usbh_code_triple code;
119+
/** Pointer to USB device this class is used for */
120+
struct usb_device *udev;
121+
/** Interface number for which this class matched */
122+
uint8_t ifnum;
122123
/** Pointer to host support class API */
123124
struct usbh_class_api *api;
124125
/** Pointer to private data */

subsys/usb/host/usbh_class.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* Copyright 2025 NXP
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <zephyr/usb/usbh.h>
9+
#include <zephyr/logging/log.h>
10+
11+
#include "usbh_class.h"
12+
#include "usbh_class_api.h"
13+
14+
LOG_MODULE_REGISTER(usbh_class, CONFIG_USBH_LOG_LEVEL);
15+
16+
bool usbh_class_is_matching(struct usbh_class_filter *const filters, size_t n_filters,
17+
struct usb_device_descriptor *const desc)
18+
{
19+
for (int i = 0; i < n_filters; i++) {
20+
const struct usbh_class_filter *filt = &filters[i];
21+
22+
if (filt->flags & USBH_CLASS_MATCH_VID) {
23+
if (desc->idVendor != filt->vid) {
24+
continue;
25+
}
26+
}
27+
28+
if (filt->flags & USBH_CLASS_MATCH_PID) {
29+
if (desc->idProduct != filt->pid) {
30+
continue;
31+
}
32+
}
33+
34+
if (filt->flags & USBH_CLASS_MATCH_DCLASS) {
35+
if (desc->bDeviceClass != filt->dclass) {
36+
continue;
37+
}
38+
}
39+
40+
if (filt->flags & USBH_CLASS_MATCH_SUB) {
41+
if (desc->bDeviceSubClass != filt->sub) {
42+
continue;
43+
}
44+
}
45+
46+
if (filt->flags & USBH_CLASS_MATCH_PROTO) {
47+
if (desc->bDeviceProtocol != filt->proto) {
48+
continue;
49+
}
50+
}
51+
52+
/* All the selected filters did match */
53+
return true;
54+
}
55+
56+
/* At the end of the filter table and still no match */
57+
return false;
58+
}

subsys/usb/host/usbh_class_api.h

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @brief USB host stack class instances API
10+
*
11+
* This file contains the USB host stack class instances API.
12+
*/
13+
14+
#ifndef ZEPHYR_INCLUDE_USBH_CLASS_API_H
15+
#define ZEPHYR_INCLUDE_USBH_CLASS_API_H
16+
17+
#include <zephyr/usb/usbh.h>
18+
19+
/**
20+
* @brief Initialization of the class implementation
21+
*
22+
* This is called for each instance during the initialization phase,
23+
* for every registered class.
24+
* It can be used to initialize underlying systems.
25+
*
26+
* @param[in] c_data Pointer to USB host class data
27+
* @param[in] uhs_ctx USB host context to assign to this class
28+
*
29+
* @return 0 on success, negative error code on failure.
30+
*/
31+
32+
static inline int usbh_class_init(struct usbh_class_data *const c_data,
33+
struct usbh_context *const uhs_ctx)
34+
{
35+
const struct usbh_class_api *api = c_data->api;
36+
37+
if (api->init != NULL) {
38+
return api->init(c_data, uhs_ctx);
39+
}
40+
41+
return -ENOTSUP;
42+
}
43+
44+
/**
45+
* @brief Request completion event handler
46+
*
47+
* Called upon completion of a request made by the host to this class.
48+
*
49+
* @param[in] c_data Pointer to USB host class data
50+
* @param[in] udev USB device connected
51+
* @param[in] xfer Completed transfer
52+
*
53+
* @return 0 on success, negative error code on failure.
54+
*/
55+
static inline int usbh_class_completion_cb(struct usbh_class_data *const c_data,
56+
struct uhc_transfer *const xfer)
57+
{
58+
const struct usbh_class_api *api = c_data->api;
59+
60+
if (api->completion_cb != NULL) {
61+
return api->completion_cb(c_data, xfer);
62+
}
63+
64+
return -ENOTSUP;
65+
}
66+
67+
/**
68+
* @brief Device initialization handler
69+
*
70+
* Called when a device is connected to the bus for every device.
71+
*
72+
* @param[in] c_data Pointer to USB host class data
73+
* @param[in] udev USB device connected
74+
* @param[in] iface The @c bInterfaceNumber or @c bFirstInterface of this class
75+
*
76+
* @return 0 on success, negative error code on failure.
77+
* @return -ENOTSUP if the class is not matching
78+
*/
79+
static inline int usbh_class_probe(struct usbh_class_data *const c_data,
80+
struct usb_device *const udev,
81+
const uint8_t iface)
82+
{
83+
const struct usbh_class_api *api = c_data->api;
84+
85+
if (api->probe != NULL) {
86+
return api->probe(c_data, udev, iface);
87+
}
88+
89+
return -ENOTSUP;
90+
}
91+
92+
/**
93+
* @brief Device removed handler
94+
*
95+
* Called when the device is removed from the bus
96+
* and it matches the class filters of this instance.
97+
*
98+
* @param[in] c_data Pointer to USB host class data
99+
* @param[in] udev USB device connected
100+
*
101+
* @return 0 on success, negative error code on failure.
102+
*/
103+
static inline int usbh_class_removed(struct usbh_class_data *const c_data)
104+
{
105+
const struct usbh_class_api *api = c_data->api;
106+
107+
if (api->removed != NULL) {
108+
return api->removed(c_data);
109+
}
110+
111+
return -ENOTSUP;
112+
}
113+
114+
/**
115+
* @brief Bus suspended handler
116+
*
117+
* Called when the host has suspending the bus.
118+
* It can be used to suspend underlying systems.
119+
*
120+
* @param[in] c_data Pointer to USB host class data
121+
* @param[in] udev USB device connected
122+
*
123+
* @return 0 on success, negative error code on failure.
124+
*/
125+
static inline int usbh_class_suspended(struct usbh_class_data *const c_data)
126+
{
127+
const struct usbh_class_api *api = c_data->api;
128+
129+
if (api->suspended != NULL) {
130+
return api->suspended(c_data);
131+
}
132+
133+
return -ENOTSUP;
134+
}
135+
136+
/**
137+
* @brief Bus resumed handler
138+
*
139+
* Called when the host resumes the activity on a bus.
140+
* It can be used to wake-up underlying systems.
141+
*
142+
* @param[in] c_data Pointer to USB host class data
143+
* @param[in] udev USB device connected
144+
*
145+
* @return 0 on success, negative error code on failure.
146+
*/
147+
static inline int usbh_class_resumed(struct usbh_class_data *const c_data)
148+
{
149+
const struct usbh_class_api *api = c_data->api;
150+
151+
if (api->resumed != NULL) {
152+
return api->resumed(c_data);
153+
}
154+
155+
return -ENOTSUP;
156+
}
157+
158+
#endif /* ZEPHYR_INCLUDE_USBD_CLASS_API_H */

0 commit comments

Comments
 (0)