Commit Graph

52 Commits

Author SHA1 Message Date
iedowse
89a43922e8 Use a different task queue for host controller and peripheral driver
tasks. Since the host controllers rely on tasks to process transfer
timeouts, if a synchronous transfer from a driver was invoked from
a task and timed out, it would never complete because the single
task thread was stuck performing the synchronous transfer so couldn't
process the timeout.

This affected the axe, udav and ural drivers.

Problem hardware provided by:	guido
2006-10-19 01:15:58 +00:00
iedowse
d74ccdf4fe Fix compile in non-debug case. 2006-10-03 08:38:08 +00:00
iedowse
46a11df83f When changing the device address and max packet size in usbd_new_device(),
close and re-open the default pipe instead of relying on the host
controller driver to notice the changes. Remove the unreliable code
that attempted to update these fields while the pipe was active.
This fixes a case where the hardware could cache and continue to
use the old address, resulting in a "getting first desc failed"
error.

PR:		usb/103167
2006-10-03 01:13:26 +00:00
imp
28b388f478 More removing compatibility macros.
md5 still the same.

"Dave, stop.  I feel my mind slipping away." -- hal
2006-09-07 00:06:42 +00:00
imp
443562c936 s/Static/static/g
s/device_ptr_t/device_t/g

No md5 changes in the .o's

# Note to the md5 tracking club: $FreeBSD$ changes md5 after every commit
# so you need to checkout -kk to get $FreeBSD$ instead of the actual value
# of the keyword.
2006-09-06 23:44:25 +00:00
iedowse
56e4b3fcb6 If a zero-length bulk or interrupt transfer is requested then assume
USBD_FORCE_SHORT_XFER to ensure that we actually build and execute
a transfer. This means that the various alloc_sqtd_chain functions
will always construct a transfer, so it is safe to modify the
allocated descriptors on return. Previously there were cases where
a zero length transfer would cause a NULL dereference.

Reported by:	bp
2006-05-28 23:37:04 +00:00
iedowse
225f58e59f Use the limited scatter-gather capabilities of ehci, ohci and uhci
host controllers to avoid the need to allocate any multi-page
physically contiguous memory blocks. This makes it possible to use
USB devices reliably on low-memory systems or when memory is too
fragmented for contiguous allocations to succeed.

The USB subsystem now uses bus_dmamap_load() directly on the buffers
supplied by USB peripheral drivers, so this also avoids having to
copy data back and forth before and after transfers. The ehci and
ohci controllers support scatter/gather as long as the buffer is
contiguous in the virtual address space. For uhci the hardware
cannot handle a physical address discontinuity within a USB packet,
so it is necessary to copy small memory fragments at times.
2006-05-28 05:27:09 +00:00
iedowse
72d76006ec Attempt to follow the procedure described in section 4.10 of the
EHCI spec for linking in new qTDs into an asynchronous QH. This
requires that there is a qTD marked as not active and not halted
at the start of the QH's list, and the hardware will know to re-fetch
the qTD on each pass rather than just looking at the overlay qTD:

  "The host controller must be able to advance the queue from the
  Fetch QH state in order to avoid all hardware/software race
  conditions. This simple mechanism allows software to simply link
  qTDs to the queue head and activate them, then the host controller
  will always find them if/when they are reachable."

This is achieved by keeping an "inactivesqtd" entry on the QH list,
and re-using it each time as the start of the next transfer, and
allocating a new qTD to become the next inactivesqtd. Then a new
transfer can be activated by just setting its "active" flag, which
avoids all the previous messing with overlay qTD state in
ehci_set_qh_qtd().
2006-05-24 03:04:11 +00:00
phk
ef310efff8 Since DELAY() was moved, most <machine/clock.h> #includes have been
unnecessary.
2006-05-16 14:37:58 +00:00
iedowse
d4f801f4ab Oops - fix the build in the !USB_DEBUG case. 2006-03-18 17:57:34 +00:00
iedowse
d6749fb19b Let the EHCI hardware track the toggle state for bulk and interrupt
transfers. This fixes some cases where the software toggle tracking
was not doing the right thing. For example, a short transfer that
transferred 0 bytes of the requested qTD transfer size does cause
a toggle change, but the existing code was assuming it didn't.

Reported and tested by: pav
MFC after:	2 weeks
2006-03-18 13:55:16 +00:00
iedowse
6ec13e63ee Save and restore the data toggle value when a pipe to an endpoint
is closed and then reopened. This appears to be necessary now that
we no longer clear endpoint stalls every time a pipe is opened.
Previously we could assume an initial toggle value of zero because
the clear-stall operation resets the device's toggle state.

Reported by:	Holger Kipp
MFC after:	3 days
2006-02-26 02:57:57 +00:00
ariff
c11e59dff7 ehci_pci.c:
ATI EHCI controllers exhibit simmilar stall issues and require
	this dropped interrupts workaround. Be verbose about it.
