Skip to content

Commit 09867af

Browse files
nomisgregkh
authored andcommitted
USB: cdc-acm: support flushing write buffers (TCOFLUSH)
If the serial device never reads data written to it (because it is "output only") then the write buffers will still be waiting for the URB to complete on close(), which will hang for 30s until the closing_wait timeout expires. This can happen with the ESP32-H2/ESP32-C6 USB serial interface. Changing the port closing_wait timeout is a privileged operation but flushing the output buffer is not a privileged operation. Implement the flush_buffer tty operation to cancel in-progress writes so that tcflush(fd, TCOFLUSH) can be used to unblock the serial port before close. Signed-off-by: Simon Arlott <simon@octiron.net> Link: https://lore.kernel.org/r/555fbc4c-043b-8932-fb9b-a208d61ffbe4@0882a8b5-c6c3-11e9-b005-00805fc181fe.uuid.home.arpa Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4b3cd78 commit 09867af

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

drivers/usb/class/cdc-acm.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,19 @@ static unsigned int acm_tty_write_room(struct tty_struct *tty)
864864
return acm_wb_is_avail(acm) ? acm->writesize : 0;
865865
}
866866

867+
static void acm_tty_flush_buffer(struct tty_struct *tty)
868+
{
869+
struct acm *acm = tty->driver_data;
870+
unsigned long flags;
871+
int i;
872+
873+
spin_lock_irqsave(&acm->write_lock, flags);
874+
for (i = 0; i < ACM_NW; i++)
875+
if (acm->wb[i].use)
876+
usb_unlink_urb(acm->wb[i].urb);
877+
spin_unlock_irqrestore(&acm->write_lock, flags);
878+
}
879+
867880
static unsigned int acm_tty_chars_in_buffer(struct tty_struct *tty)
868881
{
869882
struct acm *acm = tty->driver_data;
@@ -2027,6 +2040,7 @@ static const struct tty_operations acm_ops = {
20272040
.hangup = acm_tty_hangup,
20282041
.write = acm_tty_write,
20292042
.write_room = acm_tty_write_room,
2043+
.flush_buffer = acm_tty_flush_buffer,
20302044
.ioctl = acm_tty_ioctl,
20312045
.throttle = acm_tty_throttle,
20322046
.unthrottle = acm_tty_unthrottle,

0 commit comments

Comments
 (0)