linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PCI DMA address
@ 2008-02-18 15:05 Ke
  2008-02-18 16:49 ` Jiri Slaby
  0 siblings, 1 reply; 4+ messages in thread
From: Ke @ 2008-02-18 15:05 UTC (permalink / raw)
  To: linux-kernel

Hello all,
      How can kernel get the PCI DMA address above 16MB or 64MB?
      I hope that the all PCI devices can use a dma address above
0x1000000 at a higher memory.

Thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PCI DMA address
  2008-02-18 15:05 PCI DMA address Ke
@ 2008-02-18 16:49 ` Jiri Slaby
  0 siblings, 0 replies; 4+ messages in thread
From: Jiri Slaby @ 2008-02-18 16:49 UTC (permalink / raw)
  To: Ke; +Cc: linux-kernel

On 02/18/2008 04:05 PM, Ke wrote:
> Hello all,
>       How can kernel get the PCI DMA address above 16MB or 64MB?

Documentation/DMA*

>       I hope that the all PCI devices can use a dma address above
> 0x1000000 at a higher memory.

Depends on how much is the device broken or what it can do.

IIRC you'll always get memory from DMA-zone for < ~0U dma_masks on kernels older 
than 2.6.(around 10). If you set dma_masks to < ~0U, you will probably (in the 
meaning, kernel will try to allocate from higher space and fall back to the 
dma-zone) get higher pages nowadays. However I don't know how far this applies 
also to systems with iommu in retrospective.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PCI DMA Address
  2004-05-01  5:19 ` PCI DMA Address Robert Hancock
@ 2004-05-01 13:47   ` Richard B. Johnson
  0 siblings, 0 replies; 4+ messages in thread
From: Richard B. Johnson @ 2004-05-01 13:47 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel

On Fri, 30 Apr 2004, Robert Hancock wrote:

> I don't think ioremap is what you want here. ioremap is used to map a PCI
> memory region on the card itself. To allocate a DMA region within system
> memory to transfer to, you want something like pci_alloc_consistent (but
> 128MB seems a rather large amount to use for that function, given that it
> allocates with GFP_ATOMIC..)
>
>
> ----- Original Message -----
> From: "ina" <celina.miranda@eazix.com>
> Newsgroups: fa.linux.kernel
> Sent: Thursday, April 29, 2004 12:37 AM
> Subject: PCI DMA Address
>
>
> > Hi,
> >
> > I need to create a driver for a PCI camera device that uses DMA to
> > transfer the captured images. The system that i use is an x86 board
> > that has 128M of RAM, I reserved the top of the physical RAM during
> > bootup by passing "mem=100".
> >
> > In my driver i claimed the reserved memory by using ioremap call:
> > void* pAdd = ioremap(0x6400000,(1280x1024))
> >

There is a global object called num_physpages. It is already exported
so it can be used by modules. This is the number of pages that the
kernel owns.

The DMA address is, thus, num_physpages * PAGE_SIZE. In versions
2.4.x..., some bad code writes after the last page so you really
need to use:

long bus_address = (num_physpages * PAGE_SIZE) + PAGE_SIZE;

... for the start of the memory you own. This is the bus address
that you will give to your DMA engine. This is also the address
that you would have user-space mmap() in MAP_FIXED, for user's to
read/write directly into that DMA buffer. You make an ioctl()
function that will allow the user code to get this value. You
use the actual values calculated with no conversion. Note that
the user-mode memory-maping needs to start on a PAGE_SIZE boundary
so if you break up this memory for your DMA scatter-list, you need
to use a whole page.

For kernel code to read/write to that space, you need:

	cookie = ioremap_nocache(bus_address, len);

Where cookie is NOT a pointer and needs to be saved to iounmap()
before unloading the module, and bus_address is the address
previously shown. Note that you also need to call request_mem_region()
so somebody else doesn't grab it later. It makes your allocation
show in /proc/iomem. You should not guess at 'len'. You can check
read/writability, once-per-page, to see where real memory ends.

There are macros that allow you to read/write bytes, shorts, longs
using the cookie. Inspection shows that they make a volatile
pointer out of the cookie by using another macro called __io_virt().

In principle, on ix86 machines only, you can make your own pointers
as:

   volatile unsigned char *cp =  __io_virt(cookie);
   volatile unsigned short *sp = __io_virt(cookie);
   volatile unsigned long *lp  = __io_virt(cookie);

The pointers must be of a volatile type to force the compiler
to actually de-reference the underlying data.

These hints will allow you to make a NON-PORTABLE, but straight-
forward module that can DMA to/from memory the user has mmapped.

The new "Linux way" is to use pci_alloc_consistant() and friends.
This is supposed to make things better. You judge.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5557.45 BogoMips).
            Note 96.31% of all statistics are fiction.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PCI DMA Address
       [not found] <a826e204.0404282237.6a6b28b0@posting.google.com>
@ 2004-05-01  5:19 ` Robert Hancock
  2004-05-01 13:47   ` Richard B. Johnson
  0 siblings, 1 reply; 4+ messages in thread
From: Robert Hancock @ 2004-05-01  5:19 UTC (permalink / raw)
  To: linux-kernel

I don't think ioremap is what you want here. ioremap is used to map a PCI
memory region on the card itself. To allocate a DMA region within system
memory to transfer to, you want something like pci_alloc_consistent (but
128MB seems a rather large amount to use for that function, given that it
allocates with GFP_ATOMIC..)


----- Original Message ----- 
From: "ina" <celina.miranda@eazix.com>
Newsgroups: fa.linux.kernel
Sent: Thursday, April 29, 2004 12:37 AM
Subject: PCI DMA Address


> Hi,
>
> I need to create a driver for a PCI camera device that uses DMA to
> transfer the captured images. The system that i use is an x86 board
> that has 128M of RAM, I reserved the top of the physical RAM during
> bootup by passing "mem=100".
>
> In my driver i claimed the reserved memory by using ioremap call:
> void* pAdd = ioremap(0x6400000,(1280x1024))
>
> This is the memory where the PCI device should DMA the captured data.
> My question is how do I tell the PCI device the DMA address? I know
> that inorder for the PCI device to access the DMA address correctly, i
> have to convert the return value of ioremap into a bus address. How do
> i do this? I already used:
> virt_to_phys(pAdd)
> but this doesn't seem to work.
>
> I read somewhere that the output of ioremap cannot be directly used
> for virt_to_phys function call, but I'm not really sure...
>
> Thanks,
> Ina


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-02-18 16:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-18 15:05 PCI DMA address Ke
2008-02-18 16:49 ` Jiri Slaby
     [not found] <a826e204.0404282237.6a6b28b0@posting.google.com>
2004-05-01  5:19 ` PCI DMA Address Robert Hancock
2004-05-01 13:47   ` Richard B. Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).