Skip to content

Commit 27b505e

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 7f88f6b commit 27b505e

File tree

3 files changed

+264
-13
lines changed

3 files changed

+264
-13
lines changed

include/zephyr/usb/usbh.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,23 +90,30 @@ 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 */
103-
int (*removed)(struct usbh_class_data *const c_data);
97+
int (*completion_cb)(struct usbh_class_data *const c_data,
98+
struct usb_device *const udev,
99+
struct uhc_transfer *const xfer);
100+
/** Device connection handler */
101+
int (*probe)(struct usbh_class_data *const c_data,
102+
struct usb_device *const udev,
103+
void *const desc_start_addr,
104+
void *const desc_end_addr);
105+
/** Device removal handler */
106+
int (*removed)(struct usbh_class_data *const c_data,
107+
struct usb_device *const udev);
104108
/** Bus remote wakeup handler */
105-
int (*rwup)(struct usbh_class_data *const c_data);
109+
int (*rwup)(struct usbh_class_data *const c_data,
110+
struct usb_device *const udev);
106111
/** Bus suspended handler */
107-
int (*suspended)(struct usbh_class_data *const c_data);
112+
int (*suspended)(struct usbh_class_data *const c_data,
113+
struct usb_device *const udev);
108114
/** Bus resumed handler */
109-
int (*resumed)(struct usbh_class_data *const c_data);
115+
int (*resumed)(struct usbh_class_data *const c_data,
116+
struct usb_device *const udev);
110117
};
111118

112119
/**

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: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
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+
static inline int usbh_class_init(struct usbh_class_data *const c_data,
32+
struct usbh_context *const uhs_ctx)
33+
{
34+
const struct usbh_class_api *api = c_data->api;
35+
36+
if (api->init != NULL) {
37+
return api->init(c_data, uhs_ctx);
38+
}
39+
40+
return -ENOTSUP;
41+
}
42+
43+
/**
44+
* @brief Request completion event handler
45+
*
46+
* Called upon completion of a request made by the host to this class.
47+
*
48+
* @param[in] c_data Pointer to USB host class data
49+
* @param[in] udev USB device connected
50+
* @param[in] xfer Completed transfer
51+
*
52+
* @return 0 on success, negative error code on failure.
53+
*/
54+
static inline int usbh_class_completion_cb(struct usbh_class_data *const c_data,
55+
struct usb_device *const udev,
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, udev, 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
71+
* and it matches the class filters of this instance.
72+
*
73+
* @param[in] c_data Pointer to USB host class data
74+
* @param[in] udev USB device connected
75+
* @param[in] desc_beg Pointer to the first byte of the descriptor
76+
* @param[in] desc_end Pointer after the last byte of the USB descriptor
77+
*
78+
* @return 0 on success, negative error code on failure.
79+
*/
80+
static inline int usbh_class_probe(struct usbh_class_data *const c_data,
81+
struct usb_device *const udev,
82+
void *const desc_beg,
83+
void *const desc_end)
84+
{
85+
const struct usbh_class_api *api = c_data->api;
86+
87+
if (api->probe != NULL) {
88+
return api->probe(c_data, udev, desc_beg, desc_end);
89+
}
90+
91+
return -ENOTSUP;
92+
}
93+
94+
/**
95+
* @brief Device removed handler
96+
*
97+
* Called when the device is removed from the bus
98+
* and it matches the class filters of this instance.
99+
*
100+
* @param[in] c_data Pointer to USB host class data
101+
* @param[in] udev USB device connected
102+
*
103+
* @return 0 on success, negative error code on failure.
104+
*/
105+
static inline int usbh_class_removed(struct usbh_class_data *const c_data,
106+
struct usb_device *const udev)
107+
{
108+
const struct usbh_class_api *api = c_data->api;
109+
110+
if (api->removed != NULL) {
111+
return api->removed(c_data, udev);
112+
}
113+
114+
return -ENOTSUP;
115+
}
116+
117+
/**
118+
* @brief Bus remote wakeup handler
119+
*
120+
* Called when the device trigger a remote wakeup to the host.
121+
* and it matches the class filters.
122+
*
123+
* @param[in] c_data Pointer to USB host class data
124+
* @param[in] udev USB device connected
125+
*
126+
* @return 0 on success, negative error code on failure.
127+
*/
128+
static inline int usbh_class_rwup(struct usbh_class_data *const c_data,
129+
struct usb_device *const udev)
130+
{
131+
const struct usbh_class_api *api = c_data->api;
132+
133+
if (api->rwup != NULL) {
134+
return api->rwup(c_data, udev);
135+
}
136+
137+
return -ENOTSUP;
138+
}
139+
140+
/**
141+
* @brief Bus suspended handler
142+
*
143+
* Called when the host has suspending the bus.
144+
* It can be used to suspend underlying systems.
145+
*
146+
* @param[in] c_data Pointer to USB host class data
147+
* @param[in] udev USB device connected
148+
*
149+
* @return 0 on success, negative error code on failure.
150+
*/
151+
static inline int usbh_class_suspended(struct usbh_class_data *const c_data,
152+
struct usb_device *const udev)
153+
{
154+
const struct usbh_class_api *api = c_data->api;
155+
156+
if (api->suspended != NULL) {
157+
return api->suspended(c_data, udev);
158+
}
159+
160+
return -ENOTSUP;
161+
}
162+
163+
/**
164+
* @brief Bus resumed handler
165+
*
166+
* Called when the host resumes the activity on a bus.
167+
* It can be used to wake-up underlying systems.
168+
*
169+
* @param[in] c_data Pointer to USB host class data
170+
* @param[in] udev USB device connected
171+
*
172+
* @return 0 on success, negative error code on failure.
173+
*/
174+
static inline int usbh_class_resumed(struct usbh_class_data *const c_data,
175+
struct usb_device *const udev)
176+
{
177+
const struct usbh_class_api *api = c_data->api;
178+
179+
if (api->resumed != NULL) {
180+
return api->resumed(c_data, udev);
181+
}
182+
183+
return -ENOTSUP;
184+
}
185+
186+
#endif /* ZEPHYR_INCLUDE_USBD_CLASS_API_H */

0 commit comments

Comments
 (0)