Greg KH wrote: > On Thu, Feb 14, 2008 at 01:15:37AM +1030, David Newall wrote: > >> Consider a USB-attached serial port that is set to do RTS/CTS (or >> DSR/DTR) handshaking: What stops the kernel sending more data to it when >> the remote end lowers CTS (or DTR)? >> > > The tty layer should look at the proper flags and not send data on to > the driver in this kind of instance. > > Is this not happening properly for you? If so, which USB serial driver? >
It's not happening properly, for pl2303 (and, I admit it! on kernel 2.4.) I think there's a widespread problem (i.e. with other drivers.) None of the drivers that I've examined check CTS or DTR; or, if they do, I can't see where. Likewise, I can't see it being done in n_tty nor tty_io; not even in usbserial. The best answer I can see is write_room, but that doesn't seem quite right. It seems that data written (via *_write) will merrily be transmitted to the converter, even while the remote end is signalling to stop, even if local hardware buffers fill. I have a working solution for the 2.4 driver, but am looking towards something for 2.6 and beyond. The 2.4 solution is in two parts: first, implement a write_room function, which returns 0 when transmission is required to stop, which apparently gives a hint to the tty layer. (NB, doesn't help when using a different line discipline.) The second part is to return 0 (or maybe -EAGAIN?) in the write function when transmission is required to stop. This appears sound. (Note that the generic putchar does no error checking, and fails when the write URB is busy. That's a problem with a fairly obvious solution.) The current 2.6 driver maintains it's own buffer. I think that's a bad thing: usbserial already buffers writes, and the extra buffer copy seems unnecessary, however it does solve the putchar problem. Buffered (i.e. by the 2.6 series pl2303 driver) data is written as soon as practicable, regardless of CTS/DTR. The same general workaround, but placed in pl2303_send seems correct to me; that is, stop submitting write urbs when the remote end lowers CTS/DTR, and trigger the resume from the interrupt callback (specifically in update_line_status.) As I say, this appears to be a widespread problem. I've looked at a number of drivers and in none of them can I see anything to prevent transmission when the remote end demands a stop. I'm not sure that the tty layer, which I think I said attempts to address the problem, albeit it does a half-arsed job, is the right place to do hardware handshaking. Equally, I'm not sure that the wheel should be re-invented for every driver, but that might be unavoidable. To make it clear: Even aside from the buffer in 2.6's pl2303.c, there's a race: An in-flight write URB can fill all hardware buffers, making unsafe what previously appeared to be a safe write. I think it's essential to delay submission of the URB on a stop-transmit condition. -- 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/