2005-12-07 15:44:31

by Jason Dravet

[permalink] [raw]
Subject: wrong number of serial port detected

Hello,

I have a question about the way serial ports are detected. Since I started
using udev last year I noticed 32 ttySxx nodes in my /dev directory. I
checked dmesg and the serial port driver was detecting 32 ports. Here is
the line from dmesg:
Serial: 8250/16550 driver $Revision: 1.90 $ 32 ports, IRQ sharing enabled
In fact I don't have 32 ports. I have two serial ports on the motherboard,
both of which are disabled in the BIOS. I opened a bug in RedHat's bugzilla
system and it was promptly closed saying this was unfixable. I was told
that the kernel loaded the maximum number of ports supported by the serial
port driver. I asked why and I have not received a response. So I ask this
mailing list Can the kernel detect the proper number of serial ports or not?

Thanks,
Jason



2005-12-07 15:50:57

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 09:44:29AM -0600, Jason Dravet wrote:
> So I ask this mailing list Can the kernel detect the proper number of
> serial ports or not?

It does detect serial ports found in the machine.

However, it _always_ offers the configured number of serial devices.
This is to allow folk whose ports are not autodetected to configure
them appropriately via the setserial command. If they were not
available, they could not configure them.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-07 19:59:45

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Russell King <[email protected]>
>To: Jason Dravet <[email protected]>
>CC: [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Wed, 7 Dec 2005 15:50:34 +0000
>
>On Wed, Dec 07, 2005 at 09:44:29AM -0600, Jason Dravet wrote:
> > So I ask this mailing list Can the kernel detect the proper number of
> > serial ports or not?
>
>It does detect serial ports found in the machine.
>
>However, it _always_ offers the configured number of serial devices.
>This is to allow folk whose ports are not autodetected to configure
>them appropriately via the setserial command. If they were not
>available, they could not configure them.
>
Then may I ask how XP does it? I have to dual boot between XP and Fedora.
When I go into XP's device manager I see all of the appropriate hardware
listed, no extra serial ports. When I boot into Fedora and go into /dev, I
see the same hardware except I have 32 serial ports and 64 tty nodes (tty is
for virtual terminals right?). How can 1 OS show the correct number and
another show the wrong number? I ask so I can better understand what is
going on.

Thanks,
Jason


2005-12-07 21:15:58

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 01:59:43PM -0600, Jason Dravet wrote:
> >From: Russell King <[email protected]>
> >To: Jason Dravet <[email protected]>
> >CC: [email protected]
> >Subject: Re: wrong number of serial port detected
> >Date: Wed, 7 Dec 2005 15:50:34 +0000
> >
> >On Wed, Dec 07, 2005 at 09:44:29AM -0600, Jason Dravet wrote:
> >> So I ask this mailing list Can the kernel detect the proper number of
> >> serial ports or not?
> >
> >It does detect serial ports found in the machine.
> >
> >However, it _always_ offers the configured number of serial devices.
> >This is to allow folk whose ports are not autodetected to configure
> >them appropriately via the setserial command. If they were not
> >available, they could not configure them.
> >
> Then may I ask how XP does it? I have to dual boot between XP and Fedora.
> When I go into XP's device manager I see all of the appropriate hardware
> listed, no extra serial ports. When I boot into Fedora and go into /dev, I
> see the same hardware except I have 32 serial ports and 64 tty nodes (tty
> is for virtual terminals right?). How can 1 OS show the correct number and
> another show the wrong number? I ask so I can better understand what is
> going on.

It seems you are comparing apples (XP's device manager) with oranges
(/dev directory). They're two entirely different things.

The former lists devices which _are_ present in your system.

The latter provides the filesystem namespace for applications to access
devices which may or may not be present in your system.

I think you completely missed the second half of my point, and I'd like
to illustrate what would happen if we were to only provide serial devices
in /dev which actually existed:

1. We would only provide /dev/ttyS devices which actually existed,
which may mean just /dev/ttyS0.

2. User adds a custom serial card in their system which adds 16
additional serial ports, but is not PCI based, so is not known
to BIOS.

3. Neither XP nor Linux will find this automatically without some
help (eg, a vendor supplied driver for XP).

4. User tries the well documented "setserial /dev/ttyS2 port 0x220 irq 5"
procedure, which has been supported since Linux 1.x

5. User finds that, because there is no ttyS2 device in /dev, they
can't configure their card.

6. User files a bug.

As for your 64 VT tty device nodes - these "devices" are created
dynamically when the device node is opened. The act of opening the
device node is defined to be the creation event. If the device node
did not exist, there would be no way to create _any_ virtual terminals.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-07 21:28:12

by Xavier Bestel

[permalink] [raw]
Subject: Re: wrong number of serial port detected

Le mercredi 07 d?cembre 2005 ? 21:15 +0000, Russell King a ?crit :

> 4. User tries the well documented "setserial /dev/ttyS2 port 0x220 irq 5"
> procedure, which has been supported since Linux 1.x
>
> 5. User finds that, because there is no ttyS2 device in /dev, they
> can't configure their card.

Well, instead of polluting everybody's /dev for the 3 users having such
cards, why not just tell the user to run
MAKEDEV /dev/ttyS2 ; setserial /dev/ttyS2 port 0x220 irq 5
instead ? (Or even mknod)

Xav


2005-12-07 21:31:35

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 10:28:05PM +0100, Xavier Bestel wrote:
> Le mercredi 07 d?cembre 2005 ? 21:15 +0000, Russell King a ?crit :
>
> > 4. User tries the well documented "setserial /dev/ttyS2 port 0x220 irq 5"
> > procedure, which has been supported since Linux 1.x
> >
> > 5. User finds that, because there is no ttyS2 device in /dev, they
> > can't configure their card.
>
> Well, instead of polluting everybody's /dev for the 3 users having such
> cards, why not just tell the user to run
> MAKEDEV /dev/ttyS2 ; setserial /dev/ttyS2 port 0x220 irq 5
> instead ? (Or even mknod)

Oh sorry. Mail me your root password and IP address, let me log in
to your system, and I'll remove those device nodes right now. Thanks
for pointing that out.

Seriously, surely you aren't suggesting that I somehow have personal
control over this?

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-07 21:39:04

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 09:31:28PM +0000, Russell King wrote:
> On Wed, Dec 07, 2005 at 10:28:05PM +0100, Xavier Bestel wrote:
> > Le mercredi 07 d?cembre 2005 ? 21:15 +0000, Russell King a ?crit :
> >
> > > 4. User tries the well documented "setserial /dev/ttyS2 port 0x220 irq 5"
> > > procedure, which has been supported since Linux 1.x
> > >
> > > 5. User finds that, because there is no ttyS2 device in /dev, they
> > > can't configure their card.
> >
> > Well, instead of polluting everybody's /dev for the 3 users having such
> > cards, why not just tell the user to run
> > MAKEDEV /dev/ttyS2 ; setserial /dev/ttyS2 port 0x220 irq 5
> > instead ? (Or even mknod)
>
> Oh sorry. Mail me your root password and IP address, let me log in
> to your system, and I'll remove those device nodes right now. Thanks
> for pointing that out.
>
> Seriously, surely you aren't suggesting that I somehow have personal
> control over this?

Additionally, if you have a problem with this, the total number of
ports _is_ kernel configurable.

So if you're getting 32 ports from a distro targetted at the current
range of consumer hardware which commonly has maybe 1 or 2 and
possibly a modem card (iow probably max 4 ports), please take it up
with them.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-07 23:04:30

by Dave Jones

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 09:38:56PM +0000, Russell King wrote:
> On Wed, Dec 07, 2005 at 09:31:28PM +0000, Russell King wrote:
> > On Wed, Dec 07, 2005 at 10:28:05PM +0100, Xavier Bestel wrote:
> > > Le mercredi 07 d?cembre 2005 ? 21:15 +0000, Russell King a ?crit :
> > >
> > > > 4. User tries the well documented "setserial /dev/ttyS2 port 0x220 irq 5"
> > > > procedure, which has been supported since Linux 1.x
> > > >
> > > > 5. User finds that, because there is no ttyS2 device in /dev, they
> > > > can't configure their card.
> > >
> > > Well, instead of polluting everybody's /dev for the 3 users having such
> > > cards, why not just tell the user to run
> > > MAKEDEV /dev/ttyS2 ; setserial /dev/ttyS2 port 0x220 irq 5
> > > instead ? (Or even mknod)
> >
> > Oh sorry. Mail me your root password and IP address, let me log in
> > to your system, and I'll remove those device nodes right now. Thanks
> > for pointing that out.
> >
> > Seriously, surely you aren't suggesting that I somehow have personal
> > control over this?
>
> Additionally, if you have a problem with this, the total number of
> ports _is_ kernel configurable.
>
> So if you're getting 32 ports from a distro targetted at the current
> range of consumer hardware which commonly has maybe 1 or 2 and
> possibly a modem card (iow probably max 4 ports), please take it up
> with them.

Ok, how about something along the lines of this (completely untested) patch,
which adds a runtime param to lower the number of registered ports,
also allowing a default to be set for common cases.

Would something like this be acceptable ?

It would mean that users of kernels with NR_UARTS currently set to 32
would either also have to set the new default if they build their own
kernels, or fiddle with a module param to see past their first four ports
if they run a vendor kernel.
Given these people are the minority use-case, adding one extra option
to their modprobe.conf doesn't seem too harsh, does it ?

Dave


diff -urpN --exclude-from=/home/devel/davej/.exclude vanilla/drivers/serial/8250.c linux-2.6.14/drivers/serial/8250.c
--- vanilla/drivers/serial/8250.c 2005-12-07 17:56:56.000000000 -0500
+++ linux-2.6.14/drivers/serial/8250.c 2005-12-07 17:51:52.000000000 -0500
@@ -54,6 +54,8 @@
*/
static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;

+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
/*
* Debugging.
*/
@@ -2118,7 +2120,7 @@ static void __init serial8250_isa_init_p
return;
first = 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.line = i;
@@ -2137,7 +2139,7 @@ static void __init serial8250_isa_init_p
}

for (i = 0, up = serial8250_ports;
- i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
+ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
@@ -2159,7 +2161,7 @@ serial8250_register_ports(struct uart_dr

serial8250_isa_init_ports();

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.dev = dev;
@@ -2262,7 +2266,7 @@ static int serial8250_console_setup(stru
* if so, search for the first available port that does have
* console support.
*/
- if (co->index >= UART_NR)
+ if (co->index >= nr_uarts)
co->index = 0;
port = &serial8250_ports[co->index].port;
if (!port->iobase && !port->membase)
@@ -2298,7 +2302,7 @@ static int __init find_port(struct uart_
int line;
struct uart_port *port;

- for (line = 0; line < UART_NR; line++) {
+ for (line = 0; line < nr_uarts; line++) {
port = &serial8250_ports[line].port;
if (p->iotype == port->iotype &&
p->iobase == port->iobase &&
@@ -2422,7 +2426,7 @@ static int __devexit serial8250_remove(s
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.dev == &dev->dev)
@@ -2435,7 +2439,7 @@ static int serial8250_suspend(struct pla
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
@@ -2449,7 +2453,7 @@ static int serial8250_resume(struct plat
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
@@ -2489,7 +2493,7 @@ static struct uart_8250_port *serial8250
/*
* First, find a port entry which matches.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (uart_match_port(&serial8250_ports[i].port, port))
return &serial8250_ports[i];

@@ -2498,7 +2502,7 @@ static struct uart_8250_port *serial8250
* free entry. We look for one which hasn't been previously
* used (indicated by zero iobase).
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
@@ -2507,7 +2511,7 @@ static struct uart_8250_port *serial8250
* That also failed. Last resort is to find any entry which
* doesn't have a real port associated with it.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
return &serial8250_ports[i];

@@ -2593,7 +2597,7 @@ static int __init serial8250_init(void)
int ret, i;

printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
- "%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+ "%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");

for (i = 0; i < NR_IRQS; i++)
@@ -2653,6 +2657,9 @@ module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
" (unsafe)");

+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported.");
+
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff -urpN --exclude-from=/home/devel/davej/.exclude vanilla/drivers/serial/Kconfig linux-2.6.14/drivers/serial/Kconfig
--- vanilla/drivers/serial/Kconfig 2005-12-07 17:56:56.000000000 -0500
+++ linux-2.6.14/drivers/serial/Kconfig 2005-12-07 17:53:34.000000000 -0500
@@ -95,6 +100,15 @@ config SERIAL_8250_NR_UARTS
PCI enumeration and any ports that may be added at run-time
via hot-plug, or any ISA multi-port serial cards.

+config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+ depends on SERIAL_8250
+ default "4"
+ help
+ Set this to the maximum number of serial ports you want
+ the kernel to register at boot time. This can be overriden
+ with the parameter "nr_uarts".
+
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250



2005-12-07 23:46:12

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 06:03:02PM -0500, Dave Jones wrote:
> Ok, how about something along the lines of this (completely untested) patch,
> which adds a runtime param to lower the number of registered ports,
> also allowing a default to be set for common cases.
>
> Would something like this be acceptable ?

Sure, looks fine. The new parameter should probably be documented
though, so folk know about it.

> @@ -2653,6 +2657,9 @@ module_param(share_irqs, uint, 0644);
> MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
> " (unsafe)");
>
> +module_param(nr_uarts, uint, 0644);
> +MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported.");

Should this help string include the compile-time maximum somehow?

What limits it to the compile-time maximum?

> diff -urpN --exclude-from=/home/devel/davej/.exclude vanilla/drivers/serial/Kconfig linux-2.6.14/drivers/serial/Kconfig
> --- vanilla/drivers/serial/Kconfig 2005-12-07 17:56:56.000000000 -0500
> +++ linux-2.6.14/drivers/serial/Kconfig 2005-12-07 17:53:34.000000000 -0500
> @@ -95,6 +100,15 @@ config SERIAL_8250_NR_UARTS
> PCI enumeration and any ports that may be added at run-time
> via hot-plug, or any ISA multi-port serial cards.
>
> +config SERIAL_8250_RUNTIME_UARTS
> + int "Number of 8250/16550 serial ports to register at runtime"
> + depends on SERIAL_8250
> + default "4"

Can this be restricted to a range of 1 to SERIAL_8250_UARTS ?

> + help
> + Set this to the maximum number of serial ports you want
> + the kernel to register at boot time. This can be overriden
> + with the parameter "nr_uarts".

And should we also give a pointer to the boot-time parameter (which
I think will be 8250.nr_uarts ?)

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-08 00:50:50

by Dave Jones

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 11:46:04PM +0000, Russell King wrote:

> > Would something like this be acceptable ?
> Sure, looks fine. The new parameter should probably be documented
> though, so folk know about it.

Where to? Looks like the other 8250 params aren't documented
in Documentation/ either.
If there's another good place for it already, I'll add it there.
Shall I just add it to kernel-parameters.txt ?

> > @@ -2653,6 +2657,9 @@ module_param(share_irqs, uint, 0644);
> > MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
> > " (unsafe)");
> >
> > +module_param(nr_uarts, uint, 0644);
> > +MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported.");
>
> Should this help string include the compile-time maximum somehow?

Done.

> What limits it to the compile-time maximum?

Hey, this was a rough & ready implementation ;)
I wanted to be sure you were ok with the principle of it first.
It now clips it to NR_UARTS.

> > +config SERIAL_8250_RUNTIME_UARTS
> > + int "Number of 8250/16550 serial ports to register at runtime"
> > + depends on SERIAL_8250
> > + default "4"
>
> Can this be restricted to a range of 1 to SERIAL_8250_UARTS ?

Heh, Seems not.
menuconfig gets very confused by range 1 CONFIG_SERIAL_8250_NR_UARTS
and won't let me set it to anything.
We can always add that later though if Kconfig gets fixed.

> > + help
> > + Set this to the maximum number of serial ports you want
> > + the kernel to register at boot time. This can be overriden
> > + with the parameter "nr_uarts".
>
> And should we also give a pointer to the boot-time parameter (which
> I think will be 8250.nr_uarts ?)

Done.

Here's another iteration. I'll boot test this in a bit, and if it
does the right thing, I'll add the documenation and a sign-off
and send it your way.

Dave


diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/8250.c serial/drivers/serial/8250.c
--- vanilla/drivers/serial/8250.c 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/8250.c 2005-12-07 19:33:33.000000000 -0500
@@ -53,6 +53,8 @@
*/
static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;

+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
/*
* Debugging.
*/
@@ -2047,7 +2049,7 @@ static void __init serial8250_isa_init_p
return;
first = 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.line = i;
@@ -2066,7 +2068,7 @@ static void __init serial8250_isa_init_p
}

for (i = 0, up = serial8250_ports;
- i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
+ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
@@ -2088,7 +2090,7 @@ serial8250_register_ports(struct uart_dr

serial8250_isa_init_ports();

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.dev = dev;
@@ -2189,7 +2191,7 @@ static int serial8250_console_setup(stru
* if so, search for the first available port that does have
* console support.
*/
- if (co->index >= UART_NR)
+ if (co->index >= nr_uarts)
co->index = 0;
port = &serial8250_ports[co->index].port;
if (!port->iobase && !port->membase)
@@ -2225,7 +2227,7 @@ static int __init find_port(struct uart_
int line;
struct uart_port *port;

- for (line = 0; line < UART_NR; line++) {
+ for (line = 0; line < nr_uarts; line++) {
port = &serial8250_ports[line].port;
if (p->iotype == port->iotype &&
p->iobase == port->iobase &&
@@ -2349,7 +2351,7 @@ static int __devexit serial8250_remove(s
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.dev == dev)
@@ -2365,7 +2367,7 @@ static int serial8250_suspend(struct dev
if (level != SUSPEND_DISABLE)
return 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
@@ -2382,7 +2384,7 @@ static int serial8250_resume(struct devi
if (level != RESUME_ENABLE)
return 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
@@ -2421,7 +2423,7 @@ static struct uart_8250_port *serial8250
/*
* First, find a port entry which matches.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (uart_match_port(&serial8250_ports[i].port, port))
return &serial8250_ports[i];

@@ -2430,7 +2432,7 @@ static struct uart_8250_port *serial8250
* free entry. We look for one which hasn't been previously
* used (indicated by zero iobase).
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
@@ -2439,7 +2441,7 @@ static struct uart_8250_port *serial8250
* That also failed. Last resort is to find any entry which
* doesn't have a real port associated with it.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
return &serial8250_ports[i];

@@ -2524,8 +2526,11 @@ static int __init serial8250_init(void)
{
int ret, i;

+ if (nr_uarts > UART_NR)
+ nr_uarts = UART_NR;
+
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
- "%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+ "%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");

for (i = 0; i < NR_IRQS; i++)
@@ -2585,6 +2590,9 @@ module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
" (unsafe)");

+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_RUNTIME_UARTS) ")");
+
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/Kconfig serial/drivers/serial/Kconfig
--- vanilla/drivers/serial/Kconfig 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/Kconfig 2005-12-07 19:24:11.000000000 -0500
@@ -95,6 +95,16 @@ config SERIAL_8250_NR_UARTS
PCI enumeration and any ports that may be added at run-time
via hot-plug, or any ISA multi-port serial cards.

+config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+ depends on SERIAL_8250
+ default "4"
+ help
+ Set this to the maximum number of serial ports you want
+ the kernel to register at boot time. This can be overriden
+ with the module parameter "nr_uarts", or boot-time parameter
+ 8250.nr_uarts
+
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250

2005-12-08 03:02:05

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Russell King <[email protected]>
>To: Jason Dravet <[email protected]>
>CC: [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Wed, 7 Dec 2005 21:15:51 +0000
>
>On Wed, Dec 07, 2005 at 01:59:43PM -0600, Jason Dravet wrote:
> > >From: Russell King <[email protected]>
> > >To: Jason Dravet <[email protected]>
> > >CC: [email protected]
> > >Subject: Re: wrong number of serial port detected
> > >Date: Wed, 7 Dec 2005 15:50:34 +0000
> > >
> > >On Wed, Dec 07, 2005 at 09:44:29AM -0600, Jason Dravet wrote:
> > >> So I ask this mailing list Can the kernel detect the proper number of
> > >> serial ports or not?
> > >
> > >It does detect serial ports found in the machine.
> > >
> > >However, it _always_ offers the configured number of serial devices.
> > >This is to allow folk whose ports are not autodetected to configure
> > >them appropriately via the setserial command. If they were not
> > >available, they could not configure them.
> > >
> > Then may I ask how XP does it? I have to dual boot between XP and
>Fedora.
> > When I go into XP's device manager I see all of the appropriate hardware
> > listed, no extra serial ports. When I boot into Fedora and go into
>/dev, I
> > see the same hardware except I have 32 serial ports and 64 tty nodes
>(tty
> > is for virtual terminals right?). How can 1 OS show the correct number
>and
> > another show the wrong number? I ask so I can better understand what is
> > going on.
>
>It seems you are comparing apples (XP's device manager) with oranges
>(/dev directory). They're two entirely different things.
>
>The former lists devices which _are_ present in your system.
>
>The latter provides the filesystem namespace for applications to access
>devices which may or may not be present in your system.
>
I thought the purpose of udev was to create device manager like
functionality. I posted my question here because udev is creating 32 nodes.
Udev gets that information from the kernel serial port driver. Thanks to
your explanation I now understand. This is why I ask questions so I can
learn.

>As for your 64 VT tty device nodes - these "devices" are created
>dynamically when the device node is opened. The act of opening the
>device node is defined to be the creation event. If the device node
>did not exist, there would be no way to create _any_ virtual terminals.
>
I thought there were only 7 tty devices (Ctrl-F1 to Ctrl-F7) for local
system login? Ctrl-F7 being for Xwindows. Did I miss something?

Thank you for taking the time to answer my questions. I really appreciate
it.
Jason


2005-12-08 03:09:36

by Dave Jones

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 07:50:40PM -0500, Dave Jones wrote:

> Here's another iteration. I'll boot test this in a bit, and if it
> does the right thing, I'll add the documenation and a sign-off
> and send it your way.

Seems to the right thing.

Dave


Make the number of UARTs registered configurable.
Also add a nr_uarts module option to the 8250 code
to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS

This should appease people who complain about a proliferation
of /dev/ttyS & /sysfs nodes whilst at the same time allowing
a single kernel image to support the rarer occasions of
lots of devices.

Signed-off-by: Dave Jones <[email protected]>

diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/8250.c serial/drivers/serial/8250.c
--- vanilla/drivers/serial/8250.c 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/8250.c 2005-12-07 20:00:16.000000000 -0500
@@ -53,6 +53,8 @@
*/
static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;

+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
/*
* Debugging.
*/
@@ -2047,7 +2049,7 @@ static void __init serial8250_isa_init_p
return;
first = 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.line = i;
@@ -2066,7 +2068,7 @@ static void __init serial8250_isa_init_p
}

for (i = 0, up = serial8250_ports;
- i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
+ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
@@ -2088,7 +2090,7 @@ serial8250_register_ports(struct uart_dr

serial8250_isa_init_ports();

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.dev = dev;
@@ -2189,7 +2191,7 @@ static int serial8250_console_setup(stru
* if so, search for the first available port that does have
* console support.
*/
- if (co->index >= UART_NR)
+ if (co->index >= nr_uarts)
co->index = 0;
port = &serial8250_ports[co->index].port;
if (!port->iobase && !port->membase)
@@ -2225,7 +2227,7 @@ static int __init find_port(struct uart_
int line;
struct uart_port *port;

- for (line = 0; line < UART_NR; line++) {
+ for (line = 0; line < nr_uarts; line++) {
port = &serial8250_ports[line].port;
if (p->iotype == port->iotype &&
p->iobase == port->iobase &&
@@ -2349,7 +2351,7 @@ static int __devexit serial8250_remove(s
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.dev == dev)
@@ -2365,7 +2367,7 @@ static int serial8250_suspend(struct dev
if (level != SUSPEND_DISABLE)
return 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
@@ -2382,7 +2384,7 @@ static int serial8250_resume(struct devi
if (level != RESUME_ENABLE)
return 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == dev)
@@ -2421,7 +2423,7 @@ static struct uart_8250_port *serial8250
/*
* First, find a port entry which matches.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (uart_match_port(&serial8250_ports[i].port, port))
return &serial8250_ports[i];

@@ -2430,7 +2432,7 @@ static struct uart_8250_port *serial8250
* free entry. We look for one which hasn't been previously
* used (indicated by zero iobase).
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
@@ -2439,7 +2441,7 @@ static struct uart_8250_port *serial8250
* That also failed. Last resort is to find any entry which
* doesn't have a real port associated with it.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
return &serial8250_ports[i];

@@ -2524,8 +2526,11 @@ static int __init serial8250_init(void)
{
int ret, i;

+ if (nr_uarts > UART_NR)
+ nr_uarts = UART_NR;
+
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
- "%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+ "%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");

for (i = 0; i < NR_IRQS; i++)
@@ -2585,6 +2590,9 @@ module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
" (unsafe)");

+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/Kconfig serial/drivers/serial/Kconfig
--- vanilla/drivers/serial/Kconfig 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/Kconfig 2005-12-07 19:24:11.000000000 -0500
@@ -95,6 +95,16 @@ config SERIAL_8250_NR_UARTS
PCI enumeration and any ports that may be added at run-time
via hot-plug, or any ISA multi-port serial cards.

+config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+ depends on SERIAL_8250
+ default "4"
+ help
+ Set this to the maximum number of serial ports you want
+ the kernel to register at boot time. This can be overriden
+ with the module parameter "nr_uarts", or boot-time parameter
+ 8250.nr_uarts
+
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250
--- serial/Documentation/kernel-parameters.txt~ 2005-12-07 20:16:18.000000000 -0500
+++ serial/Documentation/kernel-parameters.txt 2005-12-07 20:17:44.000000000 -0500
@@ -982,6 +982,8 @@ running once the system is up.

nowb [ARM]

+ nr_uarts= [SERIAL] maximum number of UARTs to be registered.
+
opl3= [HW,OSS]
Format: <io>

2005-12-08 10:54:36

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 09:02:03PM -0600, Jason Dravet wrote:
> >As for your 64 VT tty device nodes - these "devices" are created
> >dynamically when the device node is opened. The act of opening the
> >device node is defined to be the creation event. If the device node
> >did not exist, there would be no way to create _any_ virtual terminals.
>
> I thought there were only 7 tty devices (Ctrl-F1 to Ctrl-F7) for local
> system login? Ctrl-F7 being for Xwindows. Did I miss something?

If you look in the "init" configuration file, /etc/inittab, you'll
see lines similar to these:

1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6

Once "init" has finished bringing up the rest of the system, it will
execute the mingetty commands, asking mingetty to open the first 6 ttys.
This opening of each tty creates the virtual console, at which point
you can switch to it.

If you add:

7:2345:respawn:/sbin/mingetty tty7
8:2345:respawn:/sbin/mingetty tty8

then you'll have login prompts on ctrl-f1 to ctrl-f8, and X will be
on tty9 (ctrl-f9).

You could even ask another program to send its output to /dev/tty12,
which you'll be able to view via ctrl-f12 - eg, I do this with the
system logger on some of my systems. At that point, you'll have
login prompts on tty1 to tty8, X on tty9 and something else on tty12.

(Note: you could comment out some of the mingetty lines in inittab,
but you should always leave at least one, in case something happens
with X and you need an alternative way to log in.)

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-09 14:37:04

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Russell King <[email protected]>
>To: Jason Dravet <[email protected]>
>CC: [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Thu, 8 Dec 2005 10:54:26 +0000
>
>On Wed, Dec 07, 2005 at 09:02:03PM -0600, Jason Dravet wrote:
> > >As for your 64 VT tty device nodes - these "devices" are created
> > >dynamically when the device node is opened. The act of opening the
> > >device node is defined to be the creation event. If the device node
> > >did not exist, there would be no way to create _any_ virtual terminals.
> >
> > I thought there were only 7 tty devices (Ctrl-F1 to Ctrl-F7) for local
> > system login? Ctrl-F7 being for Xwindows. Did I miss something?
>
>If you look in the "init" configuration file, /etc/inittab, you'll
>see lines similar to these:
>
The /etc/inittab file is where I got the number 7 from (6 tty plus 1
Xwindows). I have to change the inittab everytime I install FC since they
switched to graphical boot (FC does not like my monitor). Let me see if I
got this right: Is the reason 64 tty devices exist similiar to the reason
you gave me about the 32 serial ports? You create all the nodes so they can
be used at anytime. If there were only the 6 tty nodes created then if you
want to direct your logger to tty12, you would first have to create that
node and then tty12 could be used. If this is true how are the other 52 tty
devices accessed? I don't have a F13 or F44 keys on my keyboard.

I like the idea of the patch that Dave Jones created. The question I have
is with all of this plug and play stuff in our PCs shouldn't it be possible
to get the correct number of ports, ask the bios or the pci bus or
something?

Thanks,
Jason


2005-12-09 17:27:23

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Fri, Dec 09, 2005 at 08:37:01AM -0600, Jason Dravet wrote:
> The /etc/inittab file is where I got the number 7 from (6 tty plus 1
> Xwindows). I have to change the inittab everytime I install FC since they
> switched to graphical boot (FC does not like my monitor). Let me see if I
> got this right: Is the reason 64 tty devices exist similiar to the reason
> you gave me about the 32 serial ports?

I guess so - I don't look after the virtual console stuff.

> You create all the nodes so they
> can be used at anytime. If there were only the 6 tty nodes created then if
> you want to direct your logger to tty12, you would first have to create
> that node and then tty12 could be used. If this is true how are the other
> 52 tty devices accessed? I don't have a F13 or F44 keys on my keyboard.

There is a key combination, but it's dependent on the keymap.
dumpkeys -f and search for "Console_" - it's in keymap 2 (but
I don't know what activates keymap 2.)

> I like the idea of the patch that Dave Jones created. The question I have
> is with all of this plug and play stuff in our PCs shouldn't it be possible
> to get the correct number of ports, ask the bios or the pci bus or
> something?

If you're considering only legacy free systems, yes you are probably
right.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-09 19:54:52

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Friday 09 December 2005 7:37 am, Jason Dravet wrote:
> The question I have
> is with all of this plug and play stuff in our PCs shouldn't it be possible
> to get the correct number of ports, ask the bios or the pci bus or
> something?

Yes. ACPI (or even PNPBIOS) should tell us about all the "legacy"
ports, and PCI or other bus enumeration should tell us about all the
rest.

So in theory, if we have some flavor of PNP, we should be able to
ignore all the compiled-in stuff in SERIAL_PORT_DFNS, which is what
leads to the duplicate port detection. I've considered doing that
(and ia64 already does it), but it would almost certainly break
systems because of BIOS bugs, so I'm not sure it's worth the risk.

Having all the extra /dev/ttyS entries is a little different problem.
That is basically so "setserial /dev/ttySx" can be used to work around
the fact that the serial driver doesn't know about all existing devices.
If it did, setserial should be superfluous. Maybe there'd be a way to
implement that functionality via sysfs and get rid of the extra
/dev/ttyS entries. That'd be kind of cool.

2005-12-10 01:46:14

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Bjorn Helgaas <[email protected]>
>To: "Jason Dravet" <[email protected]>
>CC: [email protected], [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Fri, 9 Dec 2005 12:54:44 -0700
>
>On Friday 09 December 2005 7:37 am, Jason Dravet wrote:
> > The question I have
> > is with all of this plug and play stuff in our PCs shouldn't it be
>possible
> > to get the correct number of ports, ask the bios or the pci bus or
> > something?
>
>Yes. ACPI (or even PNPBIOS) should tell us about all the "legacy"
>ports, and PCI or other bus enumeration should tell us about all the
>rest.
>
>So in theory, if we have some flavor of PNP, we should be able to
>ignore all the compiled-in stuff in SERIAL_PORT_DFNS, which is what
>leads to the duplicate port detection. I've considered doing that
>(and ia64 already does it), but it would almost certainly break
>systems because of BIOS bugs, so I'm not sure it's worth the risk.

I agree that breaking things is bad, but it would be interesting to see what
would happen and if anyone complains. A gut feeling is that very few people
use more than the two serial ports that come on their motherboards. Where I
work out of the 2,500 PCs on campus, only 3 or 4 PCs actually use a serial
port. I think this would be a good survey for slashdot. I don't use the
serial ports on my PCs. I do use the serial ports on my servers. The
serial ports on the servers connect to a digi terminal server. One serial
port is the management interface to the server, the other is setup for
serial login.

The reason I started this thread is because I wanted to know why/how I was
seeing 32 serial ports in /dev when I have 0 enabled on my PC and I have 2
serial ports on my servers. Thanks to the responses I have a better
understanding of what is going on.

>Having all the extra /dev/ttyS entries is a little different problem.
>That is basically so "setserial /dev/ttySx" can be used to work around
>the fact that the serial driver doesn't know about all existing devices.
>If it did, setserial should be superfluous. Maybe there'd be a way to
>implement that functionality via sysfs and get rid of the extra
>/dev/ttyS entries. That'd be kind of cool.

sysfs is way outside my area of understanding. Anything that moves to a
more accurate /dev directory is good in my book.

Thanks,
Jason


2005-12-10 10:35:47

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Fri, Dec 09, 2005 at 12:54:44PM -0700, Bjorn Helgaas wrote:
> On Friday 09 December 2005 7:37 am, Jason Dravet wrote:
> > The question I have
> > is with all of this plug and play stuff in our PCs shouldn't it be possible
> > to get the correct number of ports, ask the bios or the pci bus or
> > something?
>
> Yes. ACPI (or even PNPBIOS) should tell us about all the "legacy"
> ports, and PCI or other bus enumeration should tell us about all the
> rest.

Unless I stick a serial card into an industrial PC. And yes, ISA
serial cards are still sold:

http://www.amplicon.co.uk/dr-prod3.cfm/groupId/10740/secid/10177.htm

ISA serial cards will not show up in ACPI, PNPBIOS or any other bus
enumeration scheme. The only way to use them is via setserial.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-10 14:25:00

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Russell King <[email protected]>
>To: Bjorn Helgaas <[email protected]>
>CC: Jason Dravet <[email protected]>, [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Sat, 10 Dec 2005 10:35:38 +0000
>
>On Fri, Dec 09, 2005 at 12:54:44PM -0700, Bjorn Helgaas wrote:
> > On Friday 09 December 2005 7:37 am, Jason Dravet wrote:
> > > The question I have
> > > is with all of this plug and play stuff in our PCs shouldn't it be
>possible
> > > to get the correct number of ports, ask the bios or the pci bus or
> > > something?
> >
> > Yes. ACPI (or even PNPBIOS) should tell us about all the "legacy"
> > ports, and PCI or other bus enumeration should tell us about all the
> > rest.
>
>Unless I stick a serial card into an industrial PC. And yes, ISA
>serial cards are still sold:
>
>http://www.amplicon.co.uk/dr-prod3.cfm/groupId/10740/secid/10177.htm
>
>ISA serial cards will not show up in ACPI, PNPBIOS or any other bus
>enumeration scheme. The only way to use them is via setserial.
>
>--
>Russell King
> Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
> maintainer of: 2.6 Serial core

How is this for an idea? The serial driver enumerates ACPI, PNPBIOS, or
whaterver it needs for the onboard serial ports. If you have a PCI based
serial card it would show up in the emuneration of the PCI bus, right? For
the case of ISA serial cards couldn't they have an option in modprobe.conf
to tell the kernel about the ISA serial card and the proper number of serial
ports on the card itself?

Thanks,
Jason


2005-12-10 15:46:36

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Sat, Dec 10, 2005 at 08:24:59AM -0600, Jason Dravet wrote:
> How is this for an idea? The serial driver enumerates ACPI, PNPBIOS, or
> whaterver it needs for the onboard serial ports. If you have a PCI based
> serial card it would show up in the emuneration of the PCI bus, right? For
> the case of ISA serial cards couldn't they have an option in modprobe.conf
> to tell the kernel about the ISA serial card and the proper number of
> serial ports on the card itself?

That's already thought about and rejected.

If you want to pass a string telling the serial module where the ports
are, you could be looking at a very _long_ string. You need to specify
the IO address, IRQ and base baud as a minimum for every port, along
with optional flags.

Assuming 5 characters for the IO address, 1 for the IRQ, and 6 for
the baud base, plus 2 for separators between each of these, and one
character separator per group, you're looking at 15 characters
minimum per port. For 8 ports, that's 120 characters. 16 would
be 240 characters. If the driver is built-in to the kernel, you're
limited to 255 characters to describe all kernel options, so you
couldn't hope to describe 32 ports.

Note that the above figures are without passing any additional
options which may be needed per port. So this is most definitely
out of the question.

The alternative is something like Dave's patch which allows you to
tell the driver the number of ports you want to support and setserial.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-10 17:56:14

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>From: Russell King <[email protected]>
>To: Jason Dravet <[email protected]>
>CC: [email protected], [email protected]
>Subject: Re: wrong number of serial port detected
>Date: Sat, 10 Dec 2005 15:46:28 +0000
>
>On Sat, Dec 10, 2005 at 08:24:59AM -0600, Jason Dravet wrote:
> > How is this for an idea? The serial driver enumerates ACPI, PNPBIOS, or
> > whaterver it needs for the onboard serial ports. If you have a PCI
>based
> > serial card it would show up in the emuneration of the PCI bus, right?
>For
> > the case of ISA serial cards couldn't they have an option in
>modprobe.conf
> > to tell the kernel about the ISA serial card and the proper number of
> > serial ports on the card itself?
>
>That's already thought about and rejected.
>
>If you want to pass a string telling the serial module where the ports
>are, you could be looking at a very _long_ string. You need to specify
>the IO address, IRQ and base baud as a minimum for every port, along
>with optional flags.
>
>Assuming 5 characters for the IO address, 1 for the IRQ, and 6 for
>the baud base, plus 2 for separators between each of these, and one
>character separator per group, you're looking at 15 characters
>minimum per port. For 8 ports, that's 120 characters. 16 would
>be 240 characters. If the driver is built-in to the kernel, you're
>limited to 255 characters to describe all kernel options, so you
>couldn't hope to describe 32 ports.

I was not aware that it worked like that. My last experience with ISA cards
was to put a line in the modules.conf that pointed to the base IO and IRQ
for the card. There was a serperate file that setup the serial ports. This
was way back in RedHat 6.x days. Thank you for the new information.

>The alternative is something like Dave's patch which allows you to
>tell the driver the number of ports you want to support and setserial.

Dave's patch is good and I look forward to seeing it in the kernel.

Thanks,
Jason


2006-01-07 16:46:46

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Wed, Dec 07, 2005 at 10:09:16PM -0500, Dave Jones wrote:
> Make the number of UARTs registered configurable.
> Also add a nr_uarts module option to the 8250 code
> to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS
>
> This should appease people who complain about a proliferation
> of /dev/ttyS & /sysfs nodes whilst at the same time allowing
> a single kernel image to support the rarer occasions of
> lots of devices.
>
> Signed-off-by: Dave Jones <[email protected]>

Any chance of an updated patch please? It doesn't appear to be
healthy:

patching file drivers/serial/8250.c
Hunk #1 succeeded at 54 (offset 1 line).
Hunk #2 succeeded at 2119 (offset 70 lines).
Hunk #3 succeeded at 2069 (offset 1 line).
Hunk #4 succeeded at 2160 (offset 70 lines).
Hunk #5 succeeded at 2194 (offset 3 lines).
Hunk #6 succeeded at 2297 with fuzz 2 (offset 70 lines).
Hunk #7 succeeded at 2352 with fuzz 1 (offset 1 line).
misordered hunks! output would be garbled
Hunk #8 FAILED at 2421.
Hunk #9 succeeded at 2381 with fuzz 2 (offset -3 lines).
Hunk #10 succeeded at 2492 (offset 69 lines).
Hunk #11 succeeded at 2429 (offset -3 lines).
Hunk #12 succeeded at 2510 (offset 69 lines).
Hunk #13 succeeded at 2523 (offset -3 lines).
Hunk #14 succeeded at 2659 (offset 69 lines).
1 out of 14 hunks FAILED -- saving rejects to file drivers/serial/8250.c.rej
patching file drivers/serial/Kconfig
patching file Documentation/kernel-parameters.txt

Thanks.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2006-01-07 21:05:51

by Dave Jones

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Sat, Jan 07, 2006 at 04:46:39PM +0000, Russell King wrote:
> On Wed, Dec 07, 2005 at 10:09:16PM -0500, Dave Jones wrote:
> > Make the number of UARTs registered configurable.
> > Also add a nr_uarts module option to the 8250 code
> > to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS
> >
> > This should appease people who complain about a proliferation
> > of /dev/ttyS & /sysfs nodes whilst at the same time allowing
> > a single kernel image to support the rarer occasions of
> > lots of devices.
> >
> > Signed-off-by: Dave Jones <[email protected]>
>
> Any chance of an updated patch please? It doesn't appear to be
> healthy:
>
> patching file drivers/serial/8250.c
> Hunk #1 succeeded at 54 (offset 1 line).
> Hunk #2 succeeded at 2119 (offset 70 lines).
> Hunk #3 succeeded at 2069 (offset 1 line).
> Hunk #4 succeeded at 2160 (offset 70 lines).
> Hunk #5 succeeded at 2194 (offset 3 lines).
> Hunk #6 succeeded at 2297 with fuzz 2 (offset 70 lines).
> Hunk #7 succeeded at 2352 with fuzz 1 (offset 1 line).
> misordered hunks! output would be garbled
> Hunk #8 FAILED at 2421.
> Hunk #9 succeeded at 2381 with fuzz 2 (offset -3 lines).
> Hunk #10 succeeded at 2492 (offset 69 lines).
> Hunk #11 succeeded at 2429 (offset -3 lines).
> Hunk #12 succeeded at 2510 (offset 69 lines).
> Hunk #13 succeeded at 2523 (offset -3 lines).
> Hunk #14 succeeded at 2659 (offset 69 lines).
> 1 out of 14 hunks FAILED -- saving rejects to file drivers/serial/8250.c.rej
> patching file drivers/serial/Kconfig
> patching file Documentation/kernel-parameters.txt



Make the number of UARTs registered configurable.
Also add a nr_uarts module option to the 8250 code
to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS

This should appease people who complain about a proliferation
of /dev/ttyS & /sysfs nodes whilst at the same time allowing
a single kernel image to support the rarer occasions of
lots of devices.

Signed-off-by: Dave Jones <[email protected]>

diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/8250.c serial/drivers/serial/8250.c
--- vanilla/drivers/serial/8250.c 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/8250.c 2005-12-07 20:00:16.000000000 -0500
@@ -53,6 +53,8 @@
*/
static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;

+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
/*
* Debugging.
*/
@@ -2047,7 +2049,7 @@ static void __init serial8250_isa_init_p
return;
first = 0;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.line = i;
@@ -2066,7 +2068,7 @@ static void __init serial8250_isa_init_p
}

for (i = 0, up = serial8250_ports;
- i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
+ i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
up->port.iobase = old_serial_port[i].port;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
@@ -2088,7 +2090,7 @@ serial8250_register_ports(struct uart_dr

serial8250_isa_init_ports();

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

up->port.dev = dev;
@@ -2189,7 +2191,7 @@ static int serial8250_console_setup(stru
* if so, search for the first available port that does have
* console support.
*/
- if (co->index >= UART_NR)
+ if (co->index >= nr_uarts)
co->index = 0;
port = &serial8250_ports[co->index].port;
if (!port->iobase && !port->membase)
@@ -2225,7 +2227,7 @@ static int __init find_port(struct uart_
int line;
struct uart_port *port;

- for (line = 0; line < UART_NR; line++) {
+ for (line = 0; line < nr_uarts; line++) {
port = &serial8250_ports[line].port;
if (p->iotype == port->iotype &&
p->iobase == port->iobase &&
@@ -2349,7 +2351,7 @@ static int __devexit serial8250_remove(s
{
int i;

- for (i = 0; i < UART_NR; i++) {
+ for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.dev == dev)
@@ -2421,7 +2423,7 @@ static struct uart_8250_port *serial8250
/*
* First, find a port entry which matches.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (uart_match_port(&serial8250_ports[i].port, port))
return &serial8250_ports[i];

@@ -2430,7 +2432,7 @@ static struct uart_8250_port *serial8250
* free entry. We look for one which hasn't been previously
* used (indicated by zero iobase).
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
@@ -2439,7 +2441,7 @@ static struct uart_8250_port *serial8250
* That also failed. Last resort is to find any entry which
* doesn't have a real port associated with it.
*/
- for (i = 0; i < UART_NR; i++)
+ for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
return &serial8250_ports[i];

@@ -2524,8 +2526,11 @@ static int __init serial8250_init(void)
{
int ret, i;

+ if (nr_uarts > UART_NR)
+ nr_uarts = UART_NR;
+
printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
- "%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+ "%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");

for (i = 0; i < NR_IRQS; i++)
@@ -2585,6 +2590,9 @@ module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
" (unsafe)");

+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff -urpN --exclude-from=/home/davej/.exclude vanilla/drivers/serial/Kconfig serial/drivers/serial/Kconfig
--- vanilla/drivers/serial/Kconfig 2005-10-27 20:02:08.000000000 -0400
+++ serial/drivers/serial/Kconfig 2005-12-07 19:24:11.000000000 -0500
@@ -95,6 +95,16 @@ config SERIAL_8250_NR_UARTS
PCI enumeration and any ports that may be added at run-time
via hot-plug, or any ISA multi-port serial cards.

+config SERIAL_8250_RUNTIME_UARTS
+ int "Number of 8250/16550 serial ports to register at runtime"
+ depends on SERIAL_8250
+ default "4"
+ help
+ Set this to the maximum number of serial ports you want
+ the kernel to register at boot time. This can be overriden
+ with the module parameter "nr_uarts", or boot-time parameter
+ 8250.nr_uarts
+
config SERIAL_8250_EXTENDED
bool "Extended 8250/16550 serial driver options"
depends on SERIAL_8250
--- serial/Documentation/kernel-parameters.txt~ 2005-12-07 20:16:18.000000000 -0500
+++ serial/Documentation/kernel-parameters.txt 2005-12-07 20:17:44.000000000 -0500
@@ -982,6 +982,8 @@ running once the system is up.

nowb [ARM]

+ nr_uarts= [SERIAL] maximum number of UARTs to be registered.
+
opl3= [HW,OSS]
Format: <io>

2006-01-08 01:23:47

by Jason Dravet

[permalink] [raw]
Subject: Re: wrong number of serial port detected

>Make the number of UARTs registered configurable.
>Also add a nr_uarts module option to the 8250 code
>to override this, up to a maximum of CONFIG_SERIAL_8250_NR_UARTS
>
>This should appease people who complain about a proliferation
>of /dev/ttyS & /sysfs nodes whilst at the same time allowing
>a single kernel image to support the rarer occasions of
>lots of devices.
>
Not to keep complaining, but I now have the following issue. I running
Fedora Cores 2.6.15-1.1826 kernel. When I run dmesg I now see this:

Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing enabled
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A

before 2.6.15 I saw
Serial: 8250/16550 driver $Revision: 1.90 $ 32 ports, IRQ sharing enabled

The serial driver now correctly reports that I have two serial ports instead
of 32. So shouldn't the patch register the minimum of
CONFIG_SERIAL_8250_NR_UARTS and the number of serial ports detected by the
serial driver?

Thanks,
Jason Dravet


2006-01-08 09:08:09

by Russell King

[permalink] [raw]
Subject: Re: wrong number of serial port detected

On Sat, Jan 07, 2006 at 07:23:46PM -0600, Jason Dravet wrote:
> Not to keep complaining, but I now have the following issue. I running
> Fedora Cores 2.6.15-1.1826 kernel. When I run dmesg I now see this:
>
> Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing enabled
> serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
> 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
>
> before 2.6.15 I saw
> Serial: 8250/16550 driver $Revision: 1.90 $ 32 ports, IRQ sharing enabled
>
> The serial driver now correctly reports that I have two serial ports
> instead of 32. So shouldn't the patch register the minimum of
> CONFIG_SERIAL_8250_NR_UARTS and the number of serial ports detected by the
> serial driver?

It's a classic chicken and egg problem. If you can solve such problems,
please feel free to send a patch.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core