summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhci.c
AgeCommit message (Collapse)Author
2020-04-03Move the responsibility of syncing the data buffers from the USBPatrick Wildt
stack into the USB controller driver, since not all of the xfers actually use DMA and some invalidations might even be harmful. The important part is to sync before handing the buffer to the controller, and to sync on a successful transfer before handing it back to the USB stack. For isoc transfers it's easier to sync the complete length of the transfer, since the buffer to flush is not filled in a contiguous fashion. For dwc2 there's a common point which takes care of the start of transfers from or to devices, where we can make sure that our buffers are synced. On completion, there's a common point before handing it off to the USB stack. For ehci there are three places which take care of the start of transfers from or to devices, where one already does the sync, while the two other places still need the sync. There are two completion handler (isoc and non-isoc), where one already has a comment asking for the need of a sync. The done handler for intr xfers does a sync that is not needed anymore after adding the sync in the completion handler. For ohci there are three places which take care of the start of transfers from or to devices, where all of them were still in need of the sync. For completion, there is one place for isoc xfers and two places for handling successful generic xfers. For uhci there are two places which take care of the start of transfers from or to device, where all of them were still in need of the sync. For completion, there is one handler for both isoc and non-isoc xfers where syncs need to occur. For xhci there are three places which take care of the start of transfers from or to device, where all of them were still in need of the sync. For completion, there is one handler for isoc and one for non-isoc xfers where syncs need to occur. With this we can revert the workaround that implicitly allocated buffers are COHERENT, since now control transfers fulfilled by the driver code (instead of the controller doing DMA) are not flushed into oblivion anymore. Tested by Janne Johansson with dwc2 (octeon) Tested by kettenis@ with xhci(4) (octeon) Tested by patrick@ with ehci(4) on a Cubox-i (armv7) Tested by patrick@ with xhci(4) on an i.MX8MQ (arm64) Tested by tobhe@ with dwc2 on a rPi 3b (arm64) ok kettenis@
2020-03-21Instead of passing the flags as part of a struct that's supposed to bePatrick Wildt
filled by the callee, change the usb_allocmem() API to take another argument for the flags. ok mpi@
2020-03-19Switch USB to use non-coherent buffers for data transfers. SincePatrick Wildt
the import in '99 all buffers allocated using usb_allocmem() have been mapped COHERENT. On some ARM SoCs, where the USB controller is not coherent with the caches, this means the buffers were mapped uncached. This drastically reduces the performance, especially on reads. We already added cache syncs before and after USB transfers, but so far those have essentially been no-ops. Since other drivers make use of the same allocation code, and those haven't been proven to have correct syncs, we can't just remove the COHERENT flag. This splits the allocation into coherent and non-coherent blocks. All drivers who call usb_allocmem() themselves now pass a flag to show they require coherent blocks. Onced verified that they also work fine without coherent, or once they have been refactored, we can remove this again. On a ure(4) connected to an i.MX8MQ, the receive performance is 10x as fast as before. The Raspberry Pi's ethernet receive speed doubled. Debugged using dt(4) Original diff from Marius Strobl Feedback from kettenis@ Tested on an i.MX8MQ (arm64) by patrick@ Tested on a Raspberry Pi (arm64) by tobhe@ Tested on an ERL (octeon) by Janne Johansson ok mpi@ gerhard@ tobhe@
2020-02-22use the UE_GET_XFERTYPE macro where applicableJasper Lievisse Adriaanse
ok mpi@
2019-11-27Convert infinite sleeps to tsleep_nsec(9).Martin Pieuchot
ok bluhm@
2019-03-12uhci: Fix delayed completions for isochronous transfers.Alexandre Ratchov
When an isochronous transfer of n frames is scheduled, the last frame i.e. frame number (n - 1) must be set to generate an interrupt. ok mpi
2019-03-11Add missing bus powered bit, from aalm@Martin Pieuchot
2019-01-31Fix compilation of amd64 kernel when optimization is disabled.Todd C. Miller
C99 inline semantics resulted in undefined symbols. OK deraadt@ mpi@ dlg@
2018-11-16free(9) sizes for interrupt & isochronous arrays.Martin Pieuchot
ok visa@
2017-05-15Replace remaining SPLUSBCHECK by a splsoftassert(IPL_SOFTUSB).Martin Pieuchot
USB is the last real user of IPL_SOFTNET.
2017-03-10Fix a use-after-free when sending root hub control transfers.Martin Pieuchot
*_root_ctrl_start() routines are synchronous and all end up calling usb_transfer_complete() in the non-error case. After calling this function it is unsafe to dereference ``xfer'' since the transfer callback has been called. So returning USBD_IN_PROGRESS is wrong in this case since transfers are always completed at this point. So return USBD_NORMAL_COMPLETION or the corresponding error code if something wrong happen.
2017-03-10Move per HC polling code to the stack.Martin Pieuchot
This code contains a use-after-free which be addressed in an upcoming diff. This fix xhci(4) polling mode. ok kettenis@
2017-02-02Remove dead assignments and now unused variables.Charles Longeau
Found by LLVM/Clang Static Analyzer. ok mpi@
2016-09-15all pools have their ipl set via pool_setipl, so fold it into pool_init.David Gwynne
the ioff argument to pool_init() is unused and has been for many years, so this replaces it with an ipl argument. because the ipl will be set on init we no longer need pool_setipl. most of these changes have been done with coccinelle using the spatch below. cocci sucks at formatting code though, so i fixed that by hand. the manpage and subr_pool.c bits i did myself. ok tedu@ jmatthew@ @ipl@ expression pp; expression ipl; expression s, a, o, f, m, p; @@ -pool_init(pp, s, a, o, f, m, p); -pool_setipl(pp, ipl); +pool_init(pp, s, a, ipl, f, m, p);
2015-06-26Revert previous. uvideo checks the transfered length of every frame andMartin Pieuchot
this break some devices. As found the hardway by Hugo Sastre via sobrado@
2015-06-22Do not update frame lengths to reflect what has really been transferedMartin Pieuchot
when an isochronous transfer is done. Frame lengths are just input values and no driver mess with them. ok ratchov@, jmatthew@
2015-03-14Remove some includes include-what-you-use claims don'tJonathan Gray
have any direct symbols used. Tested for indirect use by compiling amd64/i386/sparc64 kernels. ok tedu@ deraadt@
2014-12-19Use <sys/endian.h> instead of <machine/endian.h>Philip Guenther
ok dlg@ mpi@ bcook@ millert@ miod@
2014-12-17Avoid premature masking in the interrupt handler code that checks for removedMark Kettenis
hardware. ok mpi@, deraadt@
2014-12-09More malloc() -> mallocarray() in the kernel.Doug Hogan
ok deraadt@ tedu@
2014-10-30XFER_FREE is not used, ciao.Martin Pieuchot
2014-08-10Since USB xfer pools are accessed in interrupt context, initialize themMartin Pieuchot
with the correct ipl to prevent your CPU from locking against itself.
2014-08-10Set and check for XFER_BUSY in the common methods instead of doing itMartin Pieuchot
in every HC driver.
2014-08-05Only check if the abort transfer is the interrupt one if the pipe isMartin Pieuchot
opened with a callback. If a driver opens an interrupt pipe without callback function, like umct(4) does with one of its bulk in endpoints being reported as an interrupt endpoint, then we can end up aborting a transfer which is different from the interrupt one. Issue reported by Roberto E. Vargas Caballero, ok deraadt@
2014-07-12Protect the freelists of transfer descriptors with the appropriate splMartin Pieuchot
so that we do not end up allocating two times new descriptors. This happens if a thread finds an empty list, start allocating, got interrupted and the interrupt also finds an empty list. Fix an issue reported by Nils Frohberg. ok yuo@, pirofti@
2014-07-12add a size argument to free. will be used soon, but for now default to 0.Ted Unangst
after discussions with beck deraadt kettenis.
2014-07-10Do not set the bus dying flag during DVACT_DEACTIVATE otherwise theMartin Pieuchot
explore thread will not disconnect the root hub. The flag will be set before detaching the children, like it is done during a suspend- resume cycle. Fix a panic when unplugging a cardbus *hci(4).
2014-07-09Adds an optional bus function to set the address of a new device andMartin Pieuchot
explicitly set it when required. Right now xhci(4) does not need such function because it assigns addresses when the first pipe of a device is opened. ok yuo@, pirofti@
2014-06-04Clearing the data toggle bit only makes sense for endpoints that use it,Martin Pieuchot
since this function is optional get rid of the no-op ones. ok ratchov@
2014-06-04Use C99 initializers for pipe and bus methods.Martin Pieuchot
Apart from improving readability, this will help us reduce the number of no-op functions now that some of them are optional. ok ratchov@
2014-05-30Remove unused fields from the pipes.Martin Pieuchot
2014-05-25The default case in uhci_deactivate() was missing. Because of that,Martin Pieuchot
DVACT_QUIESCE was not passed to usb(4) and a new uhub(4) device was reattached at every resume. Problem reported by mlarkin@
2014-05-19unbreak the build when DIAGNOSTIC is not definedJonathan Gray
allows ramdisk kernels to build again
2014-05-18Do not pass an xfer pointer to the timeout routine checking for root hubMartin Pieuchot
status changes because it might be freed when detaching the root uhub(4). Also do not reschedule a timeout if the pipe is being aborted. Finally do not add more code to retrieve the 'bInterval' value of the root hub endpoint descriptor since this value is hardcoded in the uhci(4) driver.
2014-05-16Reduce the difference between HC drivers by always passing a genericMartin Pieuchot
usbd_xfer pointer to the routines processing finished transfers to make it crystal clear that the timeout and abort logic is the same everywhere.
2014-05-16There is no need to remember which usb(4) device is the child of an USBMartin Pieuchot
host controller because autoconf(9) already does it.
2014-05-09Plug an xfer leak when detaching root hubs.Martin Pieuchot
This leak is similar to the public xfer leak #1 that was affecting device interrupt pipes except that root hubs are rarely detached. Note that this xfer is never associated to any TD and is just used to indicate that some of the HC ports has changed status, so there is no need to flag it as "done" before completing it.
2014-05-08Plug one more xfer leak.Martin Pieuchot
Now that aborting interrupt pipes does not prevent us from freeing the associated xfer, make sure to flag this xfer as "done" even if there's no need to abort it in hardware.
2014-05-04Make use of usbd_xfer_isread() instead of rerolling it everywhere.Martin Pieuchot
This has the side effect of simplifying and reducing the differences between the various *hci_alloc_*_chain() functions since they are the principal place where we want to known if the transfer is a read or a write.
2014-04-29Get rid of the per-softc freelist of transfer descriptors and use aMartin Pieuchot
per-driver pool(9) instead.
2014-04-29Finally plug the public xfer leak #1 in our USB stack.Martin Pieuchot
Every call to usbd_abort_pipe() on an interrupt pipe would simply reset the intrxfer pointer, which would prevent usbd_close_pipe() to free it. Since we abort pipes in a lot of situations: when a device is detached, when a USB-to-serial adapter is closed, when an error occurs, when the machine is suspended, etc, this would result in hundreds of leaked xfers in most of my machines. xhci(4) is not affected, but you can't enable it right now since the stack is not ready :) While here put a KASSERT() to make sure drivers are only calling the interrupt abort method for intrxfer, if that's not the case, please let met know.
2014-04-27Start de-obfuscating the HC drivers.Martin Pieuchot
Since pipe methods have an xfer argument, always use it to get acces to various data structure (pipe, bus, device) instead of having a different way to get a pointer to these descriptors in every function. Also kill the {E,U}XFER() macro and use a consistent name accross all the methods for {e,u}hci_xfer.
2014-03-25Instead of matching root hubs with a custom address, that only worksMartin Pieuchot
because USB_START_ADDR is defined to 0 and the softc is M_ZERO'd, assume that root hubs are the only devices with a depth of 0. Root hubs can now happily be detached and reattached.
2014-03-15Unify the *hci_timeout() functions, there should be no functional change.Martin Pieuchot
2014-03-11Kill dead links.Martin Pieuchot
2014-03-07Transfer descriptors already have a back pointer to the USB deviceMartin Pieuchot
descriptor they are linked to, so no need to dereference their pipe pointer. Simplify a lot of affectations, no functional change. ok pirofti@
2014-03-07We already have three identical copies of the *hci_str() function,Martin Pieuchot
so merge them into usbd_str() to not introduce other copies with the upcoming HC drivers.
2013-12-09Mark a few functions with __unused.Brad Smith
ohci.c:193:1: error: unused function 'OREAD1' [-Werror,-Wunused-function] ohci.c:200:1: error: unused function 'OREAD2' [-Werror,-Wunused-function] uhci.c:256:1: error: unused function 'UREAD4' [-Werror,-Wunused-function] ok deraadt@
2013-11-09In our USB world, timeouts are in milliseconds, so use timeout_add_msec()Martin Pieuchot
coherently through all our controller drivers and kill the mstohz() macro. ok pirofti@
2013-11-07In polling mode since r1.101 we could end up dereferencing anMartin Pieuchot
uninitialized variable in case the transfer we were waiting for timed out; problem reported by oga@bitrig. So bring uhci_waitintr() in sync with its equivalent in ohci(4) and ehci(4), stop using an uhci_xfer, do not dereference it and set the correct status of the transfer.