Re: MIPS: bus_dma(9) and cache problems

2009-10-29 Thread Jason Harmening
 1. code modifies data in block and this modification ends up in
cache and is not written back to memory
 2. right after this code calls bus_dmamap_sync for this buffer
and as a result cache invalidation is performed
 3. Cache function operates on cache line size-aligned addresses
and the block in question happens to share the same cache line
with the buffer. So modification made at step (1) is lost.

What sync operation are you doing?  At least for PREREAD or PREWRITE,
I'd expect any dirty cache lines to be flushed to RAM.  If this isn't
happening, then you may want to submit a bug report.

BTW, if you haven't already found it the MIPS sync code for 9-CURRENT is here:

http://fxr.watson.org/fxr/source/mips/mips/busdma_machdep.c#L760
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org


multi-seg bus_dmamem_alloc?

2009-10-21 Thread Jason Harmening
Hi everyone,

It seems like there are starting to be some drivers that need to
allocate large chunks of DMA-able memory, and since bus_dmamem_alloc()
on most architectures is always physically contiguous, it may not work
for them.

It seems like we could use the new sglist routines to help us here:

--Define 2 new functions:

 int bus_dmamem_alloc_sglist(bus_dma_tag_t dmat, size_t size,
struct sglist *sg, int flags, bus_dmamap_t *mapp)

 void bus_dmamem_free_sglist(bus_dma_tag_t dmat, struct sglist
*sg, bus_dmamap_t map);

--For sparc64 (or anywhere else we want to use an IOMMU):

 malloc() the buffer, feed it to sglist_build(), program the IOMMU
to meet the constraints in dmat--Isn't this what we already do for
sparc64, minus the sglist part?

--For direct-mapped architectures:

 If the constraints in dmat are lenient enough, do malloc() and
sglist_build().
 Otherwise, do contigmalloc(M_NOWAIT) in a loop, in which we try
to allocate as much of the buffer as possible.  Anytime an allocation
fails, we divide the allocation size by (roughly) 2 until the
allocation succeeds, and continue allocating until either we've
allocated enough space, or the allocation size drops below PAGE_SIZE,
or we exceed dmat-maxsegs.

--Some other things we'd need:
 --bus_dmamap_load_sglist()--I think jhb already did this as part
of the sglist work, at least for amd64
 --Structures in the busdma map to track allocated buffers so we
could free them later.
 --Are there lower-level calls we could make to just allocate the
physical pages instead of malloc()/contigmalloc()?  The kva mapping
for each allocated buffer segment isn't necessary.  A lot of drivers
would probably just want to mmap the sglist to userspace anyway.
 --Could we instead just integrate this multi-seg functionality
into the default bus_dmamem_alloc()?  We'd at least have to be able
map the physical segments into a contiguous kva area--we wouldn't
necessarily have to use an sglist in this case either.

Let me know if this idea has any potential--if it does, I'd love to
try implementing it:)

--Jason
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to freebsd-hackers-unsubscr...@freebsd.org


Re: bus_dmamem_alloc

2008-06-11 Thread Jason Harmening
On Wednesday 11 June 2008, John-Mark Gurney wrote:

 Why not use the SRAM for this?  That's what my driver does...  w/ 32k
 SRAM, it's more than enough for more programs...

The DMA programs (or at least a significant chunk of them) will get stored in 
the SRAM, if there's enough room.  That's often the case with just MPEG TS, 
but once you add analog video there's usually not enough room.


  For case 1), I malloc(9) the buffers and then feed them to busdma, since
  on most machines bus_dmamem_alloc just calls contigmalloc.  Use of
  malloc(9) is suboptimal as it may result in bounce buffering for
  non-IOMMU machines with large amounts of RAM.

 I prefer to do direct to use DMA as it saves on allocating a buffer in
 the kernel, and then coping the data from that buffer...

The driver actually supports both.  Kernel-mode buffers are mmap'ed, so there 
shouldn't be a copy.  Of course user-mode buffers can still bounce...

  1)  Would it be possible to provide a bus_dmamem_alloc overload that
  takes a size parameter?   We could call it bus_dmamem_alloc_size and have
  bus_dmamem_alloc just call bus_dmamem_alloc_size with dmat-maxsize to
  preserve source-level compatibility with existing drivers.

 It would be nice, but hasn't been something someone has gotten around to
 implementing yet...

