diff options
author | joe <joe@FreeBSD.org> | 2002-03-16 12:06:01 +0000 |
---|---|---|
committer | joe <joe@FreeBSD.org> | 2002-03-16 12:06:01 +0000 |
commit | 622a58e08c7c4092c072fb433592a3d245a5c520 (patch) | |
tree | 179ca82ef7a1d5434adeeef8fd553c8a68043464 /sys/dev/usb/usbdi.c | |
parent | 688687434f7b4bf689cb76a2bfdbcbc2b34bf03d (diff) | |
download | FreeBSD-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.c | 42 |
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); |