2006-08-23 21:42:03

by Stuart MacDonald

[permalink] [raw]
Subject: Serial custom speed deprecated?

From
http://www.kernel.org/pub/linux/kernel/v2.5/ChangeLog-2.5.64

"<[email protected]>
Complain about setting custom speed or divisor on serial ports."

And the relevant patch hunk:
@@ -832,8 +826,17 @@
goto exit;
if (info->flags & UIF_INITIALIZED) {
if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
- old_custom_divisor != port->custom_divisor)
+ old_custom_divisor != port->custom_divisor) {
+ /* If they're setting up a custom divisor or speed,
+ * instead of clearing it, then bitch about it. No
+ * need to rate-limit; it's CAP_SYS_ADMIN only. */
+ if (port->flags & UPF_SPD_MASK) {
+ printk(KERN_NOTICE "%s sets custom speed on %s%d. This is deprecated.\n",
+ current->comm, info->tty->driver.name,
+ info->port->line);
+ }
uart_change_speed(info, NULL);
+ }
} else
retval = uart_startup(info, 1);
exit:

If custom speeds are deprecated, what's the new method for setting
them? Specifically, how can the SPD_CUST functionality be accomplished
without that flag? I've checked 2.5.64 and 2.6.17, and don't see how
it is possible.

..Stu


2006-08-24 09:18:24

by David Woodhouse

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Wed, 2006-08-23 at 17:41 -0400, Stuart MacDonald wrote:
> If custom speeds are deprecated, what's the new method for setting
> them? Specifically, how can the SPD_CUST functionality be accomplished
> without that flag? I've checked 2.5.64 and 2.6.17, and don't see how
> it is possible.

We need a way to set the baud rate as an _integer_ instead of the Bxxxx
flags.

--
dwmw2

2006-08-24 12:42:13

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: David Woodhouse [mailto:[email protected]]
> On Wed, 2006-08-23 at 17:41 -0400, Stuart MacDonald wrote:
> > If custom speeds are deprecated, what's the new method for setting
> > them? Specifically, how can the SPD_CUST functionality be
> accomplished
> > without that flag? I've checked 2.5.64 and 2.6.17, and don't see how
> > it is possible.
>
> We need a way to set the baud rate as an _integer_ instead of
> the Bxxxx
> flags.

Agreed. Our products have required this functionality since at least
1999.

It appears that the current method has been deprecated before the next
method has been constructed though. Is that correct?

The easiest thing is likely to add a new ioctl to serial_core.c
specifically for setting the baud rate. It takes an integer baud rate
and returns success or error. It will need to be able to call a
subdriver's set_baud_rate() as well, which means extending the ops
structure, because some hardware (like the XR16C954 IIRC) has
non-standard ways of actually programming the baud rate.

Hm, after some thought I think the core won't actually end up doing
anything except dispatching. So the better way is to add ioctls to the
subdrivers directly.

..Stu

2006-08-24 12:58:08

by Alan

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

Ar Iau, 2006-08-24 am 08:41 -0400, ysgrifennodd Stuart MacDonald:
> The easiest thing is likely to add a new ioctl to serial_core.c
> specifically for setting the baud rate. It takes an integer baud rate
> and returns success or error. It will need to be able to call a

It should take a pair, a send rate and a receive rate. We need that to
cover some corner cases.

> Hm, after some thought I think the core won't actually end up doing
> anything except dispatching. So the better way is to add ioctls to the
> subdrivers directly.

Actually to do this right we have to make a decision or two

The POSIX way of handling this requires the speeds are in the termios
structure "somewhere". We can't easily implement cfgetispeed/cfgetospeed
unless we grow the termios structure in the kernel and issue 3 new
ioctls (keeping the others as trivial translations) and then bumping
glibc and the kernel to do the right thing.

The alternative is that we provide an extra pair of speed ioctls and
glibc does the magic to hide this lot while providing a termios with the
new fields itself.

Whichever way we go glibc already has the fields present and the
libc<->application API appears to be unchanged by this.

I'd rather we went the way of extending our termios to include c_ispeed,
c_ospeed values. The code isn't hard for the remapping of the old ones
and it avoids extra ioctls and the corner case races between two speed
sets that occur if they are two ioctls.


Alan

2006-08-24 13:03:35

by David Woodhouse

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

On Thu, 2006-08-24 at 14:19 +0100, Alan Cox wrote:
> Actually to do this right we have to make a decision or two
>
> The POSIX way of handling this requires the speeds are in the termios
> structure "somewhere". We can't easily implement cfgetispeed/cfgetospeed
> unless we grow the termios structure in the kernel and issue 3 new
> ioctls (keeping the others as trivial translations) and then bumping
> glibc and the kernel to do the right thing.
>
> The alternative is that we provide an extra pair of speed ioctls and
> glibc does the magic to hide this lot while providing a termios with the
> new fields itself.
>
> Whichever way we go glibc already has the fields present and the
> libc<->application API appears to be unchanged by this.
>
> I'd rather we went the way of extending our termios to include c_ispeed,
> c_ospeed values. The code isn't hard for the remapping of the old ones
> and it avoids extra ioctls and the corner case races between two speed
> sets that occur if they are two ioctls.

Agreed. Some architectures have c_[io]speed in their struct termios
already, in fact, but others would need new ioctls for it.

--
dwmw2

2006-08-24 16:27:32

by Krzysztof Halasa

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

David Woodhouse <[email protected]> writes:

>> If custom speeds are deprecated, what's the new method for setting
>> them? Specifically, how can the SPD_CUST functionality be accomplished
>> without that flag? I've checked 2.5.64 and 2.6.17, and don't see how
>> it is possible.
>
> We need a way to set the baud rate as an _integer_ instead of the Bxxxx
> flags.

Does that mean that standard things like termios will use:
#define B9600 9600
#define B19200 19200
?
--
Krzysztof Halasa

2006-08-24 17:20:24

