OSDN Git Service

USB: omninet: refactor read-urb processing
authorJohan Hovold <jhovold@gmail.com>
Tue, 16 Apr 2013 16:01:22 +0000 (18:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Apr 2013 17:05:34 +0000 (10:05 -0700)
Refactor read-urb processing, and add sanity checks on header and data
lengths.

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/omninet.c

index 9dcaa77..7aaf969 100644 (file)
@@ -158,11 +158,26 @@ static void omninet_close(struct usb_serial_port *port)
 #define OMNINET_BULKOUTSIZE    64
 #define OMNINET_PAYLOADSIZE    (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN)
 
+static void omninet_process_read_urb(struct urb *urb)
+{
+       struct usb_serial_port *port = urb->context;
+       const struct omninet_header *hdr = urb->transfer_buffer;
+       const unsigned char *data;
+       size_t data_len;
+
+       if (urb->actual_length <= OMNINET_HEADERLEN || !hdr->oh_len)
+               return;
+
+       data = (char *)urb->transfer_buffer + OMNINET_HEADERLEN;
+       data_len = min_t(size_t, urb->actual_length - OMNINET_HEADERLEN,
+                                                               hdr->oh_len);
+       tty_insert_flip_string(&port->port, data, data_len);
+       tty_flip_buffer_push(&port->port);
+}
+
 static void omninet_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port   = urb->context;
-       unsigned char           *data   = urb->transfer_buffer;
-       struct omninet_header   *header = (struct omninet_header *) &data[0];
        int status = urb->status;
        int result;
 
@@ -172,11 +187,7 @@ static void omninet_read_bulk_callback(struct urb *urb)
                return;
        }
 
-       if (urb->actual_length && header->oh_len) {
-               tty_insert_flip_string(&port->port, data + OMNINET_HEADERLEN,
-                               header->oh_len);
-               tty_flip_buffer_push(&port->port);
-       }
+       omninet_process_read_urb(urb);
 
        /* Continue trying to always read  */
        result = usb_submit_urb(urb, GFP_ATOMIC);