4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
- #include <zephyr/kernel.h>
8
7
#include <errno.h>
9
- #include <zephyr/drivers/usb/uhc.h>
8
+
9
+ #include <zephyr/kernel.h>
10
+ #include <zephyr/usb/usbh.h>
10
11
#include <zephyr/usb/usb_ch9.h>
11
12
#include <zephyr/sys/byteorder.h>
12
13
#include <zephyr/net/buf.h>
13
14
15
+ #include "usbh_device.h"
16
+
14
17
#include <zephyr/logging/log.h>
15
18
LOG_MODULE_REGISTER (usbh_ch9 , CONFIG_USBH_LOG_LEVEL );
16
19
17
- #define SETUP_REQ_TIMEOUT 1000U
20
+ /*
21
+ * For now we set it to the upper limit defined in Chapter
22
+ * "9.2.6.4 Standard Device Requests"
23
+ * This will need to be revised and set depending on the request.
24
+ */
25
+ #define SETUP_REQ_TIMEOUT 5000U
26
+
27
+ K_SEM_DEFINE (ch9_req_sync , 0 , 1 );
18
28
19
- int usbh_req_setup (const struct device * dev ,
20
- const uint8_t addr ,
29
+ static int ch9_req_cb (struct usb_device * const udev , struct uhc_transfer * const xfer )
30
+ {
31
+ LOG_DBG ("Request finished %p, err %d" , xfer , xfer -> err );
32
+ k_sem_give (& ch9_req_sync );
33
+
34
+ return 0 ;
35
+ }
36
+
37
+ int usbh_req_setup (struct usb_device * const udev ,
21
38
const uint8_t bmRequestType ,
22
39
const uint8_t bRequest ,
23
40
const uint16_t wValue ,
24
41
const uint16_t wIndex ,
25
42
const uint16_t wLength ,
26
- uint8_t * const data )
43
+ struct net_buf * const buf )
27
44
{
28
45
struct usb_setup_packet req = {
29
46
.bmRequestType = bmRequestType ,
@@ -33,139 +50,188 @@ int usbh_req_setup(const struct device *dev,
33
50
.wLength = sys_cpu_to_le16 (wLength ),
34
51
};
35
52
struct uhc_transfer * xfer ;
36
- struct net_buf * buf ;
37
53
uint8_t ep = usb_reqtype_is_to_device (& req ) ? 0x00 : 0x80 ;
38
54
int ret ;
39
55
40
- xfer = uhc_xfer_alloc ( dev , addr , ep , 0 , 64 , SETUP_REQ_TIMEOUT , NULL , NULL );
56
+ xfer = usbh_xfer_alloc ( udev , ep , 0 , 64 , SETUP_REQ_TIMEOUT , ( void * ) ch9_req_cb );
41
57
if (!xfer ) {
42
58
return - ENOMEM ;
43
59
}
44
60
45
61
memcpy (xfer -> setup_pkt , & req , sizeof (req ));
46
62
47
- if (wLength ) {
48
- buf = uhc_xfer_buf_alloc (dev , wLength );
49
- if (!buf ) {
50
- ret = - ENOMEM ;
51
- goto buf_alloc_err ;
52
- }
53
-
54
- if (usb_reqtype_is_to_device (& req ) && data != NULL ) {
55
- net_buf_add_mem (buf , data , wLength );
56
- }
57
-
58
- ret = uhc_xfer_buf_add (dev , xfer , buf );
63
+ if (wLength && buf != NULL ) {
64
+ ret = usbh_xfer_buf_add (udev , xfer , buf );
59
65
if (ret ) {
60
66
goto buf_alloc_err ;
61
67
}
62
68
}
63
69
64
- return uhc_ep_enqueue (dev , xfer );
70
+ ret = usbh_xfer_enqueue (udev , xfer );
71
+ if (ret ) {
72
+ goto buf_alloc_err ;
73
+ }
74
+
75
+ k_sem_take (& ch9_req_sync , K_MSEC (SETUP_REQ_TIMEOUT ));
76
+ ret = xfer -> err ;
65
77
66
78
buf_alloc_err :
67
- uhc_xfer_free ( dev , xfer );
79
+ usbh_xfer_free ( udev , xfer );
68
80
69
81
return ret ;
70
82
}
71
83
72
- int usbh_req_desc (const struct device * dev ,
73
- const uint8_t addr ,
84
+ int usbh_req_desc (struct usb_device * const udev ,
74
85
const uint8_t type , const uint8_t index ,
75
86
const uint8_t id ,
76
- const uint16_t len )
87
+ const uint16_t len ,
88
+ struct net_buf * const buf )
77
89
{
78
90
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_HOST << 7 ;
79
91
const uint8_t bRequest = USB_SREQ_GET_DESCRIPTOR ;
80
92
const uint16_t wValue = (type << 8 ) | index ;
81
93
82
- return usbh_req_setup (dev , addr ,
94
+ return usbh_req_setup (udev ,
83
95
bmRequestType , bRequest , wValue , id , len ,
84
- NULL );
96
+ buf );
85
97
}
86
98
87
- int usbh_req_desc_dev (const struct device * dev ,
88
- const uint8_t addr )
99
+ int usbh_req_desc_dev (struct usb_device * const udev ,
100
+ struct usb_device_descriptor * const desc )
89
101
{
90
102
const uint8_t type = USB_DESC_DEVICE ;
91
- const uint16_t wLength = 18 ;
103
+ const uint16_t wLength = sizeof (struct usb_device_descriptor );
104
+ struct net_buf * buf ;
105
+ int ret ;
106
+
107
+ buf = usbh_xfer_buf_alloc (udev , wLength );
108
+ if (!buf ) {
109
+ return - ENOMEM ;
110
+ }
111
+
112
+ ret = usbh_req_desc (udev , type , 0 , 0 , wLength , buf );
113
+ if (ret == 0 && buf -> len == wLength ) {
114
+ memcpy (desc , buf -> data , wLength );
115
+ desc -> bcdUSB = sys_le16_to_cpu (desc -> bcdUSB );
116
+ desc -> idVendor = sys_le16_to_cpu (desc -> idVendor );
117
+ desc -> idProduct = sys_le16_to_cpu (desc -> idProduct );
118
+ desc -> bcdDevice = sys_le16_to_cpu (desc -> bcdDevice );
119
+ }
92
120
93
- return usbh_req_desc (dev , addr , type , 0 , 0 , wLength );
121
+ usbh_xfer_buf_free (udev , buf );
122
+
123
+ return ret ;
94
124
}
95
125
96
- int usbh_req_desc_cfg (const struct device * dev ,
97
- const uint8_t addr ,
126
+ int usbh_req_desc_cfg (struct usb_device * const udev ,
98
127
const uint8_t index ,
99
- const uint16_t len )
128
+ const uint16_t len ,
129
+ struct usb_cfg_descriptor * const desc )
100
130
{
101
131
const uint8_t type = USB_DESC_CONFIGURATION ;
132
+ const uint16_t wLength = len ;
133
+ struct net_buf * buf ;
134
+ int ret ;
135
+
136
+ buf = usbh_xfer_buf_alloc (udev , len );
137
+ if (!buf ) {
138
+ return - ENOMEM ;
139
+ }
102
140
103
- return usbh_req_desc (dev , addr , type , index , 0 , len );
141
+ ret = usbh_req_desc (udev , type , index , 0 , wLength , buf );
142
+ if (ret == 0 ) {
143
+ memcpy (desc , buf -> data , len );
144
+ desc -> wTotalLength = sys_le16_to_cpu (desc -> wTotalLength );
145
+ }
146
+
147
+ usbh_xfer_buf_free (udev , buf );
148
+
149
+ return ret ;
104
150
}
105
151
106
- int usbh_req_set_address (const struct device * dev ,
107
- const uint8_t addr , const uint8_t new )
152
+ int usbh_req_set_address (struct usb_device * const udev ,
153
+ const uint8_t addr )
108
154
{
109
155
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 ;
110
156
const uint8_t bRequest = USB_SREQ_SET_ADDRESS ;
157
+ int ret ;
111
158
112
- return usbh_req_setup (dev , addr ,
113
- bmRequestType , bRequest , new , 0 , 0 ,
114
- NULL );
159
+ ret = usbh_req_setup (udev , bmRequestType , bRequest , addr , 0 , 0 , NULL );
160
+ if (ret == 0 ) {
161
+ udev -> addr = addr ;
162
+ if (addr == 0 ) {
163
+ udev -> state = USB_STATE_DEFAULT ;
164
+ }
165
+
166
+ if (addr != 0 && udev -> state == USB_STATE_DEFAULT ) {
167
+ udev -> state = USB_STATE_ADDRESSED ;
168
+ }
169
+ }
170
+
171
+ return ret ;
115
172
}
116
173
117
- int usbh_req_set_cfg (const struct device * dev ,
118
- const uint8_t addr , const uint8_t new )
174
+ int usbh_req_set_cfg (struct usb_device * const udev ,
175
+ const uint8_t cfg )
119
176
{
120
177
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 ;
121
178
const uint8_t bRequest = USB_SREQ_SET_CONFIGURATION ;
179
+ int ret ;
122
180
123
- return usbh_req_setup (dev , addr ,
124
- bmRequestType , bRequest , new , 0 , 0 ,
125
- NULL );
181
+ /* Ignore the required state change condition for now. */
182
+ ret = usbh_req_setup (udev , bmRequestType , bRequest , cfg , 0 , 0 , NULL );
183
+ if (ret == 0 ) {
184
+ udev -> actual_cfg = cfg ;
185
+ if (cfg == 0 ) {
186
+ udev -> state = USB_STATE_ADDRESSED ;
187
+ }
188
+
189
+ if (cfg != 0 && udev -> state == USB_STATE_ADDRESSED ) {
190
+ udev -> state = USB_STATE_CONFIGURED ;
191
+ }
192
+ }
193
+
194
+ return ret ;
126
195
}
127
196
128
- int usbh_req_set_alt (const struct device * dev ,
129
- const uint8_t addr , const uint8_t iface ,
130
- const uint8_t alt )
197
+ int usbh_req_set_alt (struct usb_device * const udev ,
198
+ const uint8_t iface , const uint8_t alt )
131
199
{
132
200
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 |
133
201
USB_REQTYPE_RECIPIENT_INTERFACE ;
134
202
const uint8_t bRequest = USB_SREQ_SET_INTERFACE ;
135
203
const uint16_t wValue = alt ;
136
204
const uint16_t wIndex = iface ;
137
205
138
- return usbh_req_setup (dev , addr ,
206
+ return usbh_req_setup (udev ,
139
207
bmRequestType , bRequest , wValue , wIndex , 0 ,
140
208
NULL );
141
209
}
142
210
143
- int usbh_req_set_sfs_rwup (const struct device * dev ,
144
- const uint8_t addr )
211
+ int usbh_req_set_sfs_rwup (struct usb_device * const udev )
145
212
{
146
213
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 ;
147
214
const uint8_t bRequest = USB_SREQ_SET_FEATURE ;
148
215
const uint16_t wValue = USB_SFS_REMOTE_WAKEUP ;
149
216
150
- return usbh_req_setup (dev , addr ,
217
+ return usbh_req_setup (udev ,
151
218
bmRequestType , bRequest , wValue , 0 , 0 ,
152
219
NULL );
153
220
}
154
221
155
- int usbh_req_clear_sfs_rwup (const struct device * dev ,
156
- const uint8_t addr )
222
+ int usbh_req_clear_sfs_rwup (struct usb_device * const udev )
157
223
{
158
224
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 ;
159
225
const uint8_t bRequest = USB_SREQ_CLEAR_FEATURE ;
160
226
const uint16_t wValue = USB_SFS_REMOTE_WAKEUP ;
161
227
162
- return usbh_req_setup (dev , addr ,
228
+ return usbh_req_setup (udev ,
163
229
bmRequestType , bRequest , wValue , 0 , 0 ,
164
230
NULL );
165
231
}
166
232
167
- int usbh_req_set_hcfs_ppwr (const struct device * dev ,
168
- const uint8_t addr , const uint8_t port )
233
+ int usbh_req_set_hcfs_ppwr (struct usb_device * const udev ,
234
+ const uint8_t port )
169
235
{
170
236
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 |
171
237
USB_REQTYPE_TYPE_CLASS << 5 |
@@ -174,13 +240,13 @@ int usbh_req_set_hcfs_ppwr(const struct device *dev,
174
240
const uint16_t wValue = USB_HCFS_PORT_POWER ;
175
241
const uint16_t wIndex = port ;
176
242
177
- return usbh_req_setup (dev , addr ,
243
+ return usbh_req_setup (udev ,
178
244
bmRequestType , bRequest , wValue , wIndex , 0 ,
179
245
NULL );
180
246
}
181
247
182
- int usbh_req_set_hcfs_prst (const struct device * dev ,
183
- const uint8_t addr , const uint8_t port )
248
+ int usbh_req_set_hcfs_prst (struct usb_device * const udev ,
249
+ const uint8_t port )
184
250
{
185
251
const uint8_t bmRequestType = USB_REQTYPE_DIR_TO_DEVICE << 7 |
186
252
USB_REQTYPE_TYPE_CLASS << 5 |
@@ -189,7 +255,7 @@ int usbh_req_set_hcfs_prst(const struct device *dev,
189
255
const uint16_t wValue = USB_HCFS_PORT_RESET ;
190
256
const uint16_t wIndex = port ;
191
257
192
- return usbh_req_setup (dev , addr ,
258
+ return usbh_req_setup (udev ,
193
259
bmRequestType , bRequest , wValue , wIndex , 0 ,
194
260
NULL );
195
261
}
0 commit comments