That's probably my only real complaint here--it seems like dmat-maxsize 
should just be a restriction, not an allocation unit.  I don't want to sound 
ungrateful--busdma, at an API level at least, is great compared to what other 
OSes have to offer.


 I know that one person recently was working on Intel's VT IOMMU and I
 thought it was close to being committed, but I haven't been following
 the work...

That'll be awesome when it's ready.




___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


bus_dmamem_alloc

2008-06-07 Thread Jason Harmening
Hello,

I've written a FreeBSD driver for Conexant CX2388x-based PCI TV capture cards.  
Of course the driver uses busdma to be as machine-independent as possible.  
One problem I've encountered is that bus_dmamem_alloc is inadequate for my 
needs.  The CX2388x only understands 32-bit physical addreses, and the driver 
has two separate use cases for busdma:

1)  Data buffers: These buffers may be relatively large (a 640x480 RGB32 video 
frame is ~1.2M), and therefore it is desirable that these buffers not be 
physically contiguous.

2)  DMA program buffers:  The DMA engine on the CX2388x is controlled by 
special-purpose RISC instructions, usually stored in host memory, that 
provide information on, among other things, the physical layout of the data 
buffers, which enables handling of non-contiguous data buffers.  These 
programs are rarely more than a few pages in size, so for the sake of 
simplicity it is desirable that DMA program buffers be physically contiguous.

For case 1), I malloc(9) the buffers and then feed them to busdma, since on 
most machines bus_dmamem_alloc just calls contigmalloc.  Use of malloc(9) is 
suboptimal as it may result in bounce buffering for non-IOMMU machines with 
large amounts of RAM.

For case 2), I contigmalloc the DMA program buffers in the 32-bit physical 
address range and then feed them to busdma.  I don't use bus_dmamem_alloc 
here because it always allocates the maximum size specified in the 
bus_dma_tag_t.  Since the driver supports dynamic data buffer allocation and 
DMA program generation, DMA program sizes may vary significantly.  I 
therefore just create the bus_dma_tag_t with the maximum possible size for a 
DMA program buffer since I'd prefer not to have to re-create the tag every 
time the DMA program size changes.  But always allocating the maximum buffer 
size would be a huge waste of contiguous memory, so bus_dmamem_alloc is out 
of the question here too.   At the same time, use of contigmalloc is 
suboptimal as it may not be necessary to restrict the allocation to 32-bit 
physical addresses on IOMMU-equipped machines.  This is something that 
bus_dmamem_alloc could take care of, if only it supported a size parameter 
(as I believe the NetBSD version does).

So I have 3 questions:

1)  Would it be possible to provide a bus_dmamem_alloc overload that takes a 
size parameter?   We could call it bus_dmamem_alloc_size and have 
bus_dmamem_alloc just call bus_dmamem_alloc_size with dmat-maxsize to 
preserve source-level compatibility with existing drivers.

2) Are there currently any serious plans to have bus_dmamem_alloc perform 
multi-segment allocations on non-IOMMU machines?  It looks like NetBSD does 
this by reserving the physical segments and then stitching them together into 
a virtually contiguous range.  Is something like this feasible for FreeBSD?

3) Are there currently any serious plans to support IOMMUs on anything besides 
Sun machines?  The AMD AGP GART, PowerPC 970 DART, and Intel VT-d and AMD 
IOMMU all come to mind.

If any of these ideas sound feasible, I'd be more than willing to help 
research/implement/test them.

Thanks,
Jason

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: Native ATAPI MO driver

