howto map pci device registers to user space

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All:

I'm trying again to get mmapping working from user space to a cards device registers.
The platform is X86, linux 2.6.18 .

Under linux 2.4, the following code snippet was able to map 1 page of PLX register
and 1 page of card registers:
-----
bus_adr = pCrd->pPciDevInfo->resource[ bar_nmbr ].start;
bus_adr &= PCI_BASE_ADDRESS_MEM_MASK;
page_adr = bus_adr &  (PAGE_MASK);
offset   = bus_adr & ~(PAGE_MASK);
vma->vm_flags |= VM_IO | VM_RESERVED ;

prot = pgprot_noncached(__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_GLOBAL) );
vma->vm_page_prot = prot ;

rtv = remap_page_range(vma->vm_start, page_adr, length, vma->vm_page_prot);

vma->vm_start += offset;
-----

Under linux 2.6.18, documentation indicates remap_pfn_range() is the routine to use. Indeed, this works for kmallocd() pages. However for device registers it is unclear as to which pfn ( presumably the pfn for the bus adrs ... like the kernel mapping ), vm flags, and page flags are needed. The current 2.6.18 code snippet looks like:

+++++
bus_adr = pCrd->pPciDevInfo->resource[ bar_nmbr ].start;

bus_adr &= PCI_BASE_ADDRESS_MEM_MASK;
page_adr = bus_adr &  (PAGE_MASK);
offset   = bus_adr & ~(PAGE_MASK);

show_page_flags( (adr_t)bus_adr, "bus_adr:: "); }
show_page_flags( (adr_t)mAddr,   "  mAddr:: "); }

rtv = io_remap_pfn_range( vma, vma->vm_start, (__pa(bus_adr) >> PAGE_SHIFT),
                         length,  vma->vm_page_prot );

show_page_flags( (addr_t)vma->vm_start, (addr_t)0);

vma->vm_start += offset;

+++++
mAddr is the kernel virtual address of the PLX area on the card.

Results from the show_page_flags():

bus_adr:: c1738fe0:pg* f9c7ff00:va 39c7ff00:pa 00039c7f:pfn :: c0000000:flags :: < himem > 0:ct mAddr:: c17147c0:pg* f8a3ef00:va 38a3ef00:pa 00038a3e:pfn :: c0000000:flags :: < himem > 0:ct

vm->strt: c2eff4e0:pg* b7fa7000:va f7fa7000:pa 000f7fa7:pfn :: 00000000:flags :: < > 0:ct

=====================

The pfn returned is bogus, based solely upon the virtual address. For the platform running on
the following parameters are in effect:

0007fe86:max_mapnr  0007fe86:num_physpages
f8000000:high_mem   38000000:va(himem)  00038000:hi_start_pfn


======================

So, what am I missing. I would hate to lose this feature when debugging cards/drivers.

How should the call to remap_pfn_range() be setup so that it properly maps the registers?

TIA
klink


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux