comedi_parport vs. parport_pc in ACPI systems

46 views
Skip to first unread message

Der Alte

unread,
Sep 29, 2020, 9:51:16 AM9/29/20
to Comedi: Linux Control and Measurement Device Interface

Hi folks,
parport_pc must never be loaded (and rmmod-ed) if comedi_parport shall use the port!

After 2 weeks of searching  I found out, why comedi_parport always  returns
0x00FF on subdev 0 and 0x001F on subdev 1 when read (using "monitor").

After  
rmmod ppdev parport_pc
, which I had to do to allow
comedi_config -v /dev/comedi2 comedi_parport 0x0278,5
without conflict, there is no   sw-visible parallel port hardware! :-O

The parallel port is on a Supermicro X7DAL mainboard  and setup to use address 0x0278 anf IRQ 5.
If ACPI is enabled (in BIOS), parport_pc will automatically claim the parport hardware and
comedi_config -v /dev/comedi2 comedi_parport 0x0278,5   will cause
Sep 29 10:18:42 Node-06 kernel: comedi comedi2: comedi_parport: I/O port conflict (0x278,3)
rmmod ppdev parport_pc   will produce
Sep 29 10:19:20 Node-06 kernel: parport_pc 00:06: disabled
After that the  "comedi_config" call seems to succeed without error but the driver behaves as if any empty fantasy address is given. :-(

On the other hand
modprobe parport_pc    (without comedy_parport attached) produces
Sep 29 10:29:57 Node-06 kernel: parport_pc 00:06: activated
Sep 29 10:29:57 Node-06 kernel: parport_pc 00:06: reported by Plug and Play ACPI
Sep 29 10:29:57 Node-06 kernel: parport0: PC-style at 0x278 (0x678), irq 5, dma 3 [PCSPP,TRISTATE,COMPAT,EPP,ECP,DMA]
Sep 29 10:29:57 Node-06 kernel: ppdev: user-space parallel port driver

The line   "kernel: parport_pc 00:06: activated"  made me wonder...

It seems like the parport hardware is really no longer visible after parport_pc is unloaded!

This does not apply a WCH38xx parport card in a PCIe slot which we  prchased to test comedi_parport. But that one uses IRQ 16 which comedi_config seems to be unable to handle. :-(

After my suspicion that parport_pc leaves an unuseable parport I first deactivated ACPI in the BIOS and indeed parport_pc was not loaded anymore, but also the serial ports were invisible.
But comedy_parport finally began to work! :-)
The data port reads 0x0000 and the 5-bit input subdevice 1 only reads 0x000F without external connections. My test plug which grounds 2 pins ( /ACK and PE ) now finally changes the value to 0x0003. :-)

I decided to turn on ACPI again and blacklist parport_pc and ppdev in
/etc/modprobe.d/99-comedi.conf

So that file now looks like:

blacklist ppdev
blacklist parport_pc
options comedi comedi_num_legacy_minors=4

Maybe we should add a comment with a hint in the source file of comedi_parport.c and in the comedi documemtation. I searched for "parport" in comedilib.pdf and found nothing helpful.

The next thing I found out is that my
printk ("parport_interrupt() nsd=%d ", dev->n_subdevices);
is never called so far even if I force falling and rising edges on the  /ACK pin.
In "monitor" I see the bits toggle as I switch the signal level but the ISR is not called so far. That is probably caused by the semantics of the driver, which only  enables the interrupt in
parport_intr_cmd() and disables it again in parport_intr_cancel().

Seems like I first have to find an adequate demo program in ./comedilib-0.12.0/demo/ or learn to write one to test the interrupt functionality of the comedi_parport and then also adl_pci7x3c and adv_pci_dio...

Greetings,
Bernd Harries











Ian Abbott

