From owner-freebsd-usb@FreeBSD.ORG Wed Dec 19 08:55:00 2012 Return-Path: Delivered-To: freebsd-usb@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 676AD8F7; Wed, 19 Dec 2012 08:55:00 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe04.c2i.net [212.247.154.98]) by mx1.freebsd.org (Postfix) with ESMTP id 4BBDB8FC12; Wed, 19 Dec 2012 08:54:58 +0000 (UTC) X-T2-Spam-Status: No, hits=-0.2 required=5.0 tests=ALL_TRUSTED, BAYES_50 Received: from [176.74.213.204] (account mc467741@c2i.net HELO laptop015.hselasky.homeunix.org) by mailfe04.swip.net (CommuniGate Pro SMTP 5.4.4) with ESMTPA id 358726235; Wed, 19 Dec 2012 09:54:51 +0100 From: Hans Petter Selasky To: Warner Losh Subject: Re: EHCI on armv6 with Write-Back caches Date: Wed, 19 Dec 2012 09:56:28 +0100 User-Agent: KMail/1.13.7 (FreeBSD/9.1-PRERELEASE; KDE/4.8.4; amd64; ; ) References: <20121218204931.5322922d@fubar.geek.nz> <201212182044.11326.hselasky@c2i.net> <1482FC19-720A-480A-BAD2-C8CD306E2E5F@bsdimp.com> In-Reply-To: <1482FC19-720A-480A-BAD2-C8CD306E2E5F@bsdimp.com> X-Face: 'mmZ:T{)),Oru^0c+/}w'`gU1$ubmG?lp!=R4Wy\ELYo2)@'UZ24N@d2+AyewRX}mAm; Yp |U[@, _z/([?1bCfM{_"B<.J>mICJCHAzzGHI{y7{%JVz%R~yJHIji`y>Y}k1C4TfysrsUI -%GU9V5]iUZF&nRn9mJ'?&>O MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201212190956.28609.hselasky@c2i.net> Cc: Oleksandr Tymoshenko , Andrew Turner , freebsd-usb@freebsd.org X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Dec 2012 08:55:00 -0000 Hi again, Different vendors use different naming conventions about sync operations. Maybe we should start defining some names and agree about that first? usb_pc_cpu_flush: This function is a system abstraction which is supposed to ensure that all CPU cached data for the given buffer is written to RAM before this function returns. usb_pc_cpu_invalidate: This function is a system abstraction which is supposed to ensure that all CPU cached data is cleared for the given buffer. These functions have been carefully added in all the USB drivers using DMA. Atomicity: I understand that the ARM hardware is not always compatible to this approach. 1) Flushing data to RAM is not a problem in any case? Do you agree? 2) Invalidating data is a problem, because invalidation can cause nearby data to be cleared aswell. So basically for those systems which are not handling this, flushing data means a lock of all CPU's until the flush/invalidate sequence is complete? Any dispute about this? If the CPU does not support certain features we cannot have an efficient system. It is like having a CPU which doesn't support switching off interrupt levels, like an 8-bit AVR. Then no matter how you twist it, you cannot postpone an interrupt to a software thread. Same goes for DMA support. If their DMA engine doesn't support byte granularity and possibility to flush/invalidate on a per-byte basis, then implement a global system lock to flush/invalidate data like I suggest, if this is not doable in the hardware by the CPU instruction set. The approach that I was recommended several years ago, is that I can pass a pointer to a buffer, which then can be transferred by the USB engine. This pointer can be any pointer except NULL. 3) As per my knowledge, using busdma to allocate a separate buffer for a 13- byte buffer, results in having a buffer of PAGE_SIZE bytes allocated. 4) BUSDMA experts: Please verify that the flags passed to bus_dmamap_sync() causes the exact behaviour has listed on top of this e-mail to occur in the following two functions in sys/dev/usb/usb_busdma.c void usb_pc_cpu_invalidate(struct usb_page_cache *pc) { if (pc->page_offset_end == pc->page_offset_buf) { /* nothing has been loaded into this page cache! */ return; } /* * TODO: We currently do XXX_POSTREAD and XXX_PREREAD at the * same time, but in the future we should try to isolate the * different cases to optimise the code. --HPS */ bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTREAD); bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD); } void usb_pc_cpu_flush(struct usb_page_cache *pc) { if (pc->page_offset_end == pc->page_offset_buf) { /* nothing has been loaded into this page cache! */ return; } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE); } --HPS