by Alan

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Ar Iau, 2006-08-24 am 18:27 +0200, ysgrifennodd Krzysztof Halasa:
> David Woodhouse <[email protected]> writes:
>
> >> If custom speeds are deprecated, what's the new method for setting
> >> them? Specifically, how can the SPD_CUST functionality be accomplished
> >> without that flag? I've checked 2.5.64 and 2.6.17, and don't see how
> >> it is possible.
> >
> > We need a way to set the baud rate as an _integer_ instead of the Bxxxx
> > flags.
>
> Does that mean that standard things like termios will use:
> #define B9600 9600
> #define B19200 19200

That would have been very smart when Linus did Linux 0.12, unfortunately
he didn't and we've also got no spare bits. Worse still if we exported
them that way glibc has now way to map new speeds onto the old ones for
applications.

The speed_t values in the termios struct are also Bfoo encoded so it
turns out don't help.

At this point I think we need

- An ioctl to set/get the actual baud rate input/output
- Some kind of termios flag to indicate they are being used (as we have
CBAUDEX now). [We could "borrow" the 4Mbit one and dual use it IMHO]

For drivers tty_get_baud_rate would return the actual speed as before.

We would need a driver ->set_speed method for the cases where
- ioctl is called to set specific board rate
- OR termios values for tty speed change
- While we are at it we might want to make ->set_termios also allowed to
fail

[and if you had no ->set_speed method non standard speeds would be
refused by the tty layer for back compat]

Anyone got any problems with this before I go and implement it ?






2006-08-24 18:51:15

by Krzysztof Halasa

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Alan Cox <[email protected]> writes:

>> Does that mean that standard things like termios will use:
>> #define B9600 9600
>> #define B19200 19200
>
> That would have been very smart when Linus did Linux 0.12, unfortunately
> he didn't and we've also got no spare bits. Worse still if we exported
> them that way glibc has now way to map new speeds onto the old ones for
> applications.

Hmm... I'm not sure if I understand this correctly. Can't we just
create the 3 new ioctls in the kernel and teach glibc to use it?

The compatibility ioctls would talk to new ioctls only and translate
things. Anything (userspace) wanting non-traditional speeds would
have to use new interface (i.e., be compiled against the new glibc)
and the speeds would show as EXTA or EXTB or something when queried
using old ioctl.

Yes, the binary interface between glibc and userland would change
(with compatibility calls translated by glibc to new ioctls, or to
old ones on older kernels).

The old ioctls would be optional in the kernel (and perhaps in glibc,
sometime).

Not sure if we want int, uint, or long long for speed values :-)
--
Krzysztof Halasa

2006-08-24 20:43:26

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?


On Thu, 24 Aug 2006, Krzysztof Halasa wrote:

> Alan Cox <[email protected]> writes:
>
>>> Does that mean that standard things like termios will use:
>>> #define B9600 9600
>>> #define B19200 19200
>>
>> That would have been very smart when Linus did Linux 0.12, unfortunately
>> he didn't and we've also got no spare bits. Worse still if we exported
>> them that way glibc has now way to map new speeds onto the old ones for
>> applications.
>
> Hmm... I'm not sure if I understand this correctly. Can't we just
> create the 3 new ioctls in the kernel and teach glibc to use it?
>
> The compatibility ioctls would talk to new ioctls only and translate
> things. Anything (userspace) wanting non-traditional speeds would
> have to use new interface (i.e., be compiled against the new glibc)
> and the speeds would show as EXTA or EXTB or something when queried
> using old ioctl.
>
> Yes, the binary interface between glibc and userland would change
> (with compatibility calls translated by glibc to new ioctls, or to
> old ones on older kernels).
>
> The old ioctls would be optional in the kernel (and perhaps in glibc,
> sometime).
>
> Not sure if we want int, uint, or long long for speed values :-)
> --
> Krzysztof Halasa

But the baud-rates have always been some approximation that starts
at 75 and increases by powers-of-two. This is because the hardware
always had fixed clocks with dividers that divided by powers-of-two.
What is the claim for the requirement of strange baud-rates set
as an integer of dimension "baud?" Where does this requirement
come from and what devices use these?

FYI, the EXTA and EXTB were added to accommodate UARTS that
had hardware pre-scalers so that portion of the 'int' was
translated and went somewhere else than the UART divisor.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-24 21:50:52

by Alan

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Ar Iau, 2006-08-24 am 16:43 -0400, ysgrifennodd linux-os (Dick Johnson):
> at 75 and increases by powers-of-two. This is because the hardware
> always had fixed clocks with dividers that divided by powers-of-two.
> What is the claim for the requirement of strange baud-rates set
> as an integer of dimension "baud?" Where does this requirement
> come from and what devices use these?

A lot of chips will do all sorts of interesting speeds such as 31.5Kbit
because today the clocks are themselves quite configurable.


2006-08-24 22:05:53

by Russell King

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Thu, Aug 24, 2006 at 06:41:33PM +0100, Alan Cox wrote:
> We would need a driver ->set_speed method for the cases where
> - ioctl is called to set specific board rate
> - OR termios values for tty speed change
> - While we are at it we might want to make ->set_termios also allowed to
> fail

That's a little dodgy, from my reading of POSIX. ISTR POSIX prefers
a behaviour of "set what you can" from this, and when you read back
the termios settings, you get the actual settings in use.

So, eg, if you don't support CS5 but the previous setting was CS8,
tcsetattr should not return an error. The device itself should set
the other changed parameters but remain at CS8 and tcgetattr should
report CS8.

stty already knows about this, and issues warnings when you attempt
to set stuff which aren't supportted by the driver (assuming you have
a correctly behaving driver in this respect.) I've been a little
scared to push the implementation for these in the serial drivers.

> Anyone got any problems with this before I go and implement it ?

Only as long as we can end up with a numeric baud rate at the end of
the day (which is what serial has always been after.)

This represents a major improvement to the tty interface, thanks for
looking in to making it happen.

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

2006-08-24 22:22:01

by Alan

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Ar Iau, 2006-08-24 am 20:51 +0200, ysgrifennodd Krzysztof Halasa:
> Hmm... I'm not sure if I understand this correctly. Can't we just
> create the 3 new ioctls in the kernel and teach glibc to use it?

