lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20091006073233.GA66182@atlantis.8hz.com>
Date:	Tue, 6 Oct 2009 07:32:33 +0000
From:	Sean Young <sean@...s.org>
To:	Alan Cox <alan@...rguk.ukuu.org.uk>
Cc:	David Härdeman <david@...deman.nu>,
	linux-kernel@...r.kernel.org, jesse.barnes@...el.com
Subject: Re: [RFC/PATCH] Winbond CIR driver for the WPCD376I chip (ACPI/PNP id WEC1022)

On Thu, Jun 25, 2009 at 02:35:33PM +0100, Alan Cox wrote:
> On Thu, 25 Jun 2009 15:28:31 +0200 (CEST)
> David Härdeman <david@...deman.nu> wrote:
> > On Thu, June 25, 2009 15:17, Alan Cox wrote:
> > >> Which way of stopping the serial layer from grabbing the port did you
> > >> have in mind?
> > >
> > > You can vanish it with setserial as stands. There isn't a good
> > > interface for doing that from kernel side but as you can see from
> > > setserial the infrastructure is all there to add it.
> > 
> > Seems user-unfriendly...wouldn't blacklisting that particular port (using
> > ACPI or PNP id or something) be a better solution?
> 
> Possibly - what I am saying is that the mechanisms exist internally for
> this including flipping a port at run time between IR and normal modes
> when appropriate

Thanks to the documentation Jesse Barnes provided me:

This particular "serial port" is a bastardised serial port. From a 
software perspective it looks like a serial port with extensions, but 
it can only function as an IR device to the physical world (there are no 
uart pins for this port on the superio chip). So there is no reason 
to flip to "uart" mode.

Due to the extensions it can't be used with just the serial interface; 
some functions won't be available to userspace.

The problem here is that arch/x86/include/asm/serial.h defines 
SERIAL_PORT_DFN, which lists the four serial ports which are detected 
in serial8250_isa_init_ports(). The bastardised IR serial port is 
detected as a serial port and then cannot be claimed by the winbond-cir 
driver.

There is a real serial port on this superio chip which is accurately 
described by PNP. Should we really be guessing what hardware is present
and then getting a false positive on modern x86 hardware?

Alternatively, we could:

1) Detect the type of port better and discard it as unusable

I'm not sure this can be done. On an earlier version of this Super I/O 
chip (the PC8374L), this port can be used as an uart and I can't find no
way of detecting the difference other than the Super I/O chip (see below).

2) Detect the presence of the WEC1022 PNP id, somehow

Not sure how this can be done, depends on initialisation order.

3) Detect the Super I/O chip and ignore this port

This is done in the patch below. Any review comments would be appreciated;
it does work.

Actually, Super I/O detection is done in several places in the tree. 
Shouldn't there be a central place which does this detection? This would
also allow switching of port modes on Super I/O chips which do support
that.

4) Make the port vanish.

Having hardware appear and disappear because it doesn't really exist seems
like a horrible kludge to me.

Thanks,
Sean
-- 
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index b1ae774..0555453 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -926,6 +926,36 @@ static int broken_efr(struct uart_8250_port *up)
 	return 0;
 }
 
+#ifdef CONFIG_X86
+/*
+ * The WPCD376I has one fake NS16550 port (the second serial port) which can
+ * only be used for IR purposes. It cannot be used as an UART.
+ */
+#define CHIP_ID_REG	0x20	/* Super I/O ID (SID) / family */
+#define CHIP_REV_REG	0x27	/* Super I/O revision ID (SRID) */
+
+static int superio_is_WPCD376I()
+{
+	int rc = -ENOENT;
+
+	if (!request_region(0x2e, 2, "wpcd376i"))
+		return -EBUSY;
+
+	outb(CHIP_ID_REG, 0x2e);
+	if (inb(0x2e) != CHIP_ID_REG || inb(0x2f) != 0xf1)
+		goto out;
+
+	outb(CHIP_REV_REG, 0x2e);
+	if (inb(0x2e) == CHIP_REV_REG && (inb(0x2f) & 0xe0) == 0x80)
+		rc = 0;
+
+out:
+	release_region(0x2e, 2);
+
+	return rc;
+}
+#endif
+
 /*
  * We know that the chip has FIFOs.  Does it have an EFR?  The
  * EFR is located in the same register position as the IIR and
@@ -1006,9 +1036,14 @@ static void autoconfig_16550a(struct uart_8250_port *up)
 
 			serial_outp(up, UART_LCR, 0);
 
-			up->port.uartclk = 921600*16;
-			up->port.type = PORT_NS16550A;
-			up->capabilities |= UART_NATSEMI;
+			if (!superio_is_WPCD376I()) {
+				up->capabilities &= ~UART_CAP_FIFO;
+				up->port.type = PORT_UNKNOWN;
+			} else {
+				up->port.uartclk = 921600*16;
+				up->port.type = PORT_NS16550A;
+				up->capabilities |= UART_NATSEMI;
+			}
 			return;
 		}
 	}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