]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/serial/omninet.c
Merge tag 'f2fs-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[~andy/linux] / drivers / usb / serial / omninet.c
index 1e1cafe287e4e63f7b7c23a18fd9b66965228e2e..5739bf6f7200923afd280219572987a0d9b8f104 100644 (file)
@@ -33,8 +33,7 @@
 
 /* function prototypes */
 static int  omninet_open(struct tty_struct *tty, struct usb_serial_port *port);
-static void omninet_close(struct usb_serial_port *port);
-static void omninet_read_bulk_callback(struct urb *urb);
+static void omninet_process_read_urb(struct urb *urb);
 static void omninet_write_bulk_callback(struct urb *urb);
 static int  omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
                                const unsigned char *buf, int count);
@@ -61,11 +60,10 @@ static struct usb_serial_driver zyxel_omninet_device = {
        .port_probe =           omninet_port_probe,
        .port_remove =          omninet_port_remove,
        .open =                 omninet_open,
-       .close =                omninet_close,
        .write =                omninet_write,
        .write_room =           omninet_write_room,
-       .read_bulk_callback =   omninet_read_bulk_callback,
        .write_bulk_callback =  omninet_write_bulk_callback,
+       .process_read_urb =     omninet_process_read_urb,
        .disconnect =           omninet_disconnect,
 };
 
@@ -74,29 +72,28 @@ static struct usb_serial_driver * const serial_drivers[] = {
 };
 
 
-/* The protocol.
+/*
+ * The protocol.
  *
  * The omni.net always exchange 64 bytes of data with the host. The first
- * four bytes are the control header, you can see it in the above structure.
+ * four bytes are the control header.
  *
  * oh_seq is a sequence number. Don't know if/how it's used.
  * oh_len is the length of the data bytes in the packet.
  * oh_xxx Bit-mapped, related to handshaking and status info.
- *     I normally set it to 0x03 in trasmitted frames.
+ *     I normally set it to 0x03 in transmitted frames.
  *     7: Active when the TA is in a CONNECTed state.
  *     6: unknown
  *     5: handshaking, unknown
  *     4: handshaking, unknown
  *     3: unknown, usually 0
  *     2: unknown, usually 0
- *     1: handshaking, unknown, usually set to 1 in trasmitted frames
- *     0: handshaking, unknown, usually set to 1 in trasmitted frames
+ *     1: handshaking, unknown, usually set to 1 in transmitted frames
+ *     0: handshaking, unknown, usually set to 1 in transmitted frames
  * oh_pad Probably a pad byte.
  *
  * After the header you will find data bytes if oh_len was greater than zero.
- *
  */
-
 struct omninet_header {
        __u8    oh_seq;
        __u8    oh_len;
@@ -112,7 +109,7 @@ static int omninet_port_probe(struct usb_serial_port *port)
 {
        struct omninet_data *od;
 
-       od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
+       od = kzalloc(sizeof(*od), GFP_KERNEL);
        if (!od)
                return -ENOMEM;
 
@@ -135,56 +132,32 @@ static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        struct usb_serial       *serial = port->serial;
        struct usb_serial_port  *wport;
-       int                     result = 0;
 
        wport = serial->port[1];
        tty_port_tty_set(&wport->port, tty);
 
-       /* Start reading from the device */
-       result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-       if (result)
-               dev_err(&port->dev,
-                       "%s - failed submitting read urb, error %d\n",
-                       __func__, result);
-       return result;
-}
-
-static void omninet_close(struct usb_serial_port *port)
-{
-       usb_kill_urb(port->read_urb);
+       return usb_serial_generic_open(tty, port);
 }
 
+#define OMNINET_HEADERLEN      4
+#define OMNINET_BULKOUTSIZE    64
+#define OMNINET_PAYLOADSIZE    (OMNINET_BULKOUTSIZE - OMNINET_HEADERLEN)
 
-#define OMNINET_DATAOFFSET     0x04
-#define OMNINET_HEADERLEN      sizeof(struct omninet_header)
-#define OMNINET_BULKOUTSIZE    (64 - OMNINET_HEADERLEN)
-
-static void omninet_read_bulk_callback(struct urb *urb)
+static void omninet_process_read_urb(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;
+       struct usb_serial_port *port = urb->context;
+       const struct omninet_header *hdr = urb->transfer_buffer;
+       const unsigned char *data;
+       size_t data_len;
 
-       if (status) {
-               dev_dbg(&port->dev, "%s - nonzero read bulk status received: %d\n",
-                       __func__, status);
+       if (urb->actual_length <= OMNINET_HEADERLEN || !hdr->oh_len)
                return;
-       }
-
-       if (urb->actual_length && header->oh_len) {
-               tty_insert_flip_string(&port->port, data + OMNINET_DATAOFFSET,
-                               header->oh_len);
-               tty_flip_buffer_push(&port->port);
-       }
 
-       /* Continue trying to always read  */
-       result = usb_submit_urb(urb, GFP_ATOMIC);
-       if (result)
-               dev_err(&port->dev,
-                       "%s - failed resubmitting read urb, error %d\n",
-                       __func__, result);
+       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 int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -209,9 +182,9 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
                return 0;
        }
 
-       count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
+       count = (count > OMNINET_PAYLOADSIZE) ? OMNINET_PAYLOADSIZE : count;
 
-       memcpy(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET,
+       memcpy(wport->write_urb->transfer_buffer + OMNINET_HEADERLEN,
                                                                buf, count);
 
        usb_serial_debug_data(&port->dev, __func__, count,
@@ -223,7 +196,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
        header->oh_pad  = 0x00;
 
        /* send the data out the bulk port, always 64 bytes */
-       wport->write_urb->transfer_buffer_length = 64;
+       wport->write_urb->transfer_buffer_length = OMNINET_BULKOUTSIZE;
 
        result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
        if (result) {