We could implement an entirely new TCSETS/TCGETS/TCSETSA/SAW which used
different B* values so B9600 was 9600 etc and the data was stored in
c_ospeed/c_ispeed type separate fields and we'd support arbitary speeds
for input and output once and for all, shoot all the multiplier hacks
etc. As it happens the kernel code for this is easy owing to some
fortuitous good design long ago in the tty layer.

We could also implement a Linux "improved" TCSET* new set of ioctls that
had sensible speed fields, utf-8 characters for the _cc[] array and new
flags for all the utf-8 handling and the like. That would be less
compatible though.

Or we could just add a standardised extra set of speed ioctls, but then
we need to decide what occurs if I set the speed and then issue a
termios call - does it override or not.

> The old ioctls would be optional in the kernel (and perhaps in glibc,
> sometime).

The kernel side translation is thankfully really trivial.

> Not sure if we want int, uint, or long long for speed values :-)

You want speed_t according to POSIX.

I've no idea what the glibc impact of this kind of thing would be
(consider new glibc, old kernel etc). I've cc'd the libc folks but I am
not sure it is practical to do.

Alan

2006-08-25 10:59:05

by Krzysztof Halasa

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Alan Cox <[email protected]> writes:

> We could implement an entirely new TCSETS/TCGETS/TCSETSA/SAW which used
> different B* values so B9600 was 9600 etc and the data was stored in
> c_ospeed/c_ispeed type separate fields and we'd support arbitary speeds
> for input and output once and for all, shoot all the multiplier hacks
> etc. As it happens the kernel code for this is easy owing to some
> fortuitous good design long ago in the tty layer.

I think it makes most sense.

> We could also implement a Linux "improved" TCSET* new set of ioctls that
> had sensible speed fields, utf-8 characters for the _cc[] array and new
> flags for all the utf-8 handling and the like. That would be less
> compatible though.

I think compatibility at the source level is good here. UTF-8 looks
nice, though.

I think it could remain compatible - c_cc[] could grow into array of
multibyte characters with:
#define VINTR 0
#define VQUIT (1 * n)
#define VERASE (2 * n)
#define VKILL (3 * n)

where n is max number of UTF-8 bytes (5 for 32-bit UCS?)

I'm not sure if UTF-8 control codes are needed in practice, though
(I mean I just don't know).

> Or we could just add a standardised extra set of speed ioctls, but then
> we need to decide what occurs if I set the speed and then issue a
> termios call - does it override or not.

A bit messy I think. I think the first way is much better. Especially
when we have multiple changes (speed and UTF-8, for example).

>> Not sure if we want int, uint, or long long for speed values :-)
>
> You want speed_t according to POSIX.

Sure, I meant what does speed_t resolve to.

> I've no idea what the glibc impact of this kind of thing would be
> (consider new glibc, old kernel etc). I've cc'd the libc folks but I am
> not sure it is practical to do.

While obviously I'm not glibc (nor termios) expert I don't think
we should expect problems. New glibc would just issue the old ioctl
if the new one isn't available. I think similar things are already
in place.
Glibc could be compiled with minimum kernel version = 2.6.20 or so
to assume the new ioctls are always present.
--
Krzysztof Halasa

2006-08-25 11:40:14

by Nick Craig-Wood

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Alan Cox <[email protected]> wrote:
> Ar Iau, 2006-08-24 am 20:51 +0200, ysgrifennodd Krzysztof Halasa:
> > Not sure if we want int, uint, or long long for speed values :-)
>
> You want speed_t according to POSIX.

To get non-integral baud rates (of which there are a few but no longer
in common use) you'd probably want to supply a two integers which you
then divide.

This matches most hardware quite well, and for most cases you'd just
supply the divisor as 1.

--
Nick Craig-Wood <[email protected]> -- http://www.craig-wood.com/nick

2006-08-25 15:02:08

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of Alan Cox
> At this point I think we need
>
> - An ioctl to set/get the actual baud rate input/output
> - Some kind of termios flag to indicate they are being
> used (as we have
> CBAUDEX now). [We could "borrow" the 4Mbit one and dual use it IMHO]
>
> For drivers tty_get_baud_rate would return the actual speed as before.
>
> We would need a driver ->set_speed method for the cases where
> - ioctl is called to set specific board rate
> - OR termios values for tty speed change
> - While we are at it we might want to make ->set_termios also
> allowed to fail
>
> [and if you had no ->set_speed method non standard speeds would be
> refused by the tty layer for back compat]
>
> Anyone got any problems with this before I go and implement it ?

Sounds good.

..Stu

2006-08-25 15:11:15

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of Krzysztof Halasa
> Not sure if we want int, uint, or long long for speed values :-)

Our max baud rate on any product is IIRC 1,8432,00. I checked with our
hardware guys, and they think the current theoretical upper limit is
around 30,000,000.

<words style="famous,last">
A uint ought to be enough for anybody.
</words>

..Stu

2006-08-25 15:18:13

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of linux-os (Dick Johnson)
> But the baud-rates have always been some approximation that starts
> at 75 and increases by powers-of-two. This is because the hardware
> always had fixed clocks with dividers that divided by powers-of-two.
> What is the claim for the requirement of strange baud-rates set
> as an integer of dimension "baud?" Where does this requirement
> come from and what devices use these?

Perhaps you'd like to check out our products
http://www.connecttech.com/

We build a lot of custom boards that have odd clocks to generate very
odd baud rates for random serial devices. The Bxxx style has been a
thorn in my side since 1999.

Also, Oxford's 16PCI95x family has three different points of altering
the clock; the clock prescaler, the actual sample rate (which is the
classic /16 that most are used to), and the actual divisor. That can
produce pretty much any baud rate, albeit with some error.

..Stu

2006-08-25 15:21:59

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of Alan Cox
> We could implement an entirely new TCSETS/TCGETS/TCSETSA/SAW
> which used
> different B* values so B9600 was 9600 etc and the data was stored in

