April 2, 2013

parport_pc driver parallel port detection with manually provided io ports.

Forums: 

Hi,

I've been recently trying to use my cheap pci parallel port card based on ch353 chip. Unfortunately parport_pc driver works in a following way:

insmod parport_pc

It recognizes my build-in parallel port (port 0x378), but does not detect the card.
When I try (0xa800 is the pci card port):

insmod parport_pc io=0x378,0xa800

Then my pci card works well but the driver cannot recognize built-in parallel port, dmesg
gives something like this:

parport 0x378 (WARNING): CTR: wrote 0x0c, read 0xff
parport 0x378 (WARNING): DATA: wrote 0xaa, read 0xff
parport 0x378: You gave this address, but there is probably no parallel port there!

Now, when I look at the driver (linux/drivers/parport/parport_pc.c) the init function looks like this:

3611 static int __init parport_pc_init(void)
3612 {
...
3622 if (io[0]) {
3623 int i;
3624 /* Only probe the ports we were given. */
3625 user_specified = 1;
3626 for (i = 0; i < PARPORT_PC_MAX_PORTS; i++) {
3627 if (!io[i])
3628 break;
3629 if (io_hi[i] == PARPORT_IOHI_AUTO)
3630 io_hi[i] = 0x400 + io[i];
3631 parport_pc_probe_port(io[i], io_hi[i],
3632 irqval[i], dmaval[i], NULL, 0);
3633 }
3634 } else
3635 parport_pc_find_ports(irqval[0], dmaval[0]);
3636
3637 return 0;
3638 }

The reason for such behaviour seems to be obvious. The driver checks standard
ports only if no io= ports has been specified (and io= doesn't seem to work with
standard ports).

Now if I do something like this (move autodetection out of if-else statement):

3611 static int __init parport_pc_init(void)
3612 {
...
3620 parport_pc_find_ports(irqval[0], dmaval[0]);
3621
3622 if (io[0]) {
3623 int i;
3624 /* Only probe the ports we were given. */
3625 user_specified = 1;
3626 for (i = 0; i < PARPORT_PC_MAX_PORTS; i++) {
3627 if (!io[i])
3628 break;
3629 if (io_hi[i] == PARPORT_IOHI_AUTO)
3630 io_hi[i] = 0x400 + io[i];
3631 parport_pc_probe_port(io[i], io_hi[i],
3632 irqval[i], dmaval[i], NULL, 0);
3633 }
3634 }
3635
3636 return 0;
3637 }

Now autodetection seems to work and I can use both parallel ports.

Does anybody know what is the reason for parport_pc driver to work this way?
Is it a bug or am I missing something?

Regards

Click Here!