ehci.c:
ehcivar.h:
	Slight change in comments to note about issues surrounding both
	VIA and ATI EHCI controllers.

Approved by:	iedowse
2006-01-16 19:23:59 +00:00
iedowse
08f12da89e Work around a problem seen on VIA EHCI controllers where occasionally
an interrupt appears to occur before the transfer has been marked
as completed. This caused umass transfers to get stuck, especially
when writing large files. The workaround sets up a timer that
rechecks for missed completed transfers if some operations are still
pending. Other suggested workarounds, such as performing a PCI read
immediately after acknowledging the interrupts, do not appear to
help.

Obtained from:	OpenBSD
2006-01-15 21:03:19 +00:00
iedowse
057cec0ceb Set sc_dying to 1 when detaching. In NetBSD and OpenBSD this was
done by the DVACT_DEACTIVATE case in *hci_activate(), but we don't
use that code in FreeBSD so it was never set.
2006-01-15 20:41:04 +00:00
iedowse
fa768cddb0 The ehci driver doesn't use the transfer `hcpriv' field, so don't
bother setting it to NULL in ehci_root_ctrl_done().
2006-01-15 20:32:52 +00:00
nyan
0fce92f5c4 Remove bus_{mem,p}io.h and related code for a micro-optimization on i386
and amd64.  The optimization is a trivial on recent machines.

Reviewed by:	-arch (imp, marcel, dfr)
2005-05-29 04:42:30 +00:00
iedowse
00f0fc2985 Remove trailing whitespace as per NetBSD's revision 1.91. Also
update the TODO comments to more closely match current reality.
2005-03-20 22:22:18 +00:00
iedowse
cc1d054d9c It was possible to have two threads concurrently aborting the same
transfer, which lead to panics or page faults. For example if a
transfer timed out, another thread could come along and attempt to
abort the same transfer while the timeout task was sleeping in
the *_abort_xfer() function.

Add an "aborting" flag to the private transfer state in each host
controller driver and use this to ensure that the abort is only
executed once. Also prioritise normal abort requests over timeouts
so that the callback is always given a status of USB_CANCELLED even
if the timeout-initiated abort began first.

The crashes caused by this bug were mainly reported in connection
with lpd printing to a USB printer.

PR:	usb/78208, usb/78986
2005-03-19 19:08:46 +00:00
iedowse
58c85262cd Set the split transaction interrupt C-mask correctly. This is the
final piece needed to make split transaction interrupt pipes work,
which I thought I had already committed.
2005-03-14 01:03:50 +00:00
iedowse
ebf9e3f896 The EHCI qTD token has a number of error status bits that are not
cleared if the host controller retries the transfer and is successful,
but we were interpreting these bits as indicating a fatal error.
Ignore these error bits, and instead use the HALTED bit to determine
if the transfer failed. Also update the USBD_STALLED detection to
ignore these bits.

Obtained from: OpenBSD
2005-03-13 23:48:17 +00:00
iedowse
83b23d92b1 Fix the arrangement of periodic QH tree to give the correct interval
between passes over a QH. Previously the accesses to a QH were
bunched together in time, so the interval was often much longer
than intended. This now appears to match the diagrams in the EHCI
spec, so remove the XXX comment.
2005-03-13 04:07:40 +00:00
iedowse
b7e105e8d5 Fix the silly bug that prevented most EHCI interrupt transfers from
ever working correctly: the code was linking the QHs together but
then immediately overwriting the "next" pointers. Oops. Also
initialise qh_endphub, since the EHCI spec says that we should
always set the pipe multiplier field to something sensible.

This appears to make basic split transactions work, so enable split
transactions for control, bulk and interrupt pipes (split isochronous
transfers are not yet implemented). It should now be possible to
use USB1 devices even when they are connected through a USB2 hub.
2005-03-08 02:47:18 +00:00
julian
747264f265 fix a "little-endian-big-endian confusion that luckily:
1/ doesn't matter on most of our architectures
2/ will never happen unless we start queueing multiple trasactions
to a single endpoint at one time (which we do not allow yet).
If anyone has a big_endian machine with EHCI they might check this
if they are having problems with EHCI but it's unlikely even there..

