Date: Sun, 23 May 2004 21:09:01 +0100 From: Ian Dowse <iedowse@maths.tcd.ie> To: current@freebsd.org Cc: iedowse@maths.tcd.ie Subject: USB patch for better bus_dma and detachment support Message-ID: <200405232109.aa46210@salmon.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
In case anybody is interested in testing or helping with this, there's a patch at http://people.freebsd.org/~iedowse/usb.diff that attempts to begin addressing a number of problems with our current USB code: o All data buffers were allocated using bus_dma as physically contiguous memory. All transfers involve a memory copy to/from these contiguous buffers, and the contiguous memory is never freed. Use of these buffers is also inefficient, so low-memory systems tend to quickly run out of usable physical memory. o USB host controllers cannot be detached, so for example, unplugging a cardbus USB device will cause a crash. Neither of these issues is completely solved by the patch, but most I/O now avoids the need for contiguous buffers by using bus_dmamap_load() on the virtual buffer, and the system seems to survive the removal of a cardbus OHCI/EHCI controller, though memory is probably leaked. A brief description of the current state of the bus_dma changes is below. Ian The existing usb_dma_t type and DMAADDR/KERNADDR macros are very closely tied in with memory allocation code in usb_mem.c and the assumption of contiguous memory. So for now I just defined a new structure to store information about loaded segments: +/* DMA-capable memory buffer. */ +struct usb_dma_mapping { + bus_dma_segment_t segs[USB_DMA_NSEG]; /* The physical segments. */ + int nsegs; /* Number of segments. */ + bus_dmamap_t map; /* DMA mapping. */ +}; Then usbd_transfer() does a bus_dmamap_load(), and the [eou]hci drivers have been modified to handle the physical segment information for transfer buffers instead of using DMAADDR(). In the case of UHCI, it is sometimes necessary to copy individual USB packets, since the UHCI controller requires that the transfer descriptor buffer is contiguous in physical memory, whereas OHCI and EHCI only need data to be contiguous in virtual memory. The handling of all the various special cases is quite intricate, so I'm sure there are still lots of bugs and missed cases.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200405232109.aa46210>