Thu Dec 8 22:04:56 2011 UTC ()
sync usb_subr.c and usbdivar.h with the branch entirely, and most of
usbdi.c as well.


(mrg)
diff -r1.180.6.1.2.3 -r1.180.6.1.2.4 src/sys/dev/usb/usb_subr.c
diff -r1.134.2.1.2.3 -r1.134.2.1.2.4 src/sys/dev/usb/usbdi.c
diff -r1.93.8.1.2.2 -r1.93.8.1.2.3 src/sys/dev/usb/usbdivar.h

cvs diff -r1.180.6.1.2.3 -r1.180.6.1.2.4 src/sys/dev/usb/usb_subr.c (switch to unified diff)

--- src/sys/dev/usb/usb_subr.c 2011/12/08 10:41:28 1.180.6.1.2.3
+++ src/sys/dev/usb/usb_subr.c 2011/12/08 22:04:56 1.180.6.1.2.4
@@ -1,1579 +1,1572 @@ @@ -1,1579 +1,1572 @@
1/* $NetBSD: usb_subr.c,v 1.180.6.1.2.3 2011/12/08 10:41:28 mrg Exp $ */ 1/* $NetBSD: usb_subr.c,v 1.180.6.1.2.4 2011/12/08 22:04:56 mrg Exp $ */
2/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.1.2.3 2011/12/08 10:41:28 mrg Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.1.2.4 2011/12/08 22:04:56 mrg Exp $");
36 36
37#include "opt_compat_netbsd.h" 37#include "opt_compat_netbsd.h"
38#include "opt_usbverbose.h" 38#include "opt_usbverbose.h"
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/kernel.h> 42#include <sys/kernel.h>
43#include <sys/malloc.h> 43#include <sys/malloc.h>
44#include <sys/device.h> 44#include <sys/device.h>
45#include <sys/select.h> 45#include <sys/select.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47 47
48#include <sys/bus.h> 48#include <sys/bus.h>
49#include <sys/module.h> 49#include <sys/module.h>
50 50
51#include <dev/usb/usb.h> 51#include <dev/usb/usb.h>
52 52
53#include <dev/usb/usbdi.h> 53#include <dev/usb/usbdi.h>
54#include <dev/usb/usbdi_util.h> 54#include <dev/usb/usbdi_util.h>
55#include <dev/usb/usbdivar.h> 55#include <dev/usb/usbdivar.h>
56#include <dev/usb/usbdevs.h> 56#include <dev/usb/usbdevs.h>
57#include <dev/usb/usb_quirks.h> 57#include <dev/usb/usb_quirks.h>
58#include <dev/usb/usb_verbose.h> 58#include <dev/usb/usb_verbose.h>
59 59
60#include "locators.h" 60#include "locators.h"
61 61
62#ifdef USB_DEBUG 62#ifdef USB_DEBUG
63#define DPRINTF(x) if (usbdebug) printf x 63#define DPRINTF(x) if (usbdebug) printf x
64#define DPRINTFN(n,x) if (usbdebug>(n)) printf x 64#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
65extern int usbdebug; 65extern int usbdebug;
66#else 66#else
67#define DPRINTF(x) 67#define DPRINTF(x)
68#define DPRINTFN(n,x) 68#define DPRINTFN(n,x)
69#endif 69#endif
70 70
71MALLOC_DEFINE(M_USB, "USB", "USB misc. memory"); 71MALLOC_DEFINE(M_USB, "USB", "USB misc. memory");
72MALLOC_DEFINE(M_USBDEV, "USB device", "USB device driver"); 72MALLOC_DEFINE(M_USBDEV, "USB device", "USB device driver");
73MALLOC_DEFINE(M_USBHC, "USB HC", "USB host controller"); 73MALLOC_DEFINE(M_USBHC, "USB HC", "USB host controller");
74 74
75Static usbd_status usbd_set_config(usbd_device_handle, int); 75Static usbd_status usbd_set_config(usbd_device_handle, int);
76Static void usbd_devinfo(usbd_device_handle, int, char *, size_t); 76Static void usbd_devinfo(usbd_device_handle, int, char *, size_t);
77Static void usbd_devinfo_vp(usbd_device_handle, char *, size_t, char *, size_t, 77Static void usbd_devinfo_vp(usbd_device_handle, char *, size_t, char *, size_t,
78 int, int); 78 int, int);
79Static int usbd_getnewaddr(usbd_bus_handle); 79Static int usbd_getnewaddr(usbd_bus_handle);
80Static int usbd_print(void *, const char *); 80Static int usbd_print(void *, const char *);
81Static int usbd_ifprint(void *, const char *); 81Static int usbd_ifprint(void *, const char *);
82Static void usbd_free_iface_data(usbd_device_handle, int); 82Static void usbd_free_iface_data(usbd_device_handle, int);
83Static void usbd_kill_pipe(usbd_pipe_handle); 83Static void usbd_kill_pipe(usbd_pipe_handle);
84usbd_status usbd_attach_roothub(device_t, usbd_device_handle); 84usbd_status usbd_attach_roothub(device_t, usbd_device_handle);
85Static usbd_status usbd_probe_and_attach(device_t, usbd_device_handle, int, 85Static usbd_status usbd_probe_and_attach(device_t, usbd_device_handle, int,
86 int); 86 int);
87 87
88Static u_int32_t usb_cookie_no = 0; 88Static u_int32_t usb_cookie_no = 0;
89 89
90Static const char * const usbd_error_strs[] = { 90Static const char * const usbd_error_strs[] = {
91 "NORMAL_COMPLETION", 91 "NORMAL_COMPLETION",
92 "IN_PROGRESS", 92 "IN_PROGRESS",
93 "PENDING_REQUESTS", 93 "PENDING_REQUESTS",
94 "NOT_STARTED", 94 "NOT_STARTED",
95 "INVAL", 95 "INVAL",
96 "NOMEM", 96 "NOMEM",
97 "CANCELLED", 97 "CANCELLED",
98 "BAD_ADDRESS", 98 "BAD_ADDRESS",
99 "IN_USE", 99 "IN_USE",
100 "NO_ADDR", 100 "NO_ADDR",
101 "SET_ADDR_FAILED", 101 "SET_ADDR_FAILED",
102 "NO_POWER", 102 "NO_POWER",
103 "TOO_DEEP", 103 "TOO_DEEP",
104 "IOERROR", 104 "IOERROR",
105 "NOT_CONFIGURED", 105 "NOT_CONFIGURED",
106 "TIMEOUT", 106 "TIMEOUT",
107 "SHORT_XFER", 107 "SHORT_XFER",
108 "STALLED", 108 "STALLED",
109 "INTERRUPTED", 109 "INTERRUPTED",
110 "XXX", 110 "XXX",
111}; 111};
112 112
113void usb_load_verbose(void); 113void usb_load_verbose(void);
114 114
115void get_usb_vendor_stub(char *, size_t, usb_vendor_id_t); 115void get_usb_vendor_stub(char *, size_t, usb_vendor_id_t);
116void get_usb_product_stub(char *, size_t, usb_vendor_id_t, usb_product_id_t); 116void get_usb_product_stub(char *, size_t, usb_vendor_id_t, usb_product_id_t);
117 117
118void (*get_usb_vendor)(char *, size_t, usb_vendor_id_t) = get_usb_vendor_stub; 118void (*get_usb_vendor)(char *, size_t, usb_vendor_id_t) = get_usb_vendor_stub;
119void (*get_usb_product)(char *, size_t, usb_vendor_id_t, usb_product_id_t) = 119void (*get_usb_product)(char *, size_t, usb_vendor_id_t, usb_product_id_t) =
120 get_usb_product_stub; 120 get_usb_product_stub;
121 121
122int usb_verbose_loaded = 0; 122int usb_verbose_loaded = 0;
123 123
124/* 124/*
125 * Load the usbverbose module 125 * Load the usbverbose module
126 */ 126 */
127void usb_load_verbose(void) 127void usb_load_verbose(void)
128{ 128{
129 if (usb_verbose_loaded == 0) 129 if (usb_verbose_loaded == 0)
130 module_autoload("usbverbose", MODULE_CLASS_MISC); 130 module_autoload("usbverbose", MODULE_CLASS_MISC);
131} 131}
132 132
133void get_usb_vendor_stub(char *v, size_t l, usb_vendor_id_t v_id) 133void get_usb_vendor_stub(char *v, size_t l, usb_vendor_id_t v_id)
134{ 134{
135 usb_load_verbose(); 135 usb_load_verbose();
136 if (usb_verbose_loaded) 136 if (usb_verbose_loaded)
137 get_usb_vendor(v, l, v_id); 137 get_usb_vendor(v, l, v_id);
138} 138}
139 139
140void get_usb_product_stub(char *p, size_t l, usb_vendor_id_t v_id, 140void get_usb_product_stub(char *p, size_t l, usb_vendor_id_t v_id,
141 usb_product_id_t p_id) 141 usb_product_id_t p_id)
142{ 142{
143 usb_load_verbose(); 143 usb_load_verbose();
144 if (usb_verbose_loaded) 144 if (usb_verbose_loaded)
145 get_usb_product(p, l, v_id, p_id); 145 get_usb_product(p, l, v_id, p_id);
146} 146}
147 147
148const char * 148const char *
149usbd_errstr(usbd_status err) 149usbd_errstr(usbd_status err)
150{ 150{
151 static char buffer[5]; 151 static char buffer[5];
152 152
153 if (err < USBD_ERROR_MAX) { 153 if (err < USBD_ERROR_MAX) {
154 return usbd_error_strs[err]; 154 return usbd_error_strs[err];
155 } else { 155 } else {
156 snprintf(buffer, sizeof buffer, "%d", err); 156 snprintf(buffer, sizeof buffer, "%d", err);
157 return buffer; 157 return buffer;
158 } 158 }
159} 159}
160 160
161usbd_status 161usbd_status
162usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid, 162usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
163 usb_string_descriptor_t *sdesc, int *sizep) 163 usb_string_descriptor_t *sdesc, int *sizep)
164{ 164{
165 usb_device_request_t req; 165 usb_device_request_t req;
166 usbd_status err; 166 usbd_status err;
167 int actlen; 167 int actlen;
168 168
169 req.bmRequestType = UT_READ_DEVICE; 169 req.bmRequestType = UT_READ_DEVICE;
170 req.bRequest = UR_GET_DESCRIPTOR; 170 req.bRequest = UR_GET_DESCRIPTOR;
171 USETW2(req.wValue, UDESC_STRING, sindex); 171 USETW2(req.wValue, UDESC_STRING, sindex);
172 USETW(req.wIndex, langid); 172 USETW(req.wIndex, langid);
173 USETW(req.wLength, 2); /* only size byte first */ 173 USETW(req.wLength, 2); /* only size byte first */
174 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, 174 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
175 &actlen, USBD_DEFAULT_TIMEOUT); 175 &actlen, USBD_DEFAULT_TIMEOUT);
176 if (err) 176 if (err)
177 return (err); 177 return (err);
178 178
179 if (actlen < 2) 179 if (actlen < 2)
180 return (USBD_SHORT_XFER); 180 return (USBD_SHORT_XFER);
181 181
182 USETW(req.wLength, sdesc->bLength); /* the whole string */ 182 USETW(req.wLength, sdesc->bLength); /* the whole string */
183 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, 183 err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
184 &actlen, USBD_DEFAULT_TIMEOUT); 184 &actlen, USBD_DEFAULT_TIMEOUT);
185 if (err) 185 if (err)
186 return (err); 186 return (err);
187 187
188 if (actlen != sdesc->bLength) { 188 if (actlen != sdesc->bLength) {
189 DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n", 189 DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
190 sdesc->bLength, actlen)); 190 sdesc->bLength, actlen));
191 } 191 }
192 192
193 *sizep = actlen; 193 *sizep = actlen;
194 return (USBD_NORMAL_COMPLETION); 194 return (USBD_NORMAL_COMPLETION);
195} 195}
196 196
197static void 197static void
198usbd_trim_spaces(char *p) 198usbd_trim_spaces(char *p)
199{ 199{
200 char *q, *e; 200 char *q, *e;
201 201
202 q = e = p; 202 q = e = p;
203 while (*q == ' ') /* skip leading spaces */ 203 while (*q == ' ') /* skip leading spaces */
204 q++; 204 q++;
205 while ((*p = *q++)) /* copy string */ 205 while ((*p = *q++)) /* copy string */
206 if (*p++ != ' ') /* remember last non-space */ 206 if (*p++ != ' ') /* remember last non-space */
207 e = p; 207 e = p;
208 *e = '\0'; /* kill trailing spaces */ 208 *e = '\0'; /* kill trailing spaces */
209} 209}
210 210
211Static void 211Static void
212usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p, 212usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p,
213 size_t pl, int usedev, int useencoded) 213 size_t pl, int usedev, int useencoded)
214{ 214{
215 usb_device_descriptor_t *udd = &dev->ddesc; 215 usb_device_descriptor_t *udd = &dev->ddesc;
216 if (dev == NULL) 216 if (dev == NULL)
217 return; 217 return;
218 218
219 v[0] = p[0] = '\0'; 219 v[0] = p[0] = '\0';
220 220
221 if (usedev) { 221 if (usedev) {
222 if (usbd_get_string0(dev, udd->iManufacturer, v, useencoded) == 222 if (usbd_get_string0(dev, udd->iManufacturer, v, useencoded) ==
223 USBD_NORMAL_COMPLETION) 223 USBD_NORMAL_COMPLETION)
224 usbd_trim_spaces(v); 224 usbd_trim_spaces(v);
225 if (usbd_get_string0(dev, udd->iProduct, p, useencoded) == 225 if (usbd_get_string0(dev, udd->iProduct, p, useencoded) ==
226 USBD_NORMAL_COMPLETION) 226 USBD_NORMAL_COMPLETION)
227 usbd_trim_spaces(p); 227 usbd_trim_spaces(p);
228 } 228 }
229 if (v[0] == '\0') 229 if (v[0] == '\0')
230 get_usb_vendor(v, vl, UGETW(udd->idVendor)); 230 get_usb_vendor(v, vl, UGETW(udd->idVendor));
231 if (p[0] == '\0') 231 if (p[0] == '\0')
232 get_usb_product(p, pl, UGETW(udd->idVendor), 232 get_usb_product(p, pl, UGETW(udd->idVendor),
233 UGETW(udd->idProduct)); 233 UGETW(udd->idProduct));
234 234
235 if (v[0] == '\0') 235 if (v[0] == '\0')
236 snprintf(v, vl, "vendor 0x%04x", UGETW(udd->idVendor)); 236 snprintf(v, vl, "vendor 0x%04x", UGETW(udd->idVendor));
237 if (p[0] == '\0') 237 if (p[0] == '\0')
238 snprintf(p, pl, "product 0x%04x", UGETW(udd->idProduct)); 238 snprintf(p, pl, "product 0x%04x", UGETW(udd->idProduct));
239} 239}
240 240
241int 241int
242usbd_printBCD(char *cp, size_t l, int bcd) 242usbd_printBCD(char *cp, size_t l, int bcd)
243{ 243{
244 return snprintf(cp, l, "%x.%02x", bcd >> 8, bcd & 0xff); 244 return snprintf(cp, l, "%x.%02x", bcd >> 8, bcd & 0xff);
245} 245}
246 246
247Static void 247Static void
248usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l) 248usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l)
249{ 249{
250 usb_device_descriptor_t *udd = &dev->ddesc; 250 usb_device_descriptor_t *udd = &dev->ddesc;
251 char *vendor, *product; 251 char *vendor, *product;
252 int bcdDevice, bcdUSB; 252 int bcdDevice, bcdUSB;
253 char *ep; 253 char *ep;
254 254
255 vendor = malloc(USB_MAX_ENCODED_STRING_LEN * 2, M_USB, M_NOWAIT); 255 vendor = malloc(USB_MAX_ENCODED_STRING_LEN * 2, M_USB, M_NOWAIT);
256 if (vendor == NULL) { 256 if (vendor == NULL) {
257 *cp = '\0'; 257 *cp = '\0';
258 return; 258 return;
259 } 259 }
260 product = &vendor[USB_MAX_ENCODED_STRING_LEN]; 260 product = &vendor[USB_MAX_ENCODED_STRING_LEN];
261 261
262 ep = cp + l; 262 ep = cp + l;
263 263
264 usbd_devinfo_vp(dev, vendor, USB_MAX_ENCODED_STRING_LEN, 264 usbd_devinfo_vp(dev, vendor, USB_MAX_ENCODED_STRING_LEN,
265 product, USB_MAX_ENCODED_STRING_LEN, 1, 1); 265 product, USB_MAX_ENCODED_STRING_LEN, 1, 1);
266 cp += snprintf(cp, ep - cp, "%s %s", vendor, product); 266 cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
267 if (showclass) 267 if (showclass)
268 cp += snprintf(cp, ep - cp, ", class %d/%d", 268 cp += snprintf(cp, ep - cp, ", class %d/%d",
269 udd->bDeviceClass, udd->bDeviceSubClass); 269 udd->bDeviceClass, udd->bDeviceSubClass);
270 bcdUSB = UGETW(udd->bcdUSB); 270 bcdUSB = UGETW(udd->bcdUSB);
271 bcdDevice = UGETW(udd->bcdDevice); 271 bcdDevice = UGETW(udd->bcdDevice);
272 cp += snprintf(cp, ep - cp, ", rev "); 272 cp += snprintf(cp, ep - cp, ", rev ");
273 cp += usbd_printBCD(cp, ep - cp, bcdUSB); 273 cp += usbd_printBCD(cp, ep - cp, bcdUSB);
274 *cp++ = '/'; 274 *cp++ = '/';
275 cp += usbd_printBCD(cp, ep - cp, bcdDevice); 275 cp += usbd_printBCD(cp, ep - cp, bcdDevice);
276 cp += snprintf(cp, ep - cp, ", addr %d", dev->address); 276 cp += snprintf(cp, ep - cp, ", addr %d", dev->address);
277 *cp = 0; 277 *cp = 0;
278 free(vendor, M_USB); 278 free(vendor, M_USB);
279} 279}
280 280
281char * 281char *
282usbd_devinfo_alloc(usbd_device_handle dev, int showclass) 282usbd_devinfo_alloc(usbd_device_handle dev, int showclass)
283{ 283{
284 char *devinfop; 284 char *devinfop;
285 285
286 devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK); 286 devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK);
287 usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE); 287 usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE);
288 return devinfop; 288 return devinfop;
289} 289}
290 290
291void 291void
292usbd_devinfo_free(char *devinfop) 292usbd_devinfo_free(char *devinfop)
293{ 293{
294 free(devinfop, M_TEMP); 294 free(devinfop, M_TEMP);
295} 295}
296 296
297/* Delay for a certain number of ms */ 297/* Delay for a certain number of ms */
298void 298void
299usb_delay_ms(usbd_bus_handle bus, u_int ms) 299usb_delay_ms(usbd_bus_handle bus, u_int ms)
300{ 300{
301 /* Wait at least two clock ticks so we know the time has passed. */ 301 /* Wait at least two clock ticks so we know the time has passed. */
302 if (bus->use_polling || cold) 302 if (bus->use_polling || cold)
303 delay((ms+1) * 1000); 303 delay((ms+1) * 1000);
304 else 304 else
305 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1); 305 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1);
306} 306}
307 307
308/* Delay given a device handle. */ 308/* Delay given a device handle. */
309void 309void
310usbd_delay_ms(usbd_device_handle dev, u_int ms) 310usbd_delay_ms(usbd_device_handle dev, u_int ms)
311{ 311{
312 usb_delay_ms(dev->bus, ms); 312 usb_delay_ms(dev->bus, ms);
313} 313}
314 314
315usbd_status 315usbd_status
316usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) 316usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
317{ 317{
318 usb_device_request_t req; 318 usb_device_request_t req;
319 usbd_status err; 319 usbd_status err;
320 int n; 320 int n;
321 321
322 req.bmRequestType = UT_WRITE_CLASS_OTHER; 322 req.bmRequestType = UT_WRITE_CLASS_OTHER;
323 req.bRequest = UR_SET_FEATURE; 323 req.bRequest = UR_SET_FEATURE;
324 USETW(req.wValue, UHF_PORT_RESET); 324 USETW(req.wValue, UHF_PORT_RESET);
325 USETW(req.wIndex, port); 325 USETW(req.wIndex, port);
326 USETW(req.wLength, 0); 326 USETW(req.wLength, 0);
327 err = usbd_do_request(dev, &req, 0); 327 err = usbd_do_request(dev, &req, 0);
328 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n", 328 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
329 port, usbd_errstr(err))); 329 port, usbd_errstr(err)));
330 if (err) 330 if (err)
331 return (err); 331 return (err);
332 n = 10; 332 n = 10;
333 do { 333 do {
334 /* Wait for device to recover from reset. */ 334 /* Wait for device to recover from reset. */
335 usbd_delay_ms(dev, USB_PORT_RESET_DELAY); 335 usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
336 err = usbd_get_port_status(dev, port, ps); 336 err = usbd_get_port_status(dev, port, ps);
337 if (err) { 337 if (err) {
338 DPRINTF(("usbd_reset_port: get status failed %d\n", 338 DPRINTF(("usbd_reset_port: get status failed %d\n",
339 err)); 339 err));
340 return (err); 340 return (err);
341 } 341 }
342 /* If the device disappeared, just give up. */ 342 /* If the device disappeared, just give up. */
343 if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) 343 if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
344 return (USBD_NORMAL_COMPLETION); 344 return (USBD_NORMAL_COMPLETION);
345 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); 345 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
346 if (n == 0) 346 if (n == 0)
347 return (USBD_TIMEOUT); 347 return (USBD_TIMEOUT);
348 err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); 348 err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
349#ifdef USB_DEBUG 349#ifdef USB_DEBUG
350 if (err) 350 if (err)
351 DPRINTF(("usbd_reset_port: clear port feature failed %d\n", 351 DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
352 err)); 352 err));
353#endif 353#endif
354 354
355 /* Wait for the device to recover from reset. */ 355 /* Wait for the device to recover from reset. */
356 usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY); 356 usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
357 return (err); 357 return (err);
358} 358}
359 359
360usb_interface_descriptor_t * 360usb_interface_descriptor_t *
361usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx) 361usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
362{ 362{
363 char *p = (char *)cd; 363 char *p = (char *)cd;
364 char *end = p + UGETW(cd->wTotalLength); 364 char *end = p + UGETW(cd->wTotalLength);
365 usb_interface_descriptor_t *d; 365 usb_interface_descriptor_t *d;
366 int curidx, lastidx, curaidx = 0; 366 int curidx, lastidx, curaidx = 0;
367 367
368 for (curidx = lastidx = -1; p < end; ) { 368 for (curidx = lastidx = -1; p < end; ) {
369 d = (usb_interface_descriptor_t *)p; 369 d = (usb_interface_descriptor_t *)p;
370 DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d " 370 DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
371 "type=%d\n", 371 "type=%d\n",
372 ifaceidx, curidx, altidx, curaidx, 372 ifaceidx, curidx, altidx, curaidx,
373 d->bLength, d->bDescriptorType)); 373 d->bLength, d->bDescriptorType));
374 if (d->bLength == 0) /* bad descriptor */ 374 if (d->bLength == 0) /* bad descriptor */
375 break; 375 break;
376 p += d->bLength; 376 p += d->bLength;
377 if (p <= end && d->bDescriptorType == UDESC_INTERFACE) { 377 if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
378 if (d->bInterfaceNumber != lastidx) { 378 if (d->bInterfaceNumber != lastidx) {
379 lastidx = d->bInterfaceNumber; 379 lastidx = d->bInterfaceNumber;
380 curidx++; 380 curidx++;
381 curaidx = 0; 381 curaidx = 0;
382 } else 382 } else
383 curaidx++; 383 curaidx++;
384 if (ifaceidx == curidx && altidx == curaidx) 384 if (ifaceidx == curidx && altidx == curaidx)
385 return (d); 385 return (d);
386 } 386 }
387 } 387 }
388 return (NULL); 388 return (NULL);
389} 389}
390 390
391usb_endpoint_descriptor_t * 391usb_endpoint_descriptor_t *
392usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx, 392usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
393 int endptidx) 393 int endptidx)
394{ 394{
395 char *p = (char *)cd; 395 char *p = (char *)cd;
396 char *end = p + UGETW(cd->wTotalLength); 396 char *end = p + UGETW(cd->wTotalLength);
397 usb_interface_descriptor_t *d; 397 usb_interface_descriptor_t *d;
398 usb_endpoint_descriptor_t *e; 398 usb_endpoint_descriptor_t *e;
399 int curidx; 399 int curidx;
400 400
401 d = usbd_find_idesc(cd, ifaceidx, altidx); 401 d = usbd_find_idesc(cd, ifaceidx, altidx);
402 if (d == NULL) 402 if (d == NULL)
403 return (NULL); 403 return (NULL);
404 if (endptidx >= d->bNumEndpoints) /* quick exit */ 404 if (endptidx >= d->bNumEndpoints) /* quick exit */
405 return (NULL); 405 return (NULL);
406 406
407 curidx = -1; 407 curidx = -1;
408 for (p = (char *)d + d->bLength; p < end; ) { 408 for (p = (char *)d + d->bLength; p < end; ) {
409 e = (usb_endpoint_descriptor_t *)p; 409 e = (usb_endpoint_descriptor_t *)p;
410 if (e->bLength == 0) /* bad descriptor */ 410 if (e->bLength == 0) /* bad descriptor */
411 break; 411 break;
412 p += e->bLength; 412 p += e->bLength;
413 if (p <= end && e->bDescriptorType == UDESC_INTERFACE) 413 if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
414 return (NULL); 414 return (NULL);
415 if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) { 415 if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
416 curidx++; 416 curidx++;
417 if (curidx == endptidx) 417 if (curidx == endptidx)
418 return (e); 418 return (e);
419 } 419 }
420 } 420 }
421 return (NULL); 421 return (NULL);
422} 422}
423 423
424usbd_status 424usbd_status
425usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx) 425usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
426{ 426{
427 usbd_interface_handle ifc = &dev->ifaces[ifaceidx]; 427 usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
428 usb_interface_descriptor_t *idesc; 428 usb_interface_descriptor_t *idesc;
429 char *p, *end; 429 char *p, *end;
430 int endpt, nendpt; 430 int endpt, nendpt;
431 431
432 DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n", 432 DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
433 ifaceidx, altidx)); 433 ifaceidx, altidx));
434 idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx); 434 idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
435 if (idesc == NULL) 435 if (idesc == NULL)
436 return (USBD_INVAL); 436 return (USBD_INVAL);
437 ifc->device = dev; 437 ifc->device = dev;
438 ifc->idesc = idesc; 438 ifc->idesc = idesc;
439 ifc->index = ifaceidx; 439 ifc->index = ifaceidx;
440 ifc->altindex = altidx; 440 ifc->altindex = altidx;
441 nendpt = ifc->idesc->bNumEndpoints; 441 nendpt = ifc->idesc->bNumEndpoints;
442 DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt)); 442 DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
443 if (nendpt != 0) { 443 if (nendpt != 0) {
444 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint), 444 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
445 M_USB, M_NOWAIT); 445 M_USB, M_NOWAIT);
446 if (ifc->endpoints == NULL) 446 if (ifc->endpoints == NULL)
447 return (USBD_NOMEM); 447 return (USBD_NOMEM);
448 } else 448 } else
449 ifc->endpoints = NULL; 449 ifc->endpoints = NULL;
450 ifc->priv = NULL; 450 ifc->priv = NULL;
451 p = (char *)ifc->idesc + ifc->idesc->bLength; 451 p = (char *)ifc->idesc + ifc->idesc->bLength;
452 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength); 452 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
453#define ed ((usb_endpoint_descriptor_t *)p) 453#define ed ((usb_endpoint_descriptor_t *)p)
454 for (endpt = 0; endpt < nendpt; endpt++) { 454 for (endpt = 0; endpt < nendpt; endpt++) {
455 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt)); 455 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
456 for (; p < end; p += ed->bLength) { 456 for (; p < end; p += ed->bLength) {
457 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p " 457 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
458 "len=%d type=%d\n", 458 "len=%d type=%d\n",
459 p, end, ed->bLength, ed->bDescriptorType)); 459 p, end, ed->bLength, ed->bDescriptorType));
460 if (p + ed->bLength <= end && ed->bLength != 0 && 460 if (p + ed->bLength <= end && ed->bLength != 0 &&
461 ed->bDescriptorType == UDESC_ENDPOINT) 461 ed->bDescriptorType == UDESC_ENDPOINT)
462 goto found; 462 goto found;
463 if (ed->bLength == 0 || 463 if (ed->bLength == 0 ||
464 ed->bDescriptorType == UDESC_INTERFACE) 464 ed->bDescriptorType == UDESC_INTERFACE)
465 break; 465 break;
466 } 466 }
467 /* passed end, or bad desc */ 467 /* passed end, or bad desc */
468 printf("usbd_fill_iface_data: bad descriptor(s): %s\n", 468 printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
469 ed->bLength == 0 ? "0 length" : 469 ed->bLength == 0 ? "0 length" :
470 ed->bDescriptorType == UDESC_INTERFACE ? "iface desc": 470 ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
471 "out of data"); 471 "out of data");
472 goto bad; 472 goto bad;
473 found: 473 found:
474 ifc->endpoints[endpt].edesc = ed; 474 ifc->endpoints[endpt].edesc = ed;
475 if (dev->speed == USB_SPEED_HIGH) { 475 if (dev->speed == USB_SPEED_HIGH) {
476 u_int mps; 476 u_int mps;
477 /* Control and bulk endpoints have max packet limits. */ 477 /* Control and bulk endpoints have max packet limits. */
478 switch (UE_GET_XFERTYPE(ed->bmAttributes)) { 478 switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
479 case UE_CONTROL: 479 case UE_CONTROL:
480 mps = USB_2_MAX_CTRL_PACKET; 480 mps = USB_2_MAX_CTRL_PACKET;
481 goto check; 481 goto check;
482 case UE_BULK: 482 case UE_BULK:
483 mps = USB_2_MAX_BULK_PACKET; 483 mps = USB_2_MAX_BULK_PACKET;
484 check: 484 check:
485 if (UGETW(ed->wMaxPacketSize) != mps) { 485 if (UGETW(ed->wMaxPacketSize) != mps) {
486 USETW(ed->wMaxPacketSize, mps); 486 USETW(ed->wMaxPacketSize, mps);
487#ifdef DIAGNOSTIC 487#ifdef DIAGNOSTIC
488 printf("usbd_fill_iface_data: bad max " 488 printf("usbd_fill_iface_data: bad max "
489 "packet size\n"); 489 "packet size\n");
490#endif 490#endif
491 } 491 }
492 break; 492 break;
493 default: 493 default:
494 break; 494 break;
495 } 495 }
496 } 496 }
497 ifc->endpoints[endpt].refcnt = 0; 497 ifc->endpoints[endpt].refcnt = 0;
498 ifc->endpoints[endpt].datatoggle = 0; 498 ifc->endpoints[endpt].datatoggle = 0;
499 p += ed->bLength; 499 p += ed->bLength;
500 } 500 }
501#undef ed 501#undef ed
502 LIST_INIT(&ifc->pipes); 502 LIST_INIT(&ifc->pipes);
503 return (USBD_NORMAL_COMPLETION); 503 return (USBD_NORMAL_COMPLETION);
504 504
505 bad: 505 bad:
506 if (ifc->endpoints != NULL) { 506 if (ifc->endpoints != NULL) {
507 free(ifc->endpoints, M_USB); 507 free(ifc->endpoints, M_USB);
508 ifc->endpoints = NULL; 508 ifc->endpoints = NULL;
509 } 509 }
510 return (USBD_INVAL); 510 return (USBD_INVAL);
511} 511}
512 512
513void 513void
514usbd_free_iface_data(usbd_device_handle dev, int ifcno) 514usbd_free_iface_data(usbd_device_handle dev, int ifcno)
515{ 515{
516 usbd_interface_handle ifc = &dev->ifaces[ifcno]; 516 usbd_interface_handle ifc = &dev->ifaces[ifcno];
517 if (ifc->endpoints) 517 if (ifc->endpoints)
518 free(ifc->endpoints, M_USB); 518 free(ifc->endpoints, M_USB);
519} 519}
520 520
521Static usbd_status 521Static usbd_status
522usbd_set_config(usbd_device_handle dev, int conf) 522usbd_set_config(usbd_device_handle dev, int conf)
523{ 523{
524 usb_device_request_t req; 524 usb_device_request_t req;
525 525
526 req.bmRequestType = UT_WRITE_DEVICE; 526 req.bmRequestType = UT_WRITE_DEVICE;
527 req.bRequest = UR_SET_CONFIG; 527 req.bRequest = UR_SET_CONFIG;
528 USETW(req.wValue, conf); 528 USETW(req.wValue, conf);
529 USETW(req.wIndex, 0); 529 USETW(req.wIndex, 0);
530 USETW(req.wLength, 0); 530 USETW(req.wLength, 0);
531 return (usbd_do_request(dev, &req, 0)); 531 return (usbd_do_request(dev, &req, 0));
532} 532}
533 533
534usbd_status 534usbd_status
535usbd_set_config_no(usbd_device_handle dev, int no, int msg) 535usbd_set_config_no(usbd_device_handle dev, int no, int msg)
536{ 536{
537 int index; 537 int index;
538 usb_config_descriptor_t cd; 538 usb_config_descriptor_t cd;
539 usbd_status err; 539 usbd_status err;
540 540
541 if (no == USB_UNCONFIG_NO) 541 if (no == USB_UNCONFIG_NO)
542 return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg)); 542 return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
543 543
544 DPRINTFN(5,("usbd_set_config_no: %d\n", no)); 544 DPRINTFN(5,("usbd_set_config_no: %d\n", no));
545 /* Figure out what config index to use. */ 545 /* Figure out what config index to use. */
546 for (index = 0; index < dev->ddesc.bNumConfigurations; index++) { 546 for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
547 err = usbd_get_config_desc(dev, index, &cd); 547 err = usbd_get_config_desc(dev, index, &cd);
548 if (err) 548 if (err)
549 return (err); 549 return (err);
550 if (cd.bConfigurationValue == no) 550 if (cd.bConfigurationValue == no)
551 return (usbd_set_config_index(dev, index, msg)); 551 return (usbd_set_config_index(dev, index, msg));
552 } 552 }
553 return (USBD_INVAL); 553 return (USBD_INVAL);
554} 554}
555 555
556usbd_status 556usbd_status
557usbd_set_config_index(usbd_device_handle dev, int index, int msg) 557usbd_set_config_index(usbd_device_handle dev, int index, int msg)
558{ 558{
559 usb_config_descriptor_t cd, *cdp; 559 usb_config_descriptor_t cd, *cdp;
560 usbd_status err; 560 usbd_status err;
561 int i, ifcidx, nifc, len, selfpowered, power; 561 int i, ifcidx, nifc, len, selfpowered, power;
562 562
563 DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index)); 563 DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
564 564
565 if (index >= dev->ddesc.bNumConfigurations && 565 if (index >= dev->ddesc.bNumConfigurations &&
566 index != USB_UNCONFIG_INDEX) { 566 index != USB_UNCONFIG_INDEX) {
567 /* panic? */ 567 /* panic? */
568 printf("usbd_set_config_index: illegal index\n"); 568 printf("usbd_set_config_index: illegal index\n");
569 return (USBD_INVAL); 569 return (USBD_INVAL);
570 } 570 }
571 571
572 /* XXX check that all interfaces are idle */ 572 /* XXX check that all interfaces are idle */
573 if (dev->config != USB_UNCONFIG_NO) { 573 if (dev->config != USB_UNCONFIG_NO) {
574 DPRINTF(("usbd_set_config_index: free old config\n")); 574 DPRINTF(("usbd_set_config_index: free old config\n"));
575 /* Free all configuration data structures. */ 575 /* Free all configuration data structures. */
576 nifc = dev->cdesc->bNumInterface; 576 nifc = dev->cdesc->bNumInterface;
577 for (ifcidx = 0; ifcidx < nifc; ifcidx++) 577 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
578 usbd_free_iface_data(dev, ifcidx); 578 usbd_free_iface_data(dev, ifcidx);
579 free(dev->ifaces, M_USB); 579 free(dev->ifaces, M_USB);
580 free(dev->cdesc, M_USB); 580 free(dev->cdesc, M_USB);
581 dev->ifaces = NULL; 581 dev->ifaces = NULL;
582 dev->cdesc = NULL; 582 dev->cdesc = NULL;
583 dev->config = USB_UNCONFIG_NO; 583 dev->config = USB_UNCONFIG_NO;
584 } 584 }
585 585
586 if (index == USB_UNCONFIG_INDEX) { 586 if (index == USB_UNCONFIG_INDEX) {
587 /* We are unconfiguring the device, so leave unallocated. */ 587 /* We are unconfiguring the device, so leave unallocated. */
588 DPRINTF(("usbd_set_config_index: set config 0\n")); 588 DPRINTF(("usbd_set_config_index: set config 0\n"));
589 err = usbd_set_config(dev, USB_UNCONFIG_NO); 589 err = usbd_set_config(dev, USB_UNCONFIG_NO);
590 if (err) { 590 if (err) {
591 DPRINTF(("usbd_set_config_index: setting config=0 " 591 DPRINTF(("usbd_set_config_index: setting config=0 "
592 "failed, error=%s\n", usbd_errstr(err))); 592 "failed, error=%s\n", usbd_errstr(err)));
593 } 593 }
594 return (err); 594 return (err);
595 } 595 }
596 596
597 /* Get the short descriptor. */ 597 /* Get the short descriptor. */
598 err = usbd_get_config_desc(dev, index, &cd); 598 err = usbd_get_config_desc(dev, index, &cd);
599 if (err) { 599 if (err) {
600 DPRINTF(("usbd_set_config_index: get_config_desc=%d\n", err)); 600 DPRINTF(("usbd_set_config_index: get_config_desc=%d\n", err));
601 return (err); 601 return (err);
602 } 602 }
603 len = UGETW(cd.wTotalLength); 603 len = UGETW(cd.wTotalLength);
604 cdp = malloc(len, M_USB, M_NOWAIT); 604 cdp = malloc(len, M_USB, M_NOWAIT);
605 if (cdp == NULL) 605 if (cdp == NULL)
606 return (USBD_NOMEM); 606 return (USBD_NOMEM);
607 607
608 /* Get the full descriptor. Try a few times for slow devices. */ 608 /* Get the full descriptor. Try a few times for slow devices. */
609 for (i = 0; i < 3; i++) { 609 for (i = 0; i < 3; i++) {
610 err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp); 610 err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
611 if (!err) 611 if (!err)
612 break; 612 break;
613 usbd_delay_ms(dev, 200); 613 usbd_delay_ms(dev, 200);
614 } 614 }
615 if (err) { 615 if (err) {
616 DPRINTF(("usbd_set_config_index: get_desc=%d\n", err)); 616 DPRINTF(("usbd_set_config_index: get_desc=%d\n", err));
617 goto bad; 617 goto bad;
618 } 618 }
619 if (cdp->bDescriptorType != UDESC_CONFIG) { 619 if (cdp->bDescriptorType != UDESC_CONFIG) {
620 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n", 620 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
621 cdp->bDescriptorType)); 621 cdp->bDescriptorType));
622 err = USBD_INVAL; 622 err = USBD_INVAL;
623 goto bad; 623 goto bad;
624 } 624 }
625 625
626 /* 626 /*
627 * Figure out if the device is self or bus powered. 627 * Figure out if the device is self or bus powered.
628 */ 628 */
629#if 0 /* XXX various devices don't report the power state correctly */ 629#if 0 /* XXX various devices don't report the power state correctly */
630 selfpowered = 0; 630 selfpowered = 0;
631 err = usbd_get_device_status(dev, &ds); 631 err = usbd_get_device_status(dev, &ds);
632 if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED)) 632 if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
633 selfpowered = 1; 633 selfpowered = 1;
634#endif 634#endif
635 /* 635 /*
636 * Use the power state in the configuration we are going 636 * Use the power state in the configuration we are going
637 * to set. This doesn't necessarily reflect the actual 637 * to set. This doesn't necessarily reflect the actual
638 * power state of the device; the driver can control this 638 * power state of the device; the driver can control this
639 * by choosing the appropriate configuration. 639 * by choosing the appropriate configuration.
640 */ 640 */
641 selfpowered = !!(cdp->bmAttributes & UC_SELF_POWERED); 641 selfpowered = !!(cdp->bmAttributes & UC_SELF_POWERED);
642 642
643 DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, " 643 DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
644 "selfpowered=%d, power=%d\n", 644 "selfpowered=%d, power=%d\n",
645 cdp->bConfigurationValue, dev->address, cdp->bmAttributes, 645 cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
646 selfpowered, cdp->bMaxPower * 2)); 646 selfpowered, cdp->bMaxPower * 2));
647 647
648 /* Check if we have enough power. */ 648 /* Check if we have enough power. */
649#if 0 /* this is a no-op, see above */ 649#if 0 /* this is a no-op, see above */
650 if ((cdp->bmAttributes & UC_SELF_POWERED) && !selfpowered) { 650 if ((cdp->bmAttributes & UC_SELF_POWERED) && !selfpowered) {
651 if (msg) 651 if (msg)
652 printf("%s: device addr %d (config %d): " 652 printf("%s: device addr %d (config %d): "
653 "can't set self powered configuration\n", 653 "can't set self powered configuration\n",
654 device_xname(dev->bus->bdev), dev->address, 654 device_xname(dev->bus->bdev), dev->address,
655 cdp->bConfigurationValue); 655 cdp->bConfigurationValue);
656 err = USBD_NO_POWER; 656 err = USBD_NO_POWER;
657 goto bad; 657 goto bad;
658 } 658 }
659#endif 659#endif
660#ifdef USB_DEBUG 660#ifdef USB_DEBUG
661 if (dev->powersrc == NULL) { 661 if (dev->powersrc == NULL) {
662 DPRINTF(("usbd_set_config_index: No power source?\n")); 662 DPRINTF(("usbd_set_config_index: No power source?\n"));
663 err = USBD_IOERROR; 663 err = USBD_IOERROR;
664 goto bad; 664 goto bad;
665 } 665 }
666#endif 666#endif
667 power = cdp->bMaxPower * 2; 667 power = cdp->bMaxPower * 2;
668 if (power > dev->powersrc->power) { 668 if (power > dev->powersrc->power) {
669 DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power)); 669 DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
670 /* XXX print nicer message. */ 670 /* XXX print nicer message. */
671 if (msg) 671 if (msg)
672 printf("%s: device addr %d (config %d) exceeds power " 672 printf("%s: device addr %d (config %d) exceeds power "
673 "budget, %d mA > %d mA\n", 673 "budget, %d mA > %d mA\n",
674 device_xname(dev->bus->usbctl), dev->address, 674 device_xname(dev->bus->usbctl), dev->address,
675 cdp->bConfigurationValue, 675 cdp->bConfigurationValue,
676 power, dev->powersrc->power); 676 power, dev->powersrc->power);
677 err = USBD_NO_POWER; 677 err = USBD_NO_POWER;
678 goto bad; 678 goto bad;
679 } 679 }
680 dev->power = power; 680 dev->power = power;
681 dev->self_powered = selfpowered; 681 dev->self_powered = selfpowered;
682 682
683 /* Set the actual configuration value. */ 683 /* Set the actual configuration value. */
684 DPRINTF(("usbd_set_config_index: set config %d\n", 684 DPRINTF(("usbd_set_config_index: set config %d\n",
685 cdp->bConfigurationValue)); 685 cdp->bConfigurationValue));
686 err = usbd_set_config(dev, cdp->bConfigurationValue); 686 err = usbd_set_config(dev, cdp->bConfigurationValue);
687 if (err) { 687 if (err) {
688 DPRINTF(("usbd_set_config_index: setting config=%d failed, " 688 DPRINTF(("usbd_set_config_index: setting config=%d failed, "
689 "error=%s\n", 689 "error=%s\n",
690 cdp->bConfigurationValue, usbd_errstr(err))); 690 cdp->bConfigurationValue, usbd_errstr(err)));
691 goto bad; 691 goto bad;
692 } 692 }
693 693
694 /* Allocate and fill interface data. */ 694 /* Allocate and fill interface data. */
695 nifc = cdp->bNumInterface; 695 nifc = cdp->bNumInterface;
696 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface), 696 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
697 M_USB, M_NOWAIT); 697 M_USB, M_NOWAIT);
698 if (dev->ifaces == NULL) { 698 if (dev->ifaces == NULL) {
699 err = USBD_NOMEM; 699 err = USBD_NOMEM;
700 goto bad; 700 goto bad;
701 } 701 }
702 DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp)); 702 DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
703 dev->cdesc = cdp; 703 dev->cdesc = cdp;
704 dev->config = cdp->bConfigurationValue; 704 dev->config = cdp->bConfigurationValue;
705 for (ifcidx = 0; ifcidx < nifc; ifcidx++) { 705 for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
706 err = usbd_fill_iface_data(dev, ifcidx, 0); 706 err = usbd_fill_iface_data(dev, ifcidx, 0);
707 if (err) { 707 if (err) {
708 while (--ifcidx >= 0) 708 while (--ifcidx >= 0)
709 usbd_free_iface_data(dev, ifcidx); 709 usbd_free_iface_data(dev, ifcidx);
710 goto bad; 710 goto bad;
711 } 711 }
712 } 712 }
713 713
714 return (USBD_NORMAL_COMPLETION); 714 return (USBD_NORMAL_COMPLETION);
715 715
716 bad: 716 bad:
717 free(cdp, M_USB); 717 free(cdp, M_USB);
718 return (err); 718 return (err);
719} 719}
720 720
721/* XXX add function for alternate settings */ 721/* XXX add function for alternate settings */
722 722
723usbd_status 723usbd_status
724usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface, 724usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
725 struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe) 725 struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
726{ 726{
727 usbd_pipe_handle p; 727 usbd_pipe_handle p;
728 usbd_status err; 728 usbd_status err;
729 729
730 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n", 730 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
731 dev, iface, ep, pipe)); 731 dev, iface, ep, pipe));
732 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT); 732 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
733 if (p == NULL) 733 if (p == NULL)
734 return (USBD_NOMEM); 734 return (USBD_NOMEM);
735 p->device = dev; 735 p->device = dev;
736 p->iface = iface; 736 p->iface = iface;
737 p->endpoint = ep; 737 p->endpoint = ep;
738 ep->refcnt++; 738 ep->refcnt++;
739 p->refcnt = 1; 739 p->refcnt = 1;
740 p->intrxfer = 0; 740 p->intrxfer = 0;
741 p->running = 0; 741 p->running = 0;
742 p->aborting = 0; 742 p->aborting = 0;
743 p->repeat = 0; 743 p->repeat = 0;
744 p->interval = ival; 744 p->interval = ival;
745 SIMPLEQ_INIT(&p->queue); 745 SIMPLEQ_INIT(&p->queue);
746 err = dev->bus->methods->open_pipe(p); 746 err = dev->bus->methods->open_pipe(p);
747 if (err) { 747 if (err) {
748 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=" 748 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
749 "%s\n", 749 "%s\n",
750 ep->edesc->bEndpointAddress, usbd_errstr(err))); 750 ep->edesc->bEndpointAddress, usbd_errstr(err)));
751 free(p, M_USB); 751 free(p, M_USB);
752 return (err); 752 return (err);
753 } 753 }
754#if 1 
755 if (dev->bus->methods->get_locks) { 
756 dev->bus->methods->get_locks(dev->bus, &p->intr_lock, &p->lock); 
757 } else { 
758 p->intr_lock = p->lock = NULL; 
759 } 
760#endif 
761 *pipe = p; 754 *pipe = p;
762 return (USBD_NORMAL_COMPLETION); 755 return (USBD_NORMAL_COMPLETION);
763} 756}
764 757
765/* Abort the device control pipe. */ 758/* Abort the device control pipe. */
766void 759void
767usbd_kill_pipe(usbd_pipe_handle pipe) 760usbd_kill_pipe(usbd_pipe_handle pipe)
768{ 761{
769 usbd_abort_pipe(pipe); 762 usbd_abort_pipe(pipe);
770 pipe->methods->close(pipe); 763 pipe->methods->close(pipe);
771 pipe->endpoint->refcnt--; 764 pipe->endpoint->refcnt--;
772 free(pipe, M_USB); 765 free(pipe, M_USB);
773} 766}
774 767
775int 768int
776usbd_getnewaddr(usbd_bus_handle bus) 769usbd_getnewaddr(usbd_bus_handle bus)
777{ 770{
778 int addr; 771 int addr;
779 772
780 for (addr = 1; addr < USB_MAX_DEVICES; addr++) 773 for (addr = 1; addr < USB_MAX_DEVICES; addr++)
781 if (bus->devices[addr] == 0) 774 if (bus->devices[addr] == 0)
782 return (addr); 775 return (addr);
783 return (-1); 776 return (-1);
784} 777}
785 778
786usbd_status 779usbd_status
787usbd_attach_roothub(device_t parent, usbd_device_handle dev) 780usbd_attach_roothub(device_t parent, usbd_device_handle dev)
788{ 781{
789 struct usb_attach_arg uaa; 782 struct usb_attach_arg uaa;
790 usb_device_descriptor_t *dd = &dev->ddesc; 783 usb_device_descriptor_t *dd = &dev->ddesc;
791 device_t dv; 784 device_t dv;
792 785
793 uaa.device = dev; 786 uaa.device = dev;
794 uaa.usegeneric = 0; 787 uaa.usegeneric = 0;
795 uaa.port = 0; 788 uaa.port = 0;
796 uaa.vendor = UGETW(dd->idVendor); 789 uaa.vendor = UGETW(dd->idVendor);
797 uaa.product = UGETW(dd->idProduct); 790 uaa.product = UGETW(dd->idProduct);
798 uaa.release = UGETW(dd->bcdDevice); 791 uaa.release = UGETW(dd->bcdDevice);
799 uaa.class = dd->bDeviceClass; 792 uaa.class = dd->bDeviceClass;
800 uaa.subclass = dd->bDeviceSubClass; 793 uaa.subclass = dd->bDeviceSubClass;
801 uaa.proto = dd->bDeviceProtocol; 794 uaa.proto = dd->bDeviceProtocol;
802 795
803 dv = config_found_ia(parent, "usbroothubif", &uaa, 0); 796 dv = config_found_ia(parent, "usbroothubif", &uaa, 0);
804 if (dv) { 797 if (dv) {
805 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); 798 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
806 if (dev->subdevs == NULL) 799 if (dev->subdevs == NULL)
807 return (USBD_NOMEM); 800 return (USBD_NOMEM);
808 dev->subdevs[0] = dv; 801 dev->subdevs[0] = dv;
809 dev->subdevlen = 1; 802 dev->subdevlen = 1;
810 } 803 }
811 return (USBD_NORMAL_COMPLETION); 804 return (USBD_NORMAL_COMPLETION);
812} 805}
813 806
814static usbd_status 807static usbd_status
815usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port, 808usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port,
816 int usegeneric) 809 int usegeneric)
817{ 810{
818 struct usb_attach_arg uaa; 811 struct usb_attach_arg uaa;
819 usb_device_descriptor_t *dd = &dev->ddesc; 812 usb_device_descriptor_t *dd = &dev->ddesc;
820 device_t dv; 813 device_t dv;
821 int dlocs[USBDEVIFCF_NLOCS]; 814 int dlocs[USBDEVIFCF_NLOCS];
822 815
823 uaa.device = dev; 816 uaa.device = dev;
824 uaa.usegeneric = usegeneric; 817 uaa.usegeneric = usegeneric;
825 uaa.port = port; 818 uaa.port = port;
826 uaa.vendor = UGETW(dd->idVendor); 819 uaa.vendor = UGETW(dd->idVendor);
827 uaa.product = UGETW(dd->idProduct); 820 uaa.product = UGETW(dd->idProduct);
828 uaa.release = UGETW(dd->bcdDevice); 821 uaa.release = UGETW(dd->bcdDevice);
829 uaa.class = dd->bDeviceClass; 822 uaa.class = dd->bDeviceClass;
830 uaa.subclass = dd->bDeviceSubClass; 823 uaa.subclass = dd->bDeviceSubClass;
831 uaa.proto = dd->bDeviceProtocol; 824 uaa.proto = dd->bDeviceProtocol;
832 825
833 dlocs[USBDEVIFCF_PORT] = uaa.port; 826 dlocs[USBDEVIFCF_PORT] = uaa.port;
834 dlocs[USBDEVIFCF_VENDOR] = uaa.vendor; 827 dlocs[USBDEVIFCF_VENDOR] = uaa.vendor;
835 dlocs[USBDEVIFCF_PRODUCT] = uaa.product; 828 dlocs[USBDEVIFCF_PRODUCT] = uaa.product;
836 dlocs[USBDEVIFCF_RELEASE] = uaa.release; 829 dlocs[USBDEVIFCF_RELEASE] = uaa.release;
837 /* the rest is historical ballast */ 830 /* the rest is historical ballast */
838 dlocs[USBDEVIFCF_CONFIGURATION] = -1; 831 dlocs[USBDEVIFCF_CONFIGURATION] = -1;
839 dlocs[USBDEVIFCF_INTERFACE] = -1; 832 dlocs[USBDEVIFCF_INTERFACE] = -1;
840 833
841 dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print, 834 dv = config_found_sm_loc(parent, "usbdevif", dlocs, &uaa, usbd_print,
842 config_stdsubmatch); 835 config_stdsubmatch);
843 if (dv) { 836 if (dv) {
844 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); 837 dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT);
845 if (dev->subdevs == NULL) 838 if (dev->subdevs == NULL)
846 return (USBD_NOMEM); 839 return (USBD_NOMEM);
847 dev->subdevs[0] = dv; 840 dev->subdevs[0] = dv;
848 dev->subdevlen = 1; 841 dev->subdevlen = 1;
849 dev->nifaces_claimed = 1; /* XXX */ 842 dev->nifaces_claimed = 1; /* XXX */
850 } 843 }
851 return (USBD_NORMAL_COMPLETION); 844 return (USBD_NORMAL_COMPLETION);
852} 845}
853 846
854static usbd_status 847static usbd_status
855usbd_attachinterfaces(device_t parent, usbd_device_handle dev, 848usbd_attachinterfaces(device_t parent, usbd_device_handle dev,
856 int port, const int *locators) 849 int port, const int *locators)
857{ 850{
858 struct usbif_attach_arg uiaa; 851 struct usbif_attach_arg uiaa;
859 int ilocs[USBIFIFCF_NLOCS]; 852 int ilocs[USBIFIFCF_NLOCS];
860 usb_device_descriptor_t *dd = &dev->ddesc; 853 usb_device_descriptor_t *dd = &dev->ddesc;
861 int nifaces; 854 int nifaces;
862 usbd_interface_handle *ifaces; 855 usbd_interface_handle *ifaces;
863 int i, j, loc; 856 int i, j, loc;
864 device_t dv; 857 device_t dv;
865 858
866 nifaces = dev->cdesc->bNumInterface; 859 nifaces = dev->cdesc->bNumInterface;
867 ifaces = malloc(nifaces * sizeof(*ifaces), M_USB, M_NOWAIT|M_ZERO); 860 ifaces = malloc(nifaces * sizeof(*ifaces), M_USB, M_NOWAIT|M_ZERO);
868 if (!ifaces) 861 if (!ifaces)
869 return (USBD_NOMEM); 862 return (USBD_NOMEM);
870 for (i = 0; i < nifaces; i++) 863 for (i = 0; i < nifaces; i++)
871 if (!dev->subdevs[i]) 864 if (!dev->subdevs[i])
872 ifaces[i] = &dev->ifaces[i]; 865 ifaces[i] = &dev->ifaces[i];
873 866
874 uiaa.device = dev; 867 uiaa.device = dev;
875 uiaa.port = port; 868 uiaa.port = port;
876 uiaa.vendor = UGETW(dd->idVendor); 869 uiaa.vendor = UGETW(dd->idVendor);
877 uiaa.product = UGETW(dd->idProduct); 870 uiaa.product = UGETW(dd->idProduct);
878 uiaa.release = UGETW(dd->bcdDevice); 871 uiaa.release = UGETW(dd->bcdDevice);
879 uiaa.configno = dev->cdesc->bConfigurationValue; 872 uiaa.configno = dev->cdesc->bConfigurationValue;
880 uiaa.ifaces = ifaces; 873 uiaa.ifaces = ifaces;
881 uiaa.nifaces = nifaces; 874 uiaa.nifaces = nifaces;
882 ilocs[USBIFIFCF_PORT] = uiaa.port; 875 ilocs[USBIFIFCF_PORT] = uiaa.port;
883 ilocs[USBIFIFCF_VENDOR] = uiaa.vendor; 876 ilocs[USBIFIFCF_VENDOR] = uiaa.vendor;
884 ilocs[USBIFIFCF_PRODUCT] = uiaa.product; 877 ilocs[USBIFIFCF_PRODUCT] = uiaa.product;
885 ilocs[USBIFIFCF_RELEASE] = uiaa.release; 878 ilocs[USBIFIFCF_RELEASE] = uiaa.release;
886 ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno; 879 ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno;
887 880
888 for (i = 0; i < nifaces; i++) { 881 for (i = 0; i < nifaces; i++) {
889 if (!ifaces[i]) 882 if (!ifaces[i])
890 continue; /* interface already claimed */ 883 continue; /* interface already claimed */
891 uiaa.iface = ifaces[i]; 884 uiaa.iface = ifaces[i];
892 uiaa.class = ifaces[i]->idesc->bInterfaceClass; 885 uiaa.class = ifaces[i]->idesc->bInterfaceClass;
893 uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass; 886 uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass;
894 uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol; 887 uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol;
895 uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; 888 uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
896 ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno; 889 ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno;
897 if (locators != NULL) { 890 if (locators != NULL) {
898 loc = locators[USBIFIFCF_CONFIGURATION]; 891 loc = locators[USBIFIFCF_CONFIGURATION];
899 if (loc != USBIFIFCF_CONFIGURATION_DEFAULT && 892 if (loc != USBIFIFCF_CONFIGURATION_DEFAULT &&
900 loc != uiaa.configno) 893 loc != uiaa.configno)
901 continue; 894 continue;
902 loc = locators[USBIFIFCF_INTERFACE]; 895 loc = locators[USBIFIFCF_INTERFACE];
903 if (loc != USBIFIFCF_INTERFACE && loc != uiaa.ifaceno) 896 if (loc != USBIFIFCF_INTERFACE && loc != uiaa.ifaceno)
904 continue; 897 continue;
905 } 898 }
906 dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa, 899 dv = config_found_sm_loc(parent, "usbifif", ilocs, &uiaa,
907 usbd_ifprint, config_stdsubmatch); 900 usbd_ifprint, config_stdsubmatch);
908 if (!dv) 901 if (!dv)
909 continue; 902 continue;
910 ifaces[i] = 0; /* claim */ 903 ifaces[i] = 0; /* claim */
911 /* account for ifaces claimed by the driver behind our back */ 904 /* account for ifaces claimed by the driver behind our back */
912 for (j = 0; j < nifaces; j++) { 905 for (j = 0; j < nifaces; j++) {
913 if (!ifaces[j] && !dev->subdevs[j]) { 906 if (!ifaces[j] && !dev->subdevs[j]) {
914 dev->subdevs[j] = dv; 907 dev->subdevs[j] = dv;
915 dev->nifaces_claimed++; 908 dev->nifaces_claimed++;
916 } 909 }
917 } 910 }
918 } 911 }
919 912
920 free(ifaces, M_USB); 913 free(ifaces, M_USB);
921 return (USBD_NORMAL_COMPLETION); 914 return (USBD_NORMAL_COMPLETION);
922} 915}
923 916
924usbd_status 917usbd_status
925usbd_probe_and_attach(device_t parent, usbd_device_handle dev, 918usbd_probe_and_attach(device_t parent, usbd_device_handle dev,
926 int port, int addr) 919 int port, int addr)
927{ 920{
928 usb_device_descriptor_t *dd = &dev->ddesc; 921 usb_device_descriptor_t *dd = &dev->ddesc;
929 int confi, nifaces; 922 int confi, nifaces;
930 usbd_status err; 923 usbd_status err;
931 924
932 /* First try with device specific drivers. */ 925 /* First try with device specific drivers. */
933 DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); 926 DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
934 err = usbd_attachwholedevice(parent, dev, port, 0); 927 err = usbd_attachwholedevice(parent, dev, port, 0);
935 if (dev->nifaces_claimed || err) 928 if (dev->nifaces_claimed || err)
936 return (err); 929 return (err);
937 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); 930 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
938 931
939 DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n", 932 DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
940 dd->bNumConfigurations)); 933 dd->bNumConfigurations));
941 for (confi = 0; confi < dd->bNumConfigurations; confi++) { 934 for (confi = 0; confi < dd->bNumConfigurations; confi++) {
942 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n", 935 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
943 confi)); 936 confi));
944 err = usbd_set_config_index(dev, confi, 1); 937 err = usbd_set_config_index(dev, confi, 1);
945 if (err) { 938 if (err) {
946#ifdef USB_DEBUG 939#ifdef USB_DEBUG
947 DPRINTF(("%s: port %d, set config at addr %d failed, " 940 DPRINTF(("%s: port %d, set config at addr %d failed, "
948 "error=%s\n", device_xname(parent), port, 941 "error=%s\n", device_xname(parent), port,
949 addr, usbd_errstr(err))); 942 addr, usbd_errstr(err)));
950#else 943#else
951 printf("%s: port %d, set config at addr %d failed\n", 944 printf("%s: port %d, set config at addr %d failed\n",
952 device_xname(parent), port, addr); 945 device_xname(parent), port, addr);
953#endif 946#endif
954 return (err); 947 return (err);
955 } 948 }
956 nifaces = dev->cdesc->bNumInterface; 949 nifaces = dev->cdesc->bNumInterface;
957 dev->subdevs = malloc(nifaces * sizeof(device_t), M_USB, 950 dev->subdevs = malloc(nifaces * sizeof(device_t), M_USB,
958 M_NOWAIT|M_ZERO); 951 M_NOWAIT|M_ZERO);
959 if (dev->subdevs == NULL) 952 if (dev->subdevs == NULL)
960 return (USBD_NOMEM); 953 return (USBD_NOMEM);
961 dev->subdevlen = nifaces; 954 dev->subdevlen = nifaces;
962 955
963 err = usbd_attachinterfaces(parent, dev, port, NULL); 956 err = usbd_attachinterfaces(parent, dev, port, NULL);
964 957
965 if (!dev->nifaces_claimed) { 958 if (!dev->nifaces_claimed) {
966 free(dev->subdevs, M_USB); 959 free(dev->subdevs, M_USB);
967 dev->subdevs = 0; 960 dev->subdevs = 0;
968 dev->subdevlen = 0; 961 dev->subdevlen = 0;
969 } 962 }
970 if (dev->nifaces_claimed || err) 963 if (dev->nifaces_claimed || err)
971 return (err); 964 return (err);
972 } 965 }
973 /* No interfaces were attached in any of the configurations. */ 966 /* No interfaces were attached in any of the configurations. */
974 967
975 if (dd->bNumConfigurations > 1) /* don't change if only 1 config */ 968 if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
976 usbd_set_config_index(dev, 0, 0); 969 usbd_set_config_index(dev, 0, 0);
977 970
978 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n")); 971 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
979 972
980 /* Finally try the generic driver. */ 973 /* Finally try the generic driver. */
981 err = usbd_attachwholedevice(parent, dev, port, 1); 974 err = usbd_attachwholedevice(parent, dev, port, 1);
982 975
983 /* 976 /*
984 * The generic attach failed, but leave the device as it is. 977 * The generic attach failed, but leave the device as it is.
985 * We just did not find any drivers, that's all. The device is 978 * We just did not find any drivers, that's all. The device is
986 * fully operational and not harming anyone. 979 * fully operational and not harming anyone.
987 */ 980 */
988 DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); 981 DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
989 return (USBD_NORMAL_COMPLETION); 982 return (USBD_NORMAL_COMPLETION);
990} 983}
991 984
992/** 985/**
993 * Called from uhub_rescan(). usbd_new_device() for the target dev must be 986 * Called from uhub_rescan(). usbd_new_device() for the target dev must be
994 * called before calling this. 987 * called before calling this.
995 */ 988 */
996usbd_status 989usbd_status
997usbd_reattach_device(device_t parent, usbd_device_handle dev, 990usbd_reattach_device(device_t parent, usbd_device_handle dev,
998 int port, const int *locators) 991 int port, const int *locators)
999{ 992{
1000 int i, loc; 993 int i, loc;
1001 994
1002 if (locators != NULL) { 995 if (locators != NULL) {
1003 loc = locators[USBIFIFCF_PORT]; 996 loc = locators[USBIFIFCF_PORT];
1004 if (loc != USBIFIFCF_PORT_DEFAULT && loc != port) 997 if (loc != USBIFIFCF_PORT_DEFAULT && loc != port)
1005 return USBD_NORMAL_COMPLETION; 998 return USBD_NORMAL_COMPLETION;
1006 loc = locators[USBIFIFCF_VENDOR]; 999 loc = locators[USBIFIFCF_VENDOR];
1007 if (loc != USBIFIFCF_VENDOR_DEFAULT && 1000 if (loc != USBIFIFCF_VENDOR_DEFAULT &&
1008 loc != UGETW(dev->ddesc.idVendor)) 1001 loc != UGETW(dev->ddesc.idVendor))
1009 return USBD_NORMAL_COMPLETION; 1002 return USBD_NORMAL_COMPLETION;
1010 loc = locators[USBIFIFCF_PRODUCT]; 1003 loc = locators[USBIFIFCF_PRODUCT];
1011 if (loc != USBIFIFCF_PRODUCT_DEFAULT && 1004 if (loc != USBIFIFCF_PRODUCT_DEFAULT &&
1012 loc != UGETW(dev->ddesc.idProduct)) 1005 loc != UGETW(dev->ddesc.idProduct))
1013 return USBD_NORMAL_COMPLETION; 1006 return USBD_NORMAL_COMPLETION;
1014 loc = locators[USBIFIFCF_RELEASE]; 1007 loc = locators[USBIFIFCF_RELEASE];
1015 if (loc != USBIFIFCF_RELEASE_DEFAULT && 1008 if (loc != USBIFIFCF_RELEASE_DEFAULT &&
1016 loc != UGETW(dev->ddesc.bcdDevice)) 1009 loc != UGETW(dev->ddesc.bcdDevice))
1017 return USBD_NORMAL_COMPLETION; 1010 return USBD_NORMAL_COMPLETION;
1018 } 1011 }
1019 if (dev->subdevlen == 0) { 1012 if (dev->subdevlen == 0) {
1020 /* XXX: check USBIFIFCF_CONFIGURATION and 1013 /* XXX: check USBIFIFCF_CONFIGURATION and
1021 * USBIFIFCF_INTERFACE too */ 1014 * USBIFIFCF_INTERFACE too */
1022 return usbd_probe_and_attach(parent, dev, port, dev->address); 1015 return usbd_probe_and_attach(parent, dev, port, dev->address);
1023 } else if (dev->subdevlen != dev->cdesc->bNumInterface) { 1016 } else if (dev->subdevlen != dev->cdesc->bNumInterface) {
1024 /* device-specific or generic driver is already attached. */ 1017 /* device-specific or generic driver is already attached. */
1025 return USBD_NORMAL_COMPLETION; 1018 return USBD_NORMAL_COMPLETION;
1026 } 1019 }
1027 /* Does the device have unconfigured interfaces? */ 1020 /* Does the device have unconfigured interfaces? */
1028 for (i = 0; i < dev->subdevlen; i++) { 1021 for (i = 0; i < dev->subdevlen; i++) {
1029 if (dev->subdevs[i] == NULL) { 1022 if (dev->subdevs[i] == NULL) {
1030 break; 1023 break;
1031 } 1024 }
1032 } 1025 }
1033 if (i >= dev->subdevlen) 1026 if (i >= dev->subdevlen)
1034 return USBD_NORMAL_COMPLETION; 1027 return USBD_NORMAL_COMPLETION;
1035 return usbd_attachinterfaces(parent, dev, port, locators); 1028 return usbd_attachinterfaces(parent, dev, port, locators);
1036} 1029}
1037 1030
1038/* 1031/*
1039 * Get the first 8 bytes of the device descriptor. 1032 * Get the first 8 bytes of the device descriptor.
1040 * Do as Windows does: try to read 64 bytes -- there are devices which 1033 * Do as Windows does: try to read 64 bytes -- there are devices which
1041 * recognize the initial descriptor fetch (before the control endpoint's 1034 * recognize the initial descriptor fetch (before the control endpoint's
1042 * MaxPacketSize is known by the host) by exactly this length. 1035 * MaxPacketSize is known by the host) by exactly this length.
1043 */ 1036 */
1044static usbd_status 1037static usbd_status
1045usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc) 1038usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc)
1046{ 1039{
1047 usb_device_request_t req; 1040 usb_device_request_t req;
1048 char buf[64]; 1041 char buf[64];
1049 int res, actlen; 1042 int res, actlen;
1050 1043
1051 req.bmRequestType = UT_READ_DEVICE; 1044 req.bmRequestType = UT_READ_DEVICE;
1052 req.bRequest = UR_GET_DESCRIPTOR; 1045 req.bRequest = UR_GET_DESCRIPTOR;
1053 USETW2(req.wValue, UDESC_DEVICE, 0); 1046 USETW2(req.wValue, UDESC_DEVICE, 0);
1054 USETW(req.wIndex, 0); 1047 USETW(req.wIndex, 0);
1055 USETW(req.wLength, 64); 1048 USETW(req.wLength, 64);
1056 res = usbd_do_request_flags(dev, &req, buf, USBD_SHORT_XFER_OK, 1049 res = usbd_do_request_flags(dev, &req, buf, USBD_SHORT_XFER_OK,
1057 &actlen, USBD_DEFAULT_TIMEOUT); 1050 &actlen, USBD_DEFAULT_TIMEOUT);
1058 if (res) 1051 if (res)
1059 return res; 1052 return res;
1060 if (actlen < 8) 1053 if (actlen < 8)
1061 return USBD_SHORT_XFER; 1054 return USBD_SHORT_XFER;
1062 memcpy(desc, buf, 8); 1055 memcpy(desc, buf, 8);
1063 return USBD_NORMAL_COMPLETION; 1056 return USBD_NORMAL_COMPLETION;
1064} 1057}
1065 1058
1066/* 1059/*
1067 * Called when a new device has been put in the powered state, 1060 * Called when a new device has been put in the powered state,
1068 * but not yet in the addressed state. 1061 * but not yet in the addressed state.
1069 * Get initial descriptor, set the address, get full descriptor, 1062 * Get initial descriptor, set the address, get full descriptor,
1070 * and attach a driver. 1063 * and attach a driver.
1071 */ 1064 */
1072usbd_status 1065usbd_status
1073usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, 1066usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
1074 int speed, int port, struct usbd_port *up) 1067 int speed, int port, struct usbd_port *up)
1075{ 1068{
1076 usbd_device_handle dev, adev; 1069 usbd_device_handle dev, adev;
1077 struct usbd_device *hub; 1070 struct usbd_device *hub;
1078 usb_device_descriptor_t *dd; 1071 usb_device_descriptor_t *dd;
1079 usb_port_status_t ps; 1072 usb_port_status_t ps;
1080 usbd_status err; 1073 usbd_status err;
1081 int addr; 1074 int addr;
1082 int i; 1075 int i;
1083 int p; 1076 int p;
1084 1077
1085 DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n", 1078 DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
1086 bus, port, depth, speed)); 1079 bus, port, depth, speed));
1087 addr = usbd_getnewaddr(bus); 1080 addr = usbd_getnewaddr(bus);
1088 if (addr < 0) { 1081 if (addr < 0) {
1089 printf("%s: No free USB addresses, new device ignored.\n", 1082 printf("%s: No free USB addresses, new device ignored.\n",
1090 device_xname(bus->usbctl)); 1083 device_xname(bus->usbctl));
1091 return (USBD_NO_ADDR); 1084 return (USBD_NO_ADDR);
1092 } 1085 }
1093 1086
1094 dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); 1087 dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
1095 if (dev == NULL) 1088 if (dev == NULL)
1096 return (USBD_NOMEM); 1089 return (USBD_NOMEM);
1097 1090
1098 dev->bus = bus; 1091 dev->bus = bus;
1099 1092
1100 /* Set up default endpoint handle. */ 1093 /* Set up default endpoint handle. */
1101 dev->def_ep.edesc = &dev->def_ep_desc; 1094 dev->def_ep.edesc = &dev->def_ep_desc;
1102 1095
1103 /* Set up default endpoint descriptor. */ 1096 /* Set up default endpoint descriptor. */
1104 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; 1097 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
1105 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; 1098 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
1106 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; 1099 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
1107 dev->def_ep_desc.bmAttributes = UE_CONTROL; 1100 dev->def_ep_desc.bmAttributes = UE_CONTROL;
1108 /* 1101 /*
1109 * temporary, will be fixed after first descriptor fetch 1102 * temporary, will be fixed after first descriptor fetch
1110 * (which uses 64 bytes so it shouldn't be less), 1103 * (which uses 64 bytes so it shouldn't be less),
1111 * highspeed devices must support 64 byte packets anyway 1104 * highspeed devices must support 64 byte packets anyway
1112 */ 1105 */
1113 USETW(dev->def_ep_desc.wMaxPacketSize, 64); 1106 USETW(dev->def_ep_desc.wMaxPacketSize, 64);
1114 dev->def_ep_desc.bInterval = 0; 1107 dev->def_ep_desc.bInterval = 0;
1115 1108
1116 /* doesn't matter, just don't let it uninitialized */ 1109 /* doesn't matter, just don't let it uninitialized */
1117 dev->def_ep.datatoggle = 0; 1110 dev->def_ep.datatoggle = 0;
1118 1111
1119 dev->quirks = &usbd_no_quirk; 1112 dev->quirks = &usbd_no_quirk;
1120 dev->address = USB_START_ADDR; 1113 dev->address = USB_START_ADDR;
1121 dev->ddesc.bMaxPacketSize = 0; 1114 dev->ddesc.bMaxPacketSize = 0;
1122 dev->depth = depth; 1115 dev->depth = depth;
1123 dev->powersrc = up; 1116 dev->powersrc = up;
1124 dev->myhub = up->parent; 1117 dev->myhub = up->parent;
1125 1118
1126 up->device = dev; 1119 up->device = dev;
1127 1120
1128 /* Locate port on upstream high speed hub */ 1121 /* Locate port on upstream high speed hub */
1129 for (adev = dev, hub = up->parent; 1122 for (adev = dev, hub = up->parent;
1130 hub != NULL && hub->speed != USB_SPEED_HIGH; 1123 hub != NULL && hub->speed != USB_SPEED_HIGH;
1131 adev = hub, hub = hub->myhub) 1124 adev = hub, hub = hub->myhub)
1132 ; 1125 ;
1133 if (hub) { 1126 if (hub) {
1134 for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) { 1127 for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
1135 if (hub->hub->ports[p].device == adev) { 1128 if (hub->hub->ports[p].device == adev) {
1136 dev->myhsport = &hub->hub->ports[p]; 1129 dev->myhsport = &hub->hub->ports[p];
1137 goto found; 1130 goto found;
1138 } 1131 }
1139 } 1132 }
1140 panic("usbd_new_device: cannot find HS port\n"); 1133 panic("usbd_new_device: cannot find HS port\n");
1141 found: 1134 found:
1142 DPRINTFN(1,("usbd_new_device: high speed port %d\n", p)); 1135 DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
1143 } else { 1136 } else {
1144 dev->myhsport = NULL; 1137 dev->myhsport = NULL;
1145 } 1138 }
1146 dev->speed = speed; 1139 dev->speed = speed;
1147 dev->langid = USBD_NOLANG; 1140 dev->langid = USBD_NOLANG;
1148 dev->cookie.cookie = ++usb_cookie_no; 1141 dev->cookie.cookie = ++usb_cookie_no;
1149 1142
1150 /* Establish the default pipe. */ 1143 /* Establish the default pipe. */
1151 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, 1144 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1152 &dev->default_pipe); 1145 &dev->default_pipe);
1153 if (err) { 1146 if (err) {
1154 usbd_remove_device(dev, up); 1147 usbd_remove_device(dev, up);
1155 return (err); 1148 return (err);
1156 } 1149 }
1157 1150
1158 dd = &dev->ddesc; 1151 dd = &dev->ddesc;
1159 /* Try a few times in case the device is slow (i.e. outside specs.) */ 1152 /* Try a few times in case the device is slow (i.e. outside specs.) */
1160 for (i = 0; i < 10; i++) { 1153 for (i = 0; i < 10; i++) {
1161 /* Get the first 8 bytes of the device descriptor. */ 1154 /* Get the first 8 bytes of the device descriptor. */
1162 err = usbd_get_initial_ddesc(dev, dd); 1155 err = usbd_get_initial_ddesc(dev, dd);
1163 if (!err) 1156 if (!err)
1164 break; 1157 break;
1165 usbd_delay_ms(dev, 200); 1158 usbd_delay_ms(dev, 200);
1166 if ((i & 3) == 3) 1159 if ((i & 3) == 3)
1167 usbd_reset_port(up->parent, port, &ps); 1160 usbd_reset_port(up->parent, port, &ps);
1168 } 1161 }
1169 if (err) { 1162 if (err) {
1170 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc " 1163 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
1171 "failed: %d\n", addr, err)); 1164 "failed: %d\n", addr, err));
1172 usbd_remove_device(dev, up); 1165 usbd_remove_device(dev, up);
1173 return (err); 1166 return (err);
1174 } 1167 }
1175 1168
1176 /* Windows resets the port here, do likewise */ 1169 /* Windows resets the port here, do likewise */
1177 if (up->parent) 1170 if (up->parent)
1178 usbd_reset_port(up->parent, port, &ps); 1171 usbd_reset_port(up->parent, port, &ps);
1179 1172
1180 if (speed == USB_SPEED_HIGH) { 1173 if (speed == USB_SPEED_HIGH) {
1181 /* Max packet size must be 64 (sec 5.5.3). */ 1174 /* Max packet size must be 64 (sec 5.5.3). */
1182 if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) { 1175 if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
1183#ifdef DIAGNOSTIC 1176#ifdef DIAGNOSTIC
1184 printf("usbd_new_device: addr=%d bad max packet " 1177 printf("usbd_new_device: addr=%d bad max packet "
1185 "size=%d. adjusting to %d.\n", 1178 "size=%d. adjusting to %d.\n",
1186 addr, dd->bMaxPacketSize, USB_2_MAX_CTRL_PACKET); 1179 addr, dd->bMaxPacketSize, USB_2_MAX_CTRL_PACKET);
1187#endif 1180#endif
1188 dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET; 1181 dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
1189 } 1182 }
1190 } 1183 }
1191 1184
1192 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, " 1185 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
1193 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n", 1186 "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
1194 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass, 1187 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
1195 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength, 1188 dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
1196 dev->speed)); 1189 dev->speed));
1197 1190
1198 if (dd->bDescriptorType != UDESC_DEVICE) { 1191 if (dd->bDescriptorType != UDESC_DEVICE) {
1199 /* Illegal device descriptor */ 1192 /* Illegal device descriptor */
1200 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n", 1193 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
1201 dd->bDescriptorType)); 1194 dd->bDescriptorType));
1202 usbd_remove_device(dev, up); 1195 usbd_remove_device(dev, up);
1203 return (USBD_INVAL); 1196 return (USBD_INVAL);
1204 } 1197 }
1205 1198
1206 if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) { 1199 if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
1207 DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength)); 1200 DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
1208 usbd_remove_device(dev, up); 1201 usbd_remove_device(dev, up);
1209 return (USBD_INVAL); 1202 return (USBD_INVAL);
1210 } 1203 }
1211 1204
1212 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); 1205 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
1213 1206
1214 /* Set the address */ 1207 /* Set the address */
1215 DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr)); 1208 DPRINTFN(5, ("usbd_new_device: setting device address=%d\n", addr));
1216 err = usbd_set_address(dev, addr); 1209 err = usbd_set_address(dev, addr);
1217 if (err) { 1210 if (err) {
1218 DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr)); 1211 DPRINTFN(-1, ("usbd_new_device: set address %d failed\n", addr));
1219 err = USBD_SET_ADDR_FAILED; 1212 err = USBD_SET_ADDR_FAILED;
1220 usbd_remove_device(dev, up); 1213 usbd_remove_device(dev, up);
1221 return err; 1214 return err;
1222 } 1215 }
1223 1216
1224 /* Allow device time to set new address */ 1217 /* Allow device time to set new address */
1225 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); 1218 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
1226 dev->address = addr; /* new device address now */ 1219 dev->address = addr; /* new device address now */
1227 bus->devices[addr] = dev; 1220 bus->devices[addr] = dev;
1228 1221
1229 err = usbd_reload_device_desc(dev); 1222 err = usbd_reload_device_desc(dev);
1230 if (err) { 1223 if (err) {
1231 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " 1224 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
1232 "failed\n", addr)); 1225 "failed\n", addr));
1233 usbd_remove_device(dev, up); 1226 usbd_remove_device(dev, up);
1234 return (err); 1227 return (err);
1235 } 1228 }
1236 1229
1237 /* Re-establish the default pipe with the new address. */ 1230 /* Re-establish the default pipe with the new address. */
1238 usbd_kill_pipe(dev->default_pipe); 1231 usbd_kill_pipe(dev->default_pipe);
1239 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, 1232 err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
1240 &dev->default_pipe); 1233 &dev->default_pipe);
1241 if (err) { 1234 if (err) {
1242 DPRINTFN(-1, ("usbd_new_device: setup default pipe failed\n")); 1235 DPRINTFN(-1, ("usbd_new_device: setup default pipe failed\n"));
1243 usbd_remove_device(dev, up); 1236 usbd_remove_device(dev, up);
1244 return err; 1237 return err;
1245 } 1238 }
1246 1239
1247 /* Assume 100mA bus powered for now. Changed when configured. */ 1240 /* Assume 100mA bus powered for now. Changed when configured. */
1248 dev->power = USB_MIN_POWER; 1241 dev->power = USB_MIN_POWER;
1249 dev->self_powered = 0; 1242 dev->self_powered = 0;
1250 1243
1251 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n", 1244 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
1252 addr, dev, parent)); 1245 addr, dev, parent));
1253 1246
1254 usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); 1247 usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
1255 1248
1256 if (port == 0) { /* root hub */ 1249 if (port == 0) { /* root hub */
1257 KASSERT(addr == 1); 1250 KASSERT(addr == 1);
1258 usbd_attach_roothub(parent, dev); 1251 usbd_attach_roothub(parent, dev);
1259 return (USBD_NORMAL_COMPLETION); 1252 return (USBD_NORMAL_COMPLETION);
1260 } 1253 }
1261 1254
1262 err = usbd_probe_and_attach(parent, dev, port, addr); 1255 err = usbd_probe_and_attach(parent, dev, port, addr);
1263 if (err) { 1256 if (err) {
1264 usbd_remove_device(dev, up); 1257 usbd_remove_device(dev, up);
1265 return (err); 1258 return (err);
1266 } 1259 }
1267 1260
1268 return (USBD_NORMAL_COMPLETION); 1261 return (USBD_NORMAL_COMPLETION);
1269} 1262}
1270 1263
1271usbd_status 1264usbd_status
1272usbd_reload_device_desc(usbd_device_handle dev) 1265usbd_reload_device_desc(usbd_device_handle dev)
1273{ 1266{
1274 usbd_status err; 1267 usbd_status err;
1275 1268
1276 /* Get the full device descriptor. */ 1269 /* Get the full device descriptor. */
1277 err = usbd_get_device_desc(dev, &dev->ddesc); 1270 err = usbd_get_device_desc(dev, &dev->ddesc);
1278 if (err) 1271 if (err)
1279 return (err); 1272 return (err);
1280 1273
1281 /* Figure out what's wrong with this device. */ 1274 /* Figure out what's wrong with this device. */
1282 dev->quirks = usbd_find_quirk(&dev->ddesc); 1275 dev->quirks = usbd_find_quirk(&dev->ddesc);
1283 1276
1284 return (USBD_NORMAL_COMPLETION); 1277 return (USBD_NORMAL_COMPLETION);
1285} 1278}
1286 1279
1287void 1280void
1288usbd_remove_device(usbd_device_handle dev, struct usbd_port *up) 1281usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
1289{ 1282{
1290 DPRINTF(("usbd_remove_device: %p\n", dev)); 1283 DPRINTF(("usbd_remove_device: %p\n", dev));
1291 1284
1292 if (dev->default_pipe != NULL) 1285 if (dev->default_pipe != NULL)
1293 usbd_kill_pipe(dev->default_pipe); 1286 usbd_kill_pipe(dev->default_pipe);
1294 up->device = NULL; 1287 up->device = NULL;
1295 dev->bus->devices[dev->address] = NULL; 1288 dev->bus->devices[dev->address] = NULL;
1296 1289
1297 free(dev, M_USB); 1290 free(dev, M_USB);
1298} 1291}
1299 1292
1300int 1293int
1301usbd_print(void *aux, const char *pnp) 1294usbd_print(void *aux, const char *pnp)
1302{ 1295{
1303 struct usb_attach_arg *uaa = aux; 1296 struct usb_attach_arg *uaa = aux;
1304 1297
1305 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); 1298 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1306 if (pnp) { 1299 if (pnp) {
1307#define USB_DEVINFO 1024 1300#define USB_DEVINFO 1024
1308 char *devinfo; 1301 char *devinfo;
1309 if (!uaa->usegeneric) 1302 if (!uaa->usegeneric)
1310 return (QUIET); 1303 return (QUIET);
1311 devinfo = malloc(USB_DEVINFO, M_TEMP, M_WAITOK); 1304 devinfo = malloc(USB_DEVINFO, M_TEMP, M_WAITOK);
1312 usbd_devinfo(uaa->device, 1, devinfo, USB_DEVINFO); 1305 usbd_devinfo(uaa->device, 1, devinfo, USB_DEVINFO);
1313 aprint_normal("%s, %s", devinfo, pnp); 1306 aprint_normal("%s, %s", devinfo, pnp);
1314 free(devinfo, M_TEMP); 1307 free(devinfo, M_TEMP);
1315 } 1308 }
1316 aprint_normal(" port %d", uaa->port); 1309 aprint_normal(" port %d", uaa->port);
1317#if 0 1310#if 0
1318 /* 1311 /*
1319 * It gets very crowded with these locators on the attach line. 1312 * It gets very crowded with these locators on the attach line.
1320 * They are not really needed since they are printed in the clear 1313 * They are not really needed since they are printed in the clear
1321 * by each driver. 1314 * by each driver.
1322 */ 1315 */
1323 if (uaa->vendor != UHUB_UNK_VENDOR) 1316 if (uaa->vendor != UHUB_UNK_VENDOR)
1324 aprint_normal(" vendor 0x%04x", uaa->vendor); 1317 aprint_normal(" vendor 0x%04x", uaa->vendor);
1325 if (uaa->product != UHUB_UNK_PRODUCT) 1318 if (uaa->product != UHUB_UNK_PRODUCT)
1326 aprint_normal(" product 0x%04x", uaa->product); 1319 aprint_normal(" product 0x%04x", uaa->product);
1327 if (uaa->release != UHUB_UNK_RELEASE) 1320 if (uaa->release != UHUB_UNK_RELEASE)
1328 aprint_normal(" release 0x%04x", uaa->release); 1321 aprint_normal(" release 0x%04x", uaa->release);
1329#endif 1322#endif
1330 return (UNCONF); 1323 return (UNCONF);
1331} 1324}
1332 1325
1333int 1326int
1334usbd_ifprint(void *aux, const char *pnp) 1327usbd_ifprint(void *aux, const char *pnp)
1335{ 1328{
1336 struct usbif_attach_arg *uaa = aux; 1329 struct usbif_attach_arg *uaa = aux;
1337 1330
1338 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); 1331 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device));
1339 if (pnp) 1332 if (pnp)
1340 return (QUIET); 1333 return (QUIET);
1341 aprint_normal(" port %d", uaa->port); 1334 aprint_normal(" port %d", uaa->port);
1342 aprint_normal(" configuration %d", uaa->configno); 1335 aprint_normal(" configuration %d", uaa->configno);
1343 aprint_normal(" interface %d", uaa->ifaceno); 1336 aprint_normal(" interface %d", uaa->ifaceno);
1344#if 0 1337#if 0
1345 /* 1338 /*
1346 * It gets very crowded with these locators on the attach line. 1339 * It gets very crowded with these locators on the attach line.
1347 * They are not really needed since they are printed in the clear 1340 * They are not really needed since they are printed in the clear
1348 * by each driver. 1341 * by each driver.
1349 */ 1342 */
1350 if (uaa->vendor != UHUB_UNK_VENDOR) 1343 if (uaa->vendor != UHUB_UNK_VENDOR)
1351 aprint_normal(" vendor 0x%04x", uaa->vendor); 1344 aprint_normal(" vendor 0x%04x", uaa->vendor);
1352 if (uaa->product != UHUB_UNK_PRODUCT) 1345 if (uaa->product != UHUB_UNK_PRODUCT)
1353 aprint_normal(" product 0x%04x", uaa->product); 1346 aprint_normal(" product 0x%04x", uaa->product);
1354 if (uaa->release != UHUB_UNK_RELEASE) 1347 if (uaa->release != UHUB_UNK_RELEASE)
1355 aprint_normal(" release 0x%04x", uaa->release); 1348 aprint_normal(" release 0x%04x", uaa->release);
1356#endif 1349#endif
1357 return (UNCONF); 1350 return (UNCONF);
1358} 1351}
1359 1352
1360void 1353void
1361usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, 1354usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
1362 int usedev) 1355 int usedev)
1363{ 1356{
1364 struct usbd_port *p; 1357 struct usbd_port *p;
1365 int i, j, err, s; 1358 int i, j, err, s;
1366 1359
1367 di->udi_bus = device_unit(dev->bus->usbctl); 1360 di->udi_bus = device_unit(dev->bus->usbctl);
1368 di->udi_addr = dev->address; 1361 di->udi_addr = dev->address;
1369 di->udi_cookie = dev->cookie; 1362 di->udi_cookie = dev->cookie;
1370 usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor), 1363 usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor),
1371 di->udi_product, sizeof(di->udi_product), usedev, 1); 1364 di->udi_product, sizeof(di->udi_product), usedev, 1);
1372 usbd_printBCD(di->udi_release, sizeof(di->udi_release), 1365 usbd_printBCD(di->udi_release, sizeof(di->udi_release),
1373 UGETW(dev->ddesc.bcdDevice)); 1366 UGETW(dev->ddesc.bcdDevice));
1374 di->udi_serial[0] = 0; 1367 di->udi_serial[0] = 0;
1375 if (usedev) 1368 if (usedev)
1376 (void)usbd_get_string(dev, dev->ddesc.iSerialNumber, 1369 (void)usbd_get_string(dev, dev->ddesc.iSerialNumber,
1377 di->udi_serial); 1370 di->udi_serial);
1378 di->udi_vendorNo = UGETW(dev->ddesc.idVendor); 1371 di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1379 di->udi_productNo = UGETW(dev->ddesc.idProduct); 1372 di->udi_productNo = UGETW(dev->ddesc.idProduct);
1380 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice); 1373 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1381 di->udi_class = dev->ddesc.bDeviceClass; 1374 di->udi_class = dev->ddesc.bDeviceClass;
1382 di->udi_subclass = dev->ddesc.bDeviceSubClass; 1375 di->udi_subclass = dev->ddesc.bDeviceSubClass;
1383 di->udi_protocol = dev->ddesc.bDeviceProtocol; 1376 di->udi_protocol = dev->ddesc.bDeviceProtocol;
1384 di->udi_config = dev->config; 1377 di->udi_config = dev->config;
1385 di->udi_power = dev->self_powered ? 0 : dev->power; 1378 di->udi_power = dev->self_powered ? 0 : dev->power;
1386 di->udi_speed = dev->speed; 1379 di->udi_speed = dev->speed;
1387 1380
1388 if (dev->subdevlen > 0) { 1381 if (dev->subdevlen > 0) {
1389 for (i = 0, j = 0; i < dev->subdevlen && 1382 for (i = 0, j = 0; i < dev->subdevlen &&
1390 j < USB_MAX_DEVNAMES; i++) { 1383 j < USB_MAX_DEVNAMES; i++) {
1391 if (!dev->subdevs[i]) 1384 if (!dev->subdevs[i])
1392 continue; 1385 continue;
1393 strncpy(di->udi_devnames[j], 1386 strncpy(di->udi_devnames[j],
1394 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN); 1387 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1395 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; 1388 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
1396 j++; 1389 j++;
1397 } 1390 }
1398 } else { 1391 } else {
1399 j = 0; 1392 j = 0;
1400 } 1393 }
1401 for (/* j is set */; j < USB_MAX_DEVNAMES; j++) 1394 for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
1402 di->udi_devnames[j][0] = 0; /* empty */ 1395 di->udi_devnames[j][0] = 0; /* empty */
1403 1396
1404 if (dev->hub) { 1397 if (dev->hub) {
1405 for (i = 0; 1398 for (i = 0;
1406 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) && 1399 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1407 i < dev->hub->hubdesc.bNbrPorts; 1400 i < dev->hub->hubdesc.bNbrPorts;
1408 i++) { 1401 i++) {
1409 p = &dev->hub->ports[i]; 1402 p = &dev->hub->ports[i];
1410 if (p->device) 1403 if (p->device)
1411 err = p->device->address; 1404 err = p->device->address;
1412 else { 1405 else {
1413 s = UGETW(p->status.wPortStatus); 1406 s = UGETW(p->status.wPortStatus);
1414 if (s & UPS_PORT_ENABLED) 1407 if (s & UPS_PORT_ENABLED)
1415 err = USB_PORT_ENABLED; 1408 err = USB_PORT_ENABLED;
1416 else if (s & UPS_SUSPEND) 1409 else if (s & UPS_SUSPEND)
1417 err = USB_PORT_SUSPENDED; 1410 err = USB_PORT_SUSPENDED;
1418 else if (s & UPS_PORT_POWER) 1411 else if (s & UPS_PORT_POWER)
1419 err = USB_PORT_POWERED; 1412 err = USB_PORT_POWERED;
1420 else 1413 else
1421 err = USB_PORT_DISABLED; 1414 err = USB_PORT_DISABLED;
1422 } 1415 }
1423 di->udi_ports[i] = err; 1416 di->udi_ports[i] = err;
1424 } 1417 }
1425 di->udi_nports = dev->hub->hubdesc.bNbrPorts; 1418 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1426 } else 1419 } else
1427 di->udi_nports = 0; 1420 di->udi_nports = 0;
1428} 1421}
1429 1422
1430#ifdef COMPAT_30 1423#ifdef COMPAT_30
1431void 1424void
1432usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di, 1425usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di,
1433 int usedev) 1426 int usedev)
1434{ 1427{
1435 struct usbd_port *p; 1428 struct usbd_port *p;
1436 int i, j, err, s; 1429 int i, j, err, s;
1437 1430
1438 di->udi_bus = device_unit(dev->bus->usbctl); 1431 di->udi_bus = device_unit(dev->bus->usbctl);
1439 di->udi_addr = dev->address; 1432 di->udi_addr = dev->address;
1440 di->udi_cookie = dev->cookie; 1433 di->udi_cookie = dev->cookie;
1441 usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor), 1434 usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor),
1442 di->udi_product, sizeof(di->udi_product), usedev, 0); 1435 di->udi_product, sizeof(di->udi_product), usedev, 0);
1443 usbd_printBCD(di->udi_release, sizeof(di->udi_release), 1436 usbd_printBCD(di->udi_release, sizeof(di->udi_release),
1444 UGETW(dev->ddesc.bcdDevice)); 1437 UGETW(dev->ddesc.bcdDevice));
1445 di->udi_vendorNo = UGETW(dev->ddesc.idVendor); 1438 di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
1446 di->udi_productNo = UGETW(dev->ddesc.idProduct); 1439 di->udi_productNo = UGETW(dev->ddesc.idProduct);
1447 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice); 1440 di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
1448 di->udi_class = dev->ddesc.bDeviceClass; 1441 di->udi_class = dev->ddesc.bDeviceClass;
1449 di->udi_subclass = dev->ddesc.bDeviceSubClass; 1442 di->udi_subclass = dev->ddesc.bDeviceSubClass;
1450 di->udi_protocol = dev->ddesc.bDeviceProtocol; 1443 di->udi_protocol = dev->ddesc.bDeviceProtocol;
1451 di->udi_config = dev->config; 1444 di->udi_config = dev->config;
1452 di->udi_power = dev->self_powered ? 0 : dev->power; 1445 di->udi_power = dev->self_powered ? 0 : dev->power;
1453 di->udi_speed = dev->speed; 1446 di->udi_speed = dev->speed;
1454 1447
1455 if (dev->subdevlen > 0) { 1448 if (dev->subdevlen > 0) {
1456 for (i = 0, j = 0; i < dev->subdevlen && 1449 for (i = 0, j = 0; i < dev->subdevlen &&
1457 j < USB_MAX_DEVNAMES; i++) { 1450 j < USB_MAX_DEVNAMES; i++) {
1458 if (!dev->subdevs[i]) 1451 if (!dev->subdevs[i])
1459 continue; 1452 continue;
1460 strncpy(di->udi_devnames[j], 1453 strncpy(di->udi_devnames[j],
1461 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN); 1454 device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN);
1462 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; 1455 di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0';
1463 j++; 1456 j++;
1464 } 1457 }
1465 } else { 1458 } else {
1466 j = 0; 1459 j = 0;
1467 } 1460 }
1468 for (/* j is set */; j < USB_MAX_DEVNAMES; j++) 1461 for (/* j is set */; j < USB_MAX_DEVNAMES; j++)
1469 di->udi_devnames[j][0] = 0; /* empty */ 1462 di->udi_devnames[j][0] = 0; /* empty */
1470 1463
1471 if (dev->hub) { 1464 if (dev->hub) {
1472 for (i = 0; 1465 for (i = 0;
1473 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) && 1466 i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
1474 i < dev->hub->hubdesc.bNbrPorts; 1467 i < dev->hub->hubdesc.bNbrPorts;
1475 i++) { 1468 i++) {
1476 p = &dev->hub->ports[i]; 1469 p = &dev->hub->ports[i];
1477 if (p->device) 1470 if (p->device)
1478 err = p->device->address; 1471 err = p->device->address;
1479 else { 1472 else {
1480 s = UGETW(p->status.wPortStatus); 1473 s = UGETW(p->status.wPortStatus);
1481 if (s & UPS_PORT_ENABLED) 1474 if (s & UPS_PORT_ENABLED)
1482 err = USB_PORT_ENABLED; 1475 err = USB_PORT_ENABLED;
1483 else if (s & UPS_SUSPEND) 1476 else if (s & UPS_SUSPEND)
1484 err = USB_PORT_SUSPENDED; 1477 err = USB_PORT_SUSPENDED;
1485 else if (s & UPS_PORT_POWER) 1478 else if (s & UPS_PORT_POWER)
1486 err = USB_PORT_POWERED; 1479 err = USB_PORT_POWERED;
1487 else 1480 else
1488 err = USB_PORT_DISABLED; 1481 err = USB_PORT_DISABLED;
1489 } 1482 }
1490 di->udi_ports[i] = err; 1483 di->udi_ports[i] = err;
1491 } 1484 }
1492 di->udi_nports = dev->hub->hubdesc.bNbrPorts; 1485 di->udi_nports = dev->hub->hubdesc.bNbrPorts;
1493 } else 1486 } else
1494 di->udi_nports = 0; 1487 di->udi_nports = 0;
1495} 1488}
1496#endif 1489#endif
1497 1490
1498 1491
1499void 1492void
1500usb_free_device(usbd_device_handle dev) 1493usb_free_device(usbd_device_handle dev)
1501{ 1494{
1502 int ifcidx, nifc; 1495 int ifcidx, nifc;
1503 1496
1504 if (dev->default_pipe != NULL) 1497 if (dev->default_pipe != NULL)
1505 usbd_kill_pipe(dev->default_pipe); 1498 usbd_kill_pipe(dev->default_pipe);
1506 if (dev->ifaces != NULL) { 1499 if (dev->ifaces != NULL) {
1507 nifc = dev->cdesc->bNumInterface; 1500 nifc = dev->cdesc->bNumInterface;
1508 for (ifcidx = 0; ifcidx < nifc; ifcidx++) 1501 for (ifcidx = 0; ifcidx < nifc; ifcidx++)
1509 usbd_free_iface_data(dev, ifcidx); 1502 usbd_free_iface_data(dev, ifcidx);
1510 free(dev->ifaces, M_USB); 1503 free(dev->ifaces, M_USB);
1511 } 1504 }
1512 if (dev->cdesc != NULL) 1505 if (dev->cdesc != NULL)
1513 free(dev->cdesc, M_USB); 1506 free(dev->cdesc, M_USB);
1514 if (dev->subdevlen > 0) { 1507 if (dev->subdevlen > 0) {
1515 free(dev->subdevs, M_USB); 1508 free(dev->subdevs, M_USB);
1516 dev->subdevlen = 0; 1509 dev->subdevlen = 0;
1517 } 1510 }
1518 free(dev, M_USB); 1511 free(dev, M_USB);
1519} 1512}
1520 1513
1521/* 1514/*
1522 * The general mechanism for detaching drivers works as follows: Each 1515 * The general mechanism for detaching drivers works as follows: Each
1523 * driver is responsible for maintaining a reference count on the 1516 * driver is responsible for maintaining a reference count on the
1524 * number of outstanding references to its softc (e.g. from 1517 * number of outstanding references to its softc (e.g. from
1525 * processing hanging in a read or write). The detach method of the 1518 * processing hanging in a read or write). The detach method of the
1526 * driver decrements this counter and flags in the softc that the 1519 * driver decrements this counter and flags in the softc that the
1527 * driver is dying and then wakes any sleepers. It then sleeps on the 1520 * driver is dying and then wakes any sleepers. It then sleeps on the
1528 * softc. Each place that can sleep must maintain the reference 1521 * softc. Each place that can sleep must maintain the reference
1529 * count. When the reference count drops to -1 (0 is the normal value 1522 * count. When the reference count drops to -1 (0 is the normal value
1530 * of the reference count) the a wakeup on the softc is performed 1523 * of the reference count) the a wakeup on the softc is performed
1531 * signaling to the detach waiter that all references are gone. 1524 * signaling to the detach waiter that all references are gone.
1532 */ 1525 */
1533 1526
1534/* 1527/*
1535 * Called from process context when we discover that a port has 1528 * Called from process context when we discover that a port has
1536 * been disconnected. 1529 * been disconnected.
1537 */ 1530 */
1538int 1531int
1539usb_disconnect_port(struct usbd_port *up, device_t parent, int flags) 1532usb_disconnect_port(struct usbd_port *up, device_t parent, int flags)
1540{ 1533{
1541 usbd_device_handle dev = up->device; 1534 usbd_device_handle dev = up->device;
1542 device_t subdev; 1535 device_t subdev;
1543 char subdevname[16]; 1536 char subdevname[16];
1544 const char *hubname = device_xname(parent); 1537 const char *hubname = device_xname(parent);
1545 int i, rc; 1538 int i, rc;
1546 1539
1547 DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n", 1540 DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
1548 up, dev, up->portno)); 1541 up, dev, up->portno));
1549 1542
1550 if (dev == NULL) { 1543 if (dev == NULL) {
1551#ifdef DIAGNOSTIC 1544#ifdef DIAGNOSTIC
1552 printf("usb_disconnect_port: no device\n"); 1545 printf("usb_disconnect_port: no device\n");
1553#endif 1546#endif
1554 return 0; 1547 return 0;
1555 } 1548 }
1556 1549
1557 if (dev->subdevlen > 0) { 1550 if (dev->subdevlen > 0) {
1558 DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n")); 1551 DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
1559 for (i = 0; i < dev->subdevlen; i++) { 1552 for (i = 0; i < dev->subdevlen; i++) {
1560 if ((subdev = dev->subdevs[i]) == NULL) 1553 if ((subdev = dev->subdevs[i]) == NULL)
1561 continue; 1554 continue;
1562 strlcpy(subdevname, device_xname(subdev), 1555 strlcpy(subdevname, device_xname(subdev),
1563 sizeof(subdevname)); 1556 sizeof(subdevname));
1564 if ((rc = config_detach(subdev, flags)) != 0) 1557 if ((rc = config_detach(subdev, flags)) != 0)
1565 return rc; 1558 return rc;
1566 printf("%s: at %s", subdevname, hubname); 1559 printf("%s: at %s", subdevname, hubname);
1567 if (up->portno != 0) 1560 if (up->portno != 0)
1568 printf(" port %d", up->portno); 1561 printf(" port %d", up->portno);
1569 printf(" (addr %d) disconnected\n", dev->address); 1562 printf(" (addr %d) disconnected\n", dev->address);
1570 } 1563 }
1571 KASSERT(!dev->nifaces_claimed); 1564 KASSERT(!dev->nifaces_claimed);
1572 } 1565 }
1573 1566
1574 usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev); 1567 usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
1575 dev->bus->devices[dev->address] = NULL; 1568 dev->bus->devices[dev->address] = NULL;
1576 up->device = NULL; 1569 up->device = NULL;
1577 usb_free_device(dev); 1570 usb_free_device(dev);
1578 return 0; 1571 return 0;
1579} 1572}

