usbdi_util.c revision 1.29 1 1.29 augustss /* $NetBSD: usbdi_util.c,v 1.29 2000/03/27 12:33:59 augustss Exp $ */
2 1.25 augustss /* $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */
3 1.1 augustss
4 1.1 augustss /*
5 1.1 augustss * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 1.1 augustss * All rights reserved.
7 1.1 augustss *
8 1.5 augustss * This code is derived from software contributed to The NetBSD Foundation
9 1.5 augustss * by Lennart Augustsson (augustss (at) carlstedt.se) at
10 1.5 augustss * Carlstedt Research & Technology.
11 1.1 augustss *
12 1.1 augustss * Redistribution and use in source and binary forms, with or without
13 1.1 augustss * modification, are permitted provided that the following conditions
14 1.1 augustss * are met:
15 1.1 augustss * 1. Redistributions of source code must retain the above copyright
16 1.1 augustss * notice, this list of conditions and the following disclaimer.
17 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 augustss * notice, this list of conditions and the following disclaimer in the
19 1.1 augustss * documentation and/or other materials provided with the distribution.
20 1.1 augustss * 3. All advertising materials mentioning features or use of this software
21 1.1 augustss * must display the following acknowledgement:
22 1.1 augustss * This product includes software developed by the NetBSD
23 1.1 augustss * Foundation, Inc. and its contributors.
24 1.1 augustss * 4. Neither the name of The NetBSD Foundation nor the names of its
25 1.1 augustss * contributors may be used to endorse or promote products derived
26 1.1 augustss * from this software without specific prior written permission.
27 1.1 augustss *
28 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 1.1 augustss * POSSIBILITY OF SUCH DAMAGE.
39 1.1 augustss */
40 1.1 augustss
41 1.1 augustss #include <sys/param.h>
42 1.1 augustss #include <sys/systm.h>
43 1.1 augustss #include <sys/kernel.h>
44 1.1 augustss #include <sys/malloc.h>
45 1.25 augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
46 1.1 augustss #include <sys/proc.h>
47 1.14 augustss #include <sys/device.h>
48 1.22 augustss #elif defined(__FreeBSD__)
49 1.13 augustss #include <sys/bus.h>
50 1.13 augustss #endif
51 1.1 augustss
52 1.1 augustss #include <dev/usb/usb.h>
53 1.1 augustss #include <dev/usb/usbhid.h>
54 1.1 augustss
55 1.1 augustss #include <dev/usb/usbdi.h>
56 1.1 augustss #include <dev/usb/usbdi_util.h>
57 1.1 augustss
58 1.1 augustss #ifdef USB_DEBUG
59 1.17 augustss #define DPRINTF(x) if (usbdebug) logprintf x
60 1.17 augustss #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
61 1.1 augustss extern int usbdebug;
62 1.1 augustss #else
63 1.1 augustss #define DPRINTF(x)
64 1.1 augustss #define DPRINTFN(n,x)
65 1.1 augustss #endif
66 1.1 augustss
67 1.1 augustss usbd_status
68 1.1 augustss usbd_get_desc(dev, type, index, len, desc)
69 1.1 augustss usbd_device_handle dev;
70 1.1 augustss int type, index;
71 1.1 augustss int len;
72 1.1 augustss void *desc;
73 1.1 augustss {
74 1.1 augustss usb_device_request_t req;
75 1.1 augustss
76 1.26 augustss DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n",
77 1.26 augustss type, index, len));
78 1.26 augustss
79 1.1 augustss req.bmRequestType = UT_READ_DEVICE;
80 1.1 augustss req.bRequest = UR_GET_DESCRIPTOR;
81 1.1 augustss USETW2(req.wValue, type, index);
82 1.1 augustss USETW(req.wIndex, 0);
83 1.1 augustss USETW(req.wLength, len);
84 1.1 augustss return (usbd_do_request(dev, &req, desc));
85 1.1 augustss }
86 1.1 augustss
87 1.1 augustss usbd_status
88 1.26 augustss usbd_get_config_desc(dev, confidx, d)
89 1.1 augustss usbd_device_handle dev;
90 1.26 augustss int confidx;
91 1.1 augustss usb_config_descriptor_t *d;
92 1.1 augustss {
93 1.23 augustss usbd_status err;
94 1.9 augustss
95 1.26 augustss DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx));
96 1.26 augustss err = usbd_get_desc(dev, UDESC_CONFIG, confidx,
97 1.26 augustss USB_CONFIG_DESCRIPTOR_SIZE, d);
98 1.23 augustss if (err)
99 1.23 augustss return (err);
100 1.9 augustss if (d->bDescriptorType != UDESC_CONFIG) {
101 1.26 augustss DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc "
102 1.26 augustss "len=%d type=%d\n",
103 1.26 augustss confidx, d->bLength, d->bDescriptorType));
104 1.9 augustss return (USBD_INVAL);
105 1.9 augustss }
106 1.9 augustss return (USBD_NORMAL_COMPLETION);
107 1.1 augustss }
108 1.1 augustss
109 1.1 augustss usbd_status
110 1.4 augustss usbd_get_config_desc_full(dev, conf, d, size)
111 1.4 augustss usbd_device_handle dev;
112 1.4 augustss int conf;
113 1.4 augustss void *d;
114 1.4 augustss int size;
115 1.4 augustss {
116 1.4 augustss DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf));
117 1.4 augustss return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d));
118 1.4 augustss }
119 1.4 augustss
120 1.4 augustss usbd_status
121 1.1 augustss usbd_get_device_desc(dev, d)
122 1.1 augustss usbd_device_handle dev;
123 1.1 augustss usb_device_descriptor_t *d;
124 1.1 augustss {
125 1.1 augustss DPRINTFN(3,("usbd_get_device_desc:\n"));
126 1.1 augustss return (usbd_get_desc(dev, UDESC_DEVICE,
127 1.1 augustss 0, USB_DEVICE_DESCRIPTOR_SIZE, d));
128 1.1 augustss }
129 1.1 augustss
130 1.1 augustss usbd_status
131 1.1 augustss usbd_get_device_status(dev, st)
132 1.1 augustss usbd_device_handle dev;
133 1.1 augustss usb_status_t *st;
134 1.1 augustss {
135 1.1 augustss usb_device_request_t req;
136 1.1 augustss
137 1.1 augustss req.bmRequestType = UT_READ_DEVICE;
138 1.1 augustss req.bRequest = UR_GET_STATUS;
139 1.1 augustss USETW(req.wValue, 0);
140 1.1 augustss USETW(req.wIndex, 0);
141 1.1 augustss USETW(req.wLength, sizeof(usb_status_t));
142 1.1 augustss return (usbd_do_request(dev, &req, st));
143 1.1 augustss }
144 1.1 augustss
145 1.1 augustss usbd_status
146 1.1 augustss usbd_get_hub_status(dev, st)
147 1.1 augustss usbd_device_handle dev;
148 1.1 augustss usb_hub_status_t *st;
149 1.1 augustss {
150 1.1 augustss usb_device_request_t req;
151 1.1 augustss
152 1.1 augustss req.bmRequestType = UT_READ_CLASS_DEVICE;
153 1.1 augustss req.bRequest = UR_GET_STATUS;
154 1.1 augustss USETW(req.wValue, 0);
155 1.1 augustss USETW(req.wIndex, 0);
156 1.1 augustss USETW(req.wLength, sizeof(usb_hub_status_t));
157 1.1 augustss return (usbd_do_request(dev, &req, st));
158 1.1 augustss }
159 1.1 augustss
160 1.1 augustss usbd_status
161 1.1 augustss usbd_set_address(dev, addr)
162 1.1 augustss usbd_device_handle dev;
163 1.1 augustss int addr;
164 1.1 augustss {
165 1.1 augustss usb_device_request_t req;
166 1.1 augustss
167 1.1 augustss req.bmRequestType = UT_WRITE_DEVICE;
168 1.1 augustss req.bRequest = UR_SET_ADDRESS;
169 1.1 augustss USETW(req.wValue, addr);
170 1.1 augustss USETW(req.wIndex, 0);
171 1.1 augustss USETW(req.wLength, 0);
172 1.1 augustss return usbd_do_request(dev, &req, 0);
173 1.1 augustss }
174 1.1 augustss
175 1.1 augustss usbd_status
176 1.1 augustss usbd_get_port_status(dev, port, ps)
177 1.1 augustss usbd_device_handle dev;
178 1.1 augustss int port;
179 1.1 augustss usb_port_status_t *ps;
180 1.1 augustss {
181 1.1 augustss usb_device_request_t req;
182 1.1 augustss
183 1.1 augustss req.bmRequestType = UT_READ_CLASS_OTHER;
184 1.1 augustss req.bRequest = UR_GET_STATUS;
185 1.1 augustss USETW(req.wValue, 0);
186 1.1 augustss USETW(req.wIndex, port);
187 1.1 augustss USETW(req.wLength, sizeof *ps);
188 1.1 augustss return (usbd_do_request(dev, &req, ps));
189 1.16 augustss }
190 1.16 augustss
191 1.16 augustss usbd_status
192 1.16 augustss usbd_clear_hub_feature(dev, sel)
193 1.16 augustss usbd_device_handle dev;
194 1.16 augustss int sel;
195 1.16 augustss {
196 1.16 augustss usb_device_request_t req;
197 1.16 augustss
198 1.16 augustss req.bmRequestType = UT_WRITE_CLASS_DEVICE;
199 1.16 augustss req.bRequest = UR_CLEAR_FEATURE;
200 1.16 augustss USETW(req.wValue, sel);
201 1.16 augustss USETW(req.wIndex, 0);
202 1.16 augustss USETW(req.wLength, 0);
203 1.16 augustss return (usbd_do_request(dev, &req, 0));
204 1.16 augustss }
205 1.16 augustss
206 1.16 augustss usbd_status
207 1.16 augustss usbd_set_hub_feature(dev, sel)
208 1.16 augustss usbd_device_handle dev;
209 1.16 augustss int sel;
210 1.16 augustss {
211 1.16 augustss usb_device_request_t req;
212 1.16 augustss
213 1.16 augustss req.bmRequestType = UT_WRITE_CLASS_DEVICE;
214 1.16 augustss req.bRequest = UR_SET_FEATURE;
215 1.16 augustss USETW(req.wValue, sel);
216 1.16 augustss USETW(req.wIndex, 0);
217 1.16 augustss USETW(req.wLength, 0);
218 1.16 augustss return (usbd_do_request(dev, &req, 0));
219 1.1 augustss }
220 1.1 augustss
221 1.1 augustss usbd_status
222 1.1 augustss usbd_clear_port_feature(dev, port, sel)
223 1.1 augustss usbd_device_handle dev;
224 1.1 augustss int port, sel;
225 1.1 augustss {
226 1.1 augustss usb_device_request_t req;
227 1.1 augustss
228 1.1 augustss req.bmRequestType = UT_WRITE_CLASS_OTHER;
229 1.1 augustss req.bRequest = UR_CLEAR_FEATURE;
230 1.1 augustss USETW(req.wValue, sel);
231 1.1 augustss USETW(req.wIndex, port);
232 1.1 augustss USETW(req.wLength, 0);
233 1.1 augustss return (usbd_do_request(dev, &req, 0));
234 1.1 augustss }
235 1.1 augustss
236 1.1 augustss usbd_status
237 1.1 augustss usbd_set_port_feature(dev, port, sel)
238 1.1 augustss usbd_device_handle dev;
239 1.1 augustss int port, sel;
240 1.1 augustss {
241 1.1 augustss usb_device_request_t req;
242 1.1 augustss
243 1.1 augustss req.bmRequestType = UT_WRITE_CLASS_OTHER;
244 1.1 augustss req.bRequest = UR_SET_FEATURE;
245 1.1 augustss USETW(req.wValue, sel);
246 1.1 augustss USETW(req.wIndex, port);
247 1.1 augustss USETW(req.wLength, 0);
248 1.1 augustss return (usbd_do_request(dev, &req, 0));
249 1.1 augustss }
250 1.1 augustss
251 1.1 augustss
252 1.1 augustss usbd_status
253 1.1 augustss usbd_set_protocol(iface, report)
254 1.1 augustss usbd_interface_handle iface;
255 1.1 augustss int report;
256 1.1 augustss {
257 1.1 augustss usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
258 1.1 augustss usbd_device_handle dev;
259 1.1 augustss usb_device_request_t req;
260 1.23 augustss usbd_status err;
261 1.1 augustss
262 1.1 augustss DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
263 1.1 augustss iface, report, id->bInterfaceNumber));
264 1.23 augustss if (id == NULL)
265 1.8 augustss return (USBD_IOERROR);
266 1.23 augustss err = usbd_interface2device_handle(iface, &dev);
267 1.23 augustss if (err)
268 1.23 augustss return (err);
269 1.1 augustss req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
270 1.1 augustss req.bRequest = UR_SET_PROTOCOL;
271 1.1 augustss USETW(req.wValue, report);
272 1.1 augustss USETW(req.wIndex, id->bInterfaceNumber);
273 1.1 augustss USETW(req.wLength, 0);
274 1.1 augustss return (usbd_do_request(dev, &req, 0));
275 1.1 augustss }
276 1.1 augustss
277 1.1 augustss usbd_status
278 1.1 augustss usbd_set_report(iface, type, id, data, len)
279 1.1 augustss usbd_interface_handle iface;
280 1.1 augustss int type;
281 1.1 augustss int id;
282 1.1 augustss void *data;
283 1.1 augustss int len;
284 1.1 augustss {
285 1.1 augustss usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
286 1.1 augustss usbd_device_handle dev;
287 1.1 augustss usb_device_request_t req;
288 1.23 augustss usbd_status err;
289 1.1 augustss
290 1.1 augustss DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
291 1.23 augustss if (ifd == NULL)
292 1.8 augustss return (USBD_IOERROR);
293 1.23 augustss err = usbd_interface2device_handle(iface, &dev);
294 1.23 augustss if (err)
295 1.23 augustss return (err);
296 1.1 augustss req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
297 1.1 augustss req.bRequest = UR_SET_REPORT;
298 1.2 augustss USETW2(req.wValue, type, id);
299 1.2 augustss USETW(req.wIndex, ifd->bInterfaceNumber);
300 1.2 augustss USETW(req.wLength, len);
301 1.2 augustss return (usbd_do_request(dev, &req, data));
302 1.3 augustss }
303 1.3 augustss
304 1.3 augustss usbd_status
305 1.3 augustss usbd_set_report_async(iface, type, id, data, len)
306 1.3 augustss usbd_interface_handle iface;
307 1.3 augustss int type;
308 1.3 augustss int id;
309 1.3 augustss void *data;
310 1.3 augustss int len;
311 1.3 augustss {
312 1.3 augustss usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
313 1.3 augustss usbd_device_handle dev;
314 1.3 augustss usb_device_request_t req;
315 1.23 augustss usbd_status err;
316 1.3 augustss
317 1.3 augustss DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
318 1.23 augustss if (ifd == NULL)
319 1.8 augustss return (USBD_IOERROR);
320 1.23 augustss err = usbd_interface2device_handle(iface, &dev);
321 1.23 augustss if (err)
322 1.23 augustss return (err);
323 1.3 augustss req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
324 1.3 augustss req.bRequest = UR_SET_REPORT;
325 1.3 augustss USETW2(req.wValue, type, id);
326 1.3 augustss USETW(req.wIndex, ifd->bInterfaceNumber);
327 1.3 augustss USETW(req.wLength, len);
328 1.3 augustss return (usbd_do_request_async(dev, &req, data));
329 1.2 augustss }
330 1.2 augustss
331 1.2 augustss usbd_status
332 1.2 augustss usbd_get_report(iface, type, id, data, len)
333 1.2 augustss usbd_interface_handle iface;
334 1.2 augustss int type;
335 1.2 augustss int id;
336 1.2 augustss void *data;
337 1.2 augustss int len;
338 1.2 augustss {
339 1.2 augustss usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
340 1.2 augustss usbd_device_handle dev;
341 1.2 augustss usb_device_request_t req;
342 1.23 augustss usbd_status err;
343 1.2 augustss
344 1.28 augustss DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
345 1.28 augustss if (ifd == NULL)
346 1.8 augustss return (USBD_IOERROR);
347 1.23 augustss err = usbd_interface2device_handle(iface, &dev);
348 1.23 augustss if (err)
349 1.23 augustss return (err);
350 1.2 augustss req.bmRequestType = UT_READ_CLASS_INTERFACE;
351 1.2 augustss req.bRequest = UR_GET_REPORT;
352 1.1 augustss USETW2(req.wValue, type, id);
353 1.1 augustss USETW(req.wIndex, ifd->bInterfaceNumber);
354 1.1 augustss USETW(req.wLength, len);
355 1.1 augustss return (usbd_do_request(dev, &req, data));
356 1.1 augustss }
357 1.1 augustss
358 1.1 augustss usbd_status
359 1.1 augustss usbd_set_idle(iface, duration, id)
360 1.1 augustss usbd_interface_handle iface;
361 1.1 augustss int duration;
362 1.1 augustss int id;
363 1.1 augustss {
364 1.1 augustss usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
365 1.1 augustss usbd_device_handle dev;
366 1.1 augustss usb_device_request_t req;
367 1.23 augustss usbd_status err;
368 1.1 augustss
369 1.1 augustss DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
370 1.23 augustss if (ifd == NULL)
371 1.8 augustss return (USBD_IOERROR);
372 1.23 augustss err = usbd_interface2device_handle(iface, &dev);
373 1.23 augustss if (err)
374 1.23 augustss return (err);
375 1.1 augustss req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
376 1.1 augustss req.bRequest = UR_SET_IDLE;
377 1.1 augustss USETW2(req.wValue, duration, id);
378 1.1 augustss USETW(req.wIndex, ifd->bInterfaceNumber);
379 1.1 augustss USETW(req.wLength, 0);
380 1.1 augustss return (usbd_do_request(dev, &req, 0));
381 1.1 augustss }
382 1.1 augustss
383 1.1 augustss usbd_status
384 1.6 augustss usbd_get_report_descriptor(dev, ifcno, repid, size, d)
385 1.1 augustss usbd_device_handle dev;
386 1.6 augustss int ifcno;
387 1.6 augustss int repid;
388 1.1 augustss int size;
389 1.1 augustss void *d;
390 1.1 augustss {
391 1.1 augustss usb_device_request_t req;
392 1.1 augustss
393 1.1 augustss req.bmRequestType = UT_READ_INTERFACE;
394 1.1 augustss req.bRequest = UR_GET_DESCRIPTOR;
395 1.6 augustss USETW2(req.wValue, UDESC_REPORT, repid);
396 1.6 augustss USETW(req.wIndex, ifcno);
397 1.1 augustss USETW(req.wLength, size);
398 1.1 augustss return (usbd_do_request(dev, &req, d));
399 1.1 augustss }
400 1.1 augustss
401 1.1 augustss usb_hid_descriptor_t *
402 1.1 augustss usbd_get_hid_descriptor(ifc)
403 1.1 augustss usbd_interface_handle ifc;
404 1.1 augustss {
405 1.1 augustss usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
406 1.1 augustss usbd_device_handle dev;
407 1.1 augustss usb_config_descriptor_t *cdesc;
408 1.1 augustss usb_hid_descriptor_t *hd;
409 1.1 augustss char *p, *end;
410 1.23 augustss usbd_status err;
411 1.1 augustss
412 1.23 augustss if (idesc == NULL)
413 1.8 augustss return (0);
414 1.23 augustss err = usbd_interface2device_handle(ifc, &dev);
415 1.23 augustss if (err)
416 1.1 augustss return (0);
417 1.1 augustss cdesc = usbd_get_config_descriptor(dev);
418 1.1 augustss
419 1.1 augustss p = (char *)idesc + idesc->bLength;
420 1.1 augustss end = (char *)cdesc + UGETW(cdesc->wTotalLength);
421 1.1 augustss
422 1.1 augustss for (; p < end; p += hd->bLength) {
423 1.1 augustss hd = (usb_hid_descriptor_t *)p;
424 1.1 augustss if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
425 1.1 augustss return (hd);
426 1.1 augustss if (hd->bDescriptorType == UDESC_INTERFACE)
427 1.1 augustss break;
428 1.1 augustss }
429 1.1 augustss return (0);
430 1.1 augustss }
431 1.1 augustss
432 1.1 augustss usbd_status
433 1.1 augustss usbd_alloc_report_desc(ifc, descp, sizep, mem)
434 1.1 augustss usbd_interface_handle ifc;
435 1.1 augustss void **descp;
436 1.1 augustss int *sizep;
437 1.18 augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
438 1.1 augustss int mem;
439 1.9 augustss #elif defined(__FreeBSD__)
440 1.9 augustss struct malloc_type *mem;
441 1.9 augustss #endif
442 1.9 augustss
443 1.1 augustss {
444 1.6 augustss usb_interface_descriptor_t *id;
445 1.1 augustss usb_hid_descriptor_t *hid;
446 1.1 augustss usbd_device_handle dev;
447 1.23 augustss usbd_status err;
448 1.1 augustss
449 1.23 augustss err = usbd_interface2device_handle(ifc, &dev);
450 1.23 augustss if (err)
451 1.23 augustss return (err);
452 1.6 augustss id = usbd_get_interface_descriptor(ifc);
453 1.23 augustss if (id == NULL)
454 1.6 augustss return (USBD_INVAL);
455 1.1 augustss hid = usbd_get_hid_descriptor(ifc);
456 1.25 augustss if (hid == NULL)
457 1.1 augustss return (USBD_IOERROR);
458 1.1 augustss *sizep = UGETW(hid->descrs[0].wDescriptorLength);
459 1.1 augustss *descp = malloc(*sizep, mem, M_NOWAIT);
460 1.23 augustss if (*descp == NULL)
461 1.1 augustss return (USBD_NOMEM);
462 1.6 augustss /* XXX should not use 0 Report ID */
463 1.23 augustss err = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
464 1.6 augustss *sizep, *descp);
465 1.23 augustss if (err) {
466 1.1 augustss free(*descp, mem);
467 1.23 augustss return (err);
468 1.1 augustss }
469 1.1 augustss return (USBD_NORMAL_COMPLETION);
470 1.7 augustss }
471 1.7 augustss
472 1.7 augustss usbd_status
473 1.7 augustss usbd_get_config(dev, conf)
474 1.7 augustss usbd_device_handle dev;
475 1.7 augustss u_int8_t *conf;
476 1.7 augustss {
477 1.7 augustss usb_device_request_t req;
478 1.7 augustss
479 1.7 augustss req.bmRequestType = UT_READ_DEVICE;
480 1.7 augustss req.bRequest = UR_GET_CONFIG;
481 1.7 augustss USETW(req.wValue, 0);
482 1.7 augustss USETW(req.wIndex, 0);
483 1.7 augustss USETW(req.wLength, 1);
484 1.7 augustss return (usbd_do_request(dev, &req, conf));
485 1.1 augustss }
486 1.10 augustss
487 1.29 augustss Static void usbd_bulk_transfer_cb __P((usbd_xfer_handle xfer,
488 1.10 augustss usbd_private_handle priv, usbd_status status));
489 1.29 augustss Static void
490 1.23 augustss usbd_bulk_transfer_cb(xfer, priv, status)
491 1.23 augustss usbd_xfer_handle xfer;
492 1.10 augustss usbd_private_handle priv;
493 1.10 augustss usbd_status status;
494 1.10 augustss {
495 1.23 augustss wakeup(xfer);
496 1.10 augustss }
497 1.10 augustss
498 1.10 augustss usbd_status
499 1.23 augustss usbd_bulk_transfer(xfer, pipe, flags, timeout, buf, size, lbl)
500 1.23 augustss usbd_xfer_handle xfer;
501 1.10 augustss usbd_pipe_handle pipe;
502 1.10 augustss u_int16_t flags;
503 1.19 augustss u_int32_t timeout;
504 1.10 augustss void *buf;
505 1.10 augustss u_int32_t *size;
506 1.10 augustss char *lbl;
507 1.10 augustss {
508 1.23 augustss usbd_status err;
509 1.11 augustss int s, error;
510 1.10 augustss
511 1.24 augustss usbd_setup_xfer(xfer, pipe, 0, buf, *size,
512 1.24 augustss flags, timeout, usbd_bulk_transfer_cb);
513 1.12 augustss DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
514 1.11 augustss s = splusb(); /* don't want callback until tsleep() */
515 1.23 augustss err = usbd_transfer(xfer);
516 1.23 augustss if (err != USBD_IN_PROGRESS) {
517 1.10 augustss splx(s);
518 1.23 augustss return (err);
519 1.10 augustss }
520 1.23 augustss error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
521 1.11 augustss splx(s);
522 1.11 augustss if (error) {
523 1.15 augustss DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
524 1.10 augustss usbd_abort_pipe(pipe);
525 1.10 augustss return (USBD_INTERRUPTED);
526 1.10 augustss }
527 1.27 augustss usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
528 1.12 augustss DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
529 1.23 augustss if (err) {
530 1.23 augustss DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
531 1.10 augustss usbd_clear_endpoint_stall(pipe);
532 1.10 augustss }
533 1.23 augustss return (err);
534 1.10 augustss }
535 1.10 augustss
536 1.14 augustss void
537 1.14 augustss usb_detach_wait(dv)
538 1.20 augustss device_ptr_t dv;
539 1.14 augustss {
540 1.20 augustss DPRINTF(("usb_detach_wait: waiting for %s\n", USBDEVPTRNAME(dv)));
541 1.14 augustss if (tsleep(dv, PZERO, "usbdet", hz * 60))
542 1.14 augustss printf("usb_detach_wait: %s didn't detach\n",
543 1.20 augustss USBDEVPTRNAME(dv));
544 1.20 augustss DPRINTF(("usb_detach_wait: %s done\n", USBDEVPTRNAME(dv)));
545 1.14 augustss }
546 1.14 augustss
547 1.14 augustss void
548 1.14 augustss usb_detach_wakeup(dv)
549 1.20 augustss device_ptr_t dv;
550 1.14 augustss {
551 1.20 augustss DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVPTRNAME(dv)));
552 1.14 augustss wakeup(dv);
553 1.14 augustss }
554