public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* bus_to_virt equivalent
@ 2005-11-07 23:52 Anil kumar
  2005-11-08  1:37 ` Matthew Wilcox
  0 siblings, 1 reply; 4+ messages in thread
From: Anil kumar @ 2005-11-07 23:52 UTC (permalink / raw)
  To: linux-kernel, linux-scsi

Hi,

I am trying to port bus_to_virt and virt_to_bus to the
DMA-mapping scheme.
I found a way to move virt_to_bus() as follows:
page = virt_to_page(cmd->request_buffer);
offset = (unsigned long)address & ~PAGE_MASK;
dma_addr_t addr = pci_map_page(dev, page, offset,
size,direction);

But now I want to get virtual address for dma_addr_t.

Any help is greatly appreciated.

with regards,
  Anil


		
__________________________________ 
Yahoo! FareChase: Search multiple travel sites in one click.
http://farechase.yahoo.com

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

* Re: bus_to_virt equivalent
  2005-11-07 23:52 bus_to_virt equivalent Anil kumar
@ 2005-11-08  1:37 ` Matthew Wilcox
  2005-11-08 22:47   ` Anil kumar
  0 siblings, 1 reply; 4+ messages in thread
From: Matthew Wilcox @ 2005-11-08  1:37 UTC (permalink / raw)
  To: Anil kumar; +Cc: linux-kernel, linux-scsi

On Mon, Nov 07, 2005 at 03:52:47PM -0800, Anil kumar wrote:
> Hi,
> 
> I am trying to port bus_to_virt and virt_to_bus to the
> DMA-mapping scheme.
> I found a way to move virt_to_bus() as follows:
> page = virt_to_page(cmd->request_buffer);
> offset = (unsigned long)address & ~PAGE_MASK;
> dma_addr_t addr = pci_map_page(dev, page, offset,
> size,direction);
> 
> But now I want to get virtual address for dma_addr_t.

Did you *read* DMA-mapping.txt?

  Drivers converted fully to this interface should not use virt_to_bus
  any longer, nor should they use bus_to_virt. Some drivers have to
  be changed a little bit, because
  *there is no longer an equivalent to bus_to_virt in the dynamic
  DMA mapping scheme*
  - you have to always store the DMA addresses returned by the
  pci_alloc_consistent, pci_pool_alloc, and pci_map_single calls
  (pci_map_sg stores them in the scatterlist itself if the platform
  supports dynamic DMA mapping in hardware) in your driver structures
  and/or in the card registers.

The reason for this is that there may be many physical addresses which
correspond to the same bus address.  For example (this is on an HP rx8620)
the bus address c001b000 maps to 00000f000001b000 for device 00:03.0,
00000f010001b000 for device 40:03.0, 00000f020001b000 for device 80:03.0
and 00000f030001b000 for device c0:03.0.

Now, maybe we should add a function:

unsigned long device_bus_addr_to_phys(struct device *dev, dma_addr_t handle);

but we don't have one yet.  So you have to follow the rules above.

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

* Re: bus_to_virt equivalent
  2005-11-08  1:37 ` Matthew Wilcox
@ 2005-11-08 22:47   ` Anil kumar
  2005-11-08 22:53     ` Russell King
  0 siblings, 1 reply; 4+ messages in thread
From: Anil kumar @ 2005-11-08 22:47 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-kernel, linux-scsi

Hi Matthew,

Thanks for the reply.
I can store the returned dma_addr from
pci_map_sg/single or pci_map_page in a driver
structure.

struct page *page =
virt_to_page(Cmnd->request_buffer);
                unsigned long offset = ((unsigned
long)Cmnd->request_buffer &
                                        ~PAGE_MASK);
                dma_addr_t busaddr =
pci_map_page(hostdata->pci_dev,
                                                 
page, offset,
                                                 
Cmnd->request_bufflen,
                                                 
scsi_to_pci_dma_dir(Cmnd->sc_data_direction));

