[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <DD67C0CF-D330-4D40-B610-FD3EB7AA0218@zytor.com>
Date: Wed, 12 Nov 2025 11:12:22 -0800
From: "H. Peter Anvin" <hpa@...or.com>
To: Greg KH <gregkh@...uxfoundation.org>
CC: "Theodore Ts'o" <tytso@....edu>, Maarten Brock <Maarten.Brock@...ls.nl>,
"linux-serial@...r.kernel.org" <linux-serial@...r.kernel.org>,
"linux-api@...r.kernel.org" <linux-api@...r.kernel.org>,
LKML <linux-kernel@...r.kernel.org>
Subject: Re: RFC: Serial port DTR/RTS - O_NRESETDEV
On November 12, 2025 8:46:50 AM PST, Greg KH <gregkh@...uxfoundation.org> wrote:
>On Wed, Nov 12, 2025 at 08:09:45AM -0800, H. Peter Anvin wrote:
>> On November 12, 2025 3:22:56 AM PST, Greg KH <gregkh@...uxfoundation.org> wrote:
>> >On Mon, Nov 10, 2025 at 07:57:22PM -0800, H. Peter Anvin wrote:
>> >> Honestly, though, I'm far less interested in what 8250-based hardware does than e.g. USB.
>> >
>> >hahahahahahaha {snort}
>> >
>> >Hah. that's a good one.
>> >
>> >Oh, you aren't kidding.
>> >
>> >Wow, good luck with this. USB-serial adaptors are all over the place,
>> >some have real uarts in them (and so do buffering in the device, and
>> >line handling in odd ways when powered up), and some are almost just a
>> >straight pipe through to the USB host with control line handling ideas
>> >tacked on to the side as an afterthought, if at all.
>> >
>> >There is no standard here, they all work differently, and even work
>> >differently across the same device type with just barely enough hints
>> >for us to determine what is going on.
>> >
>> >So don't worry about USB, if you throw that into the mix, all bets are
>> >off and you should NEVER rely on that.
>> >
>> >Remeber USB->serial was explicitly rejected by the USB standard group,
>> >only to have it come back in the "side door" through the spec process
>> >when it turned out that Microsoft hated having to write a zillion
>> >different vendor-specific drivers because the vendor provided ones kept
>> >crashing user's machines. So what we ended up with was "just enough" to
>> >make it through the spec process, and even then line signals are
>> >probably never tested so you can't rely on them.
>> >
>> >good luck!
>> >
>> >greg "this brought up too many bad memories" k-h
>>
>> Ugh.
>>
>> I have made it very clear that I am very aware that there is broken hardware.
>
>I would posit that there is NO "non-broken" usb->serial devices out
>there. The closest I have seen was the old IO-Edgeport devices, but
>they were expensive and got bought out by some other company and in the
>end didn't succeed due to all of the "cheap" devices/chips out there
>that just did dumb tx/rx transfers over a fake serial connection.
>
>> What I'm trying to do is to deal with the (occasional) case of
>> *non*-broken hardware. Right now Linux breaks the non-broken hardware
>> for it, and I don't think the existence of broken hardware is a good
>> justification for that.
>
>No, but we have to handle both somehow.
>
>And given that we still get brand-new UART drivers sent to use every few
>months, there is just more and more "broken" hardware out there overall.
>
>Anyway, good luck coming up with a scheme to handle your crazy
>connections, I would push back and say "any device that treats a serial
>control line as a power signal is broken to start with" :)
>
>greg k-h
Yeah, well, I will certainly *not* argue with that one! Quite the contrary... *shudder*.
There are enough facepalms to go around, both on the DTE and DCE sides, and I'm not in any shape, way, or form denying that.
Nor am I trying to boil the ocean here. I'm just trying to figure out how to make the situation a bit more flexible to try to at least reduce the amount of brokenness we throw back in the face of the user.
The reason I brought up USB is that while RTS# briefly glitching on an actual RS232 line is unlikely to actually make it through the driver, which will have a cutoff of at most 10 MHz and usually much less, an ACM device receiving a SET_LINE_CONTROL message may react to it immediately, especially if it is an emulated port.(*)
The same thing is true, of course, for "uart" lines, a.k.a. TTL or CMOS level serial, which have much higher bandwidth than any physical RS232 or RS485 drivers.
Incidentally, I'm not looking at this because of a huge need on my own part; I'm doing it because it irked me to no end that glibc still hadn't implemented support for the almost two decades old support in the Linux kernel for arbitrary serial port speeds, and in the end I ended up Just Writing The Code; but there as well I ended up having several discussions with the glibc maintainers about how to deal with the unavoidable compromises involved in evolving one l the interfaces; the POSIX termios interface design from back in the '80s really caused some serious headaches.
There was fallout, as it exposed bugs in a bunch of software which had implemented their own hacks during the 17 years that glibc didn't provide any support for handling this. It gave me a *lot* of new insights in how various applications in the field actually do things and what they have to do to work around limitations in both hardware and software at the moment, and so I'm feeling kind of motivated to try to make these real life use cases a little bit less obnoxious.
The thing with RTS# and DTR# came up when I started rooting around in gtkterm's serial code probing code, but I had myself run into it using ESP32 modules.
Had I personally designed the ESP32 interface I would have used BREAK to pulse reset instead of RTS#, but that would have required a capacitor and a diode, and omg that would have added *cost!*
(This is in fact exactly what I did when I implemented my own ACM device in an FPGA, but that's a different story.)
As far as actual USB-to-serial devices are concerned, my *personal* experience with quite a few of them is that the line control signals are generally quite reliable, and transmitting BREAK usually works OK; however, whether *receiving* BREAK works is a crapshoot at the very best.
Then there are of course the ones that just lock up randomly, or seriously glitch on the USB side, but that's an entirely different kettle of fish.
And you are most definitely right that not standardizing a USB to serial device class from the very beginning was a very bad mistake. At least now newer devices tend toward using ACM and advertise as "driverless". It also allows the rest of the USB descriptor to contain more useful information about the DCE, assuming it is a device that is physically bound to or integrated in the DCE (virtual.)
I'm not saying you and Ted are *wrong*; you are most certainly not. What I'm hoping for is a bit of pragmatism that would make at least some users' lives a little easier.
None of this will, of course, help when the hardware itself is buggered to the point that there is nothing we can do about it. I'm not trying to deal with anything like that.
Things that I have identified, at least in my opinion:
1. Opening a device for configuration as opposed to data streaming; in the tty case that doesn't just improve the DTR# and RTS# issue but allows setserial, configuring line disciplines and so on.
As I have said, this is application-specific intent, which is why I strongly believe that it needs to be part of the open system call. I furthermore believe that it would have use cases beyond ttys and serial ports, which is why I'm proposing a new open flag as opposed to a sysfs attribute, which actually was my initial approach (yes, I have already prototyped some of this, and as referenced before there is an existing patchset that was never merged.)
2. Currently the setserial configurables are available in sysfs, but *only* for UARTs, whereas TIOC[GS]SERIAL is at least available to all serial devices. That code should presumably be hoisted into a higher layer; this shouldn't be too difficult.
3. The only way to determine the type of a tty driver is reading and parsing /proc/tty/drivers; that information is exported neither through ioctl nor sysfs. Exporting *that* through sysfs is probably the easiest of all the improvements.
4. There isn't a device-independent way to determine if a device is "real" (configured for hardware) or not without opening it and executing one of the termios ioctls like TCGETS (returns -EIO if there isn't anything behind it.) For a UART port it is possible to come up with an educated guess based on the aforementioned sysfs properties (does it have any kind of address associated with it?), but seriously, should stty -a /dev/ttyS0 really glitch RTS# and DTR# even though there is no intent of using the port for communication?
Let me make it very clear that I'm *not* criticizing neither you, Ted, Alan Cox nor anyone else who have been involved: on the contrary, you have done an absolutely fantastic job making Linux work with all these pieces of hardware, each with various "interesting" properties. Nor am I criticizing the tty interface as it is: it is designed to allow both interactive terminal use and use for other purposes under program control, which is really an astonishing level of flexibility. We have already shown that it can evolve to meet new needs, which sometimes requires interface extensions – like O_NOCTTY, O_NONBLOCK, CRTSCTS, termios2, and BOTHER. *And that is perfectly okay.* If anything it is a strength.
And please do recognize that I have stated from the beginning that I expect this to be a "best effort" on the part of kernel, not a guarantee. If the hardware is too broken, the user gets to keep both pieces – that's just reality.
Powered by blists - more mailing lists