Re: How to access serial port that is set in BIOS as OS Controlled

From: Bjorn Helgaas
Date: Thu Aug 11 2011 - 17:49:46 EST

On Thu, Aug 11, 2011 at 3:07 AM, Jeff Chua <jeff.chua.linux@xxxxxxxxx> wrote:
> On Thu, Aug 11, 2011 at 12:46 AM, Bjorn Helgaas <bhelgaas@xxxxxxxxxx> wrote:
>> On Fri, Aug 5, 2011 at 7:02 PM, Jeff Chua <jeff.chua.linux@xxxxxxxxx>
> wrote:
>> Ping, just a reminder :)
>> I'm pretty sure Linux only runs _SRS when we actually *change* something,
>> which doesn't seem to follow the intent of the spec.  So if
>> we can get a little more evidence here, I think it'd be worth changing
>> Linux to call _SRS for every device when it enumerates it.
> I did some test and it seems "auto" didn't enable the port. With "auto",
> dmesg showed more info (io 0x3e8-0x3ef irq 6), but port still disabled.
> After "activate", then the port can be used.

Yep, that's what I would expect. "auto" does some work in the kernel
to choose resources that look like they should work, but it doesn't
touch the firmware or the hardware itself. "activate" evaluates the
ACPI _SRS method, which is how we tell the firmware what resources we
want. The _SRS method would program those into the hardware.

> I've attached the DSDT.dat.dsl. I've reconfigured the kernel with
> CONFIG_PNP_DEBUG_MESSAGES=y, booting with "pnp.debug", but there were not a
> lot of messages in dmesg.

Oops, my mistake. You now need "pnp.debug=1" to turn the extra debug
on (I just posted a patch to update

> 00:0a PNP4972 (unknown)

> # cat /sys/bus/pnp/devices/00:0a/resources
> state = disabled
> io 0x3e8-0x3ef
> irq 6
> # setserial /dev/ttyS2 uart 16550a irq 6
> ttyS2: LSR safety check engaged!
> ttyS2: LSR safety check engaged!

Hmm, the fact that you need "setserial" is telling us there's another
Linux bug here. PNP4972 is not one of the PNP IDs the 8250_pnp driver
knows about (I would have expected ACPI to supply a "compatible device
ID" of PNP0501 so we could fall back to the generic 8250_pnp driver),
so we currently don't have a path to get the I/O port address or the
IRQ info to the serial driver automatically. On x86, the 8250 driver
has some hardcoded addresses compiled into it (ttyS2 at 0x3e8 being
one of them), and "setserial" is the manual way of changing the
default IRQ 4 to IRQ 6.

> # echo disable > /sys/bus/pnp/devices/00:0a/resources
> # dmesg
> pnp 00:0a: disabled
> # cat /sys/bus/pnp/devices/00:0a/resources
> state = disabled
> # echo activate > /sys/bus/pnp/devices/00:0a/resources
> -bash: echo: write error: Device or resource busy

This *should* work. My guess is that it's failing because the I/O
ports at 0x3e8 are still reserved. The PNP core doesn't actually
reserve anything, so it would have to be the 8250 driver. It doesn't
mention those ports in dmesg, so maybe they get reserved when you do
the "setserial." The 8250 driver has no idea that you disabled the
PNP device, so it would never release them. Then when you try to
activate it again, they're still in use. You can test this idea a
little bit by looking at /proc/ioports (1) immediately after boot, (2)
before "setserial", (3) after "setserial", and (4) after you disable
the PNP device.

I attached an experimental patch that add PNP4972 to the 8250_pnp
driver and tries to automatically activate devices. Can you give it a
try (with "pnp.debug=1")?


Attachment: intermec-uart
Description: Binary data