Find the answer to your Linux question:
Results 1 to 2 of 2
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1

    UIO - custom version of uio_pci_generic


    I have stated the problem in the attachment

  2. #2
    -->
    I am interested in UIO drivers. So to prove my basic understanding I thought I would take the
    standard uio_pci_generic.c, add some navigational comments rename it to
    uioJ_pci_generic.c and try to bind it to an unused PCI device.

    Miserable failure!!!

    So I continued the exercise with the standard uio_pci_driver.c which worked.

    What is the difference between my uioJ_pci_generic.c and the standard uio_pci_generic.c??
    Nothing that I can see.

    What, in the sequence of steps is wrong? I have pointed out some clues but I
    cannot piece them together.

    I would appreciate some help on this. Thanks in advance.

    I am using Fedora 17. I attached the code, makefile and have anotated the sequence of
    steps with comments.




    #include <linux/device.h>
    #include <linux/module.h>
    #include <linux/pci.h>
    #include <linux/slab.h>
    #include <linux/uio_driver.h>

    #define DRIVER_VERSION "0.01.0"
    #define DRIVER_AUTHOR "Neddy Seagoon <mst@redhat.com>"
    #define DRIVER_DESC "Mother : Generic UIO driver (with comments)for PCI 2.3 devices"

    struct uio_pci_generic_dev {
    struct uio_info info;
    struct pci_dev *pdev;
    };

    static inline struct uio_pci_generic_dev *
    to_uio_pci_generic_dev(struct uio_info *info)
    {
    return container_of(info, struct uio_pci_generic_dev, info);
    }

    /* Interrupt handler. Read/modify/write the command register to disable
    * the interrupt. */
    static irqreturn_t irqhandler(int irq, struct uio_info *info)
    {
    static int count = 0;
    pr_info("In UIO handler, count=%d\n", ++count);
    #if 0
    struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);

    if (!pci_check_and_mask_intx(gdev->pdev))
    return IRQ_NONE;
    #endif

    /* UIO core will signal the user process. */
    return IRQ_HANDLED;
    }

    static int probe(struct pci_dev *pdev, const struct pci_device_id *id)
    {
    struct uio_pci_generic_dev *gdev;
    int err;

    err = pci_enable_device(pdev);
    if (err) {
    dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
    __func__, err);
    return err;
    }

    pr_info("probe : pci_enable_device() Success\n");

    if (!pdev->irq) {
    dev_warn(&pdev->dev, "No IRQ assigned to device: "
    "no support for interrupts?\n");
    pci_disable_device(pdev);
    return -ENODEV;
    }

    pr_info("probe : using IRQ=%d\n", pdev->irq);

    #if 0
    if (!pci_intx_mask_supported(pdev)) {
    err = -ENODEV;
    goto err_verify;
    }
    #endif
    gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
    if (!gdev) {
    err = -ENOMEM;
    goto err_alloc;
    }

    gdev->info.name = "uioJ_pci_generic";
    gdev->info.version = DRIVER_VERSION;
    gdev->info.irq = pdev->irq;
    gdev->info.irq_flags = IRQF_SHARED;
    gdev->info.handler = irqhandler;
    gdev->pdev = pdev;

    err = uio_register_device(&pdev->dev, &gdev->info);
    if (err)
    goto err_register;

    pr_info("probe : uio_register_device() Success : %d\n", err);

    pci_set_drvdata(pdev, gdev);

    return 0;
    err_register:
    pr_info("probe : uio_register_device() Failed : %d\n", err);
    kfree(gdev);
    err_alloc:
    err_verify:
    pr_info("probe : pci_disable_device()\n");

    pci_disable_device(pdev);
    return err;
    }

    static void remove(struct pci_dev *pdev)
    {
    struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);

    pr_info("remove()\n");

    uio_unregister_device(&gdev->info);
    pci_disable_device(pdev);
    kfree(gdev);
    }

    static struct pci_driver uioJ_pci_driver = {
    .name = "uioJ_pci_generic",
    .id_table = NULL, /* only dynamic id's */
    .probe = probe,
    .remove = remove,
    };

    module_pci_driver(uioJ_pci_driver);
    MODULE_VERSION(DRIVER_VERSION);
    MODULE_LICENSE("GPL v2");
    MODULE_AUTHOR(DRIVER_AUTHOR);
    MODULE_DESCRIPTION(DRIVER_DESC);




    Step 1 : Build the module.


    obj-m += uioJ_pci_generic.o

    all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

    clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


    Step 2 : Place in the uio directory

    [root@localhost lkmPCIeGeneric]# cp uioJ_pci_generic.ko /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio
    cp: overwrite `/lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uioJ_pci_generic.ko'? y

    [root@localhost drivers]# depmod -av | grep "uio"
    /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/net/ethernet/broadcom/cnic.ko needs "__uio_register_device": /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio.ko
    /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio_cif.ko needs "__uio_register_device": /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio.ko
    /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio_aec.ko needs "__uio_register_device": /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio.ko
    /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio_sercos3.ko needs "__uio_register_device": /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio.ko
    /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio_pci_generic.ko needs "__uio_register_device": /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uio.ko
    [root@localhost uio]#



    Step 3 : Now check module and load it

    [root@localhost uio]# ls -l
    total 168
    -rwxr--r--. 1 root root 4792 May 7 2012 uio_aec.ko
    -rwxr--r--. 1 root root 4640 May 7 2012 uio_cif.ko
    -rw-r--r--. 1 root root 120924 Jun 10 13:52 uioJ_pci_generic.ko
    -rwxr--r--. 1 root root 14212 May 7 2012 uio.ko
    -rwxr--r--. 1 root root 4440 May 7 2012 uio_pci_generic.ko
    -rwxr--r--. 1 root root 5516 May 7 2012 uio_sercos3.ko

    All the names of the the modules except mine (uioJ_pci_generic.ko) are rendered with
    green text while my module is rendered with white text. <===== What does this signify ???????



    [root@localhost uio]# modinfo uioJ_pci_generic
    filename: /lib/modules/3.3.4-5.fc17.i686.PAE/kernel/drivers/uio/uioJ_pci_generic.ko
    description: Mother : Generic UIO driver (with comments)for PCI 2.3 devices
    author: Neddy Seagoon <mst@redhat.com>
    license: GPL v2
    version: 0.01.0
    srcversion: 7780AD87F53B831688C0CFD
    depends:
    vermagic: 3.3.4-5.fc17.i686.PAE SMP mod_unload 686
    [root@localhost uio]#
    [root@localhost uio]#
    [root@localhost uio]# modprobe uio
    [root@localhost uio]# modprobe uioJ_pci_generic

    I see this in /var/log/messages when I do the modprobe.....
    Jun 10 13:57:59 localhost udevd[390]: specified user 'usbmux' unknown <===== CLUE ????
    Jun 10 13:58:02 localhost dbus-daemon[685]: ** Message: No devices in use, exit


    [root@localhost uio]# lsmod
    Module Size Used by
    uioJ_pci_generic 8209 0
    uio 14412 0
    *
    *
    *
    ===> note that uio is *NOT* "used by" uioJ_pci_generic <===== CLUE ???




    Step 4 : Now replace current driver (rtl8192se) with uioJ_pci_generic driver

    [root@localhost uio]# lspci -vvn
    *
    *
    03:00.0 0280: 10ec:8172 (rev 10)
    Subsystem: 10ec:e020
    Physical Slot: 1
    Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Latency: 0, Cache Line Size: 64 bytes
    Interrupt: pin A routed to IRQ 17
    Region 0: I/O ports at 2000 [size=256]
    Region 1: Memory at f4300000 (32-bit, non-prefetchable) [size=16K]
    Capabilities: [40] Power Management version 3
    Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
    Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
    Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
    Address: 0000000000000000 Data: 0000
    Capabilities: [70] Express (v1) Legacy Endpoint, MSI 00
    DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
    ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
    DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
    RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
    MaxPayload 128 bytes, MaxReadReq 512 bytes
    DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
    LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1 <64us
    ClockPM+ Surprise- LLActRep- BwNot-
    LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
    ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
    LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
    Capabilities: [100 v1] Advanced Error Reporting
    UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
    CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
    Capabilities: [140 v1] Virtual Channel
    Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
    Arb: Fixed- WRR32- WRR64- WRR128-
    Ctrl: ArbSelect=Fixed
    Status: InProgress-
    VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
    Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
    Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
    Status: NegoPending- InProgress-
    Capabilities: [160 v1] Device Serial Number 88-55-22-fe-ff-4c-e0-00
    Kernel driver in use: rtl8192se <================= current driver


    Step 5 : unbind the current driver

    [root@localhost uio]# echo '0000:03:00.0' > /sys/bus/pci/drivers/rtl8192se/unbind
    [root@localhost uio]#

    === > Verify that no driver bound to device

    03:00.0 0280: 10ec:8172 (rev 10)
    Subsystem: 10ec:e020
    Physical Slot: 1
    Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Interrupt: pin A routed to IRQ 17
    Region 0: I/O ports at 2000 [size=256]
    Region 1: Memory at f4300000 (32-bit, non-prefetchable) [size=16K]
    Capabilities: [40] Power Management version 3
    Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
    Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
    Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
    Address: 0000000000000000 Data: 0000
    Capabilities: [70] Express (v1) Legacy Endpoint, MSI 00
    DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
    ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
    DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
    RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
    MaxPayload 128 bytes, MaxReadReq 512 bytes
    DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
    LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1 <64us
    ClockPM+ Surprise- LLActRep- BwNot-
    LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
    ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
    LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
    Capabilities: [100 v1] Advanced Error Reporting
    UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
    CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
    Capabilities: [140 v1] Virtual Channel
    Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
    Arb: Fixed- WRR32- WRR64- WRR128-
    Ctrl: ArbSelect=Fixed
    Status: InProgress-
    VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
    Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
    Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
    Status: NegoPending- InProgress-
    Capabilities: [160 v1] Device Serial Number 88-55-22-fe-ff-4c-e0-00


    Step 6 : Now bind my humble uioJ_pci_generic module

    [root@localhost uio]# echo '10ec 8172' > /sys/bus/pci/drivers/uioJ_pci_generic/new_id
    [root@localhost uio]#bash: /sys/bus/pci/drivers/uioJ_pci_generic/new_id: No such file or directory <==== Why ?????



    Step 7 : Try to bind the standard uio_pci_generic module, but first load
    the standard uio_pci_generic

    [root@localhost lkmPCIeGeneric]# modprobe uio_pci_generic
    [root@localhost lkmPCIeGeneric]# lsmod
    Module Size Used by
    uio_pci_generic 1812 0
    uioJ_pci_generic 405 0
    uio 6919 1 uio_pci_generic
    fuse 46663 2
    sunrpc 159624 1
    cpufreq_ondemand 6732 2


    ===> note that uio is "used by" uio_pci_generic but
    uio is *NOT* "used by" uioJ_pci_generic <====== CLUE ????



    Step 8: Try to bind uioJ_pci_generic to the device

    [root@localhost uio]# echo '10ec 8172' > /sys/bus/pci/drivers/uio_pci_generic/new_id

    It works....

    03:00.0 0280: 10ec:8172 (rev 10)
    Subsystem: 10ec:e020
    Physical Slot: 1
    Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Interrupt: pin A routed to IRQ 17
    Region 0: I/O ports at 2000 [size=256]
    Region 1: Memory at f4300000 (32-bit, non-prefetchable) [size=16K]
    Capabilities: [40] Power Management version 3
    Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=375mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
    Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
    Capabilities: [50] MSI: Enable- Count=1/1 Maskable- 64bit+
    Address: 0000000000000000 Data: 0000
    Capabilities: [70] Express (v1) Legacy Endpoint, MSI 00
    DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
    ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
    DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
    RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
    MaxPayload 128 bytes, MaxReadReq 512 bytes
    DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
    LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <512ns, L1 <64us
    ClockPM+ Surprise- LLActRep- BwNot-
    LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
    ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
    LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
    Capabilities: [100 v1] Advanced Error Reporting
    UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
    UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
    CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
    AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
    Capabilities: [140 v1] Virtual Channel
    Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
    Arb: Fixed- WRR32- WRR64- WRR128-
    Ctrl: ArbSelect=Fixed
    Status: InProgress-
    VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
    Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
    Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
    Status: NegoPending- InProgress-
    Capabilities: [160 v1] Device Serial Number 88-55-22-fe-ff-4c-e0-00
    Kernel driver in use: uio_pci_generic <================ driver is bound


    [root@localhost uio]# ls -l /sys/class/uio/ <=== See device is bound to standard driver
    total 0
    lrwxrwxrwx. 1 root root 0 Jun 10 13:29 uio0 -> ../../devices/pci0000:00/0000:00:1c.1/0000:03:00.0/uio/uio0
    [root@localhost uio]#

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •