Date: Fri, 14 Nov 2008 20:20:32 +0200 From: Alexander Motin <mav@FreeBSD.org> To: Hans Petter Selasky <hselasky@c2i.net> Cc: Perforce Change Reviews <perforce@freebsd.org> Subject: Re: PERFORCE change 152649 for review - busdma problem Message-ID: <491DC170.7090409@FreeBSD.org> In-Reply-To: <200811141644.55773.hselasky@c2i.net> References: <200811080910.mA89AgTZ048172@repoman.freebsd.org> <200811140915.18846.hselasky@c2i.net> <491D8282.5060506@FreeBSD.org> <200811141644.55773.hselasky@c2i.net>
next in thread | previous in thread | raw e-mail | index | archive | help
Hans Petter Selasky wrote: > The thing is, you cannot specify how many bytes are on the first page which > can take a full physical address. It is assumed that after the page offset > wraps to zero a new page begins. > > Example: > > xxx: means data > > Virtual memory: > PG0 PG1 > | xxx|xxx | > > In busdma bounce buffer: > > PG0 PG1 > |xxx |xxx | > > You see there is a hole just before PG1, and it is impossible to tell the USB > hardware to skip this hole. I have seen very alike organization at SD host controller. There is SDMA mode, to which most existing controllers limited. There is just initial address and total data size can be specified. But on every page boundary controller stops transfer and allows software to load the address of the next data page. This technique is ugly and new specification provides new ADMA and ADMA2 modes which allow start address and length to be specified for every data segment. Now within my sdhci driver I have implemented page bouncing by myself, I am preallocating one aligned 4K page and reloading it with new data on each page boundary hit. There are many different data alignment bugs/limitations in that controllers, so such unperfect DMA operation also allows me to manage most of them. Linux sdhci driver instead just don't use this page boundary interrupt, operating with only one continuous memory block, completely disabling DMA on buggy controllers. If I understand correctly present busdma API (may be not), it does not allow you to be sure that both of segment boundaries will be aligned to the page boundaries. You are only specifying maximum number of segments and maximum segment size, so busdma, if it wish, may theoretically give you several small segments instead of single complete page. So if you are not ready to receive uneven sized segments, you probably should not specify that you want to receive more then 1 segment. May be it would be good to add some flag to the bus_dma_tag_create() which would signaled that hardware is able to handle segment boundaries only at page boundaries. It would also allow us to properly combine alignment and page boundary requirements. But it is surely not easy task. Correct me please if I am wrong. -- Alexander Motin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?491DC170.7090409>