summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usbdi.c
diff options
context:
space:
mode:
authorjoe <joe@FreeBSD.org>2002-03-16 12:06:01 +0000
committerjoe <joe@FreeBSD.org>2002-03-16 12:06:01 +0000
commit622a58e08c7c4092c072fb433592a3d245a5c520 (patch)
tree179ca82ef7a1d5434adeeef8fd553c8a68043464 /sys/dev/usb/usbdi.c
parent688687434f7b4bf689cb76a2bfdbcbc2b34bf03d (diff)
downloadFreeBSD-src-622a58e08c7c4092c072fb433592a3d245a5c520.zip
FreeBSD-src-622a58e08c7c4092c072fb433592a3d245a5c520.tar.gz
Huge merge from NetBSD:
usbdi.c (1.61): =================================================================== revision 1.61 date: 2000/01/31 20:13:07; author: augustss; lines: +20 -4 Change the way the HC done method is invoked a little. =================================================================== usbdi.c (1.65): =================================================================== revision 1.65 date: 2000/03/08 15:34:10; author: augustss; lines: +4 -2 Get the status right when a polled transfer times out. =================================================================== ohci.c (1.79), uhci.c (1.89), uhcivar.h (1.24), usb_port.h (1.22), usbdivar.h (1.48): =================================================================== date: 2000/03/23 07:01:46; author: thorpej; New callout mechanism with two major improvements over the old timeout()/untimeout() API: - Clients supply callout handle storage, thus eliminating problems of resource allocation. - Insertion and removal of callouts is constant time, important as this facility is used quite a lot in the kernel. The old timeout()/untimeout() API has been removed from the kernel. =================================================================== uhci.c (1.80), usbdi.c (1.66): =================================================================== date: 2000/03/23 18:59:10; author: thorpej; Shake out some bugs from the callout changes. =================================================================== ohci.c (1.80), uhci.c (1.91), uhcivar.h (1.25), usb_port.h (1.23), usbdi.c (1.67), usbdivar.h (1.49): =================================================================== date: 2000/03/24 22:03:30; author: augustss; Some cleanup and renaming of the callouts used in USB drivers. =================================================================== uhci.c (1.92), uhcivar.h (1.26): =================================================================== date: 2000/03/24 22:57:58; author: augustss; Two major changes: Make each xfer have its own intr_info. This is necessary if we want to queue multiple xfers on an endpoint. This should get rid of the (mostly harmless) DIAGNOSTICs about intr_infos (not) being done. Change (again!) how xfers are aborted. Aborting a TD is a nightmare on the braindead UHCI controller. (Unless you stop the HC, thereby losing isoc traffic.) Hopefully I got it right this time. =================================================================== usbdivar.h (1.50): =================================================================== revision 1.50 date: 2000/03/25 00:10:19; author: augustss; lines: +4 -2 GC an unsued field and add some DIAGNOSTIC in xfer. =================================================================== ums.c: Use the callout functions instead of the timeout ones. uhci.c (1.93): =================================================================== revision 1.93 date: 2000/03/25 00:11:21; author: augustss; lines: +26 -1 Add more DIAGNOSTIC when aborting isoc. =================================================================== uhci.c (1.94), usbdivar.h (1.51): =================================================================== date: 2000/03/25 07:13:05; author: augustss; More DIAGNOSTIC. Initialize a callout handle I forgot. =================================================================== uhci.c (1.95): =================================================================== revision 1.95 date: 2000/03/25 07:23:12; author: augustss; Exp; lines: +24 -7 Improve uhci_dump_ii(). =================================================================== ohci.c (1.81), uhci.c (1.96), uhcivar.h (1.27), usb_subr.c (1.68), usbdi.c (1.68), usbdivar.h (1.52): =================================================================== date: 2000/03/25 18:02:33; author: augustss; Rename and move around callout handles to make it more sane. Add some DIAGNOSTIC. Fix buglet in isoc abort on UHCI. =================================================================== uhci.c (1.98): =================================================================== revision 1.98 date: 2000/03/27 07:39:48; author: augustss; lines: +12 -4 Make it compile without DIAGNOSTIC. =================================================================== uhci.c (1.99): =================================================================== revision 1.99 date: 2000/03/27 08:01:09; author: augustss; lines: +1 -5 Remove some debug nonsense. =================================================================== uhci.c (1.100): =================================================================== revision 1.100 date: 2000/03/27 09:41:36; author: augustss; lines: +13 -3 Don't mess with QH in bulk abort for the moment. =================================================================== uhci.c (1.102): =================================================================== revision 1.102 date: 2000/03/27 22:42:57; author: augustss; lines: +66 -26 Be a little more careful when aborting. Preallocate some TDs for large buffers. =================================================================== uhci.c (1.103): =================================================================== date: 2000/03/28 09:47:10; author: augustss; lines: +11 -1 Another patch for xfer abort... XXX The current xfer queueing and aborting semantics should really XXX be changed. It cannot be implemented in a sane way on UHCI. XXX One day when I have lots of time I'll redesign it... =================================================================== uhci.c (1.104): Correct a debug message. uhci.c (1.105): Be more defensive in a DIAGNOSTIC test. uhci.c (1.106): =================================================================== revision 1.106 date: 2000/03/29 01:49:13; author: augustss; lines: +14 -309 *SIGH* Revert back to the old method of aborting xfers. I had tested the new stuff for two months now, but as soon as I commited it the problems started to appear. Murphy, no doubt... =================================================================== usb_subr.c (1.70), usbdi.c (1.71), usbdivar.h (1.53): =================================================================== revision 1.70 date: 2000/03/29 01:45:20; author: augustss; lines: +2 -1 Do not accept new xfers for queuing while a pipe is aborting. ===================================================================
Diffstat (limited to 'sys/dev/usb/usbdi.c')
-rw-r--r--sys/dev/usb/usbdi.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 368b695..1ce6fd1 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.c,v 1.60 2000/01/19 00:23:58 augustss Exp $ */
+/* $NetBSD: usbdi.c,v 1.71 2000/03/29 01:45:21 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -237,6 +237,12 @@ usbd_close_pipe(pipe)
LIST_REMOVE(pipe, next);
pipe->endpoint->refcnt--;
pipe->methods->close(pipe);
+#if defined(__NetBSD__) && defined(DIAGNOSTIC)
+ if (callout_pending(&pipe->abort_handle)) {
+ callout_stop(&pipe->abort_handle);
+ printf("usbd_close_pipe: abort_handle pending");
+ }
+#endif
if (pipe->intrxfer != NULL)
usbd_free_xfer(pipe->intrxfer);
free(pipe, M_USB);
@@ -261,6 +267,9 @@ usbd_transfer(xfer)
#endif
xfer->done = 0;
+ if (pipe->aborting)
+ return (USBD_CANCELLED);
+
size = xfer->length;
/* If there is no buffer, allocate one. */
if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
@@ -314,8 +323,10 @@ usbd_transfer(xfer)
if (xfer->done)
break;
}
- if (!xfer->done)
+ if (!xfer->done) {
pipe->methods->abort(xfer);
+ xfer->status = USBD_TIMEOUT;
+ }
} else
/* XXX End hack XXX */
tsleep(xfer, PRIBIO, "usbsyn", 0);
@@ -381,6 +392,7 @@ usbd_alloc_xfer(dev)
if (xfer == NULL)
return (NULL);
xfer->device = dev;
+ usb_callout_init(xfer->timeout_handle);
DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
return (xfer);
}
@@ -392,6 +404,12 @@ usbd_free_xfer(xfer)
DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
usbd_free_buffer(xfer);
+#if defined(__NetBSD__) && defined(DIAGNOSTIC)
+ if (callout_pending(&xfer->timeout_handle)) {
+ callout_stop(&xfer->timeout_handle);
+ printf("usbd_free_xfer: timout_handle pending");
+ }
+#endif
xfer->device->bus->methods->freex(xfer->device->bus, xfer);
return (USBD_NORMAL_COMPLETION);
}
@@ -607,13 +625,11 @@ usbd_clear_endpoint_stall_async(pipe)
}
void
-usbd_clear_endpoint_toggle(pipe)
- usbd_pipe_handle pipe;
+usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
{
pipe->methods->cleartoggle(pipe);
}
-
usbd_status
usbd_endpoint_count(iface, count)
usbd_interface_handle iface;
@@ -752,6 +768,7 @@ usbd_ar_pipe(pipe)
usbd_dump_queue(pipe);
#endif
pipe->repeat = 0;
+ pipe->aborting = 1;
while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
pipe, xfer, pipe->methods));
@@ -759,6 +776,7 @@ usbd_ar_pipe(pipe)
pipe->methods->abort(xfer);
/* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
}
+ pipe->aborting = 0;
return (USBD_NORMAL_COMPLETION);
}
@@ -809,9 +827,6 @@ usb_transfer_complete(xfer)
}
}
- if (pipe->methods->done != NULL)
- pipe->methods->done(xfer);
-
if (!repeat) {
/* Remove request from queue. */
#ifdef DIAGNOSTIC
@@ -821,6 +836,8 @@ usb_transfer_complete(xfer)
#endif
SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next);
}
+ DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
+ repeat, SIMPLEQ_FIRST(&pipe->queue)));
/* Count completed transfers. */
++pipe->device->bus->stats.uds_requests
@@ -837,6 +854,15 @@ usb_transfer_complete(xfer)
if (xfer->callback)
xfer->callback(xfer, xfer->priv, xfer->status);
+#ifdef DIAGNOSTIC
+ if (pipe->methods->done != NULL)
+ pipe->methods->done(xfer);
+ else
+ printf("usb_transfer_complete: pipe->methods->done == NULL\n");
+#else
+ pipe->methods->done(xfer);
+#endif
+
if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
wakeup(xfer);
OpenPOWER on IntegriCloud