Segmentation issue on calling outb function Apalis iMX6

Segmentation issue on calling outb function

{
unsigned long base, len;
unsigned char __iomem *baseaddress;
dev = pci_get_device(VENDOR_ID,DEVICE_ID,NULL);

        if(dev == NULL)
        {
                printk("Device not found \n");
                return -1;
        }
pci_enable_device(dev);
base = pci_resource_start(dev, 0);
if(pci_resource_flags(dev, 0) & IORESOURCE_IO)
        {
                len =  pci_resource_len(dev, 0);
                baseaddress =ioremap(base, len);
}
outb(0x01,(unsigned int)(baseaddress+0x74));
}

I am getting segmentation address while inserting the driver.
Can you please provide your inputs

Thanks,
bevincb

Hi @bevincb

Could you provide the version of the hardware ( including Carrier Board) and software of your module?

Concerning your Issue, what exactly are you trying to do?

Best regards,
Jaski

Hi Jaski,

I am using Toradex Apalis iMX6Q V1.1A

OS details:
Linux apalis-imx6 3.14.52-00006-g0dc1453 #17 SMP Fri Feb 17 18:44:57 IST 2017 armv7l GNU/Linux
Angstrom GNU/Linux v2015.12(Core edition)

Thanks,
bevincb

Thanks for your Input. You did not answer my second question?

Hi Jaski,

I am trying to toggle an LED in a PCIe module by writing to its register at offset 0x74 from kernel space. The sample code that I have posted above will be inserted to kernel space using insmod.

Thanks,
bevincb

Hi bevincb

Thanks for your Input.

You need to check in the dmesg log if your PCIe Device was correctly initialized.

Additionally you need to check in your sample code if the mapping of the registers of the PCIe Deivce to Module Memory was correctly done by check the return code of the called functions.

Best regards,
Jaski

Hi Jaski,

I tried the code in x86 based platform with 32 bit Ubuntu 16.04 OS and I am able to toggle the LED by writing to PCI register Offsets. The following code samples are working fine in x86 based platform with 32 bit Ubuntu 16.04 OS.

           struct pci_dev *dev = NULL;
           unsigned long base = 0, len = 0;
           dev = pci_get_device(VENDOR_ID,DEVICE_ID,NULL);
           pci_enable_device(dev);
           base = pci_resource_start(dev, 0);
           outb((0x01),(base+0x74));
           struct pci_dev *dev = NULL;
           unsigned long len = 0, baseaddress = 0;
           dev = pci_get_device(VENDOR_ID,DEVICE_ID,NULL);
           pci_enable_device(dev);
           len =  pci_resource_len(dev, 0);
           baseaddress = pci_iomap(dev, 0, len);
           outb((0x01),(baseaddress+0x74));

I have noticed that in Apalis imx6 Angstrom Linux which I am using, PCI is not listed in cat /proc/iomem
It seems like PCI is not mapped to memory and I am getting segmentation fault on accessing the address received from pci_resource_start as well as from pci_iomap.

I am receiving FFFFFF00 from pci_resource_start() function and FEEFFF00 from pci_iomap() function.
and the maximum address listed in cat /proc/iomem is

10000000 - 8FFFFFFF : System RAM
      10008000 - 108ac063 : Kernel code
      10900000 - 109b14cf : Kernel data

Please let me know whether we need to configure anything at the time of building the OS for the PCI bus to be mapped in /proc/iomem

I have found an article at https://patchwork.ozlabs.org/patch/437964/ saying that:

When using PCI_PROBE_ONLY, Linux does not assign resource to PCI devices.
This causes error when calling the pci_enable_resources function, and not
allowing driver to set the PCI_COMMAND_IO and PCI_COMMAND_MEMORY flag in
the config space of endpoint device since it checks if the resource parent
is set.

Do we need to do anything before building the imx6 Linux image such that this flag is not set.

Please provide your inputs.

Thanks,
bevincb

Could you boot the module with your PCIe device connected and share the complete serial boot log in a text file? Additionally share also the output of lspci -v.

Thanks and best regards,
Jaski

link text

link text

Hi Jaski,

Please find the attached serial port log and lspci log

Thanks,
bevincb

The boot log is not complete. You can also do ( dmesg > dmesg.txt ).

link text

Hi Jaski,

Please find the attached dmesg log after bootup.

Thanks,
bevincb

Hi Jaski,

I have resolved the issue by calling pci_assign_resource function to allocate resources and map memory and after that I am able to use outb to write to required offset and toggle the user LED in the device.

But now when I try to read the device using inb, I am getting zero value as output.

Can you please provide your inputs

Thanks,
bevincb

Could you provide the output of lspci -D?
Which address did you use for the inb function?

Best regards,
Jaski

link text

Hi Jaski,

Please find the attached lspci -D dump

I have used baseaddress+0x79 for inb.
In another board with x86 arch and ubuntu 16.04 32-bit OS, I am able to read 0x0c from that offset. But in imx6, I am getting 0 as return for inb((basaddress+0x79))

Thanks,
bevincb

Hi Jaski,

Is this related to any PCI enumeration issue.
Do we need to call any function like pci_assign_resource, (which we used to resolve outb issue) to resolve the inb returning zero issue.

Please provide your inputs.

Thanks,
bevincb

Dear @bevinb,

These two issues https://community.nxp.com/thread/453186 and https://community.nxp.com/thread/387557 are related to your post. Could you go through the forum?
It seems, needs to do some kernel changes. Still, I am looking into the details. Could you wait for a couple of days, let us find concrete information and let you know.

Thank you.