I think if a numeric baud rate is going to be supported, getting away
from the B* cruft is important. Just use a number.

> Or we could just add a standardised extra set of speed
> ioctls, but then
> we need to decide what occurs if I set the speed and then issue a
> termios call - does it override or not.

I'd say yes.

..Stu

2006-08-25 15:52:39

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?


On Fri, 25 Aug 2006, Stuart MacDonald wrote:

> From: On Behalf Of linux-os (Dick Johnson)
>> But the baud-rates have always been some approximation that starts
>> at 75 and increases by powers-of-two. This is because the hardware
>> always had fixed clocks with dividers that divided by powers-of-two.
>> What is the claim for the requirement of strange baud-rates set
>> as an integer of dimension "baud?" Where does this requirement
>> come from and what devices use these?
>
> Perhaps you'd like to check out our products
> http://www.connecttech.com/
>
> We build a lot of custom boards that have odd clocks to generate very
> odd baud rates for random serial devices. The Bxxx style has been a
> thorn in my side since 1999.
>
> Also, Oxford's 16PCI95x family has three different points of altering
> the clock; the clock prescaler, the actual sample rate (which is the
> classic /16 that most are used to), and the actual divisor. That can
> produce pretty much any baud rate, albeit with some error.
>
> ..Stu
>

Well when you change things, remember that you need not only something
that translates B9600 to your new 9600 (trivial it's a #define, but
ALSO (very important!) B0 needs to hang up the modem! This means
that some value (perhaps 0), as a divisor, needs to perform this
same function.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-25 19:32:12

by Russell King

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Fri, Aug 25, 2006 at 11:21:21AM -0400, Stuart MacDonald wrote:
> From: On Behalf Of Alan Cox
> > We could implement an entirely new TCSETS/TCGETS/TCSETSA/SAW
> > which used
> > different B* values so B9600 was 9600 etc and the data was stored in
>
> I think if a numeric baud rate is going to be supported, getting away
> from the B* cruft is important. Just use a number.

The "B* cruft" is part of POSIX so needs to be retained. These are
used in conjunction with with cfgetispeed(), cfgetospeed(), cfsetispeed()
and cfsetospeed() to alter the baud rate settings in the termios
structure in an implementation defined manner.

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

2006-08-25 20:22:45

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of Russell King
> The "B* cruft" is part of POSIX so needs to be retained. These are

Ah, ok. Didn't know that.

..Stu

2006-08-25 20:39:44

by Theodore Ts'o

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Fri, Aug 25, 2006 at 08:32:03PM +0100, Russell King wrote:
> On Fri, Aug 25, 2006 at 11:21:21AM -0400, Stuart MacDonald wrote:
> > From: On Behalf Of Alan Cox
> > > We could implement an entirely new TCSETS/TCGETS/TCSETSA/SAW
> > > which used
> > > different B* values so B9600 was 9600 etc and the data was stored in
> >
> > I think if a numeric baud rate is going to be supported, getting away
> > from the B* cruft is important. Just use a number.
>
> The "B* cruft" is part of POSIX so needs to be retained. These are
> used in conjunction with with cfgetispeed(), cfgetospeed(), cfsetispeed()
> and cfsetospeed() to alter the baud rate settings in the termios
> structure in an implementation defined manner.

The B* cruft has to be maintained.

But it would be POSIX complaint for B9600 to be #defined to B9600, and
B19200 to be #defined to B19200.

What would scare me though about doing something like would be
potential for the ABI changes. Not only do you have to worry about a
consistent set of ioctl's, structure definitions, and B* defines, but
you also have to worry about userspace libraries that use B* as part
of their interface, and expect user programs to pass B* constants to
the userspace library. (Say, some kind of conveience dialout library,
for example.)

In that case, the application could have been compiled with the
new-style termios.h, but the userspace library could have been
compiled with the old-style termios.h, and hence the old-style ioctl
definitions, and the opportunities for mischief are endless.

- Ted

2006-08-25 20:54:12

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?


On Fri, 25 Aug 2006, Stuart MacDonald wrote:

> From: On Behalf Of Russell King
>> The "B* cruft" is part of POSIX so needs to be retained. These are
>
> Ah, ok. Didn't know that.
>
> ..Stu

... and why "B0" is important as well.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-26 12:16:54

by Krzysztof Halasa

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Theodore Tso <[email protected]> writes:

> What would scare me though about doing something like would be
> potential for the ABI changes. Not only do you have to worry about a
> consistent set of ioctl's, structure definitions, and B* defines, but
> you also have to worry about userspace libraries that use B* as part
> of their interface, and expect user programs to pass B* constants to
> the userspace library. (Say, some kind of conveience dialout library,
> for example.)

Right, there is a potential problem here. I don't know | think
if anything like that exists, though. If there is no such software
the issue can be ignored, and if something turns out then it just
have to be compiled with the same glibc headers (both parts).
That probably means even for binary software it's a non-issue.
--
Krzysztof Halasa

2006-08-26 18:16:45

by George Spelvin

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

> Or we could just add a standardised extra set of speed ioctls, but then
> we need to decide what occurs if I set the speed and then issue a
> termios call - does it override or not.

Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.
That would make a reasonable encoding for a custom speed.
(But I haven't checked glibc... ah, yes, it should work!
See glibc-2.4/sysdeps/unix/sysv/linux/speed.c; browse at
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/linux/?cvsroot=glibc
if you don't have a local copy source handy.)

What I'd do is, when converting to the old-style for tcgetattr, if the
current baud rate is not representable, cache it somewhere and return that
(or some other magic value). If a tcsetatt call comes in that specifies
that magic value, use the cached baud rate.

If you make the cache just the current baud rate setting (the magic
value on set means "don't alter"), that will handle a lot of programs
that just want to play with handshaking.

If you make the cache separate, you can also survive an
old-interface-using program switching to a different baud rate and then
switching back.


Also note that if you truly want to support all baud rates in historical
use, you'll need to include at least one fractional bit for 134.5 baud.
(Unless you're sure that IBM 2741 terminals are truly dead. :-))

Alternatively, you could observe that asynchronous communications only
requires agreement withing 5% between sender and receiver, so specifying
a baud rate to much better than 1% is not too important.

Half-precision floating point would be ideal for the job. :-)

2006-08-26 19:35:17

by George Spelvin

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

> Also, Oxford's 16PCI95x family has three different points of altering
> the clock; the clock prescaler, the actual sample rate (which is the
> classic /16 that most are used to), and the actual divisor. That can
> produce pretty much any baud rate, albeit with some error.

Their data sheet doesn't explain it too well, but it looks like they
use a similar implementation to the MSP430 UARTs, which are designed
to work with very low clock rates. (32768 Hz watch crystals are
popular.)

Just as a reminder, UART receive operation is generally:
- After detecting a falling edge, wait half a bit time.
- Sample the input 3x and majority-vote. If the input
line is still low, call this a start bit and prepare to
receive a character.
- Wait one bit time, sample 3x, and call the majority the start bit.
- Repeat for all data bits and the stop bit. If the stop bit isn't
1 as expected, note a framing error.

This is traditionally done by running a 16x clock sampling the
input, and after detecting a start bit on one clock (call that
clock 0), sample the start bit on clocks 7, 8 and 9, the first bit
on clocks 23, 24 and 25, etc.

MSP430 UARTs have a fully programmable clocks/bit number (no fixed /16,
although you want a few clocks per bit so the standard "sample 3x and
majority vote" algorithm works), and can add +1 clock to individual
bit times to approximate a desired baud rate more closely by dithering.
Oh, and they use both edges of the clock.

So it can go to a baud rate 1/3 of the input baud clock (sample the
start bit at 1, 1.5 and 2 clocks, then the first bit at 4, 4.5 and 5,
etc.), and proceed to 9/24, 10/24, etc.

2006-08-26 19:37:55

by Ian Stirling

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

[email protected] wrote:
>> Or we could just add a standardised extra set of speed ioctls, but then
>> we need to decide what occurs if I set the speed and then issue a
>> termios call - does it override or not.
>
<snip>
> Alternatively, you could observe that asynchronous communications only
> requires agreement withing 5% between sender and receiver, so specifying
> a baud rate to much better than 1% is not too important.

To nitpick.
For a 10 bit long word, if the receiver syncs to within 1/8th of the
middle of a bit-time at the start, you've got 2/8th of a bit-time of
disagreement possible, before you are likely to get errors, especially
on limited slew-rate signals. (more modern chips will likely sample faster)
Or 3/80, or 2.5%. If the other side has made a similar calculation, then
you should only really rely on 1%.
5% is the best possible case - that will in most circumstances cause errors.

2006-08-26 20:36:59

by George Spelvin

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

> To nitpick.
> For a 10 bit long word, if the receiver syncs to within 1/8th of the
> middle of a bit-time at the start, you've got 2/8th of a bit-time of
> disagreement possible, before you are likely to get errors, especially
> on limited slew-rate signals. (more modern chips will likely sample faster)
> Or 3/80, or 2.5%. If the other side has made a similar calculation, then
> you should only really rely on 1%.
> 5% is the best possible case - that will in most circumstances cause errors.

You're quite right; 5% assumes perfect signal edges, which you don't
get in practice, especially at high baud rates. Also, you have
frational stop bit tricks from some modems.

Still, as I suggested, half-precision floating point (1 sign, 5 exponent,
10 mantissa) as used for HDR graphics has a relative error range of 1/1024
(0.098%) to 1/2047 (0.049%), and would be an excellent match.

It's not a terribly serious suggestion, as I don't think 134.5 baud
is a serious issue these days, but it does make clear that there's no
difference between 115,200 baud and 115,299 baud.

2006-08-27 06:52:14

by Rogier Wolff

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Thu, Aug 24, 2006 at 11:11:41PM +0100, Alan Cox wrote:
> Ar Iau, 2006-08-24 am 16:43 -0400, ysgrifennodd linux-os (Dick Johnson):
> > at 75 and increases by powers-of-two. This is because the hardware
> > always had fixed clocks with dividers that divided by powers-of-two.
> > What is the claim for the requirement of strange baud-rates set
> > as an integer of dimension "baud?" Where does this requirement
> > come from and what devices use these?

> A lot of chips will do all sorts of interesting speeds such as
> 31.5Kbit because today the clocks are themselves quite configurable.

More importantly, the base-clocks are getting higher and higher, and
the division is no longer a "power-of-two". Thus 9600 is no longer
2.456MHz / 2^8, but something like 33MHz / 3438. This allows modern
hardware to run much faster baud rates, as well as custom slower baud
rates.

Note that IMHO, we should have started hiding this mess from /drivers/
a long time ago. The tty layer should convert the B_9600 thingies to
"9600", the integer, and then call the set_termios function. The
driver should be prohibited from looking at how the the baud rate came
to be 9600, and attempt to approach the requested baud rate as good as
possible. It might return a flag somewhere: Not exact. In the example
above, the resulting baud rate is about 1.4 baud off: 9598.6. This is
not a problem in very many cases.

Once this is in place, you lose a lot of "figure out the baud rate
integer from the B_xxx settings" code in all the drivers, as well as
that we get to provide a new interface to userspace without having to
change ALL drivers at the same time. This decouples the drivers from
the kernel<->userspace interface.

Roger.

--
** [email protected] ** http://www.BitWizard.nl/ ** +31-15-2600998 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
Q: It doesn't work. A: Look buddy, doesn't work is an ambiguous statement.
Does it sit on the couch all day? Is it unemployed? Please be specific!
Define 'it' and what it isn't doing. --------- Adapted from lxrbot FAQ

2006-08-27 10:00:30

by Russell King

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Sun, Aug 27, 2006 at 08:52:11AM +0200, Rogier Wolff wrote:
> Once this is in place, you lose a lot of "figure out the baud rate
> integer from the B_xxx settings" code in all the drivers, as well as
> that we get to provide a new interface to userspace without having to
> change ALL drivers at the same time. This decouples the drivers from
> the kernel<->userspace interface.

This has been helped along by serial_core - drivers have helper
functions which they call (along with their min/max baud rate)
which handles all this stuff.

The one thing your idea is missing is how to handle the "user
requested 15mbaud but I can only do 115200baud" case - POSIX
prefers you to report back what you actually selected rather
than error out. If you merely pass an integer to the drivers,
they can't do that.

Note also that some drivers effectively have run-time configurable
max baud rates, so you can't pass a fixed set of capabilities to
the tty layer on driver initialisation.

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

2006-08-28 12:17:44

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?


On Sat, 26 Aug 2006 [email protected] wrote:

>> Or we could just add a standardised extra set of speed ioctls, but then
>> we need to decide what occurs if I set the speed and then issue a
>> termios call - does it override or not.
>
> Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.

B0 is not a bit (there are no bits in 0). It won't work.

> That would make a reasonable encoding for a custom speed.
> (But I haven't checked glibc... ah, yes, it should work!
> See glibc-2.4/sysdeps/unix/sysv/linux/speed.c; browse at
> http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/linux/?cvsroot=glibc
> if you don't have a local copy source handy.)
>
> What I'd do is, when converting to the old-style for tcgetattr, if the
> current baud rate is not representable, cache it somewhere and return that
> (or some other magic value). If a tcsetatt call comes in that specifies
> that magic value, use the cached baud rate.
>
> If you make the cache just the current baud rate setting (the magic
> value on set means "don't alter"), that will handle a lot of programs
> that just want to play with handshaking.
>
> If you make the cache separate, you can also survive an
> old-interface-using program switching to a different baud rate and then
> switching back.
>
>
> Also note that if you truly want to support all baud rates in historical
> use, you'll need to include at least one fractional bit for 134.5 baud.
> (Unless you're sure that IBM 2741 terminals are truly dead. :-))
>
> Alternatively, you could observe that asynchronous communications only
> requires agreement withing 5% between sender and receiver, so specifying
> a baud rate to much better than 1% is not too important.
>
> Half-precision floating point would be ideal for the job. :-)
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-28 14:15:23

by Stuart MacDonald

[permalink] [raw]
Subject: RE: Serial custom speed deprecated?

From: On Behalf Of Rogier Wolff
> Note that IMHO, we should have started hiding this mess from /drivers/
> a long time ago. The tty layer should convert the B_9600 thingies to
> "9600", the integer, and then call the set_termios function. The
> driver should be prohibited from looking at how the the baud rate came
> to be 9600, and attempt to approach the requested baud rate as good as
> possible. It might return a flag somewhere: Not exact. In the example
> above, the resulting baud rate is about 1.4 baud off: 9598.6. This is
> not a problem in very many cases.
>
> Once this is in place, you lose a lot of "figure out the baud rate
> integer from the B_xxx settings" code in all the drivers, as well as
> that we get to provide a new interface to userspace without having to
> change ALL drivers at the same time. This decouples the drivers from
> the kernel<->userspace interface.

I'll second the motion. :-)

..Stu

2006-08-28 14:18:26

by Alan

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Ar Llu, 2006-08-28 am 08:17 -0400, ysgrifennodd linux-os (Dick Johnson):
> On Sat, 26 Aug 2006 [email protected] wrote:
>
> >> Or we could just add a standardised extra set of speed ioctls, but then
> >> we need to decide what occurs if I set the speed and then issue a
> >> termios call - does it override or not.
> >
> > Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.
>
> B0 is not a bit (there are no bits in 0). It won't work.

Well that is how it is implemented and everyone else seems happy. If it
violates your personal laws of physics you'll just have to cope.

2006-08-28 14:50:51

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?


On Mon, 28 Aug 2006, Alan Cox wrote:

> Ar Llu, 2006-08-28 am 08:17 -0400, ysgrifennodd linux-os (Dick Johnson):
>> On Sat, 26 Aug 2006 [email protected] wrote:
>>
>>>> Or we could just add a standardised extra set of speed ioctls, but then
>>>> we need to decide what occurs if I set the speed and then issue a
>>>> termios call - does it override or not.
>>>
>>> Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.
>>
>> B0 is not a bit (there are no bits in 0). It won't work.
>
> Well that is how it is implemented and everyone else seems happy. If it
> violates your personal laws of physics you'll just have to cope.

It has nothing to do with 'personal laws of physics'. On all recent
implementations, B0 is 0, i.e., the absence of any bits set. Therefore,
there is no observable difference between CBAUDEX and CBAUDEX | B0,
as shown above. Therefore, as I stated, it won't work.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-28 15:51:42

by Michael Poole

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

linux-os \(Dick Johnson\) writes:

> On Mon, 28 Aug 2006, Alan Cox wrote:
>
>> Ar Llu, 2006-08-28 am 08:17 -0400, ysgrifennodd linux-os (Dick Johnson):
>>> On Sat, 26 Aug 2006 [email protected] wrote:
>>>
>>>>> Or we could just add a standardised extra set of speed ioctls, but then
>>>>> we need to decide what occurs if I set the speed and then issue a
>>>>> termios call - does it override or not.
>>>>
>>>> Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.
>>>
>>> B0 is not a bit (there are no bits in 0). It won't work.
>>
>> Well that is how it is implemented and everyone else seems happy. If it
>> violates your personal laws of physics you'll just have to cope.
>
> It has nothing to do with 'personal laws of physics'. On all recent
> implementations, B0 is 0, i.e., the absence of any bits set. Therefore,
> there is no observable difference between CBAUDEX and CBAUDEX | B0,
> as shown above. Therefore, as I stated, it won't work.

What baud rate does your system define CBAUDEX | B0 to be? On my
AMD64 machine, both the x86-64 and i386 asm/termbits.h files skip
CBAUDEX -- B38400 is 0000017 and B57600 is 0010001 (CBAUDEX | B50).
The headers do not define any baud rate between those two, either by
rate or by c_cflag value.

Michael Poole

2006-08-28 16:39:53

by Alan

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

Ar Llu, 2006-08-28 am 10:50 -0400, ysgrifennodd linux-os (Dick Johnson):
> It has nothing to do with 'personal laws of physics'. On all recent
> implementations, B0 is 0, i.e., the absence of any bits set. Therefore,
> there is no observable difference between CBAUDEX and CBAUDEX | B0,
> as shown above.

Correct

> Therefore, as I stated, it won't work.

Incorrect


The state

(flag & CBAUD) == (CBAUDEX|0)

is not currently used

CBAUDEX|1 .. CBAUDX|15 are used as are 0-15.


2006-08-28 16:57:13

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?


On Mon, 28 Aug 2006, Michael Poole wrote:

> linux-os \(Dick Johnson\) writes:
>
>> On Mon, 28 Aug 2006, Alan Cox wrote:
>>
>>> Ar Llu, 2006-08-28 am 08:17 -0400, ysgrifennodd linux-os (Dick Johnson):
>>>> On Sat, 26 Aug 2006 [email protected] wrote:
>>>>
>>>>>> Or we could just add a standardised extra set of speed ioctls, but then
>>>>>> we need to decide what occurs if I set the speed and then issue a
>>>>>> termios call - does it override or not.
>>>>>
>>>>> Actually, we're not QUITE out of bits. CBAUDEX | B0 is not taken.
>>>>
>>>> B0 is not a bit (there are no bits in 0). It won't work.
>>>
>>> Well that is how it is implemented and everyone else seems happy. If it
>>> violates your personal laws of physics you'll just have to cope.
>>
>> It has nothing to do with 'personal laws of physics'. On all recent
>> implementations, B0 is 0, i.e., the absence of any bits set. Therefore,
>> there is no observable difference between CBAUDEX and CBAUDEX | B0,
>> as shown above. Therefore, as I stated, it won't work.
>
> What baud rate does your system define CBAUDEX | B0 to be? On my

B0 is 0 (zero), no bits. If you are trying to play semantic games and
claim B0 is 1, i.e., bit 0, then it would not be written as B0, it
would be written as B(0) or B:0. B0 is defined to be the baud-rate
used to hang up the modem. It is zero in all bits on most all
implementations including my Sun. On most recent Linux distributions,
CBAUDEX is (octal) 0010000. Since B0 is zero, ORing it into CBAUDEX
does nothing.

> AMD64 machine, both the x86-64 and i386 asm/termbits.h files skip
> CBAUDEX -- B38400 is 0000017 and B57600 is 0010001 (CBAUDEX | B50).
> The headers do not define any baud rate between those two, either by
> rate or by c_cflag value.
>
> Michael Poole
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-28 17:24:13

by George Spelvin

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

> The state
>
> (flag & CBAUD) == (CBAUDEX|0)
>
> is not currently used
>
> CBAUDEX|1 .. CBAUDX|15 are used as are 0-15.

a) thank you; I've been wondering why so many people seem unable to see
the obvious.

b) I should mention, on the Alpha, CBAUDEX is defined as 0, and the used
states are 0..30, so the spare state is 31

But again, there *is* a spare state that can be used when a custom
baud rate is queried via the backward-compatible inerface.

2006-08-28 17:40:37

by Michael Poole

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

linux-os \(Dick Johnson\) writes:

> On Mon, 28 Aug 2006, Michael Poole wrote:
>
>> What baud rate does your system define CBAUDEX | B0 to be? On my
>
> B0 is 0 (zero), no bits. If you are trying to play semantic games and
> claim B0 is 1, i.e., bit 0, then it would not be written as B0, it
> would be written as B(0) or B:0. B0 is defined to be the baud-rate
> used to hang up the modem. It is zero in all bits on most all
> implementations including my Sun. On most recent Linux distributions,
> CBAUDEX is (octal) 0010000. Since B0 is zero, ORing it into CBAUDEX
> does nothing.

Thanks, Sherlock! Again: What does CBAUDEX, by itself, do on your
system? As Alan Cox obviously thought the rest of the world was
bright enough to notice, and as I tried to explain, the CBAUDEX bit is
currently not defined when set by itself (i.e. as if it were CBAUDEX,
CBAUDEX | B0, CBAUDEX << 0 or however else you want to denote it);
there is always some other low-order (CBAUD) bit associated with it:

>> AMD64 machine, both the x86-64 and i386 asm/termbits.h files skip
>> CBAUDEX -- B38400 is 0000017 and B57600 is 0010001 (CBAUDEX | B50).
>> The headers do not define any baud rate between those two, either by
>> rate or by c_cflag value.

Michael Poole

2006-08-28 18:14:44

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?


On Mon, 28 Aug 2006, Michael Poole wrote:

> linux-os \(Dick Johnson\) writes:
>
>> On Mon, 28 Aug 2006, Michael Poole wrote:
>>
>>> What baud rate does your system define CBAUDEX | B0 to be? On my
>>
>> B0 is 0 (zero), no bits. If you are trying to play semantic games and
>> claim B0 is 1, i.e., bit 0, then it would not be written as B0, it
>> would be written as B(0) or B:0. B0 is defined to be the baud-rate
>> used to hang up the modem. It is zero in all bits on most all
>> implementations including my Sun. On most recent Linux distributions,
>> CBAUDEX is (octal) 0010000. Since B0 is zero, ORing it into CBAUDEX
>> does nothing.
>
> Thanks, Sherlock! Again: What does CBAUDEX, by itself, do on your
> system? As Alan Cox obviously thought the rest of the world was
> bright enough to notice, and as I tried to explain, the CBAUDEX bit is
> currently not defined when set by itself (i.e. as if it were CBAUDEX,
> CBAUDEX | B0, CBAUDEX << 0 or however else you want to denote it);
> there is always some other low-order (CBAUD) bit associated with it:
>

Certainly CBAUDEX does not represent a baud-rate itself. It is
a bit that is used to extend the baud-rate setting from the values
that could fit within the (CBAUD & ~CBAUDEX) mask so B50 through
B38400 could become B57600 through B4000000 when this bit is set.

The confusion arises when you use B0 in your argument. CBAUDEX was
the relevant bit, sufficiently defined, without adding a non-existent
bit.

I am sensitive to 'B0' because any new implementation must also
provide for its functionality. There still are modem-controlled
or connected devices that need to secure a line by hanging up.

>>> AMD64 machine, both the x86-64 and i386 asm/termbits.h files skip
>>> CBAUDEX -- B38400 is 0000017 and B57600 is 0010001 (CBAUDEX | B50).
>>> The headers do not define any baud rate between those two, either by
>>> rate or by c_cflag value.
>
> Michael Poole
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.62 BogoMips).
New book: http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2006-08-28 20:09:31

by Russell King

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Mon, Aug 28, 2006 at 10:14:30AM -0400, Stuart MacDonald wrote:
> From: On Behalf Of Rogier Wolff
> > Note that IMHO, we should have started hiding this mess from /drivers/
> > a long time ago. The tty layer should convert the B_9600 thingies to
> > "9600", the integer, and then call the set_termios function. The
> > driver should be prohibited from looking at how the the baud rate came
> > to be 9600, and attempt to approach the requested baud rate as good as
> > possible. It might return a flag somewhere: Not exact. In the example
> > above, the resulting baud rate is about 1.4 baud off: 9598.6. This is
> > not a problem in very many cases.
> >
> > Once this is in place, you lose a lot of "figure out the baud rate
> > integer from the B_xxx settings" code in all the drivers, as well as
> > that we get to provide a new interface to userspace without having to
> > change ALL drivers at the same time. This decouples the drivers from
> > the kernel<->userspace interface.
>
> I'll second the motion. :-)

You might do, but it's incompatible with the POSIX standard. As I
explained to Rogier (he took it off list) there's no need for "inexact"
flags.

If we pass a baud rate via tcsetattr() (or ioctl), you should set what
ever settings you can. If you can set _no_ settings, you return an
error. If you can set at least one setting, you do not return an error,
and you only set those settings you can do.

When you subsequently read the settings via tcgetattr(), POSIX requires
that the returned information be what the port is _actually_ doing.

So, this means that if you can only do 9599 baud and not 9600 baud,
maybe you should be returning 9599 baud.

On the same subject, if you don't support RTS/CTS flow control, and
userland requests CRTSCTS, you shouldn't be allowing CRTSCTS to be set.
And indeed, if you don't allow that in the kernel today, stty will
correctly issue a warning that it was "unable to perform all requested
operations".

So, while I whole heartedly agree with passing baud rates numerically,
I do not think we need any of this inexact flagging nonsense provided
we implement something as userland programs expect - iow, the POSIX
behaviour.

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

2006-08-29 06:20:52

by Rogier Wolff

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Mon, Aug 28, 2006 at 09:09:18PM +0100, Russell King wrote:

> So, while I whole heartedly agree with passing baud rates
> numerically, I do not think we need any of this inexact flagging
> nonsense provided we implement something as userland programs expect
> - iow, the POSIX behaviour.

I fully agree we should implement Posix behaviour. Wether that specifies
what userland programmers expect is where I disagree.

If you happen to change RTS/CTS at the same time as you change baud,
the call will return succes, even though the most important part (for
you) of your call failed. Note that if the succes of the call depends
on the previous state of RTS/CTS. Thus the error will depend on
whatever happened before. This creates difficult-to-diagnose problems
for sysadmins.

Anyway, this would not happen if the programmer had read the full text
of the POSIX spec. IMHO, most programmers have a good idea of the
filosopy, and program against that: If some call fails it returns
error.

Anyway, here I am again rambling against the Posix spec. But again:
we should implement POSIX as good as we can. Alan already did the
most important footwork. Good job!

Roger.

--
** [email protected] ** http://www.BitWizard.nl/ ** +31-15-2600998 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
Q: It doesn't work. A: Look buddy, doesn't work is an ambiguous statement.
Does it sit on the couch all day? Is it unemployed? Please be specific!
Define 'it' and what it isn't doing. --------- Adapted from lxrbot FAQ

2006-08-29 07:46:29

by Russell King

[permalink] [raw]
Subject: Re: Serial custom speed deprecated?

On Tue, Aug 29, 2006 at 08:20:49AM +0200, Rogier Wolff wrote:
> On Mon, Aug 28, 2006 at 09:09:18PM +0100, Russell King wrote:
> > So, while I whole heartedly agree with passing baud rates
> > numerically, I do not think we need any of this inexact flagging
> > nonsense provided we implement something as userland programs expect
> > - iow, the POSIX behaviour.
>
> I fully agree we should implement Posix behaviour. Wether that specifies
> what userland programmers expect is where I disagree.
>
> If you happen to change RTS/CTS at the same time as you change baud,
> the call will return succes, even though the most important part (for
> you) of your call failed. Note that if the succes of the call depends
> on the previous state of RTS/CTS. Thus the error will depend on
> whatever happened before. This creates difficult-to-diagnose problems
> for sysadmins.

I disagree. POSIX recommends the following sequence when setting termios
modes:

tcgetattr(fd, &termios);
/* modify termios */
if (tcsetattr(fd, &termios) == -1)
/* whatever error handling, none of the modes worked */
tcgetattr(fd, &real_termios);

and in that respect it's the classic negotiation between two differing
sets of code - the application asks for what it wants, and then requests
what it actually got. It can then check real_termios to see if the
settings it actually got are compatible with what it wants to achieve.

For example, if it couldn't enable CRTSCTS, it might decide to use XON/
XOFF flow control instead.

If tcsetattr() were to return an error if _any_ mode failed, then you
wouldn't know if it failed because CRTSCTS wasn't supported, or the
baud rate, or maybe some other mode you asked for. That's multiple
times worse, and it would actually result in lots of programs failing
just because one setting wasn't supported - and will result in more
sysadmins scratching their collective heads.

So, the key idea here is that fiddling with termios is a _negotiation_
between the application and the driver.

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