X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fserial%2Fvisor.c;h=0bb6262ad89c702524753938fb9d2618f0ff4a48;hb=8e8ece46a861c84343256819eaec77e608ff9217;hp=6c0d51638824bea8f8ddab59dbd2693116df360a;hpb=a6d8dea2993ef90fb69b81372daa0b63f8aa940e;p=linux-2.6.git diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 6c0d51638..0bb6262ad 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -386,6 +386,7 @@ struct visor_private { int bytes_in; int bytes_out; int outstanding_urbs; + int throttled; }; /* number of outstanding urbs to prevent userspace DoS from happening */ @@ -415,6 +416,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp) priv->bytes_in = 0; priv->bytes_out = 0; priv->outstanding_urbs = 0; + priv->throttled = 0; spin_unlock_irqrestore(&priv->lock, flags); /* @@ -602,6 +604,7 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) struct tty_struct *tty; unsigned long flags; int i; + int throttled; int result; dbg("%s - port %d", __FUNCTION__, port->number); @@ -627,18 +630,21 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs) } spin_lock_irqsave(&priv->lock, flags); priv->bytes_in += urb->actual_length; + throttled = priv->throttled; spin_unlock_irqrestore(&priv->lock, flags); - /* Continue trying to always read */ - usb_fill_bulk_urb (port->read_urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, - port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + /* Continue trying to always read if we should */ + if (!throttled) { + usb_fill_bulk_urb (port->read_urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + if (result) + dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); + } return; } @@ -683,16 +689,26 @@ exit: static void visor_throttle (struct usb_serial_port *port) { + struct visor_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + dbg("%s - port %d", __FUNCTION__, port->number); - usb_kill_urb(port->read_urb); + spin_lock_irqsave(&priv->lock, flags); + priv->throttled = 1; + spin_unlock_irqrestore(&priv->lock, flags); } static void visor_unthrottle (struct usb_serial_port *port) { + struct visor_private *priv = usb_get_serial_port_data(port); + unsigned long flags; int result; dbg("%s - port %d", __FUNCTION__, port->number); + spin_lock_irqsave(&priv->lock, flags); + priv->throttled = 0; + spin_unlock_irqrestore(&priv->lock, flags); port->read_urb->dev = port->serial->dev; result = usb_submit_urb(port->read_urb, GFP_ATOMIC);