Hi,
I am writing a device driver for PCI-X card in linux. Card memory is mapped
to BAR-2 register.
I got the physical address from BAR-2 using pci_resource_start() function.
Then i try to get virtual address using ioremap_nocache(). But it returns
virtual address as 0xffffffff.Pls help me to resolve the issue./***************************************************************************
* Function Name : PCINRZProbe()
*
* Interface Description: This function is used to configure for the PCI
* NRZ Tester card device driver. This will be
* called from kernel when pci_module_init()
* called from device driver.
*
* Input Value : PCI device configuration and ID structures passed
* by kernel.
*
* Return Value : EFAIL - Device is not configured properly.
* SUCCESS -.Device is configured suceesfully
****************************************************************************/
int
__devinit PCINRZProbe(struct pci_dev *pstPciDev,
const struct pci_device_id *id){/*** To get the result **/
int16 iResult = 0;
struct page *page;
MSG("Probe Module of the PCI-NRZ is called - \n");/**** Enable the PCI device ********/
if (pci_enable_device(pstPciDev)){
MSG("PCI Tester Card Device Driver is not"
" enabled in probe function\n");
return -EIO;
}/*** Allocate the memory for PCI NRZ Tester card configuration
structure ****/
if ((pstCard = kmalloc(sizeof(struct pci_nrz), GFP_KERNEL)) == NULL)
{
MSG("Out of memory for PCI NRZ Tester card configuration\n");
return -ENOMEM;
}/** Initializing the card configuration structure memory with 0***/
memset(pstCard, 0, sizeof(*pstCard));
/* Have the link to pcidev structure */
pstCard->pstPCI_Dev = pstPciDev;/* Get the FPGA register starting address */
/*PCINRZGetBARValue(PCI_BAR_0); commented for time being *//* Get the Rx/Tx buffer starting address */
printk("About to read the BAR-2 value- ");
PCINRZGetBARValue(PCI_BAR_2);/* Get the IRQ number from PCI dev structure allocated by kernel */
iResult = pci_read_config_byte(pstPciDev,
PCI_INTERRUPT_LINE, &(pstCard->irq));
if(iResult) {
/** IRQ is not allocated **/
MSG("IRQ is not allocated for PCI NRZ Tester card\n");
kfree(pstCard);
//kfree(pstCard->RxBuffer);
//kfree(pstCard->TxBuffer);
return EFAIL;
}
MSG("IRQ number allocated for PCI Tester card DD is %d\n", pstCard->irq);
/* Set the PCI device as Master */
//pci_set_master(pstPciDev);/* Register the IRQ with ISR handler */
if (request_irq(pstCard->irq, &PCINRZisr, SA_SHIRQ,
DEVICE_NAME, pstCard)) {
MSG("Unable to register irq %d with ISR Handler \n", pstCard->irq);
kfree(pstCard);
//kfree(pstCard->RxBuffer);
//kfree(pstCard->TxBuffer);
return EFAIL;
}/* Set the driver structure */
pci_set_drvdata(pstPciDev, pstCard);/* Register char driver */pstCard->uiDevMajorNo = 0;
iResult = register_chrdev(pstCard->uiDevMajorNo,
DEVICE_NAME, &stPciNrzDrvfops);
if (iResult < 0)
{
MSG("Couldn't register PCI Tester card device driver\n");
/* Free the IRQ */
free_irq(pstCard->irq, pstCard);
/* Release the memory regions already allocated */
kfree(pstCard);
//kfree(pstCard->RxBuffer);
//kfree(pstCard->TxBuffer);
return EFAIL;
}
else
{
pstCard->uiDevMajorNo = iResult;
MSG("PCI NRZ Tester DD is registered with major number %d, %d\n",
pstCard->uiDevMajorNo, iResult);
}
/* Initialize the wait queue head */
init_waitqueue_head(&(pstCard->WaitQueue));
/* Set the flag to know that driver is registered */
pstCard->bDriverSet = TRUE;
/* Return successfully */
return SUCCESS;
}/***************************************************************************
* Function Name : PCINRZGetBARValue()
*
* Interface Description: This function is used to get the base address of
* FPGA register and base address of
* Rx/Tx Buffer.
*
* Input Value : None.
*
* Return Value : None.
*
****************************************************************************/
static void
PCINRZGetBARValue(int16 iBarNo)
{
/* Used to get the PCI configuration BAR register values */
ulong64 ulResult = 0;
if(PCI_BAR_2 == iBarNo)
{
/* Read the BAR value to get FPGA starting address */
/* Get the FPGA Base address */
ulResult = pci_resource_start(pstCard->pstPCI_Dev, PCI_BAR_2);
pstCard->uiFPGARegStartAddr = ulResult;/* Get the FPGA End address */
ulResult = pci_resource_end(pstCard->pstPCI_Dev, PCI_BAR_2);
pstCard->uiFPGARegEndAddr = ulResult;/* Get the FPGA Register length */
pstCard->uiFPGARegMemLen = pci_resource_len(pstCard->pstPCI_Dev,
PCI_BAR_2);
/* Get the FPGA Register flag - whether it is IO or memory */
pstCard->bFPGARegFlag = pci_resource_flags(pstCard->pstPCI_Dev,
PCI_BAR_2);
/* Request memory region for Tx Buffer */
if(request_mem_region(pstCard->uiFPGARegStartAddr,
pstCard->uiFPGARegMemLen, DEVICE_NAME))
{
/* Remap the physical address to virtual address
with non-cacheable*/
pstCard->uiFPGARegStartVirAddr =
ioremap(pstCard->uiFPGARegStartAddr, pstCard->uiFPGARegMemLen);
printk("Physical address of the BAR-2 is %x - \n",
pstCard->uiFPGARegStartAddr);
printk("Virtual address of the BAR-2 is %x - \n", (pstCard->uiFPGARegStartVirAddr));
printk("About to write and read ifrom FPGA Registers - \n");if(pstCard->uiFPGARegStartVirAddr)
{
writel(0xAAAA, (pstCard->uiFPGARegStartVirAddr + 0x2000));
uiResult = readl((pstCard->uiFPGARegStartVirAddr + 0x2000) );
printk("Value read from FPGA register-1 is %x - \n",uiResult);writel(0xAAAA, (pstCard->uiFPGARegStartVirAddr + 0x2004));
uiResult = readl((pstCard->uiFPGARegStartVirAddr + 0x2004) );
printk("Value read from FPGA register is %x - \n",uiResult);uiResult = readl((pstCard->uiFPGARegStartVirAddr + 0x200C) );
printk("Value read from FPGA register is %x - \n",uiResult);uiResult = readl((pstCard->uiFPGARegStartVirAddr + 0x2010) );
printk("Value read from FPGA register is %x - \n",uiResult);
}
}
}
}
Regards,
Munees.
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
DISCLAIMER
The contents of this e-mail and any attachment(s) are confidential and intended for the
named recipient(s) only. It shall not attach any liability on the originator or HCL or its
affiliates. Any views or opinions presented in this email are solely those of the author and
may not necessarily reflect the opinions of HCL or its affiliates. Any form of reproduction,
dissemination, copying, disclosure, modification, distribution and / or publication of this
message without the prior written consent of the author of this e-mail is strictly
prohibited. If you have received this email in error please delete it and notify the sender
immediately. Before opening any mail and attachments please check them for viruses and
defect.
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/