But how do I convert this returned "busaddr" into a
virtual addr?

regards,
Anil

--- Matthew Wilcox <matthew@wil.cx> wrote:

> On Mon, Nov 07, 2005 at 03:52:47PM -0800, Anil kumar
> wrote:
> > Hi,
> > 
> > I am trying to port bus_to_virt and virt_to_bus to
> the
> > DMA-mapping scheme.
> > I found a way to move virt_to_bus() as follows:
> > page = virt_to_page(cmd->request_buffer);
> > offset = (unsigned long)address & ~PAGE_MASK;
> > dma_addr_t addr = pci_map_page(dev, page, offset,
> > size,direction);
> > 
> > But now I want to get virtual address for
> dma_addr_t.
> 
> Did you *read* DMA-mapping.txt?
> 
>   Drivers converted fully to this interface should
> not use virt_to_bus
>   any longer, nor should they use bus_to_virt. Some
> drivers have to
>   be changed a little bit, because
>   *there is no longer an equivalent to bus_to_virt
> in the dynamic
>   DMA mapping scheme*
>   - you have to always store the DMA addresses
> returned by the
>   pci_alloc_consistent, pci_pool_alloc, and
> pci_map_single calls
>   (pci_map_sg stores them in the scatterlist itself
> if the platform
>   supports dynamic DMA mapping in hardware) in your
> driver structures
>   and/or in the card registers.
> 
> The reason for this is that there may be many
> physical addresses which
> correspond to the same bus address.  For example
> (this is on an HP rx8620)
> the bus address c001b000 maps to 00000f000001b000
> for device 00:03.0,
> 00000f010001b000 for device 40:03.0,
> 00000f020001b000 for device 80:03.0
> and 00000f030001b000 for device c0:03.0.
> 
> Now, maybe we should add a function:
> 
> unsigned long device_bus_addr_to_phys(struct device
> *dev, dma_addr_t handle);
> 
> but we don't have one yet.  So you have to follow
> the rules above.
> 



	
		
__________________________________ 
Yahoo! Mail - PC Magazine Editors' Choice 2005 
http://mail.yahoo.com

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

* Re: bus_to_virt equivalent
  2005-11-08 22:47   ` Anil kumar
@ 2005-11-08 22:53     ` Russell King
  0 siblings, 0 replies; 4+ messages in thread
From: Russell King @ 2005-11-08 22:53 UTC (permalink / raw)
  To: Anil kumar; +Cc: Matthew Wilcox, linux-kernel, linux-scsi

On Tue, Nov 08, 2005 at 02:47:00PM -0800, Anil kumar wrote:
> Hi Matthew,
> 
> Thanks for the reply.
> I can store the returned dma_addr from
> pci_map_sg/single or pci_map_page in a driver
> structure.
> 
> struct page *page =
> virt_to_page(Cmnd->request_buffer);
>                 unsigned long offset = ((unsigned
> long)Cmnd->request_buffer &
>                                         ~PAGE_MASK);
>                 dma_addr_t busaddr =
> pci_map_page(hostdata->pci_dev,
>                                                  
> page, offset,
>                                                  
> Cmnd->request_bufflen,
>                                                  
> scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
> 
> But how do I convert this returned "busaddr" into a
> virtual addr?

You don't - that's architecture implementation detail which drivers
have _zero_ business knowing about.

As far as you're concerned, the virtual address is Cmnd->request_buffer.

Anyway, you're using the wrong interface - pci_map_single() takes
a virtual address.  No need to play around getting the offset and
struct page for pci_map_page() when pci_map_single() implements
what you require.

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 Serial core

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

end of thread, other threads:[~2005-11-08 22:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-07 23:52 bus_to_virt equivalent Anil kumar
2005-11-08  1:37 ` Matthew Wilcox
2005-11-08 22:47   ` Anil kumar
2005-11-08 22:53     ` Russell King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox