Hi NXP Support Team,
We have a LS1028A based custom board in which PCIe2.0, is connected with PCIe switch (PEX8604) and another PCIe is connected to IGLOO2 COMM FPGA as shown in attached block diagram.
In our PCie driver Makefile we are compiling as module and modified below things:
obj-m += sms_pcieDriver.o
under driver/Makefile we are compiling as module as shown below:
obj-m += sms_pcieDriver/
below is our pcie_dma_init() function code:
----------------------
static int __init pcie_dma_init (void)
{
int irq;
int ret = -ENOMEM;
int user_bus_no = pciebusno;
int bar_num =0;
printk(KERN_ALERT "\r\nchecking device at bus no : %i\n",pciebusno);
g_pdev = pci_get_device (PCIE_VENDOR_ID, PCI_ANY_ID, g_pdev);
if (NULL == g_pdev)
{
printk(KERN_EMERG"\r\n%s: Init: Hardware not found.\n", DRV_NAME);
return FAILURE;
}
#ifdef DEBUG
printk(KERN_EMERG"\r\nInit: PCIe_DMA Device Found.\n", DRV_NAME);
#endif
for(bar_num =0; bar_num < NO_OF_BARS; bar_num++)
{
bar_addr[bar_num] = pci_resource_start(g_pdev, bar_num);
if(bar_addr[bar_num] < 0)
{
printk(KERN_EMERG "\r\nbar_addr[%d]: Failed to get address\n",bar_num);
return FAILURE;
}
printk (KERN_EMERG "\r\nbar_addr[%d] = %lX\n", bar_num,bar_addr[bar_num]);
bar_mem_len[bar_num] = pci_resource_len(g_pdev, bar_num);
printk (KERN_EMERG "\r\nbar_mem_len[%d] = %lX\n", bar_num,bar_mem_len[bar_num]);
/* Re-map IO memory to kernel address space */
IOAddress[bar_num] = (unsigned long)ioremap(bar_addr[bar_num], bar_mem_len[bar_num]);
if (!IOAddress[bar_num])
{
printk(KERN_EMERG "\r\nInit: ioremap for bar_addr[%d] FAILED.\n",bar_num, DRV_NAME);
return FAILURE;
}
else
{
#ifdef DEBUG
printk(KERN_EMERG "\r\nInit: SUCCESSED.\n", DRV_NAME);
#endif
}
fsl_dma_ctrl_addr = (unsigned long)ioremap(DMA_CONTROLLER_ADDRESS,DMA_CONTROLLER_MAP_SIZE);
if (!fsl_dma_ctrl_addr)
{
printk(KERN_EMERG "\r\nInit: ioremap for fsl_dma_ctrl_addr FAILED.\n", DRV_NAME);
return FAILURE;
}
else
{
#ifdef DEBUG
printk(KERN_EMERG "\r\nInit: fsl_dma_ctrl_addr SUCCESSED.\n", DRV_NAME);
#endif
}
if(request_mem_region(bar_addr[bar_num],bar_mem_len[bar_num], DRV_NAME) == NULL)
{
printk(KERN_EMERG "\r\nreq_mem_region FAILED\n", DRV_NAME);
}
}
/* Initialize PCI device */
if (pci_enable_device(g_pdev) < 0)
{
printk(KERN_EMERG "\r\npci enable device failed returning error \r\n");
ret = -EIO;
return ret;
}
#ifdef DEBUG
printk(KERN_EMERG "\r\nPCIe_DMA Device enabled\n", DRV_NAME);
#endif
/* Enables bus-mastering on the device */
pci_set_master (g_pdev);
/* Allocate memory for global structure */
if ((g_pcie_dma = kmalloc(sizeof(pcie_dma_data), GFP_KERNEL)) == NULL)
{
printk (KERN_EMERG "\r\nFailed to allocate memory\r\n");
return FAILURE;
}
#ifdef DEBUG
printk (KERN_EMERG "\r\nRegistering PCIe_DMA driver\r\n");
#endif
/* Register a new pci driver */
ret = pci_register_driver(&pcie_dma_driver);
major_pcie_dma = register_chrdev (0, DRV_NAME, &pcie_dma_fops);
#ifdef DEBUG
printk (KERN_EMERG "\r\nMajor Number - PCIe_DMA = %d \r\n", major_pcie_dma);
#endif
/* Major number should be greater than 0 */
if(major_pcie_dma < 0)
{
printk(KERN_EMERG "\r\nUnable to get a major for PCIe_DMA\n");
return major_pcie_dma;
}
return 0;
}
-----------------------------------
With lspci command we are able to enumerate FPGA ,then we trying to load our PCIe driver module file using insmod command but we are getting below error:
--------------------------
log print:
root@TinyLinux:~# lspci
0000:00:00.0 Class 0200: Device 1957:e100 (rev 01)
0000:00:00.1 Class 0200: Device 1957:e100 (rev 01)
0000:00:00.2 Class 0200: Device 1957:e100 (rev 01)
0000:00:00.3 Class 0880: Device 1957:ee01 (rev 01)
0000:00:00.4 Class 0880: Device 1957:ee02 (rev 01)
0000:00:00.5 Class 0208: Device 1957:eef0 (rev 01)
0000:00:00.6 Class 0200: Device 1957:e100 (rev 01)
0000:00:1f.0 Class 0807: Device 1957:e001 (rev 01)
0001:00:00.0 Class 0604: Device 1957:82c0 (rev 10)
0001:01:00.0 Class 0604: Device 10b5:8604 (rev ba)
0001:02:01.0 Class 0604: Device 10b5:8604 (rev ba)
0001:02:04.0 Class 0604: Device 10b5:8604 (rev ba)
0001:02:05.0 Class 0604: Device 10b5:8604 (rev ba)
0002:00:00.0 Class 0604: Device 1957:82c0 (rev 10)
0002:01:00.0 Class 0000: Device 11aa:1556
root@TinyLinux:/home# insmod sms_pcieDriver.ko
[ 238.420952]
[ 238.420952] checking device at bus no : 0
[ 238.426572]
[ 238.426572] Init: PCIe_DMA Device Found.
[ 238.432126] pci 0002:01:00.0: can't enable device: BAR 0 [mem 0x8840000000-0x88407fffff 64bit pref] not claimed
[ 238.442263]
[ 238.442263] pci enable device failed returning error
[ 238.481007]
[ 238.481007] checking device at bus no : 0
[ 238.486632]
[ 238.486632] Init: PCIe_DMA Device Found.
[ 238.492172] pci 0002:01:00.0: can't enable device: BAR 0 [mem 0x8840000000-0x88407fffff 64bit pref] not claimed
[ 238.502299]
[ 238.502299] pci enable device failed returning error
insmod: can't insert 'sms_pcieDriver.ko': Input/output error
Note:
11aa:1556 is the device id and vendor id of COMM FPGA.
--------------------------
Please help us on this.
Regards,
Amit Keshri
The error message "can't enable device: BAR 0 [mem 0x8840000000-0x88407fffff 64bit pref] not claimed" is caused by the some regions not reserved.
This piece of code print the error message in pci_enable_resources.
if (!r->parent) {
pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
i, r);
return -EINVAL;
}
Please follow this steps:
1. use pci_request_regions() to reserve all memory region
2. Call pci_ioremap_bar() to map bars
3. Call pci_enable_device to enable the device