Submitted by:	Hans Petter Selasky <hselasky@c2i.net>
MFC after:	3 days
2005-01-09 23:49:45 +00:00
imp
4b319958e7 Start each of the license/copyright comments with /*-, minor shuffle of lines 2005-01-06 01:43:34 +00:00
julian
b625b904ff Fix comment. One of the two "Step 4" shuold be a "step 5" 2005-01-05 01:04:35 +00:00
julian
ad31868542 Rewrite ehci_abort_xfer() to use the method hinted at in the EHCI spec.
to remove a transaction from the async schedule. The previous method didn't
work well and led to the hardware writing to free'd buffers etc, as
it didn't always know that the transaction had been aborted.

Written after consultation with David Brownell who wrote the Linux
EHCI driver.

As part of this give the sqh structure a "previous" pointer.

MFC after:	1 week
2004-12-29 01:21:18 +00:00
julian
dbd1bd5be7 Slight change to formatting so that 'ctags' doesn't
give up on teh file half way through.. Might have been my
mistake earlier anyhow. No actual code change

MFC after:	5 days
2004-12-18 01:20:18 +00:00
phk
a410ae531e Make LINT compile.
When leaving functions for ddb use don't make them static: it makes
gcc think they are unused.

Shouldn't this be in #ifdef DDB anyway ?
2004-12-14 07:46:28 +00:00
julian
ccc36e1e1b A bunch more whitespace and formatting diff reductions for NetBSD.
Obtained from:	NetBSD
MFC after:	1 week
2004-12-14 04:47:24 +00:00
julian
cc6f359e9f Don't abandon ship just because the number of companions doesn't seem correct.
Obtained from:	NetBSD
MFC after:	1 week
2004-12-14 04:05:10 +00:00
julian
6846f0b857 Small formatting change..
Move a declaration to the same place as in NetBSD.

Obtained from:	NetBSD
MFC after:	1 week
2004-12-14 03:54:08 +00:00
iedowse
2d37c72581 Fix just the worst of the timeout race conditions that the previous
backed out commits were trying to address: when cancelling the timeout
callout, also cancel the abort_task event, since it is possible that
the timeout has already fired and set up an abort_task.
2004-11-16 00:48:27 +00:00
iedowse
b431db5c74 Back out my recent changes for timeout races, as there have been
reports of problems. The bug is probably that there are cases where
`xfer->timeout && !sc->sc_bus.use_polling' is not a suitable test
for an active timeout callout, so an explicit flag will be necessary.
Apologies for the breakage.
2004-11-12 02:57:35 +00:00
iedowse
3e514b9f37 Attempt to fix a number of race conditions in the handling of
transfer timeouts that typically cause a transfer to be completed
twice, resulting in panics and page faults:

 o A transfer completion interrupt could arrive while an abort_task
   event was set up, so the transfer would be aborted after it had
   completed. This is very easy to reproduce. Fix this by setting
   the transfer status to USBD_TIMEOUT before scheduling the
   abort_task so that the transfer completion code will ignore it.

 o The transfer completion code could execute concurrently with the
   timeout callout, leaving the callout blocked (e.g. waiting for
   Giant) while the transfer completion code runs. In this case,
   callout_stop() does not prevent the callout from running, so
   again the timeout code would run after the transfer was complete.
   Handle this case by checking the return value from callout_stop(),
   and ignoring the transfer if the callout could not be removed.

 o Finally, protect against a timeout callout occurring while a
   transfer is being aborted by another process. Here we arrange
   for the timeout processing to ignore the transfer, and use
   callout_drain() to ensure that the callout has really gone before
   completing the transfer.

This was tested by repeatedly performing USB transfers with a timeout
set to approximately the same as the normal transfer completion
time. In the PR below, apparently this occurred by accident with a
particular printer and the default timeout.

PR:		kern/71491
2004-11-09 20:51:32 +00:00
iedowse
d96345ff47 The ehci_dump() function shouldn't be declared static, as it is
just a convenience function to be called from debuggers that gets
compiled in when EHCI_DEBUG is defined. Move its declaration to
make this more obvious.
2004-11-03 15:12:18 +00:00
iedowse
cb7e434051 Merge recent USB2/EHCI related changes from NetBSD:
o Reduce the interrupt delay to 2 microframes.
 o Follow the spec more closely when updating the overlay qTD in the QH.
 o No need to generate an interrupt at the data part of a control
   transfer, it's generated by the status transfer.
 o Make sure to update the data toggle on short transfers.
 o Turn the printf about needing toggle update into a DPRINTF.
 o Keep track of what high speed port (if any) a device belongs to
   so we can set the transaction translator fields for the transfer.
 o Verbosely refuse to open low/full speed pipes that depend on
   unimplemented split transaction support.
 o Fix various typos in comments.

Obtained from:	NetBSD
2004-11-03 01:52:50 +00:00
iedowse
33771cab2b Save and restore state across suspend/resume events.
Submitted by:	David Gwynne <dlg@openbsd.org>
Obtained from:	OpenBSD (+ extra patches supplied by David)
2004-10-30 15:13:09 +00:00
iedowse
4d8c7e2781 Make the USB subsystem unloadable and detachable, though currently
a significant amount of memory may be leaked each time a host
controller is detached.
2004-08-02 15:37:35 +00:00
iedowse
5b775a536b Attempt to follow the correct procedure for synchronising with the
system BIOS to disable legacy device emulation as per the "EHCI
Extended Capability: Pre-OS to OS Handoff Synchronisation" section
of the EHCI spec. BIOSes that implement legacy emulation using SMIs
are supposed to disable the emulation when this procedure is performed.
2004-08-02 12:56:01 +00:00
iedowse
dd6baeae21 Implement basic support for EHCI interrupt pipes. This is unlikely
to be particularly correct or optimal, but it seems to be enough
to allow the attachment of USB2 hubs and USB2 devices connected via
USB2 hubs. None of the split transaction support is implemented in
our USB stack, so USB1 peripherals will definitely not work when
connected via USB2 hubs.
2004-08-01 18:47:42 +00:00
le
60a6d65c03 Diff reduction to NetBSD.
ehci.c rev. 1.69, author: mycroft
uhci.c rev. 1.179, author: mycroft
   hcpriv is not actually used here.  Remove references to it.

Obtained from:   NetBSD
2004-07-19 20:47:46 +00:00
le
2f3742942c MFNetBSD.
rev. 1.67, author: mycroft
   Fix a byte order error.

rev. 1.68, author: mycroft
   Adjust some silliness that was causing us to do extra work for
   "frame list rollover" interrupts, which we pretty much ignore.

Obtained from:   NetBSD
2004-07-15 19:25:06 +00:00
marcel
4c8ddc3ef6 Unbreak -O2 build: initialize nstatus to avoid uninitialized warning. 2004-07-03 02:10:52 +00:00
le
1a49f27fe6 MFNetBSD.
rev 1.66, author: mycroft
   Fix an endianness problem (EHCI_NULL was being double-swapped).

Obtained from:  NetBSD
2004-07-01 21:17:50 +00:00
le
cd721672a0 MFNetBSD ehci.c and ehcireg.h
ehci.c (1.55), ehcireg.h (1.16); author: mycroft
     Set the data toggle correctly, and use EHCI_QTD_DTC.  This fixes
     problems with my ALi-based drive enclosure (it works now, rather
     than failing to attach).  Also seems to work with a GL811-based
     enclosure and an ASUS enclosure with a CD-RW, on both Intel and
     NEC controllers.

     Note: The ALi enclosure is currently very SLOW, due to some issue
     with taking too long to notice that the QTD is complete.  This
     requires more investigation.

ehci.c (1.56); author: mycroft
     Failure to properly mask off UE_DIR_IN from the endpoint address
     was causing OHCI_ED_FORMAT_ISO and EHCI_QH_HRECL to get set
     spuriously, causing rather interesting lossage.

     Suddenly I get MUCH better performance with ehci...

ehci.c (1.58); author: mycroft
     Fix a stupid bug in ehci_check_intr() that caused use to try to
     complete a transaction that was still running.  Now ehci can
     handle multiple devices being active at once.

ehci.c (1.59); author: enami
     As the ehci_idone() now uses the variable `epipe'
     unconditionally, always declare it (in other words, make this
     file compile w/o EHCI_DEBUG).

ehci.c (1.60); author: mycroft
     Remove comment about the data toggle being borked.

ehci.c (1.61); author: mycroft
     Update comment.

ehci.c (1.62); author: mycroft
     Adjust a couple of comments to make it clear WTF is going on.

ehci.c (1.63); author: mycroft
     Fix an error in a debug printf().

ehci.c (1.64), ehcireg.h (1.17); author: mycroft
     Further cleanup of toggle handling.  Now that we use EHCI_QH_DTC,
     we don't need to fiddle with the TOGGLE bit in the overlay
     descriptor, so minimize how much we fuss with it.

Obtained from:   NetBSD
2004-06-26 00:52:37 +00:00
julian
14cb41a101 Diff reduction to NetBSD
Trying to figure out why this only works with SOME EHCI  controllers.

Obtained from:	NetBSD
MFC after:	1 week
2004-03-19 07:14:23 +00:00
joe
f6f94ac7fc MFNetBSD:
date: 2003/10/18 04:50:35;  author: simonb
    Remove assigned-to but otherwise unused variables.
    Remove unreachable break after return statements.
2003-11-10 00:20:52 +00:00
joe
59ab76006a MFNetBSD:
- remove the unnecessary elm arg from SIMPLEQ_REMOVE_HEAD().
  this mirrors the functionality of SLIST_REMOVE_HEAD() (the other
  singly-linked list type) and FreeBSD's STAILQ_REMOVE_HEAD()
2003-11-09 23:54:21 +00:00
obrien
c63dab466c Use __FBSDID().
Also some minor style cleanups.
2003-08-24 17:55:58 +00:00