Talking to parallel port in 2.6 kernel without using parport - Kernel

This is a discussion on Talking to parallel port in 2.6 kernel without using parport - Kernel ; All, I have an existing 2.4 linux driver which talks directly to a parallel port to send commands to some propriatary hardware. I am attemping to convert this to a 2.6 driver (kernel version 2.6.18), but am experiencing problems. My ...

+ Reply to Thread
Results 1 to 8 of 8

Thread: Talking to parallel port in 2.6 kernel without using parport

  1. Talking to parallel port in 2.6 kernel without using parport

    All,

    I have an existing 2.4 linux driver which talks directly to a parallel port
    to send commands to some propriatary
    hardware. I am attemping to convert this to a 2.6 driver (kernel version
    2.6.18), but am experiencing problems.

    My 2.4 driver's init routine looked something like what is below. Our
    proprietary application uses this driver to talk
    to our proprietary hardware across the parallel port without using the
    parport layers.


    int __init pp_init()
    {
    mdcmajor = register_chrdev(mdcmajor,"pp", &pp_fops);
    if (mdcmajor < 0)
    {
    printk(KERN_ERR "pp: unable to get major %d\n", mdcmajor);
    return - EIO;
    }
    else
    printk(KERN_INFO "pp: major number= %d\n", mdcmajor);

    // Set the pins on the parallel port
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);
    x = inb(STATUS);
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);

    return 0;
    }


    I modified my init routine for 2.6 as below. The driver loads correctly and
    I see evidence of it in
    /proc/modules and /proc/devices. However, I can not open it.

    static int __init pp_init(void)
    {
    int status;
    dev_t dev;

    dev = MKDEV(mdcmajor, 0);
    status = register_chrdev_region(dev, 1, "pp");
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to get major %d\n", mdcmajor);
    return - EIO;
    }
    else
    printk(KERN_INFO "pp: major number= %d\n", mdcmajor);
    cdev_init(&chrdev, &pp_fops);
    chrdev.owner = THIS_MODULE;
    chrdev.ops = &pp_fops;
    status = cdev_add (&chrdev, dev, 1);
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to add device %d to system. status =
    %d\n", mdcmajor, status);
    return -ENODEV;
    }

    // Set the pins on the parallel port
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);
    x = inb(STATUS);
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);

    ****************

    I have some other 2.6 PCI drivers that work correctly. It's init module
    does a pci_register_driver followed by
    a register_chrdev_region, cdev_init and cdev_add. I've been reading the
    Documentation directories included
    with the kernel concerning the Driver Model. I am assuming there is some
    "glue" I am missing because I am not
    going through a "bus" layer like I am with my PCI drivers. It seemed that I
    should use the Platform devices, so I
    tried what you see below.

    static struct platform_device *pp_platform_device;
    static struct platform_driver drv = {
    .probe = pp_probe,
    .remove = pp_remove,
    .driver = {
    .name = "pp",
    .owner = THIS_MODULE,
    },
    };

    static int __init pp_init(void)
    {
    int status;
    dev_t dev;

    status = platform_driver_register(&drv);
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to register with platform, error = %d",
    status);
    // platform_device_unregister(pp_platform_device);
    status = -ENODEV;
    return status;
    }
    printk(KERN_INFO "pp: registerd with platform\n");
    // I read on LKML that platform_device_register_simple is going away.
    // Instead, implement probe and remove so manual binding and unbinding
    // will work.
    pp_platform_device = platform_device_register_simple("pp", -1, NULL, 0);
    if (pp_platform_device < 0)
    {
    printk(KERN_ERR "pp: unable to register device, error = %d\n",
    pp_platform_device);
    platform_driver_unregister(&drv);
    status = -ENODEV;
    return status;
    }

    dev = MKDEV(MDC_MAJOR, 0);
    status = register_chrdev_region(dev, 1, "pp");
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to get major %d\n", mdcmajor);
    return - EIO;
    }
    else
    printk(KERN_INFO "pp: major number= %d\n", mdcmajor);


    cdev_init(&chrdev, &pp_fops);
    chrdev.owner = THIS_MODULE;
    chrdev.ops = &pp_fops;
    status = cdev_add (&chrdev, dev, 1);
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to add device %d to system. status =
    %d\n", mdcmajor, status);
    return -ENODEV;
    }



    // Set the pins on the parallel port
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);
    x = inb(STATUS);
    outb(0x04, CONTROL);
    outb(0xFF, STATUS);

    for (i=0; i<256; i++)
    memory_array[i] = 0;


    printk (KERN_INFO "pp: Initialized OK.\n");
    return 0;
    }

    ***** However, I am still unable to open my device. Can someone tell me
    what I am missing?
    What do I need to do to talk to the parallel port myself and NOT go through
    parport?

    Thanks in advance for your help!

    Kathy Frazier

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: Talking to parallel port in 2.6 kernel without using parport

    > ***** However, I am still unable to open my device. Can someone tell me
    > what I am missing?
    > What do I need to do to talk to the parallel port myself and NOT go through
    > parport?


    You should go through parport. The parport layer is there for a reason.
    You drive on the road not through fields (even if shorter distances)
    please show the same respect for the kernel and your users (plus it'll
    make your job easier).

    If you need to hog the device because it doesn't follow 1284 or other
    sharing standards the parport_register_device can be called with
    PARPORT_DEV_EXCL in flags, which means you want to sit on it.

    So for something like a standard PC built in port (for the little time
    they have left before they go away in hardware..)

    struct parport *p = parport_find_base(0x378 /* etc */);

    parport_register_device(p, "mywidget", NULL,
    my_irq_handler, PARPORT_DEV_EXCL, &mystruct)
    parport_enable_irq(p);

    where mystruct is a private object that will be passed back to you in the
    callbacks. If you don't use the IRQ then don't call parport_enable_irq
    and my_irq_handler can also be NULL.

    Alan

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. RE: Talking to parallel port in 2.6 kernel without using parport

    Alan,

    Thanks for your response. I had some shifting priorities, but I finally had
    a chance to try your suggestion. Unfortunately I am still having trouble.
    In my init routine, I do:


    dev = MKDEV(MY_MAJOR, 0);
    status = register_chrdev_region(dev, 1, MY_DEVNAME);
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to get major %d\n", MY_MAJOR);
    return - EIO;
    }
    else
    printk(KERN_INFO "pp: major number= %d\n", MY_MAJOR);

    printk(KERN_INFO "pp: Adding character device\n");
    cdev_init(&chrdev, &pp_fops);
    chrdev.owner = THIS_MODULE;
    chrdev.ops = &pp_fops;
    status = cdev_add (&chrdev, dev, 1);
    if (status < 0)
    {
    printk(KERN_ERR "pp: unable to add device %d to system. status =
    %d\n", MY_MAJOR, status);
    return -ENODEV;
    }
    printk(KERN_INFO "pp: registering with parport\n");
    if (parport_register_driver(&ppdrv))
    {
    printk(KERN_ERR "pp: unable to register driver with parport\n");
    unregister_chrdev(mymajor, MY_DEVNAME);
    return -EIO;
    }

    my_parport = parport_find_base(DATA);
    if (!my_parport)
    {
    printk(KERN_WARNING "pp: no associated port!");
    return -ENXIO;
    }
    else
    {
    printk(KERN_INFO "pp: Found base 0x%x for parport device %s number %d
    module state = %d ref count=%d flags = 0x%x\n",
    DATA, my_parport->name, my_parport->number,
    my_parport->ops->owner->state,
    my_parport->ops->owner->ref[0].count,
    my_parport->physport->flags);
    }
    table[0].dev = parport_register_device(my_parport, MY_DEVNAME, NULL,
    NULL, NULL, PARPORT_FLAG_EXCL, (void *) &table[0]);
    if (table[0].dev == NULL)
    {
    printk(KERN_ERR "pp: Error registering device\n");
    return;
    }
    else
    printk(KERN_INFO "pp: Registered device with parport\n");


    Everthing happens as expected, except that the parport_register_device fails
    returning NULL.

    One of our engineers downloaded source code a while back from
    linux-2.6.18-rc7, but I am not sure how close that is to what is installed
    on my system (uname -r returns 2.6.18-1.2798.fc6. When I set my printk to 8
    (echo 8 > /proc/sys/kernel/printk), there are no messages shown on the
    failure. According to the source code I have, the only silent failure in
    parport_register_device is:

    If (!try_module_get(port->ops->owner)) {
    return NULL;
    }

    The printk debug I have following the parport_find_base gives the following
    result:

    pp: Found base 0x378 for parport device parport0 number 0, module state = 0
    ref count=1 flags=0x0
    pp: Error registering device

    When I change the flags from PARPORT_FLAG_EXCL to 0 in the call to
    parport_register_device, the call returns a non-zero to indicate success.

    Can you tell me what I am missing? Where can I get the actual source code
    that goes with this version to further unravel this?

    Thanks in advance for your help! Please CC me.

    Kathy Frazier

    -----Original Message-----
    From: linux-kernel-owner@vger.kernel.org
    [mailto:linux-kernel-owner@vger.kernel.org] On Behalf Of Alan Cox
    Sent: Monday, April 14, 2008 8:40 AM
    To: Kathy Frazier
    Cc: linux-kernel@vger.kernel.org
    Subject: Re: Talking to parallel port in 2.6 kernel without using parport

    > ***** However, I am still unable to open my device. Can someone tell
    > me what I am missing?
    > What do I need to do to talk to the parallel port myself and NOT go
    > through parport?


    You should go through parport. The parport layer is there for a reason.
    You drive on the road not through fields (even if shorter distances) please
    show the same respect for the kernel and your users (plus it'll make your
    job easier).

    If you need to hog the device because it doesn't follow 1284 or other
    sharing standards the parport_register_device can be called with
    PARPORT_DEV_EXCL in flags, which means you want to sit on it.

    So for something like a standard PC built in port (for the little time they
    have left before they go away in hardware..)

    struct parport *p = parport_find_base(0x378 /* etc */);

    parport_register_device(p, "mywidget", NULL,
    my_irq_handler, PARPORT_DEV_EXCL, &mystruct)
    parport_enable_irq(p);

    where mystruct is a private object that will be passed back to you in the
    callbacks. If you don't use the IRQ then don't call parport_enable_irq and
    my_irq_handler can also be NULL.

    Alan

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org More majordomo info at
    http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: Talking to parallel port in 2.6 kernel without using parport

    > One of our engineers downloaded source code a while back from
    > linux-2.6.18-rc7, but I am not sure how close that is to what is installed
    > on my system (uname -r returns 2.6.18-1.2798.fc6. When I set my printk to 8
    > (echo 8 > /proc/sys/kernel/printk), there are no messages shown on the
    > failure. According to the source code I have, the only silent failure in
    > parport_register_device is:


    Nothing immediately strikes me.

    > When I change the flags from PARPORT_FLAG_EXCL to 0 in the call to
    > parport_register_device, the call returns a non-zero to indicate success.


    Do you have the printer driver loaded already ? (and does it behave if
    you do rmmod lp first)

    > Can you tell me what I am missing? Where can I get the actual source code
    > that goes with this version to further unravel this?


    From the .fc6 it would be an old Fedora kernel so very close to standard
    2.6.18 from kernel.org, but the Fedora Core kernels are available from
    the Fedora download pages - the .srpm package for each kernel is the one
    matching the same binary - so google for "2.6.18-1.2798.fc6.src.rpm"

    http://www.mjmwired.net/resources/mjm-fedora-fc6.html has a few notes on
    it.

    To be honest this area of the kernel hasn't changed much over recent
    times. Let me know if you can't figure out what is going on.
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. Re: Talking to parallel port in 2.6 kernel without using parport

    > > Can you tell me what I am missing? Where can I get the actual source code
    > > that goes with this version to further unravel this?


    About two years ago (~2.6.18) I wrote one driver that needed exclusive
    access to the parallel port and, like this time, Alan Cox guided me
    (thank you Alan!). If you want, you can check the code at
    drivers/auxdisplay/ks0108.c. I tested it as of 2.6.25 and worked fine,
    so it could be a good reference for you. In addition, the code is
    pretty straightforward!

    >
    > To be honest this area of the kernel hasn't changed much over recent
    > times. Let me know if you can't figure out what is going on.
    >


    Right, I haven't had to change the code since 2.6.18.

    --
    Miguel Ojeda
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. RE: Talking to parallel port in 2.6 kernel without using parport

    Alan,

    That was a problem! The lp driver was already loaded. If I remove it and
    then load my driver, it returns with success from parport_register_device.
    Thanks for your help!

    Regards,
    Kathy

    -----Original Message-----
    From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk]
    Sent: Friday, April 25, 2008 1:12 PM
    To: Kathy Frazier
    Cc: 'Kathy Frazier'; linux-kernel@vger.kernel.org
    Subject: Re: Talking to parallel port in 2.6 kernel without using parport

    > One of our engineers downloaded source code a while back from
    > linux-2.6.18-rc7, but I am not sure how close that is to what is
    > installed on my system (uname -r returns 2.6.18-1.2798.fc6. When I
    > set my printk to 8 (echo 8 > /proc/sys/kernel/printk), there are no
    > messages shown on the failure. According to the source code I have,
    > the only silent failure in parport_register_device is:


    Nothing immediately strikes me.

    > When I change the flags from PARPORT_FLAG_EXCL to 0 in the call to
    > parport_register_device, the call returns a non-zero to indicate success.


    Do you have the printer driver loaded already ? (and does it behave if you
    do rmmod lp first)

    > Can you tell me what I am missing? Where can I get the actual source
    > code that goes with this version to further unravel this?


    From the .fc6 it would be an old Fedora kernel so very close to standard
    2.6.18 from kernel.org, but the Fedora Core kernels are available from the
    Fedora download pages - the .srpm package for each kernel is the one
    matching the same binary - so google for "2.6.18-1.2798.fc6.src.rpm"

    http://www.mjmwired.net/resources/mjm-fedora-fc6.html has a few notes on it.


    To be honest this area of the kernel hasn't changed much over recent times.
    Let me know if you can't figure out what is going on.

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. RE: Talking to parallel port in 2.6 kernel without using parport

    Miguel,

    Thanks for your response! I took a look at ks0108.c. You are right: very
    straightforward and a good reference. I had added some other things based
    on what I saw in /drivers/char/ppdev.c, lp.c and tipar.c. After reviewing
    yours, I am realizing I really don't need some of that, so I can simplify
    mine.

    My biggest problem was that lp was loaded. When I remove that, my call to
    parport_register_device returns success!

    Thanks for your help!

    Regards,
    Kathy



    -----Original Message-----
    From: Miguel Ojeda [mailto:miguel.ojeda.sandonis@gmail.com]
    Sent: Friday, April 25, 2008 2:18 PM
    To: Alan Cox
    Cc: Kathy Frazier; linux-kernel@vger.kernel.org
    Subject: Re: Talking to parallel port in 2.6 kernel without using parport

    > > Can you tell me what I am missing? Where can I get the actual

    > source code > that goes with this version to further unravel this?


    About two years ago (~2.6.18) I wrote one driver that needed exclusive
    access to the parallel port and, like this time, Alan Cox guided me (thank
    you Alan!). If you want, you can check the code at
    drivers/auxdisplay/ks0108.c. I tested it as of 2.6.25 and worked fine, so it
    could be a good reference for you. In addition, the code is pretty
    straightforward!

    >
    > To be honest this area of the kernel hasn't changed much over recent
    > times. Let me know if you can't figure out what is going on.
    >


    Right, I haven't had to change the code since 2.6.18.

    --
    Miguel Ojeda

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. Re: Talking to parallel port in 2.6 kernel without using parport

    On Mon, Apr 28, 2008 at 8:06 PM, Kathy Frazier
    wrote:
    > Miguel,
    >
    > Thanks for your response! I took a look at ks0108.c. You are right: very
    > straightforward and a good reference. I had added some other things based
    > on what I saw in /drivers/char/ppdev.c, lp.c and tipar.c. After reviewing
    > yours, I am realizing I really don't need some of that, so I can simplify
    > mine.


    I'm glad the code is helpful.

    >
    > My biggest problem was that lp was loaded. When I remove that, my call to
    > parport_register_device returns success!
    >


    Yeah, I made the same mistake two years ago too.

    >
    > Thanks for your help!
    >


    You are welcome!

    --
    Miguel Ojeda
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread