Commit f72ae608 authored by Dan Drown's avatar Dan Drown Committed by Greg Kroah-Hartman
Browse files

usb: cdc-acm: move ldisc dcd notification outside of acm's read lock



dcd_change notification call moved outside of the acm->read_lock
to protect any future tty ldisc that calls wait_serial_change()

Signed-off-by: default avatarDan Drown <dan-netdev@drown.org>
Acked-by: default avatarOliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/ZN1zV/zjPgpGlHXo@vps3.drown.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 23e60c8d
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -319,14 +319,8 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
		}

		difference = acm->ctrlin ^ newctrl;
		spin_lock_irqsave(&acm->read_lock, flags);
		acm->ctrlin = newctrl;
		acm->oldcount = acm->iocount;

		if (difference & USB_CDC_SERIAL_STATE_DSR)
			acm->iocount.dsr++;
		if (difference & USB_CDC_SERIAL_STATE_DCD) {
			if (acm->port.tty) {
		if ((difference & USB_CDC_SERIAL_STATE_DCD) && acm->port.tty) {
			struct tty_ldisc *ld = tty_ldisc_ref(acm->port.tty);
			if (ld) {
				if (ld->ops->dcd_change)
@@ -334,8 +328,15 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
				tty_ldisc_deref(ld);
			}
		}

		spin_lock_irqsave(&acm->read_lock, flags);
		acm->ctrlin = newctrl;
		acm->oldcount = acm->iocount;

		if (difference & USB_CDC_SERIAL_STATE_DSR)
			acm->iocount.dsr++;
		if (difference & USB_CDC_SERIAL_STATE_DCD)
			acm->iocount.dcd++;
		}
		if (newctrl & USB_CDC_SERIAL_STATE_BREAK) {
			acm->iocount.brk++;
			tty_insert_flip_char(&acm->port, 0, TTY_BREAK);