unread,
Sep 29, 2020, 12:34:50 PM9/29/20
to comed...@googlegroups.com
The parallel port may have been left in an enhanced mode by the
parport_pc driver. It must be at least 10 years since I tried using
comedi_parport, but I think it only works if the port is in "SPP" mode.

> This does not apply a WCH38xx parport card in a PCIe slot which we
> prchased to test comedi_parport. But that one uses IRQ 16 which
> comedi_config seems to be unable to handle. :-(

That may be because the comedi_parport driver does not set the
IRQF_SHARED flag when it calls request_irq() (which is reasonable since
it was only really meant to be used with ISA bus or built-in parallel
ports). Perhaps IRQ 16 is already taken by another device (cat
/proc/interrupts)?

> After my suspicion <https://www.dict.cc/?s=suspicion> that parport_pc
> leaves an unuseable parport I first deactivated ACPI in the BIOS and
> indeed parport_pc was not loaded anymore, but also the serial ports were
> invisible.

I should be possible to limit the parallel port mode to "SPP" in the
BIOS settings, which should stop the parport_pc driver leaving the port
in an enhanced mode when the module is unloaded.

> But comedy_parport finally began to work! :-)
> The data port reads 0x0000 and the 5-bit input subdevice 1 only reads
> 0x000F without external connections. My test plug which grounds 2 pins (
> /ACK and PE ) now finally changes the value to 0x0003. :-)
>
> I decided to turn on ACPI again and blacklist parport_pc and ppdev in
> /etc/modprobe.d/99-comedi.conf
>
> So that file now looks like:
>
> blacklist ppdev
> blacklist parport_pc
> options comedi comedi_num_legacy_minors=4
>
> Maybe we should add a comment with a hint in the source file of
> comedi_parport.c and in the comedi documemtation. I searched for
> "parport" in comedilib.pdf and found nothing helpful.

I suppose it would be nice if it mentioned SPP mode somewhere!

>
> The next thing I found out is that my
> printk ("parport_interrupt() nsd=%d ", dev->n_subdevices);
> is never called so far even if I force falling and rising edges on the
> /ACK pin.
> In "monitor" I see the bits toggle as I switch the signal level but the
> ISR is not called so far. That is probably caused by the semantics of
> the driver, which only  enables the interrupt in
> parport_intr_cmd() and disables it again in parport_intr_cancel().
>
> Seems like I first have to find an adequate demo program in
> ./comedilib-0.12.0/demo/ or learn to write one to test the interrupt
> functionality of the comedi_parport and then also adl_pci7x3c and
> adv_pci_dio...

The existing demo programs seem to use timed commands, which won't work
with comedi_parport. The "ledclock" demo might do something.

>
> Greetings,
> Bernd Harries


--
-=( Ian Abbott <abb...@mev.co.uk> || MEV Ltd. is a company )=-
-=( registered in England & Wales. Regd. number: 02862268. )=-
-=( Regd. addr.: S11 & 12 Building 67, Europa Business Park, )=-
-=( Bird Hall Lane, STOCKPORT, SK3 0XA, UK. || www.mev.co.uk )=-

Der Alte

unread,
Oct 1, 2020, 6:35:20 AM10/1/20
to Comedi: Linux Control and Measurement Device Interface


Hi Ian,

thanks for your help.
IIRC, I already tried to  limit the parallel port mode to "SPP" in the
BIOS settings last week. I tried all 4 possible modes.
That limited the resource size (range 27b .. 27f  was no longer claimed ) but did not help as far as I remember.
But I want to try it again soon.

My feeling is that the hardware becomes completely invisible like an empty address range. The x86 -arch doesn't have /DTACK and /BERR as I know it from the good old Motorola 68k arch (ATARI clone with 68040 cpu) and so the read access to the IO addresses just result in all 1s on the data bus.

But anyway, I will check the PP-modes again later.

Greetings, Bernd

Der Alte

unread,
Oct 1, 2020, 6:45:19 AM10/1/20
to Comedi: Linux Control and Measurement Device Interface
Hi Ian,