cvs diff -r1.134.2.1.2.3 -r1.134.2.1.2.4 src/sys/dev/usb/usbdi.c (switch to unified diff)

--- src/sys/dev/usb/usbdi.c 2011/12/08 20:21:31 1.134.2.1.2.3
+++ src/sys/dev/usb/usbdi.c 2011/12/08 22:04:56 1.134.2.1.2.4
@@ -1,1258 +1,1259 @@ @@ -1,1258 +1,1259 @@
1/* $NetBSD: usbdi.c,v 1.134.2.1.2.3 2011/12/08 20:21:31 mrg Exp $ */ 1/* $NetBSD: usbdi.c,v 1.134.2.1.2.4 2011/12/08 22:04:56 mrg Exp $ */
2/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.1.2.3 2011/12/08 20:21:31 mrg Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.1.2.4 2011/12/08 22:04:56 mrg Exp $");
36 36
37#include "opt_compat_netbsd.h" 37#include "opt_compat_netbsd.h"
38#include "opt_usb.h" 38#include "opt_usb.h"
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/kernel.h> 42#include <sys/kernel.h>
43#include <sys/device.h> 43#include <sys/device.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/proc.h> 45#include <sys/proc.h>
46 46
47#include <sys/bus.h> 47#include <sys/bus.h>
48 48
49#include <dev/usb/usb.h> 49#include <dev/usb/usb.h>
50#include <dev/usb/usbdi.h> 50#include <dev/usb/usbdi.h>
51#include <dev/usb/usbdi_util.h> 51#include <dev/usb/usbdi_util.h>
52#include <dev/usb/usbdivar.h> 52#include <dev/usb/usbdivar.h>
53#include <dev/usb/usb_mem.h> 53#include <dev/usb/usb_mem.h>
54#include <dev/usb/usb_quirks.h> 54#include <dev/usb/usb_quirks.h>
55 55
56/* UTF-8 encoding stuff */ 56/* UTF-8 encoding stuff */
57#include <fs/unicode.h> 57#include <fs/unicode.h>
58 58
59#ifdef USB_DEBUG 59#ifdef USB_DEBUG
60#define DPRINTF(x) if (usbdebug) printf x 60#define DPRINTF(x) if (usbdebug) printf x
61#define DPRINTFN(n,x) if (usbdebug>(n)) printf x 61#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
62extern int usbdebug; 62extern int usbdebug;
63#else 63#else
64#define DPRINTF(x) 64#define DPRINTF(x)
65#define DPRINTFN(n,x) 65#define DPRINTFN(n,x)
66#endif 66#endif
67 67
68Static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe); 68Static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe);
69Static void usbd_do_request_async_cb 69Static void usbd_do_request_async_cb
70 (usbd_xfer_handle, usbd_private_handle, usbd_status); 70 (usbd_xfer_handle, usbd_private_handle, usbd_status);
71Static void usbd_start_next(usbd_pipe_handle pipe); 71Static void usbd_start_next(usbd_pipe_handle pipe);
72Static usbd_status usbd_open_pipe_ival 72Static usbd_status usbd_open_pipe_ival
73 (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int); 73 (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
74 74
75static inline int 75static inline int
76usbd_xfer_isread(usbd_xfer_handle xfer) 76usbd_xfer_isread(usbd_xfer_handle xfer)
77{ 77{
78 if (xfer->rqflags & URQ_REQUEST) 78 if (xfer->rqflags & URQ_REQUEST)
79 return (xfer->request.bmRequestType & UT_READ); 79 return (xfer->request.bmRequestType & UT_READ);
80 else 80 else
81 return (xfer->pipe->endpoint->edesc->bEndpointAddress & 81 return (xfer->pipe->endpoint->edesc->bEndpointAddress &
82 UE_DIR_IN); 82 UE_DIR_IN);
83} 83}
84 84
85#if defined(USB_DEBUG) || defined(EHCI_DEBUG) 85#if defined(USB_DEBUG) || defined(EHCI_DEBUG)
86void 86void
87usbd_dump_iface(struct usbd_interface *iface) 87usbd_dump_iface(struct usbd_interface *iface)
88{ 88{
89 printf("usbd_dump_iface: iface=%p\n", iface); 89 printf("usbd_dump_iface: iface=%p\n", iface);
90 if (iface == NULL) 90 if (iface == NULL)
91 return; 91 return;
92 printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n", 92 printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
93 iface->device, iface->idesc, iface->index, iface->altindex, 93 iface->device, iface->idesc, iface->index, iface->altindex,
94 iface->priv); 94 iface->priv);
95} 95}
96 96
97void 97void
98usbd_dump_device(struct usbd_device *dev) 98usbd_dump_device(struct usbd_device *dev)
99{ 99{
100 printf("usbd_dump_device: dev=%p\n", dev); 100 printf("usbd_dump_device: dev=%p\n", dev);
101 if (dev == NULL) 101 if (dev == NULL)
102 return; 102 return;
103 printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe); 103 printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
104 printf(" address=%d config=%d depth=%d speed=%d self_powered=%d " 104 printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
105 "power=%d langid=%d\n", 105 "power=%d langid=%d\n",
106 dev->address, dev->config, dev->depth, dev->speed, 106 dev->address, dev->config, dev->depth, dev->speed,
107 dev->self_powered, dev->power, dev->langid); 107 dev->self_powered, dev->power, dev->langid);
108} 108}
109 109
110void 110void
111usbd_dump_endpoint(struct usbd_endpoint *endp) 111usbd_dump_endpoint(struct usbd_endpoint *endp)
112{ 112{
113 printf("usbd_dump_endpoint: endp=%p\n", endp); 113 printf("usbd_dump_endpoint: endp=%p\n", endp);
114 if (endp == NULL) 114 if (endp == NULL)
115 return; 115 return;
116 printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt); 116 printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
117 if (endp->edesc) 117 if (endp->edesc)
118 printf(" bEndpointAddress=0x%02x\n", 118 printf(" bEndpointAddress=0x%02x\n",
119 endp->edesc->bEndpointAddress); 119 endp->edesc->bEndpointAddress);
120} 120}
121 121
122void 122void
123usbd_dump_queue(usbd_pipe_handle pipe) 123usbd_dump_queue(usbd_pipe_handle pipe)
124{ 124{
125 usbd_xfer_handle xfer; 125 usbd_xfer_handle xfer;
126 126
127 printf("usbd_dump_queue: pipe=%p\n", pipe); 127 printf("usbd_dump_queue: pipe=%p\n", pipe);
128 SIMPLEQ_FOREACH(xfer, &pipe->queue, next) { 128 SIMPLEQ_FOREACH(xfer, &pipe->queue, next) {
129 printf(" xfer=%p\n", xfer); 129 printf(" xfer=%p\n", xfer);
130 } 130 }
131} 131}
132 132
133void 133void
134usbd_dump_pipe(usbd_pipe_handle pipe) 134usbd_dump_pipe(usbd_pipe_handle pipe)
135{ 135{
136 printf("usbd_dump_pipe: pipe=%p\n", pipe); 136 printf("usbd_dump_pipe: pipe=%p\n", pipe);
137 if (pipe == NULL) 137 if (pipe == NULL)
138 return; 138 return;
139 usbd_dump_iface(pipe->iface); 139 usbd_dump_iface(pipe->iface);
140 usbd_dump_device(pipe->device); 140 usbd_dump_device(pipe->device);
141 usbd_dump_endpoint(pipe->endpoint); 141 usbd_dump_endpoint(pipe->endpoint);
142 printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n", 142 printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n",
143 pipe->refcnt, pipe->running, pipe->aborting); 143 pipe->refcnt, pipe->running, pipe->aborting);
144 printf(" intrxfer=%p, repeat=%d, interval=%d\n", 144 printf(" intrxfer=%p, repeat=%d, interval=%d\n",
145 pipe->intrxfer, pipe->repeat, pipe->interval); 145 pipe->intrxfer, pipe->repeat, pipe->interval);
146} 146}
147#endif 147#endif
148 148
149usbd_status 149usbd_status
150usbd_open_pipe(usbd_interface_handle iface, u_int8_t address, 150usbd_open_pipe(usbd_interface_handle iface, u_int8_t address,
151 u_int8_t flags, usbd_pipe_handle *pipe) 151 u_int8_t flags, usbd_pipe_handle *pipe)
152{ 152{
153 return (usbd_open_pipe_ival(iface, address, flags, pipe, 153 return (usbd_open_pipe_ival(iface, address, flags, pipe,
154 USBD_DEFAULT_INTERVAL)); 154 USBD_DEFAULT_INTERVAL));
155} 155}
156 156
157usbd_status 157usbd_status
158usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address, 158usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address,
159 u_int8_t flags, usbd_pipe_handle *pipe, int ival) 159 u_int8_t flags, usbd_pipe_handle *pipe, int ival)
160{ 160{
161 usbd_pipe_handle p; 161 usbd_pipe_handle p;
162 struct usbd_endpoint *ep; 162 struct usbd_endpoint *ep;
163 usbd_status err; 163 usbd_status err;
164 int i; 164 int i;
165 165
166 DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n", 166 DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
167 iface, address, flags)); 167 iface, address, flags));
168 168
169 for (i = 0; i < iface->idesc->bNumEndpoints; i++) { 169 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
170 ep = &iface->endpoints[i]; 170 ep = &iface->endpoints[i];
171 if (ep->edesc == NULL) 171 if (ep->edesc == NULL)
172 return (USBD_IOERROR); 172 return (USBD_IOERROR);
173 if (ep->edesc->bEndpointAddress == address) 173 if (ep->edesc->bEndpointAddress == address)
174 goto found; 174 goto found;
175 } 175 }
176 return (USBD_BAD_ADDRESS); 176 return (USBD_BAD_ADDRESS);
177 found: 177 found:
178 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0) 178 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
179 return (USBD_IN_USE); 179 return (USBD_IN_USE);
180 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p); 180 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
181 if (err) 181 if (err)
182 return (err); 182 return (err);
183 LIST_INSERT_HEAD(&iface->pipes, p, next); 183 LIST_INSERT_HEAD(&iface->pipes, p, next);
184 *pipe = p; 184 *pipe = p;
185 return (USBD_NORMAL_COMPLETION); 185 return (USBD_NORMAL_COMPLETION);
186} 186}
187 187
188usbd_status 188usbd_status
189usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address, 189usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
190 u_int8_t flags, usbd_pipe_handle *pipe, 190 u_int8_t flags, usbd_pipe_handle *pipe,
191 usbd_private_handle priv, void *buffer, u_int32_t len, 191 usbd_private_handle priv, void *buffer, u_int32_t len,
192 usbd_callback cb, int ival) 192 usbd_callback cb, int ival)
193{ 193{
194 usbd_status err; 194 usbd_status err;
195 usbd_xfer_handle xfer; 195 usbd_xfer_handle xfer;
196 usbd_pipe_handle ipipe; 196 usbd_pipe_handle ipipe;
197 197
198 DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n", 198 DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n",
199 address, flags, len)); 199 address, flags, len));
200 200
201 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE, 201 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE,
202 &ipipe, ival); 202 &ipipe, ival);
203 if (err) 203 if (err)
204 return (err); 204 return (err);
205 xfer = usbd_alloc_xfer(iface->device); 205 xfer = usbd_alloc_xfer(iface->device);
206 if (xfer == NULL) { 206 if (xfer == NULL) {
207 err = USBD_NOMEM; 207 err = USBD_NOMEM;
208 goto bad1; 208 goto bad1;
209 } 209 }
210 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags, 210 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
211 USBD_NO_TIMEOUT, cb); 211 USBD_NO_TIMEOUT, cb);
212 ipipe->intrxfer = xfer; 212 ipipe->intrxfer = xfer;
213 ipipe->repeat = 1; 213 ipipe->repeat = 1;
214 err = usbd_transfer(xfer); 214 err = usbd_transfer(xfer);
215 *pipe = ipipe; 215 *pipe = ipipe;
216 if (err != USBD_IN_PROGRESS) 216 if (err != USBD_IN_PROGRESS)
217 goto bad2; 217 goto bad2;
218 return (USBD_NORMAL_COMPLETION); 218 return (USBD_NORMAL_COMPLETION);
219 219
220 bad2: 220 bad2:
221 ipipe->intrxfer = NULL; 221 ipipe->intrxfer = NULL;
222 ipipe->repeat = 0; 222 ipipe->repeat = 0;
223 usbd_free_xfer(xfer); 223 usbd_free_xfer(xfer);
224 bad1: 224 bad1:
225 usbd_close_pipe(ipipe); 225 usbd_close_pipe(ipipe);
226 return (err); 226 return (err);
227} 227}
228 228
229usbd_status 229usbd_status
230usbd_close_pipe(usbd_pipe_handle pipe) 230usbd_close_pipe(usbd_pipe_handle pipe)
231{ 231{
232 //int s; 
233 232
234#ifdef DIAGNOSTIC 233#ifdef DIAGNOSTIC
235 if (pipe == NULL) { 234 if (pipe == NULL) {
236 printf("usbd_close_pipe: pipe==NULL\n"); 235 printf("usbd_close_pipe: pipe==NULL\n");
237 return (USBD_NORMAL_COMPLETION); 236 return (USBD_NORMAL_COMPLETION);
238 } 237 }
239#endif 238#endif
240 239
241 //usbd_lock_pipe(pipe); 
242 if (--pipe->refcnt != 0) 240 if (--pipe->refcnt != 0)
243 return (USBD_NORMAL_COMPLETION); 241 return (USBD_NORMAL_COMPLETION);
244 if (! SIMPLEQ_EMPTY(&pipe->queue)) 242 if (! SIMPLEQ_EMPTY(&pipe->queue))
245 return (USBD_PENDING_REQUESTS); 243 return (USBD_PENDING_REQUESTS);
246 LIST_REMOVE(pipe, next); 244 LIST_REMOVE(pipe, next);
247 pipe->endpoint->refcnt--; 245 pipe->endpoint->refcnt--;
248 pipe->methods->close(pipe); 246 pipe->methods->close(pipe);
249 //usbd_lock_pipe(pipe); 
250 if (pipe->intrxfer != NULL) 247 if (pipe->intrxfer != NULL)
251 usbd_free_xfer(pipe->intrxfer); 248 usbd_free_xfer(pipe->intrxfer);
252 free(pipe, M_USB); 249 free(pipe, M_USB);
253 return (USBD_NORMAL_COMPLETION); 250 return (USBD_NORMAL_COMPLETION);
254} 251}
255 252
256usbd_status 253usbd_status
257usbd_transfer(usbd_xfer_handle xfer) 254usbd_transfer(usbd_xfer_handle xfer)
258{ 255{
259 usbd_pipe_handle pipe = xfer->pipe; 256 usbd_pipe_handle pipe = xfer->pipe;
260 usb_dma_t *dmap = &xfer->dmabuf; 257 usb_dma_t *dmap = &xfer->dmabuf;
261 usbd_status err; 258 usbd_status err;
262 unsigned int size, flags; 259 unsigned int size, flags;
263 int s; 260 int s;
264 261
265 DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%#x, pipe=%p, running=%d\n", 262 DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%#x, pipe=%p, running=%d\n",
266 xfer, xfer->flags, pipe, pipe->running)); 263 xfer, xfer->flags, pipe, pipe->running));
267 264
268#ifdef USB_DEBUG 265#ifdef USB_DEBUG
269 if (usbdebug > 5) 266 if (usbdebug > 5)
270 usbd_dump_queue(pipe); 267 usbd_dump_queue(pipe);
271#endif 268#endif
272 xfer->done = 0; 269 xfer->done = 0;
273 270
274 if (pipe->aborting) 271 if (pipe->aborting)
275 return (USBD_CANCELLED); 272 return (USBD_CANCELLED);
276 273
277 size = xfer->length; 274 size = xfer->length;
278 /* If there is no buffer, allocate one. */ 275 /* If there is no buffer, allocate one. */
279 if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) { 276 if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
280 struct usbd_bus *bus = pipe->device->bus; 277 struct usbd_bus *bus = pipe->device->bus;
281 278
282#ifdef DIAGNOSTIC 279#ifdef DIAGNOSTIC
283 if (xfer->rqflags & URQ_AUTO_DMABUF) 280 if (xfer->rqflags & URQ_AUTO_DMABUF)
284 printf("usbd_transfer: has old buffer!\n"); 281 printf("usbd_transfer: has old buffer!\n");
285#endif 282#endif
286 err = bus->methods->allocm(bus, dmap, size); 283 err = bus->methods->allocm(bus, dmap, size);
287 if (err) 284 if (err)
288 return (err); 285 return (err);
289 xfer->rqflags |= URQ_AUTO_DMABUF; 286 xfer->rqflags |= URQ_AUTO_DMABUF;
290 } 287 }
291 288
292 flags = xfer->flags; 289 flags = xfer->flags;
293 290
294 /* Copy data if going out. */ 291 /* Copy data if going out. */
295 if (!(flags & USBD_NO_COPY) && size != 0 && !usbd_xfer_isread(xfer)) 292 if (!(flags & USBD_NO_COPY) && size != 0 && !usbd_xfer_isread(xfer))
296 memcpy(KERNADDR(dmap, 0), xfer->buffer, size); 293 memcpy(KERNADDR(dmap, 0), xfer->buffer, size);
297 294
298 /* xfer is not valid after the transfer method unless synchronous */ 295 /* xfer is not valid after the transfer method unless synchronous */
299 err = pipe->methods->transfer(xfer); 296 err = pipe->methods->transfer(xfer);
300 297
301 if (err != USBD_IN_PROGRESS && err) { 298 if (err != USBD_IN_PROGRESS && err) {
302 /* The transfer has not been queued, so free buffer. */ 299 /* The transfer has not been queued, so free buffer. */
303 if (xfer->rqflags & URQ_AUTO_DMABUF) { 300 if (xfer->rqflags & URQ_AUTO_DMABUF) {
304 struct usbd_bus *bus = pipe->device->bus; 301 struct usbd_bus *bus = pipe->device->bus;
305 302
306 bus->methods->freem(bus, &xfer->dmabuf); 303 bus->methods->freem(bus, &xfer->dmabuf);
307 xfer->rqflags &= ~URQ_AUTO_DMABUF; 304 xfer->rqflags &= ~URQ_AUTO_DMABUF;
308 } 305 }
309 } 306 }
310 307
311 if (!(flags & USBD_SYNCHRONOUS)) 308 if (!(flags & USBD_SYNCHRONOUS))
312 return (err); 309 return (err);
313 310
314 /* Sync transfer, wait for completion. */ 311 /* Sync transfer, wait for completion. */
315 if (err != USBD_IN_PROGRESS) 312 if (err != USBD_IN_PROGRESS)
316 return (err); 313 return (err);
317 usbd_lock_pipe(pipe); 314 usbd_lock_pipe(pipe);
318 if (!xfer->done) { 315 if (!xfer->done) {
319 if (pipe->device->bus->use_polling) 316 if (pipe->device->bus->use_polling)
320 panic("usbd_transfer: not done"); 317 panic("usbd_transfer: not done");
321 318
322 if (pipe->lock) 319 if (pipe->device->bus->lock)
323 cv_wait(&xfer->cv, pipe->lock); 320 cv_wait(&xfer->cv, pipe->device->bus->lock);
324 else 321 else
325 tsleep(xfer, PRIBIO, "usbsyn", 0); 322 tsleep(xfer, PRIBIO, "usbsyn", 0);
326 } 323 }
327 usbd_unlock_pipe(pipe); 324 usbd_unlock_pipe(pipe);
328 return (xfer->status); 325 return (xfer->status);
329} 326}
330 327
331/* Like usbd_transfer(), but waits for completion. */ 328/* Like usbd_transfer(), but waits for completion. */
332usbd_status 329usbd_status
333usbd_sync_transfer(usbd_xfer_handle xfer) 330usbd_sync_transfer(usbd_xfer_handle xfer)
334{ 331{
335 xfer->flags |= USBD_SYNCHRONOUS; 332 xfer->flags |= USBD_SYNCHRONOUS;
336 return (usbd_transfer(xfer)); 333 return (usbd_transfer(xfer));
337} 334}
338 335
339void * 336void *
340usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size) 337usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
341{ 338{
342 struct usbd_bus *bus = xfer->device->bus; 339 struct usbd_bus *bus = xfer->device->bus;
343 usbd_status err; 340 usbd_status err;
344 341
345#ifdef DIAGNOSTIC 342#ifdef DIAGNOSTIC
346 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) 343 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
347 printf("usbd_alloc_buffer: xfer already has a buffer\n"); 344 printf("usbd_alloc_buffer: xfer already has a buffer\n");
348#endif 345#endif
349 err = bus->methods->allocm(bus, &xfer->dmabuf, size); 346 err = bus->methods->allocm(bus, &xfer->dmabuf, size);
350 if (err) 347 if (err)
351 return (NULL); 348 return (NULL);
352 xfer->rqflags |= URQ_DEV_DMABUF; 349 xfer->rqflags |= URQ_DEV_DMABUF;
353 return (KERNADDR(&xfer->dmabuf, 0)); 350 return (KERNADDR(&xfer->dmabuf, 0));
354} 351}
355 352
356void 353void
357usbd_free_buffer(usbd_xfer_handle xfer) 354usbd_free_buffer(usbd_xfer_handle xfer)
358{ 355{
359#ifdef DIAGNOSTIC 356#ifdef DIAGNOSTIC
360 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) { 357 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
361 printf("usbd_free_buffer: no buffer\n"); 358 printf("usbd_free_buffer: no buffer\n");
362 return; 359 return;
363 } 360 }
364#endif 361#endif
365 xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF); 362 xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
366 xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf); 363 xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
367} 364}
368 365
369void * 366void *
370usbd_get_buffer(usbd_xfer_handle xfer) 367usbd_get_buffer(usbd_xfer_handle xfer)
371{ 368{
372 if (!(xfer->rqflags & URQ_DEV_DMABUF)) 369 if (!(xfer->rqflags & URQ_DEV_DMABUF))
373 return (0); 370 return (0);
374 return (KERNADDR(&xfer->dmabuf, 0)); 371 return (KERNADDR(&xfer->dmabuf, 0));
375} 372}
376 373
377usbd_xfer_handle 374usbd_xfer_handle
378usbd_alloc_xfer(usbd_device_handle dev) 375usbd_alloc_xfer(usbd_device_handle dev)
379{ 376{
380 usbd_xfer_handle xfer; 377 usbd_xfer_handle xfer;
381 378
382 xfer = dev->bus->methods->allocx(dev->bus); 379 xfer = dev->bus->methods->allocx(dev->bus);
383 if (xfer == NULL) 380 if (xfer == NULL)
384 return (NULL); 381 return (NULL);
385 xfer->device = dev; 382 xfer->device = dev;
386 callout_init(&xfer->timeout_handle, 0); 383 callout_init(&xfer->timeout_handle, 0);
387 cv_init(&xfer->cv, "usbxfer"); 384 cv_init(&xfer->cv, "usbxfer");
388 cv_init(&xfer->hccv, "usbhcxfer"); 385 cv_init(&xfer->hccv, "usbhcxfer");
389 DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer)); 386 DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
390 return (xfer); 387 return (xfer);
391} 388}
392 389
393usbd_status 390usbd_status
394usbd_free_xfer(usbd_xfer_handle xfer) 391usbd_free_xfer(usbd_xfer_handle xfer)
395{ 392{
396 DPRINTFN(5,("usbd_free_xfer: %p\n", xfer)); 393 DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
397 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) 394 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
398 usbd_free_buffer(xfer); 395 usbd_free_buffer(xfer);
399#if defined(DIAGNOSTIC) 396#if defined(DIAGNOSTIC)
400 if (callout_pending(&xfer->timeout_handle)) { 397 if (callout_pending(&xfer->timeout_handle)) {
401 callout_stop(&xfer->timeout_handle); 398 callout_stop(&xfer->timeout_handle);
402 printf("usbd_free_xfer: timout_handle pending"); 399 printf("usbd_free_xfer: timout_handle pending");
403 } 400 }
404#endif 401#endif
405 cv_destroy(&xfer->cv); 402 cv_destroy(&xfer->cv);
406 cv_destroy(&xfer->hccv); 403 cv_destroy(&xfer->hccv);
407 xfer->device->bus->methods->freex(xfer->device->bus, xfer); 404 xfer->device->bus->methods->freex(xfer->device->bus, xfer);
408 return (USBD_NORMAL_COMPLETION); 405 return (USBD_NORMAL_COMPLETION);
409} 406}
410 407
411void 408void
412usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, 409usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
413 usbd_private_handle priv, void *buffer, u_int32_t length, 410 usbd_private_handle priv, void *buffer, u_int32_t length,
414 u_int16_t flags, u_int32_t timeout, 411 u_int16_t flags, u_int32_t timeout,
415 usbd_callback callback) 412 usbd_callback callback)
416{ 413{
417 xfer->pipe = pipe; 414 xfer->pipe = pipe;
418 xfer->priv = priv; 415 xfer->priv = priv;
419 xfer->buffer = buffer; 416 xfer->buffer = buffer;
420 xfer->length = length; 417 xfer->length = length;
421 xfer->actlen = 0; 418 xfer->actlen = 0;
422 xfer->flags = flags; 419 xfer->flags = flags;
423 xfer->timeout = timeout; 420 xfer->timeout = timeout;
424 xfer->status = USBD_NOT_STARTED; 421 xfer->status = USBD_NOT_STARTED;
425 xfer->callback = callback; 422 xfer->callback = callback;
426 xfer->rqflags &= ~URQ_REQUEST; 423 xfer->rqflags &= ~URQ_REQUEST;
427 xfer->nframes = 0; 424 xfer->nframes = 0;
428} 425}
429 426
430void 427void
431usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev, 428usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
432 usbd_private_handle priv, u_int32_t timeout, 429 usbd_private_handle priv, u_int32_t timeout,
433 usb_device_request_t *req, void *buffer, 430 usb_device_request_t *req, void *buffer,
434 u_int32_t length, u_int16_t flags, 431 u_int32_t length, u_int16_t flags,
435 usbd_callback callback) 432 usbd_callback callback)
436{ 433{
437 xfer->pipe = dev->default_pipe; 434 xfer->pipe = dev->default_pipe;
438 xfer->priv = priv; 435 xfer->priv = priv;
439 xfer->buffer = buffer; 436 xfer->buffer = buffer;
440 xfer->length = length; 437 xfer->length = length;
441 xfer->actlen = 0; 438 xfer->actlen = 0;
442 xfer->flags = flags; 439 xfer->flags = flags;
443 xfer->timeout = timeout; 440 xfer->timeout = timeout;
444 xfer->status = USBD_NOT_STARTED; 441 xfer->status = USBD_NOT_STARTED;
445 xfer->callback = callback; 442 xfer->callback = callback;
446 xfer->request = *req; 443 xfer->request = *req;
447 xfer->rqflags |= URQ_REQUEST; 444 xfer->rqflags |= URQ_REQUEST;
448 xfer->nframes = 0; 445 xfer->nframes = 0;
449} 446}
450 447
451void 448void
452usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, 449usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
453 usbd_private_handle priv, u_int16_t *frlengths, 450 usbd_private_handle priv, u_int16_t *frlengths,
454 u_int32_t nframes, u_int16_t flags, usbd_callback callback) 451 u_int32_t nframes, u_int16_t flags, usbd_callback callback)
455{ 452{
456 xfer->pipe = pipe; 453 xfer->pipe = pipe;
457 xfer->priv = priv; 454 xfer->priv = priv;
458 xfer->buffer = 0; 455 xfer->buffer = 0;
459 xfer->length = 0; 456 xfer->length = 0;
460 xfer->actlen = 0; 457 xfer->actlen = 0;
461 xfer->flags = flags; 458 xfer->flags = flags;
462 xfer->timeout = USBD_NO_TIMEOUT; 459 xfer->timeout = USBD_NO_TIMEOUT;
463 xfer->status = USBD_NOT_STARTED; 460 xfer->status = USBD_NOT_STARTED;
464 xfer->callback = callback; 461 xfer->callback = callback;
465 xfer->rqflags &= ~URQ_REQUEST; 462 xfer->rqflags &= ~URQ_REQUEST;
466 xfer->frlengths = frlengths; 463 xfer->frlengths = frlengths;
467 xfer->nframes = nframes; 464 xfer->nframes = nframes;
468} 465}
469 466
470void 467void
471usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv, 468usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
472 void **buffer, u_int32_t *count, usbd_status *status) 469 void **buffer, u_int32_t *count, usbd_status *status)
473{ 470{
474 if (priv != NULL) 471 if (priv != NULL)
475 *priv = xfer->priv; 472 *priv = xfer->priv;
476 if (buffer != NULL) 473 if (buffer != NULL)
477 *buffer = xfer->buffer; 474 *buffer = xfer->buffer;
478 if (count != NULL) 475 if (count != NULL)
479 *count = xfer->actlen; 476 *count = xfer->actlen;
480 if (status != NULL) 477 if (status != NULL)
481 *status = xfer->status; 478 *status = xfer->status;
482} 479}
483 480
484usb_config_descriptor_t * 481usb_config_descriptor_t *
485usbd_get_config_descriptor(usbd_device_handle dev) 482usbd_get_config_descriptor(usbd_device_handle dev)
486{ 483{
487#ifdef DIAGNOSTIC 484#ifdef DIAGNOSTIC
488 if (dev == NULL) { 485 if (dev == NULL) {
489 printf("usbd_get_config_descriptor: dev == NULL\n"); 486 printf("usbd_get_config_descriptor: dev == NULL\n");
490 return (NULL); 487 return (NULL);
491 } 488 }
492#endif 489#endif
493 return (dev->cdesc); 490 return (dev->cdesc);
494} 491}
495 492
496usb_interface_descriptor_t * 493usb_interface_descriptor_t *
497usbd_get_interface_descriptor(usbd_interface_handle iface) 494usbd_get_interface_descriptor(usbd_interface_handle iface)
498{ 495{
499#ifdef DIAGNOSTIC 496#ifdef DIAGNOSTIC
500 if (iface == NULL) { 497 if (iface == NULL) {
501 printf("usbd_get_interface_descriptor: dev == NULL\n"); 498 printf("usbd_get_interface_descriptor: dev == NULL\n");
502 return (NULL); 499 return (NULL);
503 } 500 }
504#endif 501#endif
505 return (iface->idesc); 502 return (iface->idesc);
506} 503}
507 504
508usb_device_descriptor_t * 505usb_device_descriptor_t *
509usbd_get_device_descriptor(usbd_device_handle dev) 506usbd_get_device_descriptor(usbd_device_handle dev)
510{ 507{
511 return (&dev->ddesc); 508 return (&dev->ddesc);
512} 509}
513 510
514usb_endpoint_descriptor_t * 511usb_endpoint_descriptor_t *
515usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index) 512usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
516{ 513{
517 if (index >= iface->idesc->bNumEndpoints) 514 if (index >= iface->idesc->bNumEndpoints)
518 return (0); 515 return (0);
519 return (iface->endpoints[index].edesc); 516 return (iface->endpoints[index].edesc);
520} 517}
521 518
522/* Some drivers may wish to abort requests on the default pipe, * 519/* Some drivers may wish to abort requests on the default pipe, *
523 * but there is no mechanism for getting a handle on it. */ 520 * but there is no mechanism for getting a handle on it. */
524usbd_status 521usbd_status
525usbd_abort_default_pipe(struct usbd_device *device) 522usbd_abort_default_pipe(struct usbd_device *device)
526{ 523{
527 524
528 return usbd_abort_pipe(device->default_pipe); 525 return usbd_abort_pipe(device->default_pipe);
529} 526}
530 527
531usbd_status 528usbd_status
532usbd_abort_pipe(usbd_pipe_handle pipe) 529usbd_abort_pipe(usbd_pipe_handle pipe)
533{ 530{
534 usbd_status err; 531 usbd_status err;
535 int s; 532 int s;
536 usbd_xfer_handle intrxfer = pipe->intrxfer; 533 usbd_xfer_handle intrxfer = pipe->intrxfer;
537 534
538#ifdef DIAGNOSTIC 535#ifdef DIAGNOSTIC
539 if (pipe == NULL) { 536 if (pipe == NULL) {
540 printf("usbd_abort_pipe: pipe==NULL\n"); 537 printf("usbd_abort_pipe: pipe==NULL\n");
541 return (USBD_NORMAL_COMPLETION); 538 return (USBD_NORMAL_COMPLETION);
542 } 539 }
543#endif 540#endif
544 usbd_lock_pipe(pipe); 541 usbd_lock_pipe(pipe);
545 err = usbd_ar_pipe(pipe); 542 err = usbd_ar_pipe(pipe);
546 usbd_unlock_pipe(pipe); 543 usbd_unlock_pipe(pipe);
547 if (pipe->intrxfer != intrxfer) 544 if (pipe->intrxfer != intrxfer)
548 usbd_free_xfer(intrxfer); 545 usbd_free_xfer(intrxfer);
549 return (err); 546 return (err);
550} 547}
551 548
552usbd_status 549usbd_status
553usbd_clear_endpoint_stall(usbd_pipe_handle pipe) 550usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
554{ 551{
555 usbd_device_handle dev = pipe->device; 552 usbd_device_handle dev = pipe->device;
556 usb_device_request_t req; 553 usb_device_request_t req;
557 usbd_status err; 554 usbd_status err;
558 555
559 DPRINTFN(8, ("usbd_clear_endpoint_stall\n")); 556 DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
560 557
561 /* 558 /*
562 * Clearing en endpoint stall resets the endpoint toggle, so 559 * Clearing en endpoint stall resets the endpoint toggle, so
563 * do the same to the HC toggle. 560 * do the same to the HC toggle.
564 */ 561 */
565 pipe->methods->cleartoggle(pipe); 562 pipe->methods->cleartoggle(pipe);
566 563
567 req.bmRequestType = UT_WRITE_ENDPOINT; 564 req.bmRequestType = UT_WRITE_ENDPOINT;
568 req.bRequest = UR_CLEAR_FEATURE; 565 req.bRequest = UR_CLEAR_FEATURE;
569 USETW(req.wValue, UF_ENDPOINT_HALT); 566 USETW(req.wValue, UF_ENDPOINT_HALT);
570 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); 567 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
571 USETW(req.wLength, 0); 568 USETW(req.wLength, 0);
572 err = usbd_do_request(dev, &req, 0); 569 err = usbd_do_request(dev, &req, 0);
573#if 0 570#if 0
574XXX should we do this? 571XXX should we do this?
575 if (!err) { 572 if (!err) {
576 pipe->state = USBD_PIPE_ACTIVE; 573 pipe->state = USBD_PIPE_ACTIVE;
577 /* XXX activate pipe */ 574 /* XXX activate pipe */
578 } 575 }
579#endif 576#endif
580 return (err); 577 return (err);
581} 578}
582 579
583usbd_status 580usbd_status
584usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe) 581usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
585{ 582{
586 usbd_device_handle dev = pipe->device; 583 usbd_device_handle dev = pipe->device;
587 usb_device_request_t req; 584 usb_device_request_t req;
588 usbd_status err; 585 usbd_status err;
589 586
590 pipe->methods->cleartoggle(pipe); 587 pipe->methods->cleartoggle(pipe);
591 588
592 req.bmRequestType = UT_WRITE_ENDPOINT; 589 req.bmRequestType = UT_WRITE_ENDPOINT;
593 req.bRequest = UR_CLEAR_FEATURE; 590 req.bRequest = UR_CLEAR_FEATURE;
594 USETW(req.wValue, UF_ENDPOINT_HALT); 591 USETW(req.wValue, UF_ENDPOINT_HALT);
595 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); 592 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
596 USETW(req.wLength, 0); 593 USETW(req.wLength, 0);
597 err = usbd_do_request_async(dev, &req, 0); 594 err = usbd_do_request_async(dev, &req, 0);
598 return (err); 595 return (err);
599} 596}
600 597
601void 598void
602usbd_clear_endpoint_toggle(usbd_pipe_handle pipe) 599usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
603{ 600{
604 pipe->methods->cleartoggle(pipe); 601 pipe->methods->cleartoggle(pipe);
605} 602}
606 603
607usbd_status 604usbd_status
608usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count) 605usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count)
609{ 606{
610#ifdef DIAGNOSTIC 607#ifdef DIAGNOSTIC
611 if (iface == NULL || iface->idesc == NULL) { 608 if (iface == NULL || iface->idesc == NULL) {
612 printf("usbd_endpoint_count: NULL pointer\n"); 609 printf("usbd_endpoint_count: NULL pointer\n");
613 return (USBD_INVAL); 610 return (USBD_INVAL);
614 } 611 }
615#endif 612#endif
616 *count = iface->idesc->bNumEndpoints; 613 *count = iface->idesc->bNumEndpoints;
617 return (USBD_NORMAL_COMPLETION); 614 return (USBD_NORMAL_COMPLETION);
618} 615}
619 616
620usbd_status 617usbd_status
621usbd_interface_count(usbd_device_handle dev, u_int8_t *count) 618usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
622{ 619{
623 if (dev->cdesc == NULL) 620 if (dev->cdesc == NULL)
624 return (USBD_NOT_CONFIGURED); 621 return (USBD_NOT_CONFIGURED);
625 *count = dev->cdesc->bNumInterface; 622 *count = dev->cdesc->bNumInterface;
626 return (USBD_NORMAL_COMPLETION); 623 return (USBD_NORMAL_COMPLETION);
627} 624}
628 625
629void 626void
630usbd_interface2device_handle(usbd_interface_handle iface, 627usbd_interface2device_handle(usbd_interface_handle iface,
631 usbd_device_handle *dev) 628 usbd_device_handle *dev)
632{ 629{
633 *dev = iface->device; 630 *dev = iface->device;
634} 631}
635 632
636usbd_status 633usbd_status
637usbd_device2interface_handle(usbd_device_handle dev, 634usbd_device2interface_handle(usbd_device_handle dev,
638 u_int8_t ifaceno, usbd_interface_handle *iface) 635 u_int8_t ifaceno, usbd_interface_handle *iface)
639{ 636{
640 if (dev->cdesc == NULL) 637 if (dev->cdesc == NULL)
641 return (USBD_NOT_CONFIGURED); 638 return (USBD_NOT_CONFIGURED);
642 if (ifaceno >= dev->cdesc->bNumInterface) 639 if (ifaceno >= dev->cdesc->bNumInterface)
643 return (USBD_INVAL); 640 return (USBD_INVAL);
644 *iface = &dev->ifaces[ifaceno]; 641 *iface = &dev->ifaces[ifaceno];
645 return (USBD_NORMAL_COMPLETION); 642 return (USBD_NORMAL_COMPLETION);
646} 643}
647 644
648usbd_device_handle 645usbd_device_handle
649usbd_pipe2device_handle(usbd_pipe_handle pipe) 646usbd_pipe2device_handle(usbd_pipe_handle pipe)
650{ 647{
651 return (pipe->device); 648 return (pipe->device);
652} 649}
653 650
654/* XXXX use altno */ 651/* XXXX use altno */
655usbd_status 652usbd_status
656usbd_set_interface(usbd_interface_handle iface, int altidx) 653usbd_set_interface(usbd_interface_handle iface, int altidx)
657{ 654{
658 usb_device_request_t req; 655 usb_device_request_t req;
659 usbd_status err; 656 usbd_status err;
660 void *endpoints; 657 void *endpoints;
661 658
662 if (LIST_FIRST(&iface->pipes) != 0) 659 if (LIST_FIRST(&iface->pipes) != 0)
663 return (USBD_IN_USE); 660 return (USBD_IN_USE);
664 661
665 endpoints = iface->endpoints; 662 endpoints = iface->endpoints;
666 err = usbd_fill_iface_data(iface->device, iface->index, altidx); 663 err = usbd_fill_iface_data(iface->device, iface->index, altidx);
667 if (err) 664 if (err)
668 return (err); 665 return (err);
669 666
670 /* new setting works, we can free old endpoints */ 667 /* new setting works, we can free old endpoints */
671 if (endpoints != NULL) 668 if (endpoints != NULL)
672 free(endpoints, M_USB); 669 free(endpoints, M_USB);
673 670
674#ifdef DIAGNOSTIC 671#ifdef DIAGNOSTIC
675 if (iface->idesc == NULL) { 672 if (iface->idesc == NULL) {
676 printf("usbd_set_interface: NULL pointer\n"); 673 printf("usbd_set_interface: NULL pointer\n");
677 return (USBD_INVAL); 674 return (USBD_INVAL);
678 } 675 }
679#endif 676#endif
680 677
681 req.bmRequestType = UT_WRITE_INTERFACE; 678 req.bmRequestType = UT_WRITE_INTERFACE;
682 req.bRequest = UR_SET_INTERFACE; 679 req.bRequest = UR_SET_INTERFACE;
683 USETW(req.wValue, iface->idesc->bAlternateSetting); 680 USETW(req.wValue, iface->idesc->bAlternateSetting);
684 USETW(req.wIndex, iface->idesc->bInterfaceNumber); 681 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
685 USETW(req.wLength, 0); 682 USETW(req.wLength, 0);
686 return (usbd_do_request(iface->device, &req, 0)); 683 return (usbd_do_request(iface->device, &req, 0));
687} 684}
688 685
689int 686int
690usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno) 687usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
691{ 688{
692 char *p = (char *)cdesc; 689 char *p = (char *)cdesc;
693 char *end = p + UGETW(cdesc->wTotalLength); 690 char *end = p + UGETW(cdesc->wTotalLength);
694 usb_interface_descriptor_t *d; 691 usb_interface_descriptor_t *d;
695 int n; 692 int n;
696 693
697 for (n = 0; p < end; p += d->bLength) { 694 for (n = 0; p < end; p += d->bLength) {
698 d = (usb_interface_descriptor_t *)p; 695 d = (usb_interface_descriptor_t *)p;
699 if (p + d->bLength <= end && 696 if (p + d->bLength <= end &&
700 d->bDescriptorType == UDESC_INTERFACE && 697 d->bDescriptorType == UDESC_INTERFACE &&
701 d->bInterfaceNumber == ifaceno) 698 d->bInterfaceNumber == ifaceno)
702 n++; 699 n++;
703 } 700 }
704 return (n); 701 return (n);
705} 702}
706 703
707int 704int
708usbd_get_interface_altindex(usbd_interface_handle iface) 705usbd_get_interface_altindex(usbd_interface_handle iface)
709{ 706{
710 return (iface->altindex); 707 return (iface->altindex);
711} 708}
712 709
713usbd_status 710usbd_status
714usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface) 711usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface)
715{ 712{
716 usb_device_request_t req; 713 usb_device_request_t req;
717 714
718 req.bmRequestType = UT_READ_INTERFACE; 715 req.bmRequestType = UT_READ_INTERFACE;
719 req.bRequest = UR_GET_INTERFACE; 716 req.bRequest = UR_GET_INTERFACE;
720 USETW(req.wValue, 0); 717 USETW(req.wValue, 0);
721 USETW(req.wIndex, iface->idesc->bInterfaceNumber); 718 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
722 USETW(req.wLength, 1); 719 USETW(req.wLength, 1);
723 return (usbd_do_request(iface->device, &req, aiface)); 720 return (usbd_do_request(iface->device, &req, aiface));
724} 721}
725 722
726/*** Internal routines ***/ 723/*** Internal routines ***/
727 724
728/* Dequeue all pipe operations, called at splusb(). */ 725/* Dequeue all pipe operations, called at splusb(). */
729Static usbd_status 726Static usbd_status
730usbd_ar_pipe(usbd_pipe_handle pipe) 727usbd_ar_pipe(usbd_pipe_handle pipe)
731{ 728{
732 usbd_xfer_handle xfer; 729 usbd_xfer_handle xfer;
733 730
734 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); 731 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
735 732
736 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe)); 733 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
737#ifdef USB_DEBUG 734#ifdef USB_DEBUG
738 if (usbdebug > 5) 735 if (usbdebug > 5)
739 usbd_dump_queue(pipe); 736 usbd_dump_queue(pipe);
740#endif 737#endif
741 pipe->repeat = 0; 738 pipe->repeat = 0;
742 pipe->aborting = 1; 739 pipe->aborting = 1;
743 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) { 740 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
744 DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n", 741 DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
745 pipe, xfer, pipe->methods)); 742 pipe, xfer, pipe->methods));
746 /* Make the HC abort it (and invoke the callback). */ 743 /* Make the HC abort it (and invoke the callback). */
747 if (pipe->device->bus->lock) 744 if (pipe->device->bus->lock)
748 mutex_exit(pipe->device->bus->lock); 745 mutex_exit(pipe->device->bus->lock);
749 pipe->methods->abort(xfer); 746 pipe->methods->abort(xfer);
750 if (pipe->device->bus->lock) 747 if (pipe->device->bus->lock)
751 mutex_enter(pipe->device->bus->lock); 748 mutex_enter(pipe->device->bus->lock);
752 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ 749 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
753 } 750 }
754 pipe->aborting = 0; 751 pipe->aborting = 0;
755 return (USBD_NORMAL_COMPLETION); 752 return (USBD_NORMAL_COMPLETION);
756} 753}
757 754
758/* Called at splusb() */ 755/* Called at splusb() */
759void 756void
760usb_transfer_complete(usbd_xfer_handle xfer) 757usb_transfer_complete(usbd_xfer_handle xfer)
761{ 758{
762 usbd_pipe_handle pipe = xfer->pipe; 759 usbd_pipe_handle pipe = xfer->pipe;
763 usb_dma_t *dmap = &xfer->dmabuf; 760 usb_dma_t *dmap = &xfer->dmabuf;
764 int sync = xfer->flags & USBD_SYNCHRONOUS; 761 int sync = xfer->flags & USBD_SYNCHRONOUS;
765 int erred = xfer->status == USBD_CANCELLED || 762 int erred = xfer->status == USBD_CANCELLED ||
766 xfer->status == USBD_TIMEOUT; 763 xfer->status == USBD_TIMEOUT;
767 int repeat, polling; 764 int repeat, polling;
768 765
769 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d " 766 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
770 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen)); 767 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
771 768
772 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); 769 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
773 770
774#ifdef DIAGNOSTIC 771#ifdef DIAGNOSTIC
775 if (xfer->busy_free != XFER_ONQU) { 772 if (xfer->busy_free != XFER_ONQU) {
776 printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n", 773 printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n",
777 xfer, xfer->busy_free); 774 xfer, xfer->busy_free);
778 } 775 }
779#endif 776#endif
780 777
781#ifdef DIAGNOSTIC 778#ifdef DIAGNOSTIC
782 if (pipe == NULL) { 779 if (pipe == NULL) {
783 printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer); 780 printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
784 return; 781 return;
785 } 782 }
786#endif 783#endif
787 repeat = pipe->repeat; 784 repeat = pipe->repeat;
788 polling = pipe->device->bus->use_polling; 785 polling = pipe->device->bus->use_polling;
789 /* XXXX */ 786 /* XXXX */
790 if (polling) 787 if (polling)
791 pipe->running = 0; 788 pipe->running = 0;
792 789
793 if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 && 790 if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
794 usbd_xfer_isread(xfer)) { 791 usbd_xfer_isread(xfer)) {
795#ifdef DIAGNOSTIC 792#ifdef DIAGNOSTIC
796 if (xfer->actlen > xfer->length) { 793 if (xfer->actlen > xfer->length) {
797 printf("usb_transfer_complete: actlen > len %d > %d\n", 794 printf("usb_transfer_complete: actlen > len %d > %d\n",
798 xfer->actlen, xfer->length); 795 xfer->actlen, xfer->length);
799 xfer->actlen = xfer->length; 796 xfer->actlen = xfer->length;
800 } 797 }
801#endif 798#endif
802 memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen); 799 memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen);
803 } 800 }
804 801
805 /* if we allocated the buffer in usbd_transfer() we free it here. */ 802 /* if we allocated the buffer in usbd_transfer() we free it here. */
806 if (xfer->rqflags & URQ_AUTO_DMABUF) { 803 if (xfer->rqflags & URQ_AUTO_DMABUF) {
807 if (!repeat) { 804 if (!repeat) {
808 struct usbd_bus *bus = pipe->device->bus; 805 struct usbd_bus *bus = pipe->device->bus;
809 bus->methods->freem(bus, dmap); 806 bus->methods->freem(bus, dmap);
810 xfer->rqflags &= ~URQ_AUTO_DMABUF; 807 xfer->rqflags &= ~URQ_AUTO_DMABUF;
811 } 808 }
812 } 809 }
813 810
814 if (!repeat) { 811 if (!repeat) {
815 /* Remove request from queue. */ 812 /* Remove request from queue. */
816#ifdef DIAGNOSTIC 813#ifdef DIAGNOSTIC
817 if (xfer != SIMPLEQ_FIRST(&pipe->queue)) 814 if (xfer != SIMPLEQ_FIRST(&pipe->queue))
818 printf("usb_transfer_complete: bad dequeue %p != %p\n", 815 printf("usb_transfer_complete: bad dequeue %p != %p\n",
819 xfer, SIMPLEQ_FIRST(&pipe->queue)); 816 xfer, SIMPLEQ_FIRST(&pipe->queue));
820 xfer->busy_free = XFER_BUSY; 817 xfer->busy_free = XFER_BUSY;
821#endif 818#endif
822 SIMPLEQ_REMOVE_HEAD(&pipe->queue, next); 819 SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
823 } 820 }
824 DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n", 821 DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
825 repeat, SIMPLEQ_FIRST(&pipe->queue))); 822 repeat, SIMPLEQ_FIRST(&pipe->queue)));
826 823
827 /* Count completed transfers. */ 824 /* Count completed transfers. */
828 ++pipe->device->bus->stats.uds_requests 825 ++pipe->device->bus->stats.uds_requests
829 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE]; 826 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
830 827
831 xfer->done = 1; 828 xfer->done = 1;
832 if (!xfer->status && xfer->actlen < xfer->length && 829 if (!xfer->status && xfer->actlen < xfer->length &&
833 !(xfer->flags & USBD_SHORT_XFER_OK)) { 830 !(xfer->flags & USBD_SHORT_XFER_OK)) {
834 DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n", 831 DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
835 xfer->actlen, xfer->length)); 832 xfer->actlen, xfer->length));
836 xfer->status = USBD_SHORT_XFER; 833 xfer->status = USBD_SHORT_XFER;
837 } 834 }
838 835
839 if (repeat) { 836 if (repeat) {
840 if (xfer->callback) { 837 if (xfer->callback) {
841 if (pipe->lock) mutex_exit(pipe->lock); 838 if (pipe->device->bus->lock)
 839 mutex_exit(pipe->device->bus->lock);
842 xfer->callback(xfer, xfer->priv, xfer->status); 840 xfer->callback(xfer, xfer->priv, xfer->status);
843 if (pipe->lock) mutex_enter(pipe->lock); 841 if (pipe->device->bus->lock)
 842 mutex_enter(pipe->device->bus->lock);
844 } 843 }
845 pipe->methods->done(xfer); 844 pipe->methods->done(xfer);
846 } else { 845 } else {
847 pipe->methods->done(xfer); 846 pipe->methods->done(xfer);
848 if (xfer->callback) { 847 if (xfer->callback) {
849 if (pipe->device->bus->lock) 848 if (pipe->device->bus->lock)
850 mutex_exit(pipe->device->bus->lock); 849 mutex_exit(pipe->device->bus->lock);
851 xfer->callback(xfer, xfer->priv, xfer->status); 850 xfer->callback(xfer, xfer->priv, xfer->status);
852 if (pipe->device->bus->lock) 851 if (pipe->device->bus->lock)
853 mutex_enter(pipe->device->bus->lock); 852 mutex_enter(pipe->device->bus->lock);
854 } 853 }
855 } 854 }
856 855
857 if (sync && !polling) { 856 if (sync && !polling) {
858 if (pipe->device->bus->lock) 857 if (pipe->device->bus->lock)
859 cv_broadcast(&xfer->cv); 858 cv_broadcast(&xfer->cv);
860 else 859 else
861 wakeup(xfer); 860 wakeup(xfer);
862 } 861 }
863 862
864 if (!repeat) { 863 if (!repeat) {
865 /* XXX should we stop the queue on all errors? */ 864 /* XXX should we stop the queue on all errors? */
866 if (erred && pipe->iface != NULL) /* not control pipe */ 865 if (erred && pipe->iface != NULL) /* not control pipe */
867 pipe->running = 0; 866 pipe->running = 0;
868 else 867 else
869 usbd_start_next(pipe); 868 usbd_start_next(pipe);
870 } 869 }
871} 870}
872 871
873usbd_status 872usbd_status
874usb_insert_transfer(usbd_xfer_handle xfer) 873usb_insert_transfer(usbd_xfer_handle xfer)
875{ 874{
876 usbd_pipe_handle pipe = xfer->pipe; 875 usbd_pipe_handle pipe = xfer->pipe;
877 usbd_status err; 876 usbd_status err;
878 int s; 877 int s;
879 878
880 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n", 879 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
881 pipe, pipe->running, xfer->timeout)); 880 pipe, pipe->running, xfer->timeout));
882 881
883 //KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); 882 //KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
884 883
885#ifdef DIAGNOSTIC 884#ifdef DIAGNOSTIC
886 if (xfer->busy_free != XFER_BUSY) { 885 if (xfer->busy_free != XFER_BUSY) {
887 printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n", 886 printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
888 xfer, xfer->busy_free); 887 xfer, xfer->busy_free);
889 return (USBD_INVAL); 888 return (USBD_INVAL);
890 } 889 }
891 xfer->busy_free = XFER_ONQU; 890 xfer->busy_free = XFER_ONQU;
892#endif 891#endif
893 s = splusb(); 892 s = splusb();
894 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next); 893 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
895 if (pipe->running) 894 if (pipe->running)
896 err = USBD_IN_PROGRESS; 895 err = USBD_IN_PROGRESS;
897 else { 896 else {
898 pipe->running = 1; 897 pipe->running = 1;
899 err = USBD_NORMAL_COMPLETION; 898 err = USBD_NORMAL_COMPLETION;
900 } 899 }
901 splx(s); 900 splx(s);
902 return (err); 901 return (err);
903} 902}
904 903
905/* Called at splusb() */ 904/* Called at splusb() */
906void 905void
907usbd_start_next(usbd_pipe_handle pipe) 906usbd_start_next(usbd_pipe_handle pipe)
908{ 907{
909 usbd_xfer_handle xfer; 908 usbd_xfer_handle xfer;
910 usbd_status err; 909 usbd_status err;
911 910
 911 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 912
912#ifdef DIAGNOSTIC 913#ifdef DIAGNOSTIC
913 if (pipe == NULL) { 914 if (pipe == NULL) {
914 printf("usbd_start_next: pipe == NULL\n"); 915 printf("usbd_start_next: pipe == NULL\n");
915 return; 916 return;
916 } 917 }
917 if (pipe->methods == NULL || pipe->methods->start == NULL) { 918 if (pipe->methods == NULL || pipe->methods->start == NULL) {
918 printf("usbd_start_next: pipe=%p no start method\n", pipe); 919 printf("usbd_start_next: pipe=%p no start method\n", pipe);
919 return; 920 return;
920 } 921 }
921#endif 922#endif
922 923
923 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); 924 KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
924 925
925 /* Get next request in queue. */ 926 /* Get next request in queue. */
926 xfer = SIMPLEQ_FIRST(&pipe->queue); 927 xfer = SIMPLEQ_FIRST(&pipe->queue);
927 DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer)); 928 DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
928 if (xfer == NULL) { 929 if (xfer == NULL) {
929 pipe->running = 0; 930 pipe->running = 0;
930 } else { 931 } else {
931 if (pipe->device->bus->lock) 932 if (pipe->device->bus->lock)
932 mutex_exit(pipe->device->bus->lock); 933 mutex_exit(pipe->device->bus->lock);
933 err = pipe->methods->start(xfer); 934 err = pipe->methods->start(xfer);
934 if (pipe->device->bus->lock) 935 if (pipe->device->bus->lock)
935 mutex_enter(pipe->device->bus->lock); 936 mutex_enter(pipe->device->bus->lock);
936 if (err != USBD_IN_PROGRESS) { 937 if (err != USBD_IN_PROGRESS) {
937 printf("usbd_start_next: error=%d\n", err); 938 printf("usbd_start_next: error=%d\n", err);
938 pipe->running = 0; 939 pipe->running = 0;
939 /* XXX do what? */ 940 /* XXX do what? */
940 } 941 }
941 } 942 }
942} 943}
943 944
944usbd_status 945usbd_status
945usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data) 946usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
946{ 947{
947 return (usbd_do_request_flags(dev, req, data, 0, 0, 948 return (usbd_do_request_flags(dev, req, data, 0, 0,
948 USBD_DEFAULT_TIMEOUT)); 949 USBD_DEFAULT_TIMEOUT));
949} 950}
950 951
951usbd_status 952usbd_status
952usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req, 953usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
953 void *data, u_int16_t flags, int *actlen, u_int32_t timo) 954 void *data, u_int16_t flags, int *actlen, u_int32_t timo)
954{ 955{
955 return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req, 956 return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
956 data, flags, actlen, timo)); 957 data, flags, actlen, timo));
957} 958}
958 959
959usbd_status 960usbd_status
960usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe, 961usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
961 usb_device_request_t *req, void *data, u_int16_t flags, int *actlen, 962 usb_device_request_t *req, void *data, u_int16_t flags, int *actlen,
962 u_int32_t timeout) 963 u_int32_t timeout)
963{ 964{
964 usbd_xfer_handle xfer; 965 usbd_xfer_handle xfer;
965 usbd_status err; 966 usbd_status err;
966 967
967#ifdef DIAGNOSTIC 968#ifdef DIAGNOSTIC
968 if (dev->bus->intr_context) { 969 if (dev->bus->intr_context) {
969 printf("usbd_do_request: not in process context\n"); 970 printf("usbd_do_request: not in process context\n");
970 return (USBD_INVAL); 971 return (USBD_INVAL);
971 } 972 }
972#endif 973#endif
973 974
974 xfer = usbd_alloc_xfer(dev); 975 xfer = usbd_alloc_xfer(dev);
975 if (xfer == NULL) 976 if (xfer == NULL)
976 return (USBD_NOMEM); 977 return (USBD_NOMEM);
977 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, 978 usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
978 data, UGETW(req->wLength), flags, 0); 979 data, UGETW(req->wLength), flags, 0);
979 xfer->pipe = pipe; 980 xfer->pipe = pipe;
980 err = usbd_sync_transfer(xfer); 981 err = usbd_sync_transfer(xfer);
981#if defined(USB_DEBUG) || defined(DIAGNOSTIC) 982#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
982 if (xfer->actlen > xfer->length) { 983 if (xfer->actlen > xfer->length) {
983 DPRINTF(("%s: overrun addr=%d type=0x%02x req=0x" 984 DPRINTF(("%s: overrun addr=%d type=0x%02x req=0x"
984 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", 985 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
985 __func__, dev->address, xfer->request.bmRequestType, 986 __func__, dev->address, xfer->request.bmRequestType,
986 xfer->request.bRequest, UGETW(xfer->request.wValue), 987 xfer->request.bRequest, UGETW(xfer->request.wValue),
987 UGETW(xfer->request.wIndex), 988 UGETW(xfer->request.wIndex),
988 UGETW(xfer->request.wLength), 989 UGETW(xfer->request.wLength),
989 xfer->length, xfer->actlen)); 990 xfer->length, xfer->actlen));
990 } 991 }
991#endif 992#endif
992 if (actlen != NULL) 993 if (actlen != NULL)
993 *actlen = xfer->actlen; 994 *actlen = xfer->actlen;
994 if (err == USBD_STALLED) { 995 if (err == USBD_STALLED) {
995 /* 996 /*
996 * The control endpoint has stalled. Control endpoints 997 * The control endpoint has stalled. Control endpoints
997 * should not halt, but some may do so anyway so clear 998 * should not halt, but some may do so anyway so clear
998 * any halt condition. 999 * any halt condition.
999 */ 1000 */
1000 usb_device_request_t treq; 1001 usb_device_request_t treq;
1001 usb_status_t status; 1002 usb_status_t status;
1002 u_int16_t s; 1003 u_int16_t s;
1003 usbd_status nerr; 1004 usbd_status nerr;
1004 1005
1005 treq.bmRequestType = UT_READ_ENDPOINT; 1006 treq.bmRequestType = UT_READ_ENDPOINT;
1006 treq.bRequest = UR_GET_STATUS; 1007 treq.bRequest = UR_GET_STATUS;
1007 USETW(treq.wValue, 0); 1008 USETW(treq.wValue, 0);
1008 USETW(treq.wIndex, 0); 1009 USETW(treq.wIndex, 0);
1009 USETW(treq.wLength, sizeof(usb_status_t)); 1010 USETW(treq.wLength, sizeof(usb_status_t));
1010 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, 1011 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1011 &treq, &status,sizeof(usb_status_t), 1012 &treq, &status,sizeof(usb_status_t),
1012 0, 0); 1013 0, 0);
1013 nerr = usbd_sync_transfer(xfer); 1014 nerr = usbd_sync_transfer(xfer);
1014 if (nerr) 1015 if (nerr)
1015 goto bad; 1016 goto bad;
1016 s = UGETW(status.wStatus); 1017 s = UGETW(status.wStatus);
1017 DPRINTF(("usbd_do_request: status = 0x%04x\n", s)); 1018 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
1018 if (!(s & UES_HALT)) 1019 if (!(s & UES_HALT))
1019 goto bad; 1020 goto bad;
1020 treq.bmRequestType = UT_WRITE_ENDPOINT; 1021 treq.bmRequestType = UT_WRITE_ENDPOINT;
1021 treq.bRequest = UR_CLEAR_FEATURE; 1022 treq.bRequest = UR_CLEAR_FEATURE;
1022 USETW(treq.wValue, UF_ENDPOINT_HALT); 1023 USETW(treq.wValue, UF_ENDPOINT_HALT);
1023 USETW(treq.wIndex, 0); 1024 USETW(treq.wIndex, 0);
1024 USETW(treq.wLength, 0); 1025 USETW(treq.wLength, 0);
1025 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, 1026 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1026 &treq, &status, 0, 0, 0); 1027 &treq, &status, 0, 0, 0);
1027 nerr = usbd_sync_transfer(xfer); 1028 nerr = usbd_sync_transfer(xfer);
1028 if (nerr) 1029 if (nerr)
1029 goto bad; 1030 goto bad;
1030 } 1031 }
1031 1032
1032 bad: 1033 bad:
1033 if (err) { 1034 if (err) {
1034 DPRINTF(("%s: returning err=%s\n", __func__, usbd_errstr(err))); 1035 DPRINTF(("%s: returning err=%s\n", __func__, usbd_errstr(err)));
1035 } 1036 }
1036 usbd_free_xfer(xfer); 1037 usbd_free_xfer(xfer);
1037 return (err); 1038 return (err);
1038} 1039}
1039 1040
1040void 1041void
1041usbd_do_request_async_cb(usbd_xfer_handle xfer, 1042usbd_do_request_async_cb(usbd_xfer_handle xfer,
1042 usbd_private_handle priv, usbd_status status) 1043 usbd_private_handle priv, usbd_status status)
1043{ 1044{
1044#if defined(USB_DEBUG) || defined(DIAGNOSTIC) 1045#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1045 if (xfer->actlen > xfer->length) { 1046 if (xfer->actlen > xfer->length) {
1046 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x" 1047 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1047 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", 1048 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1048 xfer->pipe->device->address, 1049 xfer->pipe->device->address,
1049 xfer->request.bmRequestType, 1050 xfer->request.bmRequestType,
1050 xfer->request.bRequest, UGETW(xfer->request.wValue), 1051 xfer->request.bRequest, UGETW(xfer->request.wValue),
1051 UGETW(xfer->request.wIndex), 1052 UGETW(xfer->request.wIndex),
1052 UGETW(xfer->request.wLength), 1053 UGETW(xfer->request.wLength),
1053 xfer->length, xfer->actlen)); 1054 xfer->length, xfer->actlen));
1054 } 1055 }
1055#endif 1056#endif
1056 usbd_free_xfer(xfer); 1057 usbd_free_xfer(xfer);
1057} 1058}
1058 1059
1059/* 1060/*
1060 * Execute a request without waiting for completion. 1061 * Execute a request without waiting for completion.
1061 * Can be used from interrupt context. 1062 * Can be used from interrupt context.
1062 */ 1063 */
1063usbd_status 1064usbd_status
1064usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req, 1065usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req,
1065 void *data) 1066 void *data)
1066{ 1067{
1067 usbd_xfer_handle xfer; 1068 usbd_xfer_handle xfer;
1068 usbd_status err; 1069 usbd_status err;
1069 1070
1070 xfer = usbd_alloc_xfer(dev); 1071 xfer = usbd_alloc_xfer(dev);
1071 if (xfer == NULL) 1072 if (xfer == NULL)
1072 return (USBD_NOMEM); 1073 return (USBD_NOMEM);
1073 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req, 1074 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
1074 data, UGETW(req->wLength), 0, usbd_do_request_async_cb); 1075 data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
1075 err = usbd_transfer(xfer); 1076 err = usbd_transfer(xfer);
1076 if (err != USBD_IN_PROGRESS) { 1077 if (err != USBD_IN_PROGRESS) {
1077 usbd_free_xfer(xfer); 1078 usbd_free_xfer(xfer);
1078 return (err); 1079 return (err);
1079 } 1080 }
1080 return (USBD_NORMAL_COMPLETION); 1081 return (USBD_NORMAL_COMPLETION);
1081} 1082}
1082 1083
1083const struct usbd_quirks * 1084const struct usbd_quirks *
1084usbd_get_quirks(usbd_device_handle dev) 1085usbd_get_quirks(usbd_device_handle dev)
1085{ 1086{
1086#ifdef DIAGNOSTIC 1087#ifdef DIAGNOSTIC
1087 if (dev == NULL) { 1088 if (dev == NULL) {
1088 printf("usbd_get_quirks: dev == NULL\n"); 1089 printf("usbd_get_quirks: dev == NULL\n");
1089 return 0; 1090 return 0;
1090 } 1091 }
1091#endif 1092#endif
1092 return (dev->quirks); 1093 return (dev->quirks);
1093} 1094}
1094 1095
1095/* XXX do periodic free() of free list */ 1096/* XXX do periodic free() of free list */
1096 1097
1097/* 1098/*
1098 * Called from keyboard driver when in polling mode. 1099 * Called from keyboard driver when in polling mode.
1099 */ 1100 */
1100void 1101void
1101usbd_dopoll(usbd_interface_handle iface) 1102usbd_dopoll(usbd_interface_handle iface)
1102{ 1103{
1103 iface->device->bus->methods->do_poll(iface->device->bus); 1104 iface->device->bus->methods->do_poll(iface->device->bus);
1104} 1105}
1105 1106
1106void 1107void
1107usbd_set_polling(usbd_device_handle dev, int on) 1108usbd_set_polling(usbd_device_handle dev, int on)
1108{ 1109{
1109 if (on) 1110 if (on)
1110 dev->bus->use_polling++; 1111 dev->bus->use_polling++;
1111 else 1112 else
1112 dev->bus->use_polling--; 1113 dev->bus->use_polling--;
1113 1114
1114 /* Kick the host controller when switching modes */ 1115 /* Kick the host controller when switching modes */
1115 dev->bus->methods->soft_intr(dev->bus); 1116 dev->bus->methods->soft_intr(dev->bus);
1116} 1117}
1117 1118
1118 1119
1119usb_endpoint_descriptor_t * 1120usb_endpoint_descriptor_t *
1120usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address) 1121usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
1121{ 1122{
1122 struct usbd_endpoint *ep; 1123 struct usbd_endpoint *ep;
1123 int i; 1124 int i;
1124 1125
1125 for (i = 0; i < iface->idesc->bNumEndpoints; i++) { 1126 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1126 ep = &iface->endpoints[i]; 1127 ep = &iface->endpoints[i];
1127 if (ep->edesc->bEndpointAddress == address) 1128 if (ep->edesc->bEndpointAddress == address)
1128 return (iface->endpoints[i].edesc); 1129 return (iface->endpoints[i].edesc);
1129 } 1130 }
1130 return (0); 1131 return (0);
1131} 1132}
1132 1133
1133/* 1134/*
1134 * usbd_ratecheck() can limit the number of error messages that occurs. 1135 * usbd_ratecheck() can limit the number of error messages that occurs.
1135 * When a device is unplugged it may take up to 0.25s for the hub driver 1136 * When a device is unplugged it may take up to 0.25s for the hub driver
1136 * to notice it. If the driver continuosly tries to do I/O operations 1137 * to notice it. If the driver continuosly tries to do I/O operations
1137 * this can generate a large number of messages. 1138 * this can generate a large number of messages.
1138 */ 1139 */
1139int 1140int
1140usbd_ratecheck(struct timeval *last) 1141usbd_ratecheck(struct timeval *last)
1141{ 1142{
1142 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ 1143 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1143 1144
1144 return (ratecheck(last, &errinterval)); 1145 return (ratecheck(last, &errinterval));
1145} 1146}
1146 1147
1147/* 1148/*
1148 * Search for a vendor/product pair in an array. The item size is 1149 * Search for a vendor/product pair in an array. The item size is
1149 * given as an argument. 1150 * given as an argument.
1150 */ 1151 */
1151const struct usb_devno * 1152const struct usb_devno *
1152usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, 1153usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1153 u_int16_t vendor, u_int16_t product) 1154 u_int16_t vendor, u_int16_t product)
1154{ 1155{
1155 while (nentries-- > 0) { 1156 while (nentries-- > 0) {
1156 u_int16_t tproduct = tbl->ud_product; 1157 u_int16_t tproduct = tbl->ud_product;
1157 if (tbl->ud_vendor == vendor && 1158 if (tbl->ud_vendor == vendor &&
1158 (tproduct == product || tproduct == USB_PRODUCT_ANY)) 1159 (tproduct == product || tproduct == USB_PRODUCT_ANY))
1159 return (tbl); 1160 return (tbl);
1160 tbl = (const struct usb_devno *)((const char *)tbl + sz); 1161 tbl = (const struct usb_devno *)((const char *)tbl + sz);
1161 } 1162 }
1162 return (NULL); 1163 return (NULL);
1163} 1164}
1164 1165
1165 1166
1166void 1167void
1167usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter) 1168usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
1168{ 1169{
1169 const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); 1170 const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
1170 1171
1171 iter->cur = (const uByte *)cd; 1172 iter->cur = (const uByte *)cd;
1172 iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); 1173 iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
1173} 1174}
1174 1175
1175const usb_descriptor_t * 1176const usb_descriptor_t *
1176usb_desc_iter_next(usbd_desc_iter_t *iter) 1177usb_desc_iter_next(usbd_desc_iter_t *iter)
1177{ 1178{
1178 const usb_descriptor_t *desc; 1179 const usb_descriptor_t *desc;
1179 1180
1180 if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) { 1181 if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
1181 if (iter->cur != iter->end) 1182 if (iter->cur != iter->end)
1182 printf("usb_desc_iter_next: bad descriptor\n"); 1183 printf("usb_desc_iter_next: bad descriptor\n");
1183 return NULL; 1184 return NULL;
1184 } 1185 }
1185 desc = (const usb_descriptor_t *)iter->cur; 1186 desc = (const usb_descriptor_t *)iter->cur;
1186 if (desc->bLength == 0) { 1187 if (desc->bLength == 0) {
1187 printf("usb_desc_iter_next: descriptor length = 0\n"); 1188 printf("usb_desc_iter_next: descriptor length = 0\n");
1188 return NULL; 1189 return NULL;
1189 } 1190 }
1190 iter->cur += desc->bLength; 1191 iter->cur += desc->bLength;
1191 if (iter->cur > iter->end) { 1192 if (iter->cur > iter->end) {
1192 printf("usb_desc_iter_next: descriptor length too large\n"); 1193 printf("usb_desc_iter_next: descriptor length too large\n");
1193 return NULL; 1194 return NULL;
1194 } 1195 }
1195 return desc; 1196 return desc;
1196} 1197}
1197 1198
1198usbd_status 1199usbd_status
1199usbd_get_string(usbd_device_handle dev, int si, char *buf) 1200usbd_get_string(usbd_device_handle dev, int si, char *buf)
1200{ 1201{
1201 return usbd_get_string0(dev, si, buf, 1); 1202 return usbd_get_string0(dev, si, buf, 1);
1202} 1203}
1203 1204
1204usbd_status 1205usbd_status
1205usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode) 1206usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode)
1206{ 1207{
1207 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; 1208 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
1208 usb_string_descriptor_t us; 1209 usb_string_descriptor_t us;
1209 char *s; 1210 char *s;
1210 int i, n; 1211 int i, n;
1211 u_int16_t c; 1212 u_int16_t c;
1212 usbd_status err; 1213 usbd_status err;
1213 int size; 1214 int size;
1214 1215
1215 buf[0] = '\0'; 1216 buf[0] = '\0';
1216 if (si == 0) 1217 if (si == 0)
1217 return (USBD_INVAL); 1218 return (USBD_INVAL);
1218 if (dev->quirks->uq_flags & UQ_NO_STRINGS) 1219 if (dev->quirks->uq_flags & UQ_NO_STRINGS)
1219 return (USBD_STALLED); 1220 return (USBD_STALLED);
1220 if (dev->langid == USBD_NOLANG) { 1221 if (dev->langid == USBD_NOLANG) {
1221 /* Set up default language */ 1222 /* Set up default language */
1222 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, 1223 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
1223 &size); 1224 &size);
1224 if (err || size < 4) { 1225 if (err || size < 4) {
1225 DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n")); 1226 DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
1226 dev->langid = 0; /* Well, just pick something then */ 1227 dev->langid = 0; /* Well, just pick something then */
1227 } else { 1228 } else {
1228 /* Pick the first language as the default. */ 1229 /* Pick the first language as the default. */
1229 dev->langid = UGETW(us.bString[0]); 1230 dev->langid = UGETW(us.bString[0]);
1230 } 1231 }
1231 } 1232 }
1232 err = usbd_get_string_desc(dev, si, dev->langid, &us, &size); 1233 err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
1233 if (err) 1234 if (err)
1234 return (err); 1235 return (err);
1235 s = buf; 1236 s = buf;
1236 n = size / 2 - 1; 1237 n = size / 2 - 1;
1237 if (unicode) { 1238 if (unicode) {
1238 for (i = 0; i < n; i++) { 1239 for (i = 0; i < n; i++) {
1239 c = UGETW(us.bString[i]); 1240 c = UGETW(us.bString[i]);
1240 if (swap) 1241 if (swap)
1241 c = (c >> 8) | (c << 8); 1242 c = (c >> 8) | (c << 8);
1242 s += wput_utf8(s, 3, c); 1243 s += wput_utf8(s, 3, c);
1243 } 1244 }
1244 *s++ = 0; 1245 *s++ = 0;
1245 } 1246 }
1246#ifdef COMPAT_30 1247#ifdef COMPAT_30
1247 else { 1248 else {
1248 for (i = 0; i < n; i++) { 1249 for (i = 0; i < n; i++) {
1249 c = UGETW(us.bString[i]); 1250 c = UGETW(us.bString[i]);
1250 if (swap) 1251 if (swap)
1251 c = (c >> 8) | (c << 8); 1252 c = (c >> 8) | (c << 8);
1252 *s++ = (c < 0x80) ? c : '?'; 1253 *s++ = (c < 0x80) ? c : '?';
1253 } 1254 }
1254 *s++ = 0; 1255 *s++ = 0;
1255 } 1256 }
1256#endif 1257#endif
1257 return (USBD_NORMAL_COMPLETION); 1258 return (USBD_NORMAL_COMPLETION);
1258} 1259}

