Resolving physical addresses (change in 2.4.x?)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 12 lines
Even recognizing these as unmapped and resolving anew, produced a frozen machine once the DMA used these addresses. Was there a change in 2.4.x so that my resolving routine now works incorrect?
/*resolve virt. addresses to phys.*/
unsigned longch_get_physpage(unsigned long virtaddr){
/*Stuff for browsing through the memory page tables*/pgd_t*pgd_t_dir;
pmd_t*pmd_t_dir;
pte_t*pte_t_dir;
Quoted 6 lines
/*Get physical address*/ pgd_t_dir=pgd_offset(current->mm,virtaddr); pmd_t_dir=pmd_offset(pgd_t_dir,virtaddr); pte_t_dir=pte_offset(pmd_t_dir,virtaddr); return
virt_to_bus((void *)pte_page(*pte_t_dir));
}
Are you crazy? This routing could NEVER work; pge_page returns a pointer to a struct page. I always was suspicious of this technique; even if you find out how to use page_address, what do you do about the bus address? On some architectures, the bus address is only known to the part that manages a north bridge; it may even be stored in hardware registers. No matter how popular this trick is, it is highly illegal.
To work properly, your driver has to remember virtual and bus addresses that were mapped with pci_alloc_sg. They are returned to you for this very purpose. In most cases you have to to track I/Os anyway, so just add a field to whatever management structure you use.
-- Pete