IRQ 16 of the PCIe parport  is indeed shared with other devices.

Node-01:~ # cat /proc/interrupts
...
  16:         84          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   16-fasteoi   ehci_hcd:usb1, pci1730, parport0
...

Would or_ing  IRQF_SHARED  to the flags  help here  or would it insist in shared IRQs and no longer allow ISA IRQs?

Ciao, Bernd





Ian Abbott schrieb am Dienstag, 29. September 2020 um 18:34:50 UTC+2:

Ian Abbott

unread,
Oct 1, 2020, 7:50:13 AM10/1/20
to comed...@googlegroups.com
Hi Bernd,


On 01/10/2020 11:45, Der Alte wrote:
Hi Ian,

IRQ 16 of the PCIe parport  is indeed shared with other devices.

Node-01:~ # cat /proc/interrupts
...
  16:         84          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0          0  IR-IO-APIC   16-fasteoi   ehci_hcd:usb1, pci1730, parport0
...

Would or_ing  IRQF_SHARED  to the flags  help here  or would it insist in shared IRQs and no longer allow ISA IRQs?

Ciao, Bernd

You can OR in the IRQF_SHARED flag for your local testing with a PCI parallel card. This will not be done in the upstream version that is meant for use with ISA ports that do not have shared interrupts.

The PCI device's I/O and/or memory regions might be disabled in the "Command" register in the PCI type 0 configuration header. (Bit 0 enables I/O access and bit 1 enables memory access.). It is possible to enable it by writing "1" to the PCI device's /sys/bus/pci/devices/XXXX/enable file.

Der Alte

unread,
Oct 1, 2020, 10:44:46 AM10/1/20
to Comedi: Linux Control and Measurement Device Interface
Hi Ian,

I have now set the onboard legacy parport on the X7DAL to a simpler mode,  look at [ 3259.722814] below,
and look what happens:
parport_pc is still blacklisted and thus comedi_parport first works after reboot.

[ 1453.069921] parport_attach() 2020_10_01_13:00 
[ 1469.558328] parport_intr_cmdtest() 2020_10_01_13:00 
[ 1469.558386] parport_intr_cmdtest() 2020_10_01_13:00 
[ 1469.558457] parport_intr_cmdtest() 2020_10_01_13:00 
[ 1469.558463] parport_intr_cmd() 2020_10_01_13:00 
[ 1482.303369] parport_interrupt() nsd=4
[ 1482.303385] parport_interrupt() nsd=4
[ 1485.974679] parport_interrupt() nsd=4
[ 3204.046891] parport_intr_cancel() 2020_10_01_13:00 
[ 3259.722723] parport_pc 00:07: reported by Plug and Play ACPI
[ 3259.722814] parport0: PC-style at 0x278, irq 5 [PCSPP]
[ 3309.449007] parport_pc 00:07: disabled
[ 3887.535855] parport_attach() 2020_10_01_13:00 

At [ 3204.046891] I Itopped the test, unloaded comedi_parport and modprobed parport_pc.
It would not print "activated" as the device was not disabled initially.
But as soon as I unload parport_pc, it leaves the hardware "disabled"   at [ 3309.449007]

channel             data                                                       
dio 0:0:00          0000 0000 1111 1111                     DD=$00FF
 di 0:1:00          0000 0000 0001 1111                     DD=$001F
 do 0:2:00          0000 0000 0000 0000                     DD=$0000
 di 0:3:00          0000 0000 0000 0000                     DD=$0000

To me it looks like unloading parport_pc has turned off the HW by some pnp_xyz () call.

Ciao, Bernd

Ian Abbott

unread,
Oct 2, 2020, 5:40:58 AM10/2/20
to comed...@googlegroups.com, Der Alte
Hi Bernd,
Indeed, it looks like pnp_device_remove() in "drivers/pnp/driver.c"
calls the device driver's ->remove() handler (which will be pointing to
the parport_pc_pnp_remove() function in "drivers/parport/parport_pc.c")
and then calls pnp_disable_dev() in "drivers/pnp/manager.c" to
deactivate it.