2005-10-31 Thread Jason Harmening
On Monday 24 October 2005 11:27, Søren Schmidt wrote:
 On 24/10/2005, at 3:49, Jason Harmening wrote:
  Hi,
 
  I have a 2.3G Fujitsu MO drive, and I've gotten tired of using
  atapicam to
  access it.  I'm thinking of writing a native ATAPI driver that
  could be added
  to the kernel through a configuration line like:
 
  device atapimo
 
  I've been doing a little work to see how feasible this is--the
  kernel already
  defines the ATA_ATAPI_TYPE_OPTICAL device type that is received
  from my drive
  during probing.  But ATA_ATAPI_TYPE_OPTICAL isn't actually used
  anywhere, and
  there is no driver that can actually recognize and attach to an
  ATAPI MO
  drive.
 
  I modified the atapifd driver (src/sys/dev/ata/atapi-fd.c) to also
  recognize
  ATA_ATAPI_TYPE_OPTICAL, and my drive was actually recognized during
  probing
  as afd0, but afd_attach returned an error.  It looks as if afd_sense
  () was
  failing, which I'm guessing is because ATAPI MO drives (or mine, at
  least)
  use a different capabilities page code and/or capabilities page
  structure
  than ATAPI floppies.  The atapi-fd driver uses 0x5 for its
  Capabilities and
  Mechanical Status page code, while everything else (atapi-cd,
  atapi-tape)
  uses 0x2a.  All three drivers have distinctly different structures
  for this
  page.
 
  So I'm wondering: do ATAPI MO drives use a capabilities page code/
  structure
  more like CD/DVD drives, or do they have their own unique ATAPI page
  structure?  If so, where can I find a document outlining the
  structure?
 
  I've found loads of documents detailing the page structure for CD/
  DVD drives,
  but nothing for MO drives (or floppies or tape drives for that
  matter).
 
  Also, beyond the capabilities page, are there any other special
  considerations
  I'd need to make for an MO driver?

 I did plan to write such  a driver back when, but HW seemed to have
 disappeared from all the vendors I've asked so it was pu ton the
 backburner.
 Anyhow I should have the docs somewhere so it should be possible to
 get this working...

 Søren Schmidt
 [EMAIL PROTECTED]


I finally managed to find some documentation from Fujitsu, and it turns out my 
drive (and older Fujitsu MO drives as well) use exactly the same capabilities 
page and page code that are already defined in atapi-fd.h.  The reason my 
drive was failing afd_sense() was that by default it returns an 8-byte block 
descriptor between the header and the actual page.  But there's a Disable 
Block Descriptor bit at byte1, bit3 of the MODE SENSE command that will 
prevent it from doing this if set.  It looks like the ATAPI floppies and 
earlier MO drives just ignored this bit and never returned the block 
descriptor.  So I just changed the second character in the command array in 
afd_sense() from 0 to 8, added ATA_ATAPI_TYPE_OPTICAL to afd_probe(), and the 
drive now works as afd0.

From what I've seen, the DBD bit seems to be a standard part of the MODE SENSE 
command block, so I don't think having it set will mess with any of the other 
drives supported by atapifd.  

Reading, writing, deleting, prevent/allow eject, and newfs (UFS2) all work 
with the drive as afd0--haven't tried anything else yet.  

Jason Harmening
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


Native ATAPI MO driver

2005-10-24 Thread Jason Harmening
Hi,

I have a 2.3G Fujitsu MO drive, and I've gotten tired of using atapicam to 
access it.  I'm thinking of writing a native ATAPI driver that could be added 
to the kernel through a configuration line like:

device atapimo

I've been doing a little work to see how feasible this is--the kernel already 
defines the ATA_ATAPI_TYPE_OPTICAL device type that is received from my drive 
during probing.  But ATA_ATAPI_TYPE_OPTICAL isn't actually used anywhere, and 
there is no driver that can actually recognize and attach to an ATAPI MO 
drive.  

I modified the atapifd driver (src/sys/dev/ata/atapi-fd.c) to also recognize 
ATA_ATAPI_TYPE_OPTICAL, and my drive was actually recognized during probing 
as afd0, but afd_attach returned an error.  It looks as if afd_sense() was 
failing, which I'm guessing is because ATAPI MO drives (or mine, at least) 
use a different capabilities page code and/or capabilities page structure 
than ATAPI floppies.  The atapi-fd driver uses 0x5 for its Capabilities and 
Mechanical Status page code, while everything else (atapi-cd, atapi-tape) 
uses 0x2a.  All three drivers have distinctly different structures for this 
page.

So I'm wondering: do ATAPI MO drives use a capabilities page code/structure 
more like CD/DVD drives, or do they have their own unique ATAPI page 
structure?  If so, where can I find a document outlining the structure?  

I've found loads of documents detailing the page structure for CD/DVD drives, 
but nothing for MO drives (or floppies or tape drives for that matter).

Also, beyond the capabilities page, are there any other special considerations 
I'd need to make for an MO driver?

Any answers would be really awesome.

Thanks,
Jason Harmening
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]