This is a note to let you know that I've just added the patch titled

    USB: gamin_gps: Fix for data transfer problems in native mode

to my usb git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
in the usb-next branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will also will be merged in the next major kernel release
during the merge window.

If you have any questions about this process, please let me know.


>From b4026c4584cd70858d4d3450abfb1cd0714d4f32 Mon Sep 17 00:00:00 2001
From: Hermann Kneissel <[email protected]>
Date: Fri, 29 Apr 2011 08:58:43 +0200
Subject: USB: gamin_gps: Fix for data transfer problems in native mode

This patch fixes a problem where data received from the gps is sometimes
transferred incompletely to the serial port. If used in native mode now
all data received via the bulk queue will be forwarded to the serial
port.

Signed-off-by: Hermann Kneissel <[email protected]>
Cc: stable <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/serial/garmin_gps.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 26710b1..b0a7a9e 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1,7 +1,7 @@
 /*
  * Garmin GPS driver
  *
- * Copyright (C) 2006-2009 Hermann Kneissel [email protected]
+ * Copyright (C) 2006-2011 Hermann Kneissel [email protected]
  *
  * The latest version of the driver can be found at
  * http://sourceforge.net/projects/garmin-gps/
@@ -51,7 +51,7 @@ static int debug;
  */
 
 #define VERSION_MAJOR  0
-#define VERSION_MINOR  33
+#define VERSION_MINOR  36
 
 #define _STR(s) #s
 #define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b)
@@ -410,6 +410,7 @@ static int gsp_send_ack(struct garmin_data *garmin_data_p, 
__u8 pkt_id)
  */
 static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count)
 {
+       unsigned long flags;
        const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
        __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
 
@@ -458,7 +459,9 @@ static int gsp_rec_packet(struct garmin_data 
*garmin_data_p, int count)
        /* if this was an abort-transfer command, flush all
           queued data. */
        if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
+               spin_lock_irqsave(&garmin_data_p->lock, flags);
                garmin_data_p->flags |= FLAGS_DROP_DATA;
+               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
                pkt_clear(garmin_data_p);
        }
 
@@ -943,7 +946,7 @@ static int garmin_open(struct tty_struct *tty, struct 
usb_serial_port *port)
        spin_lock_irqsave(&garmin_data_p->lock, flags);
        garmin_data_p->mode  = initial_mode;
        garmin_data_p->count = 0;
-       garmin_data_p->flags = 0;
+       garmin_data_p->flags &= FLAGS_SESSION_REPLY1_SEEN;
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
        /* shutdown any bulk reads that might be going on */
@@ -1178,7 +1181,8 @@ static int garmin_write_room(struct tty_struct *tty)
 
 
 static void garmin_read_process(struct garmin_data *garmin_data_p,
-                                unsigned char *data, unsigned data_length)
+                                unsigned char *data, unsigned data_length,
+                                int bulk_data)
 {
        unsigned long flags;
 
@@ -1193,7 +1197,8 @@ static void garmin_read_process(struct garmin_data 
*garmin_data_p,
                   send it directly to the tty port */
                if (garmin_data_p->flags & FLAGS_QUEUING) {
                        pkt_add(garmin_data_p, data, data_length);
-               } else if (getLayerId(data) == GARMIN_LAYERID_APPL) {
+               } else if (bulk_data || 
+                          getLayerId(data) == GARMIN_LAYERID_APPL) {
 
                        spin_lock_irqsave(&garmin_data_p->lock, flags);
                        garmin_data_p->flags |= APP_RESP_SEEN;
@@ -1237,7 +1242,7 @@ static void garmin_read_bulk_callback(struct urb *urb)
        usb_serial_debug_data(debug, &port->dev,
                                __func__, urb->actual_length, data);
 
-       garmin_read_process(garmin_data_p, data, urb->actual_length);
+       garmin_read_process(garmin_data_p, data, urb->actual_length, 1);
 
        if (urb->actual_length == 0 &&
                        0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) {
@@ -1346,7 +1351,7 @@ static void garmin_read_int_callback(struct urb *urb)
                        __func__, garmin_data_p->serial_num);
        }
 
-       garmin_read_process(garmin_data_p, data, urb->actual_length);
+       garmin_read_process(garmin_data_p, data, urb->actual_length, 0);
 
        port->interrupt_in_urb->dev = port->serial->dev;
        retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1461,6 +1466,7 @@ static int garmin_attach(struct usb_serial *serial)
        garmin_data_p->timer.function = timeout_handler;
        garmin_data_p->port = port;
        garmin_data_p->state = 0;
+       garmin_data_p->flags = 0;
        garmin_data_p->count = 0;
        usb_set_serial_port_data(port, garmin_data_p);
 
-- 
1.7.4.2


_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to