| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
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: |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
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 | |
| @@ -219,44 +219,41 @@ usbd_open_pipe_intr(usbd_interface_handl | | | @@ -219,44 +219,41 @@ usbd_open_pipe_intr(usbd_interface_handl |
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 | |
229 | usbd_status | | 229 | usbd_status |
230 | usbd_close_pipe(usbd_pipe_handle pipe) | | 230 | usbd_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 | |
256 | usbd_status | | 253 | usbd_status |
257 | usbd_transfer(usbd_xfer_handle xfer) | | 254 | usbd_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; |
| @@ -309,28 +306,28 @@ usbd_transfer(usbd_xfer_handle xfer) | | | @@ -309,28 +306,28 @@ usbd_transfer(usbd_xfer_handle xfer) |
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. */ |
332 | usbd_status | | 329 | usbd_status |
333 | usbd_sync_transfer(usbd_xfer_handle xfer) | | 330 | usbd_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)); |
| @@ -828,29 +825,31 @@ usb_transfer_complete(usbd_xfer_handle x | | | @@ -828,29 +825,31 @@ usb_transfer_complete(usbd_xfer_handle x |
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 | |
| @@ -899,26 +898,28 @@ usb_insert_transfer(usbd_xfer_handle xfe | | | @@ -899,26 +898,28 @@ usb_insert_transfer(usbd_xfer_handle xfe |
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() */ |
906 | void | | 905 | void |
907 | usbd_start_next(usbd_pipe_handle pipe) | | 906 | usbd_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 | |