ubt.c revision 1.10 1 1.10 dsainty /* $NetBSD: ubt.c,v 1.10 2004/01/04 05:47:43 dsainty Exp $ */
2 1.1 augustss
3 1.1 augustss /*
4 1.5 dsainty * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
5 1.1 augustss * All rights reserved.
6 1.1 augustss *
7 1.1 augustss * This code is derived from software contributed to The NetBSD Foundation
8 1.5 dsainty * by Lennart Augustsson (lennart (at) augustsson.net) and
9 1.5 dsainty * David Sainty (David.Sainty (at) dtsp.co.nz).
10 1.1 augustss *
11 1.1 augustss * Redistribution and use in source and binary forms, with or without
12 1.1 augustss * modification, are permitted provided that the following conditions
13 1.1 augustss * are met:
14 1.1 augustss * 1. Redistributions of source code must retain the above copyright
15 1.1 augustss * notice, this list of conditions and the following disclaimer.
16 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 augustss * notice, this list of conditions and the following disclaimer in the
18 1.1 augustss * documentation and/or other materials provided with the distribution.
19 1.1 augustss * 3. All advertising materials mentioning features or use of this software
20 1.1 augustss * must display the following acknowledgement:
21 1.1 augustss * This product includes software developed by the NetBSD
22 1.1 augustss * Foundation, Inc. and its contributors.
23 1.1 augustss * 4. Neither the name of The NetBSD Foundation nor the names of its
24 1.1 augustss * contributors may be used to endorse or promote products derived
25 1.1 augustss * from this software without specific prior written permission.
26 1.1 augustss *
27 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.1 augustss * POSSIBILITY OF SUCH DAMAGE.
38 1.1 augustss */
39 1.1 augustss
40 1.1 augustss #include <sys/cdefs.h>
41 1.10 dsainty __KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.10 2004/01/04 05:47:43 dsainty Exp $");
42 1.1 augustss
43 1.1 augustss #include <sys/param.h>
44 1.1 augustss #include <sys/systm.h>
45 1.1 augustss #include <sys/kernel.h>
46 1.5 dsainty #include <sys/malloc.h>
47 1.1 augustss #include <sys/device.h>
48 1.1 augustss #include <sys/lock.h>
49 1.1 augustss #include <sys/ioctl.h>
50 1.1 augustss #include <sys/conf.h>
51 1.1 augustss #include <sys/file.h>
52 1.1 augustss #include <sys/poll.h>
53 1.1 augustss #include <sys/select.h>
54 1.1 augustss #include <sys/proc.h>
55 1.1 augustss
56 1.5 dsainty #include <dev/usb/ubtreg.h>
57 1.1 augustss #include <dev/usb/usb.h>
58 1.1 augustss #include <dev/usb/usbdi.h>
59 1.1 augustss #include <dev/usb/usbdi_util.h>
60 1.1 augustss #include <dev/usb/usbdevs.h>
61 1.1 augustss
62 1.3 augustss #include <dev/bluetooth/bluetooth.h>
63 1.3 augustss
64 1.1 augustss #ifdef UBT_DEBUG
65 1.1 augustss #define DPRINTF(x) if (ubtdebug) logprintf x
66 1.1 augustss #define DPRINTFN(n,x) if (ubtdebug>(n)) logprintf x
67 1.7 augustss int ubtdebug = 49;
68 1.1 augustss #else
69 1.1 augustss #define DPRINTF(x)
70 1.1 augustss #define DPRINTFN(n,x)
71 1.1 augustss #endif
72 1.1 augustss
73 1.1 augustss /*
74 1.1 augustss * Protocol related definitions
75 1.1 augustss */
76 1.1 augustss
77 1.1 augustss struct ubt_softc {
78 1.1 augustss USBBASEDEVICE sc_dev;
79 1.1 augustss usbd_device_handle sc_udev;
80 1.3 augustss usbd_interface_handle sc_ctl_iface;
81 1.3 augustss usbd_interface_handle sc_isoc_iface;
82 1.1 augustss
83 1.5 dsainty /* Control */
84 1.5 dsainty usbd_pipe_handle sc_ctl_pipe;
85 1.5 dsainty usbd_xfer_handle sc_ctl_xfer;
86 1.5 dsainty u_int8_t *sc_ctl_buf;
87 1.5 dsainty
88 1.5 dsainty /* Events */
89 1.5 dsainty int sc_evt_addr;
90 1.5 dsainty usbd_pipe_handle sc_evt_pipe;
91 1.5 dsainty usbd_xfer_handle sc_evt_xfer;
92 1.5 dsainty u_int8_t *sc_evt_buf;
93 1.5 dsainty
94 1.5 dsainty /* ACL data (in) */
95 1.5 dsainty int sc_aclrd_addr;
96 1.5 dsainty usbd_pipe_handle sc_aclrd_pipe;
97 1.5 dsainty usbd_xfer_handle sc_aclrd_xfer;
98 1.5 dsainty u_int8_t *sc_aclrd_buf;
99 1.5 dsainty int sc_aclrd_running;
100 1.5 dsainty
101 1.5 dsainty /* ACL data (out) */
102 1.5 dsainty int sc_aclwr_addr;
103 1.5 dsainty usbd_pipe_handle sc_aclwr_pipe;
104 1.5 dsainty usbd_xfer_handle sc_aclwr_xfer;
105 1.5 dsainty u_int8_t *sc_aclwr_buf;
106 1.1 augustss
107 1.5 dsainty struct device *sc_child;
108 1.5 dsainty struct btframe_callback_methods const *sc_cb;
109 1.5 dsainty
110 1.1 augustss int sc_refcnt;
111 1.1 augustss char sc_dying;
112 1.1 augustss };
113 1.1 augustss
114 1.5 dsainty static int ubt_open(void *h, int flag, int mode, usb_proc_ptr p);
115 1.5 dsainty static int ubt_close(void *h, int flag, int mode, usb_proc_ptr p);
116 1.5 dsainty
117 1.6 dsainty static u_int8_t* ubt_alloc_control(void*, size_t, struct btframe_buffer**);
118 1.6 dsainty static int ubt_send_control(void*, struct btframe_buffer*, size_t);
119 1.6 dsainty
120 1.6 dsainty static u_int8_t* ubt_alloc_acldata(void*, size_t, struct btframe_buffer**);
121 1.6 dsainty static int ubt_send_acldata(void*, struct btframe_buffer*, size_t);
122 1.6 dsainty
123 1.6 dsainty static u_int8_t* ubt_alloc_scodata(void*, size_t, struct btframe_buffer**);
124 1.6 dsainty static int ubt_send_scodata(void*, struct btframe_buffer*, size_t);
125 1.5 dsainty
126 1.5 dsainty static int ubt_splraise(void);
127 1.5 dsainty
128 1.5 dsainty static void ubt_event_cb(usbd_xfer_handle, usbd_private_handle, usbd_status);
129 1.5 dsainty static void ubt_aclrd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status);
130 1.5 dsainty static void ubt_aclrd_request(struct ubt_softc *);
131 1.5 dsainty
132 1.5 dsainty static struct btframe_methods const ubt_methods = {
133 1.6 dsainty ubt_open, ubt_close,
134 1.6 dsainty {ubt_alloc_control, ubt_send_control},
135 1.6 dsainty {ubt_alloc_acldata, ubt_send_acldata},
136 1.6 dsainty {ubt_alloc_scodata, ubt_send_scodata},
137 1.10 dsainty ubt_splraise
138 1.5 dsainty };
139 1.5 dsainty
140 1.1 augustss USB_DECLARE_DRIVER(ubt);
141 1.1 augustss
142 1.1 augustss USB_MATCH(ubt)
143 1.1 augustss {
144 1.1 augustss USB_MATCH_START(ubt, uaa);
145 1.1 augustss usb_interface_descriptor_t *id;
146 1.1 augustss
147 1.1 augustss DPRINTFN(50,("ubt_match\n"));
148 1.1 augustss
149 1.1 augustss if (uaa->iface == NULL)
150 1.1 augustss return (UMATCH_NONE);
151 1.1 augustss
152 1.1 augustss id = usbd_get_interface_descriptor(uaa->iface);
153 1.1 augustss if (id != NULL &&
154 1.1 augustss id->bInterfaceClass == UICLASS_WIRELESS &&
155 1.1 augustss id->bInterfaceSubClass == UISUBCLASS_RF &&
156 1.1 augustss id->bInterfaceProtocol == UIPROTO_BLUETOOTH)
157 1.1 augustss return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
158 1.1 augustss return (UMATCH_NONE);
159 1.1 augustss }
160 1.1 augustss
161 1.1 augustss USB_ATTACH(ubt)
162 1.1 augustss {
163 1.1 augustss USB_ATTACH_START(ubt, sc, uaa);
164 1.1 augustss usbd_device_handle dev = uaa->device;
165 1.1 augustss usbd_interface_handle iface = uaa->iface;
166 1.3 augustss struct bt_attach_args bt;
167 1.5 dsainty usb_interface_descriptor_t const *id;
168 1.1 augustss char devinfo[1024];
169 1.5 dsainty usb_endpoint_descriptor_t const *ed;
170 1.1 augustss u_int8_t epcount;
171 1.1 augustss int i;
172 1.1 augustss
173 1.1 augustss DPRINTFN(10,("ubt_attach: sc=%p\n", sc));
174 1.1 augustss
175 1.1 augustss usbd_devinfo(dev, 0, devinfo);
176 1.1 augustss USB_ATTACH_SETUP;
177 1.1 augustss printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
178 1.1 augustss
179 1.1 augustss sc->sc_udev = dev;
180 1.3 augustss sc->sc_ctl_iface = iface;
181 1.1 augustss
182 1.5 dsainty /*
183 1.3 augustss * The control interface comes before the isoc interface
184 1.3 augustss * according to the spec, so we find it first.
185 1.3 augustss */
186 1.1 augustss epcount = 0;
187 1.1 augustss (void)usbd_endpoint_count(iface, &epcount);
188 1.5 dsainty
189 1.5 dsainty sc->sc_evt_addr = -1;
190 1.5 dsainty sc->sc_aclrd_addr = -1;
191 1.5 dsainty sc->sc_aclwr_addr = -1;
192 1.5 dsainty
193 1.1 augustss for (i = 0; i < epcount; i++) {
194 1.1 augustss ed = usbd_interface2endpoint_descriptor(iface, i);
195 1.1 augustss if (ed == NULL) {
196 1.1 augustss printf("%s: couldn't get ep %d\n",
197 1.1 augustss USBDEVNAME(sc->sc_dev), i);
198 1.1 augustss USB_ATTACH_ERROR_RETURN;
199 1.1 augustss }
200 1.5 dsainty
201 1.5 dsainty DPRINTFN(10, ("%s: addr=%d attr=%d\n", __func__,
202 1.5 dsainty (int)ed->bEndpointAddress,
203 1.5 dsainty (int)ed->bmAttributes));
204 1.5 dsainty
205 1.1 augustss if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
206 1.5 dsainty UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
207 1.5 dsainty sc->sc_evt_addr = ed->bEndpointAddress;
208 1.5 dsainty } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
209 1.5 dsainty UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
210 1.5 dsainty sc->sc_aclrd_addr = ed->bEndpointAddress;
211 1.1 augustss } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
212 1.1 augustss UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
213 1.5 dsainty sc->sc_aclwr_addr = ed->bEndpointAddress;
214 1.1 augustss }
215 1.1 augustss }
216 1.5 dsainty
217 1.5 dsainty if (sc->sc_evt_addr == -1 ||
218 1.5 dsainty sc->sc_aclrd_addr == -1 || sc->sc_aclwr_addr == -1) {
219 1.1 augustss printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
220 1.1 augustss USB_ATTACH_ERROR_RETURN;
221 1.1 augustss }
222 1.1 augustss
223 1.3 augustss /* XXX works because isoc comes after ctl */
224 1.3 augustss /* Grab isoc interface as well. */
225 1.3 augustss for (i = 0; i < uaa->nifaces; i++) {
226 1.3 augustss if (uaa->ifaces[i] == NULL)
227 1.3 augustss continue;
228 1.3 augustss id = usbd_get_interface_descriptor(uaa->ifaces[i]);
229 1.3 augustss if (id != NULL &&
230 1.3 augustss id->bInterfaceClass == UICLASS_WIRELESS &&
231 1.3 augustss id->bInterfaceSubClass == UISUBCLASS_RF &&
232 1.3 augustss id->bInterfaceProtocol == UIPROTO_BLUETOOTH) {
233 1.3 augustss sc->sc_isoc_iface = uaa->ifaces[i];
234 1.3 augustss uaa->ifaces[i] = NULL;
235 1.3 augustss }
236 1.3 augustss }
237 1.3 augustss
238 1.3 augustss printf("%s: has%s isoc data\n", USBDEVNAME(sc->sc_dev),
239 1.3 augustss sc->sc_isoc_iface != NULL ? "" : " no");
240 1.3 augustss
241 1.1 augustss usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
242 1.1 augustss USBDEV(sc->sc_dev));
243 1.1 augustss
244 1.5 dsainty bt.bt_methods = &ubt_methods;
245 1.5 dsainty bt.bt_cb = &sc->sc_cb;
246 1.8 dsainty bt.bt_handle = sc;
247 1.5 dsainty
248 1.3 augustss sc->sc_child = config_found(self, &bt, bt_print);
249 1.1 augustss
250 1.1 augustss USB_ATTACH_SUCCESS_RETURN;
251 1.1 augustss }
252 1.1 augustss
253 1.5 dsainty static void
254 1.5 dsainty ubt_abortdealloc(struct ubt_softc *sc)
255 1.5 dsainty {
256 1.5 dsainty DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
257 1.5 dsainty
258 1.5 dsainty if (sc->sc_evt_pipe != NULL) {
259 1.5 dsainty usbd_abort_pipe(sc->sc_evt_pipe);
260 1.5 dsainty usbd_close_pipe(sc->sc_evt_pipe);
261 1.5 dsainty sc->sc_evt_pipe = NULL;
262 1.5 dsainty }
263 1.5 dsainty if (sc->sc_evt_buf != NULL) {
264 1.5 dsainty free(sc->sc_evt_buf, M_USBDEV);
265 1.5 dsainty sc->sc_evt_buf = NULL;
266 1.5 dsainty }
267 1.5 dsainty if (sc->sc_aclrd_pipe != NULL) {
268 1.5 dsainty usbd_abort_pipe(sc->sc_aclrd_pipe);
269 1.5 dsainty usbd_close_pipe(sc->sc_aclrd_pipe);
270 1.5 dsainty sc->sc_aclrd_pipe = NULL;
271 1.5 dsainty }
272 1.5 dsainty if (sc->sc_aclwr_pipe != NULL) {
273 1.5 dsainty usbd_abort_pipe(sc->sc_aclwr_pipe);
274 1.5 dsainty usbd_close_pipe(sc->sc_aclwr_pipe);
275 1.5 dsainty sc->sc_aclwr_pipe = NULL;
276 1.5 dsainty }
277 1.5 dsainty if (sc->sc_aclrd_xfer != NULL) {
278 1.5 dsainty usbd_free_xfer(sc->sc_aclrd_xfer);
279 1.5 dsainty sc->sc_aclrd_xfer = NULL;
280 1.5 dsainty sc->sc_aclrd_buf = NULL;
281 1.5 dsainty }
282 1.5 dsainty if (sc->sc_aclwr_xfer != NULL) {
283 1.5 dsainty usbd_free_xfer(sc->sc_aclwr_xfer);
284 1.5 dsainty sc->sc_aclwr_xfer = NULL;
285 1.5 dsainty sc->sc_aclwr_buf = NULL;
286 1.5 dsainty }
287 1.5 dsainty }
288 1.5 dsainty
289 1.1 augustss USB_DETACH(ubt)
290 1.1 augustss {
291 1.1 augustss USB_DETACH_START(ubt, sc);
292 1.1 augustss int s;
293 1.1 augustss int rv = 0;
294 1.1 augustss
295 1.5 dsainty DPRINTF(("%s: sc=%p flags=%d\n", __func__, sc, flags));
296 1.1 augustss
297 1.1 augustss sc->sc_dying = 1;
298 1.5 dsainty
299 1.1 augustss /* Abort all pipes. Causes processes waiting for transfer to wake. */
300 1.5 dsainty ubt_abortdealloc(sc);
301 1.1 augustss
302 1.5 dsainty DPRINTFN(1, ("%s: waiting for USB detach\n", __func__));
303 1.1 augustss s = splusb();
304 1.1 augustss if (--sc->sc_refcnt >= 0) {
305 1.1 augustss /* Wait for processes to go away. */
306 1.1 augustss usb_detach_wait(USBDEV(sc->sc_dev));
307 1.1 augustss }
308 1.1 augustss splx(s);
309 1.5 dsainty DPRINTFN(1, ("%s: USB detach complete\n", __func__));
310 1.1 augustss
311 1.1 augustss if (sc->sc_child != NULL) {
312 1.5 dsainty DPRINTFN(1, ("%s: waiting for child detach\n", __func__));
313 1.1 augustss rv = config_detach(sc->sc_child, flags);
314 1.1 augustss sc->sc_child = NULL;
315 1.5 dsainty DPRINTFN(1, ("%s: child detach complete\n", __func__));
316 1.1 augustss }
317 1.1 augustss
318 1.1 augustss usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
319 1.1 augustss USBDEV(sc->sc_dev));
320 1.1 augustss
321 1.5 dsainty DPRINTFN(1, ("%s: driver detached\n", __func__));
322 1.5 dsainty
323 1.1 augustss return (rv);
324 1.1 augustss }
325 1.1 augustss
326 1.1 augustss int
327 1.1 augustss ubt_activate(device_ptr_t self, enum devact act)
328 1.1 augustss {
329 1.1 augustss struct ubt_softc *sc = (struct ubt_softc *)self;
330 1.1 augustss int error = 0;
331 1.1 augustss
332 1.1 augustss switch (act) {
333 1.1 augustss case DVACT_ACTIVATE:
334 1.1 augustss return (EOPNOTSUPP);
335 1.1 augustss break;
336 1.1 augustss
337 1.1 augustss case DVACT_DEACTIVATE:
338 1.1 augustss sc->sc_dying = 1;
339 1.1 augustss if (sc->sc_child != NULL)
340 1.1 augustss error = config_deactivate(sc->sc_child);
341 1.1 augustss break;
342 1.1 augustss }
343 1.1 augustss return (error);
344 1.5 dsainty }
345 1.5 dsainty
346 1.5 dsainty static int
347 1.5 dsainty ubt_open(void *h, int flag, int mode, usb_proc_ptr p)
348 1.5 dsainty {
349 1.5 dsainty struct ubt_softc *sc = h;
350 1.5 dsainty int error;
351 1.5 dsainty usbd_status err;
352 1.5 dsainty
353 1.5 dsainty DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
354 1.5 dsainty
355 1.5 dsainty sc->sc_evt_buf = malloc(BTHCI_EVENT_MAX_LEN, M_USBDEV, M_NOWAIT);
356 1.5 dsainty if (sc->sc_evt_buf == NULL) {
357 1.5 dsainty error = ENOMEM;
358 1.5 dsainty goto bad0;
359 1.5 dsainty }
360 1.5 dsainty
361 1.5 dsainty err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_evt_addr,
362 1.5 dsainty USBD_SHORT_XFER_OK, &sc->sc_evt_pipe,
363 1.5 dsainty sc, sc->sc_evt_buf, BTHCI_EVENT_MAX_LEN,
364 1.5 dsainty ubt_event_cb, UBT_EVENT_EP_INTERVAL);
365 1.5 dsainty if (err != USBD_NORMAL_COMPLETION) {
366 1.5 dsainty error = EIO;
367 1.5 dsainty goto bad1;
368 1.5 dsainty }
369 1.5 dsainty
370 1.5 dsainty err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclrd_addr,
371 1.5 dsainty 0, &sc->sc_aclrd_pipe);
372 1.5 dsainty if (err != USBD_NORMAL_COMPLETION) {
373 1.5 dsainty error = EIO;
374 1.5 dsainty goto bad2;
375 1.5 dsainty }
376 1.5 dsainty
377 1.5 dsainty err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_aclwr_addr,
378 1.5 dsainty 0, &sc->sc_aclwr_pipe);
379 1.5 dsainty if (err != USBD_NORMAL_COMPLETION) {
380 1.5 dsainty error = EIO;
381 1.5 dsainty goto bad3;
382 1.5 dsainty }
383 1.5 dsainty
384 1.5 dsainty sc->sc_ctl_xfer = usbd_alloc_xfer(sc->sc_udev);
385 1.5 dsainty if (sc->sc_ctl_xfer == NULL) {
386 1.5 dsainty error = ENOMEM;
387 1.5 dsainty goto bad4;
388 1.5 dsainty }
389 1.5 dsainty sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev);
390 1.5 dsainty if (sc->sc_aclrd_xfer == NULL) {
391 1.5 dsainty error = ENOMEM;
392 1.5 dsainty goto bad5;
393 1.5 dsainty }
394 1.5 dsainty sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev);
395 1.5 dsainty if (sc->sc_aclwr_xfer == NULL) {
396 1.5 dsainty error = ENOMEM;
397 1.5 dsainty goto bad6;
398 1.5 dsainty }
399 1.5 dsainty
400 1.5 dsainty /* Buffers */
401 1.5 dsainty sc->sc_ctl_buf = usbd_alloc_buffer(sc->sc_ctl_xfer,
402 1.5 dsainty BTHCI_COMMAND_MAX_LEN);
403 1.5 dsainty if (sc->sc_ctl_buf == NULL) {
404 1.5 dsainty error = ENOMEM;
405 1.5 dsainty goto bad7;
406 1.5 dsainty }
407 1.5 dsainty sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer,
408 1.5 dsainty BTHCI_ACL_DATA_MAX_LEN);
409 1.5 dsainty if (sc->sc_aclrd_buf == NULL) {
410 1.5 dsainty error = ENOMEM;
411 1.5 dsainty goto bad7;
412 1.5 dsainty }
413 1.5 dsainty sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer,
414 1.5 dsainty BTHCI_ACL_DATA_MAX_LEN);
415 1.5 dsainty if (sc->sc_aclwr_buf == NULL) {
416 1.5 dsainty error = ENOMEM;
417 1.5 dsainty goto bad7;
418 1.5 dsainty }
419 1.5 dsainty
420 1.5 dsainty /* Start reading */
421 1.5 dsainty ubt_aclrd_request(sc);
422 1.5 dsainty
423 1.5 dsainty return 0;
424 1.5 dsainty
425 1.5 dsainty bad7:
426 1.5 dsainty usbd_free_xfer(sc->sc_aclwr_xfer);
427 1.5 dsainty sc->sc_aclwr_xfer = NULL;
428 1.5 dsainty bad6:
429 1.5 dsainty usbd_free_xfer(sc->sc_aclrd_xfer);
430 1.5 dsainty sc->sc_aclrd_xfer = NULL;
431 1.5 dsainty bad5:
432 1.5 dsainty usbd_free_xfer(sc->sc_ctl_xfer);
433 1.5 dsainty sc->sc_ctl_xfer = NULL;
434 1.5 dsainty bad4:
435 1.5 dsainty usbd_close_pipe(sc->sc_aclwr_pipe);
436 1.5 dsainty sc->sc_aclwr_pipe = NULL;
437 1.5 dsainty bad3:
438 1.5 dsainty usbd_close_pipe(sc->sc_aclrd_pipe);
439 1.5 dsainty sc->sc_aclrd_pipe = NULL;
440 1.5 dsainty bad2:
441 1.5 dsainty usbd_close_pipe(sc->sc_evt_pipe);
442 1.5 dsainty sc->sc_evt_pipe = NULL;
443 1.5 dsainty bad1:
444 1.5 dsainty free(sc->sc_evt_buf, M_USBDEV);
445 1.5 dsainty sc->sc_evt_buf = NULL;
446 1.5 dsainty bad0:
447 1.5 dsainty return error;
448 1.5 dsainty }
449 1.5 dsainty
450 1.5 dsainty static int
451 1.5 dsainty ubt_close(void *h, int flag, int mode, usb_proc_ptr p)
452 1.5 dsainty {
453 1.5 dsainty struct ubt_softc *sc = h;
454 1.5 dsainty
455 1.5 dsainty DPRINTFN(0, ("%s: sc=%p\n", __func__, sc));
456 1.5 dsainty
457 1.5 dsainty ubt_abortdealloc(sc);
458 1.5 dsainty
459 1.5 dsainty return 0;
460 1.5 dsainty }
461 1.5 dsainty
462 1.6 dsainty static u_int8_t*
463 1.6 dsainty ubt_alloc_control(void *h, size_t len, struct btframe_buffer **buf)
464 1.6 dsainty {
465 1.6 dsainty struct ubt_softc *sc = h;
466 1.6 dsainty
467 1.6 dsainty /*
468 1.6 dsainty * We should be catching this earlier, but at the moment a
469 1.6 dsainty * user request can generate oversized allocations.
470 1.6 dsainty */
471 1.6 dsainty if (len > BTHCI_COMMAND_MAX_LEN)
472 1.6 dsainty return NULL;
473 1.6 dsainty
474 1.6 dsainty *buf = (struct btframe_buffer*)sc->sc_ctl_buf;
475 1.6 dsainty return sc->sc_ctl_buf;
476 1.6 dsainty }
477 1.6 dsainty
478 1.5 dsainty static int
479 1.6 dsainty ubt_send_control(void *h, struct btframe_buffer *buf, size_t len)
480 1.5 dsainty {
481 1.5 dsainty struct ubt_softc *sc = h;
482 1.5 dsainty usb_device_request_t req;
483 1.5 dsainty usbd_status status;
484 1.5 dsainty
485 1.5 dsainty DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
486 1.5 dsainty
487 1.6 dsainty #ifdef DIAGNOSTIC
488 1.6 dsainty if ((u_int8_t*)buf != sc->sc_ctl_buf)
489 1.6 dsainty panic("ubt_control() called with wrong buffer");
490 1.6 dsainty #endif
491 1.6 dsainty
492 1.5 dsainty if (sc->sc_dying)
493 1.5 dsainty return EIO;
494 1.5 dsainty
495 1.5 dsainty if (len < BTHCI_COMMAND_MIN_LEN || len > BTHCI_COMMAND_MAX_LEN)
496 1.5 dsainty return EINVAL;
497 1.5 dsainty
498 1.5 dsainty sc->sc_refcnt++;
499 1.5 dsainty
500 1.5 dsainty memset(&req, 0, sizeof(req));
501 1.5 dsainty req.bmRequestType = UT_WRITE_CLASS_DEVICE;
502 1.5 dsainty USETW(req.wLength, len);
503 1.5 dsainty
504 1.5 dsainty usbd_setup_default_xfer(sc->sc_ctl_xfer,
505 1.5 dsainty sc->sc_udev,
506 1.5 dsainty sc,
507 1.5 dsainty USBD_DEFAULT_TIMEOUT,
508 1.5 dsainty &req, sc->sc_ctl_buf, len,
509 1.5 dsainty USBD_SYNCHRONOUS | USBD_NO_COPY, NULL);
510 1.5 dsainty
511 1.5 dsainty status = usbd_transfer(sc->sc_ctl_xfer);
512 1.5 dsainty
513 1.5 dsainty if (--sc->sc_refcnt < 0)
514 1.5 dsainty usb_detach_wakeup(USBDEV(sc->sc_dev));
515 1.5 dsainty
516 1.5 dsainty if (status != USBD_NORMAL_COMPLETION)
517 1.5 dsainty return EIO;
518 1.5 dsainty
519 1.5 dsainty return 0;
520 1.5 dsainty }
521 1.5 dsainty
522 1.6 dsainty static u_int8_t*
523 1.6 dsainty ubt_alloc_acldata(void *h, size_t len, struct btframe_buffer **buf)
524 1.6 dsainty {
525 1.6 dsainty struct ubt_softc *sc = h;
526 1.6 dsainty
527 1.6 dsainty /*
528 1.6 dsainty * We should be catching this earlier, but at the moment a
529 1.6 dsainty * user request can generate oversized allocations.
530 1.6 dsainty */
531 1.6 dsainty if (len > BTHCI_ACL_DATA_MAX_LEN)
532 1.6 dsainty return NULL;
533 1.6 dsainty
534 1.6 dsainty *buf = (struct btframe_buffer*)sc->sc_aclwr_buf;
535 1.6 dsainty return sc->sc_aclwr_buf;
536 1.6 dsainty }
537 1.6 dsainty
538 1.5 dsainty static int
539 1.6 dsainty ubt_send_acldata(void *h, struct btframe_buffer *buf, size_t len)
540 1.5 dsainty {
541 1.5 dsainty struct ubt_softc *sc = h;
542 1.5 dsainty usbd_status status;
543 1.5 dsainty
544 1.5 dsainty DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
545 1.5 dsainty
546 1.6 dsainty #ifdef DIAGNOSTIC
547 1.6 dsainty if ((u_int8_t*)buf != sc->sc_aclwr_buf)
548 1.6 dsainty panic("ubt_sendacldata() called with wrong buffer");
549 1.6 dsainty #endif
550 1.6 dsainty
551 1.5 dsainty if (sc->sc_dying)
552 1.5 dsainty return EIO;
553 1.5 dsainty
554 1.5 dsainty if (len < BTHCI_ACL_DATA_MIN_LEN || len > BTHCI_ACL_DATA_MAX_LEN)
555 1.5 dsainty return EINVAL;
556 1.5 dsainty
557 1.5 dsainty sc->sc_refcnt++;
558 1.5 dsainty
559 1.5 dsainty usbd_setup_xfer(sc->sc_aclwr_xfer,
560 1.5 dsainty sc->sc_aclwr_pipe,
561 1.5 dsainty (usbd_private_handle)sc,
562 1.5 dsainty sc->sc_aclwr_buf, len,
563 1.5 dsainty USBD_SYNCHRONOUS | USBD_NO_COPY,
564 1.5 dsainty USBD_DEFAULT_TIMEOUT,
565 1.5 dsainty NULL);
566 1.5 dsainty
567 1.5 dsainty status = usbd_transfer(sc->sc_aclwr_xfer);
568 1.5 dsainty
569 1.5 dsainty if (--sc->sc_refcnt < 0)
570 1.5 dsainty usb_detach_wakeup(USBDEV(sc->sc_dev));
571 1.5 dsainty
572 1.5 dsainty if (status != USBD_NORMAL_COMPLETION)
573 1.5 dsainty return EIO;
574 1.5 dsainty
575 1.5 dsainty return 0;
576 1.5 dsainty }
577 1.5 dsainty
578 1.6 dsainty static u_int8_t*
579 1.6 dsainty ubt_alloc_scodata(void *h, size_t len, struct btframe_buffer **buf)
580 1.6 dsainty {
581 1.6 dsainty return NULL;
582 1.6 dsainty }
583 1.6 dsainty
584 1.5 dsainty static int
585 1.6 dsainty ubt_send_scodata(void *h, struct btframe_buffer *buf, size_t len)
586 1.5 dsainty {
587 1.5 dsainty struct ubt_softc *sc = h;
588 1.5 dsainty
589 1.5 dsainty DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
590 1.5 dsainty
591 1.5 dsainty if (sc->sc_dying)
592 1.5 dsainty return EIO;
593 1.5 dsainty
594 1.5 dsainty return ENXIO;
595 1.5 dsainty }
596 1.5 dsainty
597 1.5 dsainty static void
598 1.5 dsainty ubt_event_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
599 1.5 dsainty {
600 1.5 dsainty struct ubt_softc *sc = h;
601 1.5 dsainty void *buf;
602 1.5 dsainty u_int32_t size;
603 1.5 dsainty
604 1.5 dsainty DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc,
605 1.5 dsainty usbd_errstr(status)));
606 1.5 dsainty
607 1.5 dsainty if (status != USBD_NORMAL_COMPLETION || sc->sc_dying ||
608 1.5 dsainty sc->sc_child == NULL)
609 1.5 dsainty return;
610 1.5 dsainty
611 1.5 dsainty usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL);
612 1.5 dsainty
613 1.5 dsainty sc->sc_cb->bt_recveventdata(sc->sc_child, buf, (size_t)size);
614 1.5 dsainty }
615 1.5 dsainty
616 1.5 dsainty static void
617 1.5 dsainty ubt_aclrd_request(struct ubt_softc *sc)
618 1.5 dsainty {
619 1.5 dsainty usbd_status status;
620 1.5 dsainty int s;
621 1.5 dsainty
622 1.5 dsainty DPRINTFN(1,("%s: sc=%p\n", __func__, sc));
623 1.5 dsainty
624 1.5 dsainty if (sc->sc_dying)
625 1.5 dsainty return;
626 1.5 dsainty
627 1.5 dsainty s = splusb();
628 1.5 dsainty if (sc->sc_aclrd_running) {
629 1.5 dsainty splx(s);
630 1.5 dsainty return;
631 1.5 dsainty }
632 1.5 dsainty sc->sc_aclrd_running = 1;
633 1.5 dsainty splx(s);
634 1.6 dsainty
635 1.5 dsainty usbd_setup_xfer(sc->sc_aclrd_xfer, sc->sc_aclrd_pipe,
636 1.5 dsainty sc, sc->sc_aclrd_buf, BTHCI_ACL_DATA_MAX_LEN,
637 1.5 dsainty USBD_SHORT_XFER_OK | USBD_NO_COPY,
638 1.5 dsainty USBD_NO_TIMEOUT, ubt_aclrd_cb);
639 1.5 dsainty
640 1.5 dsainty status = usbd_transfer(sc->sc_aclrd_xfer);
641 1.9 dsainty
642 1.9 dsainty /* Cancellation is normal on device shutdown */
643 1.9 dsainty if (status == USBD_IN_PROGRESS || status == USBD_CANCELLED)
644 1.5 dsainty return;
645 1.5 dsainty
646 1.5 dsainty DPRINTFN(1,("%s: read request failed: %s\n", __func__,
647 1.5 dsainty usbd_errstr(status)));
648 1.5 dsainty
649 1.5 dsainty sc->sc_aclrd_running = 0;
650 1.10 dsainty /* XXX now what!? */
651 1.5 dsainty }
652 1.5 dsainty
653 1.5 dsainty static void
654 1.5 dsainty ubt_aclrd_cb(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status)
655 1.5 dsainty {
656 1.5 dsainty struct ubt_softc *sc = h;
657 1.5 dsainty void *buf;
658 1.5 dsainty u_int32_t size;
659 1.5 dsainty
660 1.5 dsainty DPRINTFN(1,("%s: sc=%p status=%s\n", __func__, sc,
661 1.5 dsainty usbd_errstr(status)));
662 1.5 dsainty
663 1.5 dsainty sc->sc_aclrd_running = 0;
664 1.5 dsainty
665 1.5 dsainty if (status != USBD_NORMAL_COMPLETION || sc->sc_dying ||
666 1.5 dsainty sc->sc_child == NULL)
667 1.5 dsainty return;
668 1.5 dsainty
669 1.5 dsainty usbd_get_xfer_status(xfer, NULL, &buf, &size, NULL);
670 1.5 dsainty
671 1.5 dsainty sc->sc_cb->bt_recvacldata(sc->sc_child, buf, (size_t)size);
672 1.5 dsainty
673 1.10 dsainty /* Re-issue the request */
674 1.10 dsainty if (!sc->sc_dying)
675 1.5 dsainty ubt_aclrd_request(sc);
676 1.5 dsainty }
677 1.5 dsainty
678 1.5 dsainty static int
679 1.5 dsainty ubt_splraise(void)
680 1.5 dsainty {
681 1.5 dsainty return splusb();
682 1.1 augustss }
683