Skip site navigation (1)Skip section navigation (2)
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>