You can look at the state of the resources by:

cat /sys/bus/pnp/devices/00:07/resources

It will probably report "state = disabled" on the first line. You
should be able to activate it by writing the word "activate" to the same
file:

sudo sh -c "echo activate > /sys/bus/pnp/devices/00:07/resources"

Then read the resources file again and it should hopefully report "state
= active" on the first line.

Der Alte

unread,
Oct 2, 2020, 8:36:32 AM10/2/20
to Comedi: Linux Control and Measurement Device Interface
Hi Ian,

thanks for your detailed help!

Yes indeed, I could activate the device with e
cho activate > /sys/bus/pnp/devices/00:07/resources
even while monitor was running.
The values immediately changed fromm $00FF and $001F to the values shown below.
I have only the  PE line (0x04) grounded in the moment.

Fri Oct  2 12:15:14 202       000005 Jan  1 00:00:00 1970 UTC +000000us
channel             data                                                       
dio 0:0:00          0000 0000 0000 0100                     DD=$0004
 di 0:1:00          0000 0000 0000 1011                     DD=$000B

 do 0:2:00          0000 0000 0000 0000                     DD=$0000
 di 0:3:00          0000 0000 0000 0000                     DD=$0000

Maybe it's time to add some if-s and some of the pnp_xyz calls to comedi_parport, too. :-)

I have cloned and modified the ledclock.c  demo to a "ext_trig.c" and call gettimeofday() after select() returns with a filled fd_set. It works with comedi_parport, adl_pci7x3x and adv_pci_dio. I even started multiple instances of the Program. One is on the IDI0 (sd 7) subdev and one is on the IDI1 subdev (sd 8).
and it seems to work so far. But of course, the external push buttons and switches which I connected for testing are bouncing and thus cause multiple interrupts when pressed...

Greetings, Bernd

Der Alte

unread,
Oct 2, 2020, 11:14:58 AM10/2/20
to Comedi: Linux Control and Measurement Device Interface
Hi Ian,

> You can OR in the IRQF_SHARED flag for your local testing with a PCI parallel card. This will not be done
> in the upstream version that is meant for use with ISA ports that do not have shared interrupts.

I tried that today but that seems not enough because the ISR is not smart enough for shared IRQs.
Our pci1730 also uses IRQ 16 and parport doesn't assume such situations.

So I tried something like this in parport_interrupt() to check the STATUS_REG also:
  ...
    ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
    if (!(ctrl & PARPORT_CTRL_IRQ_ENA))
        return IRQ_NONE;

   stat_reg = inb(dev->iobase + PARPORT_STATUS_REG);
    if(stat_reg & 0x04)
        return IRQ_NONE;

    if((stat_reg & 0x04) == 0)  /* /ACK Pulse occurred */
    {
      ISRprintf(" /ACK sd%u r_of=%02X stat=%d \n", 3, PARPORT_CTRL_REG, stat_reg);
      comedi_buf_write_samples(s, &stat_reg  /*s->state*/, 1);
      comedi_handle_events(dev, s);
    }
    /*endif*/
    return IRQ_HANDLED;

Ciao, Bernd

Der Alte

unread,
Oct 5, 2020, 4:36:29 AM10/5/20
to Comedi: Linux Control and Measurement Device Interface
Hi Folks,

Friday I wrote:
>  if((stat_reg & 0x04) == 0)  /* /ACK Pulse occurred */

Hmm, it looks like that bit doesn't behave the same on all HW generations. In the older chipsets it isn't cleared after an /ACK-edge occurred. Thus ii might not be so easy to find out wether the parport was the source of the IRQ.

Ciao, Bernd
Reply all
Reply to author
Forward
0 new messages