diff options
Diffstat (limited to 'drivers/usb/class')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 95 | ||||
| -rw-r--r-- | drivers/usb/class/cdc-acm.h | 1 | 
2 files changed, 14 insertions, 82 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 27346d69f393..9ede35cecb12 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -310,17 +310,17 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)  		if (difference & ACM_CTRL_DSR)  			acm->iocount.dsr++; -		if (difference & ACM_CTRL_BRK) -			acm->iocount.brk++; -		if (difference & ACM_CTRL_RI) -			acm->iocount.rng++;  		if (difference & ACM_CTRL_DCD)  			acm->iocount.dcd++; -		if (difference & ACM_CTRL_FRAMING) +		if (newctrl & ACM_CTRL_BRK) +			acm->iocount.brk++; +		if (newctrl & ACM_CTRL_RI) +			acm->iocount.rng++; +		if (newctrl & ACM_CTRL_FRAMING)  			acm->iocount.frame++; -		if (difference & ACM_CTRL_PARITY) +		if (newctrl & ACM_CTRL_PARITY)  			acm->iocount.parity++; -		if (difference & ACM_CTRL_OVERRUN) +		if (newctrl & ACM_CTRL_OVERRUN)  			acm->iocount.overrun++;  		spin_unlock_irqrestore(&acm->read_lock, flags); @@ -355,7 +355,6 @@ static void acm_ctrl_irq(struct urb *urb)  	case -ENOENT:  	case -ESHUTDOWN:  		/* this urb is terminated, clean up */ -		acm->nb_index = 0;  		dev_dbg(&acm->control->dev,  			"%s - urb shutting down with status: %d\n",  			__func__, status); @@ -780,20 +779,9 @@ static int acm_tty_write(struct tty_struct *tty,  	}  	if (acm->susp_count) { -		if (acm->putbuffer) { -			/* now to preserve order */ -			usb_anchor_urb(acm->putbuffer->urb, &acm->delayed); -			acm->putbuffer = NULL; -		}  		usb_anchor_urb(wb->urb, &acm->delayed);  		spin_unlock_irqrestore(&acm->write_lock, flags);  		return count; -	} else { -		if (acm->putbuffer) { -			/* at this point there is no good way to handle errors */ -			acm_start_wb(acm, acm->putbuffer); -			acm->putbuffer = NULL; -		}  	}  	stat = acm_start_wb(acm, wb); @@ -804,66 +792,6 @@ static int acm_tty_write(struct tty_struct *tty,  	return count;  } -static void acm_tty_flush_chars(struct tty_struct *tty) -{ -	struct acm *acm = tty->driver_data; -	struct acm_wb *cur; -	int err; -	unsigned long flags; - -	spin_lock_irqsave(&acm->write_lock, flags); - -	cur = acm->putbuffer; -	if (!cur) /* nothing to do */ -		goto out; - -	acm->putbuffer = NULL; -	err = usb_autopm_get_interface_async(acm->control); -	if (err < 0) { -		cur->use = 0; -		acm->putbuffer = cur; -		goto out; -	} - -	if (acm->susp_count) -		usb_anchor_urb(cur->urb, &acm->delayed); -	else -		acm_start_wb(acm, cur); -out: -	spin_unlock_irqrestore(&acm->write_lock, flags); -	return; -} - -static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch) -{ -	struct acm *acm = tty->driver_data; -	struct acm_wb *cur; -	int wbn; -	unsigned long flags; - -overflow: -	cur = acm->putbuffer; -	if (!cur) { -		spin_lock_irqsave(&acm->write_lock, flags); -		wbn = acm_wb_alloc(acm); -		if (wbn >= 0) { -			cur = &acm->wb[wbn]; -			acm->putbuffer = cur; -		} -		spin_unlock_irqrestore(&acm->write_lock, flags); -		if (!cur) -			return 0; -	} - -	if (cur->len == acm->writesize) { -		acm_tty_flush_chars(tty); -		goto overflow; -	} - -	cur->buf[cur->len++] = ch; -	return 1; -} -  static int acm_tty_write_room(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; @@ -1585,6 +1513,7 @@ static void acm_disconnect(struct usb_interface *intf)  {  	struct acm *acm = usb_get_intfdata(intf);  	struct tty_struct *tty; +	int i;  	/* sibling interface is already cleaning up */  	if (!acm) @@ -1615,6 +1544,11 @@ static void acm_disconnect(struct usb_interface *intf)  	tty_unregister_device(acm_tty_driver, acm->minor); +	usb_free_urb(acm->ctrlurb); +	for (i = 0; i < ACM_NW; i++) +		usb_free_urb(acm->wb[i].urb); +	for (i = 0; i < acm->rx_buflimit; i++) +		usb_free_urb(acm->read_urbs[i]);  	acm_write_buffers_free(acm);  	usb_free_coherent(acm->dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);  	acm_read_buffers_free(acm); @@ -1707,6 +1641,7 @@ static int acm_pre_reset(struct usb_interface *intf)  	struct acm *acm = usb_get_intfdata(intf);  	clear_bit(EVENT_RX_STALL, &acm->flags); +	acm->nb_index = 0; /* pending control transfers are lost */  	return 0;  } @@ -1987,8 +1922,6 @@ static const struct tty_operations acm_ops = {  	.cleanup =		acm_tty_cleanup,  	.hangup =		acm_tty_hangup,  	.write =		acm_tty_write, -	.put_char =		acm_tty_put_char, -	.flush_chars =		acm_tty_flush_chars,  	.write_room =		acm_tty_write_room,  	.ioctl =		acm_tty_ioctl,  	.throttle =		acm_tty_throttle, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index eacc116e83da..ca06b20d7af9 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -96,7 +96,6 @@ struct acm {  	unsigned long read_urbs_free;  	struct urb *read_urbs[ACM_NR];  	struct acm_rb read_buffers[ACM_NR]; -	struct acm_wb *putbuffer;			/* for acm_tty_put_char() */  	int rx_buflimit;  	spinlock_t read_lock;  	u8 *notification_buffer;			/* to reassemble fragmented notifications */  | 
