Hi peter, thanks for help. Your reply is explaining how things should be done. I am doing the similar steps to access the BARs of a card. I will try to explain the problem in some more details:- Start physical addr of BAR is allocated by BIOS. In linux-2.6.9, whether BAR start phys addr is below OR above 4GB, i.e. whether 32-bit BAR phys addr(all higher bits 0) OR 64-bit phys addr(some higher bits non-zero), I am able to access the BAR region using ioremap() & then readl()/writel(). For linux-2.6.22-8, if BAR start phys addr is below 4GB, things are working fine here also. But, for linux-2.6.22-8, when BAR start phys addr is above 4GB, I am not able to read/write on the BAR region. ioremap() is not failing. But read data is all 1's instead of actual data. Any ideas on where to look for? -Yogeshwar On 10/3/07, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: > On 10/2/07, yogeshwar sonawane <yogyas@xxxxxxxxx> wrote: > > Hello all, > > > > For accessing memory-mapped 64bit-BAR regions of a PCI card, the > > respective BAR regions has to be made accessible to the kernel using > > ioremap() function. > > Then readl()/writel() are working fine on the address returned by ioremap(). > > This is working in linux-2.6.9. > > Here is an extraction from 2.6.23-rc5/drivers/pci/msi.c that > illustrate exactly what you have been saying (my remarks in ***): > > static int msix_capability_init(struct pci_dev *dev, > struct msix_entry *entries, int nvec) > { > void __iomem *base; > > *** first pci_resource_start() is to get the physical address > phys_addr = pci_resource_start (dev, bir) + table_offset; > *** then ioremap() is applied to convert it to virtual address > base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); > > *** then assign to the structure > entry->mask_base = base; > > And in the following function readl() and writel() are shown: > > static void msix_flush_writes(unsigned int irq) > { > > int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + > PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; > ***Here below is shown how readl() is applied to the virtual address mask_base > readl(entry->mask_base + offset); > > static int msi_free_irqs(struct pci_dev* dev) > { > > list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { > if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) { > *** Here writel() is applied to the virtual address mask_base. > writel(1, entry->mask_base + entry->msi_attrib.entry_nr > * PCI_MSIX_ENTRY_SIZE > + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); > > if (list_is_last(&entry->list, &dev->msi_list)) > iounmap(entry->mask_base); > *** The mask_base is here unmap, since it has been ioremap() earlier. > Beyond this point, the virtual address mask_base can therefore not > be used to write anymore. > } > list_del(&entry->list); > kfree(entry); > } > -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