From owner-freebsd-current@FreeBSD.ORG Sun May 23 13:09:22 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7D6D216A4CE for ; Sun, 23 May 2004 13:09:22 -0700 (PDT) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id ACF3343D2D for ; Sun, 23 May 2004 13:09:21 -0700 (PDT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 23 May 2004 21:09:01 +0100 (BST) To: current@freebsd.org Date: Sun, 23 May 2004 21:09:01 +0100 From: Ian Dowse Message-ID: <200405232109.aa46210@salmon.maths.tcd.ie> cc: iedowse@maths.tcd.ie Subject: USB patch for better bus_dma and detachment support X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 May 2004 20:09:22 -0000 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.