cvs diff -r1.93.8.1.2.2 -r1.93.8.1.2.3 src/sys/dev/usb/usbdivar.h (switch to unified diff)

--- src/sys/dev/usb/usbdivar.h 2011/12/08 10:41:28 1.93.8.1.2.2
+++ src/sys/dev/usb/usbdivar.h 2011/12/08 22:04:56 1.93.8.1.2.3
@@ -1,323 +1,318 @@ @@ -1,323 +1,318 @@
1/* $NetBSD: usbdivar.h,v 1.93.8.1.2.2 2011/12/08 10:41:28 mrg Exp $ */ 1/* $NetBSD: usbdivar.h,v 1.93.8.1.2.3 2011/12/08 22:04:56 mrg Exp $ */
2/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/callout.h> 34#include <sys/callout.h>
35#include <sys/mutex.h> 35#include <sys/mutex.h>
36 36
37/* 37/*
38 * Discussion about locking in the USB code: 38 * Discussion about locking in the USB code:
39 * 39 *
40 * There are two locks presented by the host controller: the interrupt lock 40 * There are two locks presented by the host controller: the interrupt lock
41 * and the thread lock. The interrupt lock, either a spin or adaptive mutex, 41 * and the thread lock. The interrupt lock, either a spin or adaptive mutex,
42 * manages hardware state and anything else touched in an interrupt context. 42 * manages hardware state and anything else touched in an interrupt context.
43 * The thread lock has everything else.  43 * The thread lock has everything else.
44 * 44 *
45 * List of hardware interface methods, and which locks are held when each 45 * List of hardware interface methods, and which locks are held when each
46 * is called by this module: 46 * is called by this module:
47 * 47 *
48 * BUS METHOD INTR THREAD NOTES 48 * BUS METHOD INTR THREAD NOTES
49 * ----------------------- ------- ------- ------------------------- 49 * ----------------------- ------- ------- -------------------------
50 * open_pipe - - might want to take thread lock? 50 * open_pipe - - might want to take thread lock?
51 * soft_intr - - intr lock is taken sometimes, thread lock taken often, but nothing demanded? 51 * soft_intr - - intr lock is taken sometimes, thread lock taken often, but nothing demanded?
52 * do_poll - - might want to take thread lock? 52 * do_poll - - might want to take thread lock?
53 * allocm - - 53 * allocm - -
54 * freem - - 54 * freem - -
55 * allocx - - 55 * allocx - -
56 * freex - - 56 * freex - -
57 * get_locks - - Called at attach time 57 * get_locks - - Called at attach time
58 * 58 *
59 * PIPE METHOD INTR THREAD NOTES 59 * PIPE METHOD INTR THREAD NOTES
60 * ----------------------- ------- ------- ------------------------- 60 * ----------------------- ------- ------- -------------------------
61 * transfer - - 61 * transfer - -
62 * start - - 62 * start - -
63 * abort - - 63 * abort - -
64 * close - x 64 * close - x
65 * cleartoggle - - 65 * cleartoggle - -
66 * done - x 66 * done - x
67 * 67 *
68 * The above semantics are likely to change. 68 * The above semantics are likely to change.
69 *  69 *
70 */ 70 */
71 71
72/* From usb_mem.h */ 72/* From usb_mem.h */
73struct usb_dma_block; 73struct usb_dma_block;
74typedef struct { 74typedef struct {
75 struct usb_dma_block *block; 75 struct usb_dma_block *block;
76 u_int offs; 76 u_int offs;
77} usb_dma_t; 77} usb_dma_t;
78 78
79struct usbd_xfer; 79struct usbd_xfer;
80struct usbd_pipe; 80struct usbd_pipe;
81 81
82struct usbd_endpoint { 82struct usbd_endpoint {
83 usb_endpoint_descriptor_t *edesc; 83 usb_endpoint_descriptor_t *edesc;
84 int refcnt; 84 int refcnt;
85 int datatoggle; 85 int datatoggle;
86}; 86};
87 87
88struct usbd_bus_methods { 88struct usbd_bus_methods {
89 usbd_status (*open_pipe)(struct usbd_pipe *pipe); 89 usbd_status (*open_pipe)(struct usbd_pipe *pipe);
90 void (*soft_intr)(void *); 90 void (*soft_intr)(void *);
91 void (*do_poll)(struct usbd_bus *); 91 void (*do_poll)(struct usbd_bus *);
92 usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *, 92 usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *,
93 u_int32_t bufsize); 93 u_int32_t bufsize);
94 void (*freem)(struct usbd_bus *, usb_dma_t *); 94 void (*freem)(struct usbd_bus *, usb_dma_t *);
95 struct usbd_xfer * (*allocx)(struct usbd_bus *); 95 struct usbd_xfer * (*allocx)(struct usbd_bus *);
96 void (*freex)(struct usbd_bus *, struct usbd_xfer *); 96 void (*freex)(struct usbd_bus *, struct usbd_xfer *);
97 void (*get_locks)(struct usbd_bus *, 97 void (*get_locks)(struct usbd_bus *,
98 kmutex_t **, kmutex_t **); 98 kmutex_t **, kmutex_t **);
99}; 99};
100 100
101struct usbd_pipe_methods { 101struct usbd_pipe_methods {
102 usbd_status (*transfer)(usbd_xfer_handle xfer); 102 usbd_status (*transfer)(usbd_xfer_handle xfer);
103 usbd_status (*start)(usbd_xfer_handle xfer); 103 usbd_status (*start)(usbd_xfer_handle xfer);
104 void (*abort)(usbd_xfer_handle xfer); 104 void (*abort)(usbd_xfer_handle xfer);
105 void (*close)(usbd_pipe_handle pipe); 105 void (*close)(usbd_pipe_handle pipe);
106 void (*cleartoggle)(usbd_pipe_handle pipe); 106 void (*cleartoggle)(usbd_pipe_handle pipe);
107 void (*done)(usbd_xfer_handle xfer); 107 void (*done)(usbd_xfer_handle xfer);
108}; 108};
109 109
110#if 0 /* notyet */ 110#if 0 /* notyet */
111struct usbd_tt { 111struct usbd_tt {
112 struct usbd_hub *hub; 112 struct usbd_hub *hub;
113}; 113};
114#endif 114#endif
115 115
116struct usbd_port { 116struct usbd_port {
117 usb_port_status_t status; 117 usb_port_status_t status;
118 u_int16_t power; /* mA of current on port */ 118 u_int16_t power; /* mA of current on port */
119 u_int8_t portno; 119 u_int8_t portno;
120 u_int8_t restartcnt; 120 u_int8_t restartcnt;
121#define USBD_RESTART_MAX 5 121#define USBD_RESTART_MAX 5
122 u_int8_t reattach; 122 u_int8_t reattach;
123 struct usbd_device *device; /* Connected device */ 123 struct usbd_device *device; /* Connected device */
124 struct usbd_device *parent; /* The ports hub */ 124 struct usbd_device *parent; /* The ports hub */
125#if 0 125#if 0
126 struct usbd_tt *tt; /* Transaction translator (if any) */ 126 struct usbd_tt *tt; /* Transaction translator (if any) */
127#endif 127#endif
128}; 128};
129 129
130struct usbd_hub { 130struct usbd_hub {
131 usbd_status (*explore)(usbd_device_handle hub); 131 usbd_status (*explore)(usbd_device_handle hub);
132 void *hubsoftc; 132 void *hubsoftc;
133 usb_hub_descriptor_t hubdesc; 133 usb_hub_descriptor_t hubdesc;
134 struct usbd_port ports[1]; 134 struct usbd_port ports[1];
135}; 135};
136 136
137/*****/ 137/*****/
138 138
139struct usbd_bus { 139struct usbd_bus {
140 /* Filled by HC driver */ 140 /* Filled by HC driver */
141 void *hci_private; 141 void *hci_private;
142 const struct usbd_bus_methods *methods; 142 const struct usbd_bus_methods *methods;
143 u_int32_t pipe_size; /* size of a pipe struct */ 143 u_int32_t pipe_size; /* size of a pipe struct */
144 /* Filled by usb driver */ 144 /* Filled by usb driver */
145 kmutex_t *intr_lock; 145 kmutex_t *intr_lock;
146 kmutex_t *lock; 146 kmutex_t *lock;
147 struct usbd_device *root_hub; 147 struct usbd_device *root_hub;
148 usbd_device_handle devices[USB_MAX_DEVICES]; 148 usbd_device_handle devices[USB_MAX_DEVICES];
149 char needs_explore;/* a hub a signalled a change */ 149 char needs_explore;/* a hub a signalled a change */
150 char use_polling; 150 char use_polling;
151 device_t usbctl; 151 device_t usbctl;
152 struct usb_device_stats stats; 152 struct usb_device_stats stats;
153 int intr_context; 153 int intr_context;
154 u_int no_intrs; 154 u_int no_intrs;
155 int usbrev; /* USB revision */ 155 int usbrev; /* USB revision */
156#define USBREV_UNKNOWN 0 156#define USBREV_UNKNOWN 0
157#define USBREV_PRE_1_0 1 157#define USBREV_PRE_1_0 1
158#define USBREV_1_0 2 158#define USBREV_1_0 2
159#define USBREV_1_1 3 159#define USBREV_1_1 3
160#define USBREV_2_0 4 160#define USBREV_2_0 4
161#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" } 161#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
162 162
163 void *soft; /* soft interrupt cookie */ 163 void *soft; /* soft interrupt cookie */
164 bus_dma_tag_t dmatag; /* DMA tag */ 164 bus_dma_tag_t dmatag; /* DMA tag */
165}; 165};
166 166
167struct usbd_device { 167struct usbd_device {
168 struct usbd_bus *bus; /* our controller */ 168 struct usbd_bus *bus; /* our controller */
169 struct usbd_pipe *default_pipe; /* pipe 0 */ 169 struct usbd_pipe *default_pipe; /* pipe 0 */
170 u_int8_t address; /* device addess */ 170 u_int8_t address; /* device addess */
171 u_int8_t config; /* current configuration # */ 171 u_int8_t config; /* current configuration # */
172 u_int8_t depth; /* distance from root hub */ 172 u_int8_t depth; /* distance from root hub */
173 u_int8_t speed; /* low/full/high speed */ 173 u_int8_t speed; /* low/full/high speed */
174 u_int8_t self_powered; /* flag for self powered */ 174 u_int8_t self_powered; /* flag for self powered */
175 u_int16_t power; /* mA the device uses */ 175 u_int16_t power; /* mA the device uses */
176 int16_t langid; /* language for strings */ 176 int16_t langid; /* language for strings */
177#define USBD_NOLANG (-1) 177#define USBD_NOLANG (-1)
178 usb_event_cookie_t cookie; /* unique connection id */ 178 usb_event_cookie_t cookie; /* unique connection id */
179 struct usbd_port *powersrc; /* upstream hub port, or 0 */ 179 struct usbd_port *powersrc; /* upstream hub port, or 0 */
180 struct usbd_device *myhub; /* upstream hub */ 180 struct usbd_device *myhub; /* upstream hub */
181 struct usbd_port *myhsport; /* closest high speed port */ 181 struct usbd_port *myhsport; /* closest high speed port */
182 struct usbd_endpoint def_ep; /* for pipe 0 */ 182 struct usbd_endpoint def_ep; /* for pipe 0 */
183 usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */ 183 usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */
184 struct usbd_interface *ifaces; /* array of all interfaces */ 184 struct usbd_interface *ifaces; /* array of all interfaces */
185 usb_device_descriptor_t ddesc; /* device descriptor */ 185 usb_device_descriptor_t ddesc; /* device descriptor */
186 usb_config_descriptor_t *cdesc; /* full config descr */ 186 usb_config_descriptor_t *cdesc; /* full config descr */
187 const struct usbd_quirks *quirks; /* device quirks, always set */ 187 const struct usbd_quirks *quirks; /* device quirks, always set */
188 struct usbd_hub *hub; /* only if this is a hub */ 188 struct usbd_hub *hub; /* only if this is a hub */
189 int subdevlen; /* array length of following */ 189 int subdevlen; /* array length of following */
190 device_t *subdevs; /* sub-devices */ 190 device_t *subdevs; /* sub-devices */
191 int nifaces_claimed; /* number of ifaces in use */ 191 int nifaces_claimed; /* number of ifaces in use */
192}; 192};
193 193
194struct usbd_interface { 194struct usbd_interface {
195 struct usbd_device *device; 195 struct usbd_device *device;
196 usb_interface_descriptor_t *idesc; 196 usb_interface_descriptor_t *idesc;
197 int index; 197 int index;
198 int altindex; 198 int altindex;
199 struct usbd_endpoint *endpoints; 199 struct usbd_endpoint *endpoints;
200 void *priv; 200 void *priv;
201 LIST_HEAD(, usbd_pipe) pipes; 201 LIST_HEAD(, usbd_pipe) pipes;
202}; 202};
203 203
204struct usbd_pipe { 204struct usbd_pipe {
205 struct usbd_interface *iface; 205 struct usbd_interface *iface;
206 struct usbd_device *device; 206 struct usbd_device *device;
207 struct usbd_endpoint *endpoint; 207 struct usbd_endpoint *endpoint;
208 int refcnt; 208 int refcnt;
209 char running; 209 char running;
210 char aborting; 210 char aborting;
211 SIMPLEQ_HEAD(, usbd_xfer) queue; 211 SIMPLEQ_HEAD(, usbd_xfer) queue;
212 LIST_ENTRY(usbd_pipe) next; 212 LIST_ENTRY(usbd_pipe) next;
213 213
214 usbd_xfer_handle intrxfer; /* used for repeating requests */ 214 usbd_xfer_handle intrxfer; /* used for repeating requests */
215 char repeat; 215 char repeat;
216 int interval; 216 int interval;
217 217
218 kmutex_t *intr_lock; 
219 kmutex_t *lock; 
220 
221 /* Filled by HC driver. */ 218 /* Filled by HC driver. */
222 const struct usbd_pipe_methods *methods; 219 const struct usbd_pipe_methods *methods;
223}; 220};
224 221
225struct usbd_xfer { 222struct usbd_xfer {
226 struct usbd_pipe *pipe; 223 struct usbd_pipe *pipe;
227 void *priv; 224 void *priv;
228 void *buffer; 225 void *buffer;
229 kcondvar_t cv; 226 kcondvar_t cv;
230 u_int32_t length; 227 u_int32_t length;
231 u_int32_t actlen; 228 u_int32_t actlen;
232 u_int16_t flags; 229 u_int16_t flags;
233 u_int32_t timeout; 230 u_int32_t timeout;
234 usbd_status status; 231 usbd_status status;
235 usbd_callback callback; 232 usbd_callback callback;
236 volatile u_int8_t done; 233 volatile u_int8_t done;
237 u_int8_t busy_free; /* used for DIAGNOSTIC */ 234 u_int8_t busy_free; /* used for DIAGNOSTIC */
238#define XFER_FREE 0x46 235#define XFER_FREE 0x46
239#define XFER_BUSY 0x55 236#define XFER_BUSY 0x55
240#define XFER_ONQU 0x9e 237#define XFER_ONQU 0x9e
241 238
242 /* For control pipe */ 239 /* For control pipe */
243 usb_device_request_t request; 240 usb_device_request_t request;
244 241
245 /* For isoc */ 242 /* For isoc */
246 u_int16_t *frlengths; 243 u_int16_t *frlengths;
247 int nframes; 244 int nframes;
248 245
249 /* For memory allocation */ 246 /* For memory allocation */
250 struct usbd_device *device; 247 struct usbd_device *device;
251 usb_dma_t dmabuf; 248 usb_dma_t dmabuf;
252 249
253 u_int8_t rqflags; 250 u_int8_t rqflags;
254#define URQ_REQUEST 0x01 251#define URQ_REQUEST 0x01
255#define URQ_AUTO_DMABUF 0x10 252#define URQ_AUTO_DMABUF 0x10
256#define URQ_DEV_DMABUF 0x20 253#define URQ_DEV_DMABUF 0x20
257 254
258 SIMPLEQ_ENTRY(usbd_xfer) next; 255 SIMPLEQ_ENTRY(usbd_xfer) next;
259 256
260 void *hcpriv; /* private use by the HC driver */ 257 void *hcpriv; /* private use by the HC driver */
261 u_int8_t hcflags; /* private use by the HC driver */ 258 u_int8_t hcflags; /* private use by the HC driver */
262#define UXFER_ABORTING 0x01 /* xfer is aborting. */ 259#define UXFER_ABORTING 0x01 /* xfer is aborting. */
263#define UXFER_ABORTWAIT 0x02 /* abort completion is being awaited. */ 260#define UXFER_ABORTWAIT 0x02 /* abort completion is being awaited. */
264 kcondvar_t hccv; /* private use by the HC driver */ 261 kcondvar_t hccv; /* private use by the HC driver */
265 262
266 struct callout timeout_handle; 263 struct callout timeout_handle;
267}; 264};
268 265
269void usbd_init(void); 266void usbd_init(void);
270void usbd_finish(void); 267void usbd_finish(void);
271 268
272#if defined(USB_DEBUG) || defined(EHCI_DEBUG) 269#if defined(USB_DEBUG) || defined(EHCI_DEBUG)
273void usbd_dump_iface(struct usbd_interface *iface); 270void usbd_dump_iface(struct usbd_interface *iface);
274void usbd_dump_device(struct usbd_device *dev); 271void usbd_dump_device(struct usbd_device *dev);
275void usbd_dump_endpoint(struct usbd_endpoint *endp); 272void usbd_dump_endpoint(struct usbd_endpoint *endp);
276void usbd_dump_queue(usbd_pipe_handle pipe); 273void usbd_dump_queue(usbd_pipe_handle pipe);
277void usbd_dump_pipe(usbd_pipe_handle pipe); 274void usbd_dump_pipe(usbd_pipe_handle pipe);
278#endif 275#endif
279 276
280/* Routines from usb_subr.c */ 277/* Routines from usb_subr.c */
281int usbctlprint(void *, const char *); 278int usbctlprint(void *, const char *);
282void usb_delay_ms(usbd_bus_handle, u_int); 279void usb_delay_ms(usbd_bus_handle, u_int);
283usbd_status usbd_reset_port(usbd_device_handle, int, usb_port_status_t *); 280usbd_status usbd_reset_port(usbd_device_handle, int, usb_port_status_t *);
284usbd_status usbd_setup_pipe(usbd_device_handle dev, 281usbd_status usbd_setup_pipe(usbd_device_handle dev,
285 usbd_interface_handle iface, 282 usbd_interface_handle iface,
286 struct usbd_endpoint *, int, 283 struct usbd_endpoint *, int,
287 usbd_pipe_handle *pipe); 284 usbd_pipe_handle *pipe);
288usbd_status usbd_new_device(device_t, usbd_bus_handle, int, int, int, 285usbd_status usbd_new_device(device_t, usbd_bus_handle, int, int, int,
289 struct usbd_port *); 286 struct usbd_port *);
290usbd_status usbd_reattach_device(device_t, usbd_device_handle, 287usbd_status usbd_reattach_device(device_t, usbd_device_handle,
291 int, const int *); 288 int, const int *);
292 289
293void usbd_remove_device(usbd_device_handle, struct usbd_port *); 290void usbd_remove_device(usbd_device_handle, struct usbd_port *);
294int usbd_printBCD(char *, size_t, int); 291int usbd_printBCD(char *, size_t, int);
295usbd_status usbd_fill_iface_data(usbd_device_handle, int, int); 292usbd_status usbd_fill_iface_data(usbd_device_handle, int, int);
296void usb_free_device(usbd_device_handle); 293void usb_free_device(usbd_device_handle);
297 294
298usbd_status usb_insert_transfer(usbd_xfer_handle); 295usbd_status usb_insert_transfer(usbd_xfer_handle);
299void usb_transfer_complete(usbd_xfer_handle); 296void usb_transfer_complete(usbd_xfer_handle);
300int usb_disconnect_port(struct usbd_port *, device_t, int); 297int usb_disconnect_port(struct usbd_port *, device_t, int);
301 298
302/* Routines from usb.c */ 299/* Routines from usb.c */
303void usb_needs_explore(usbd_device_handle); 300void usb_needs_explore(usbd_device_handle);
304void usb_needs_reattach(usbd_device_handle); 301void usb_needs_reattach(usbd_device_handle);
305void usb_schedsoftintr(struct usbd_bus *); 302void usb_schedsoftintr(struct usbd_bus *);
306 303
307#define usbd_lock(m) if (m) { s = -1; mutex_enter(m); } else s = splusb() 
308#define usbd_unlock(m) if (m) { s = -1; mutex_exit(m); } else splx(s) 
309#define usbd_lock_pipe(p) do { \ 304#define usbd_lock_pipe(p) do { \
310 if ((p)->device->bus->lock) { \ 305 if ((p)->device->bus->lock) { \
311 s = -1; \ 306 s = -1; \
312 mutex_enter((p)->device->bus->lock); \ 307 mutex_enter((p)->device->bus->lock); \
313 } else \ 308 } else \
314 s = splusb(); \ 309 s = splusb(); \
315} while (0) 310} while (0)
316 311
317#define usbd_unlock_pipe(p) do { \ 312#define usbd_unlock_pipe(p) do { \
318 if ((p)->device->bus->lock) { \ 313 if ((p)->device->bus->lock) { \
319 s = -1; \ 314 s = -1; \
320 mutex_exit((p)->device->bus->lock); \ 315 mutex_exit((p)->device->bus->lock); \
321 } else \ 316 } else \
322 splx(s); \ 317 splx(s); \
323} while (0) 318} while (0)