Commit b4026c45 authored by Hermann Kneissel's avatar Hermann Kneissel Committed by Greg Kroah-Hartman

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: default avatarHermann Kneissel <herkne@gmx.de>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 7701846f
/* /*
* Garmin GPS driver * Garmin GPS driver
* *
* Copyright (C) 2006-2009 Hermann Kneissel herkne@users.sourceforge.net * Copyright (C) 2006-2011 Hermann Kneissel herkne@gmx.de
* *
* The latest version of the driver can be found at * The latest version of the driver can be found at
* http://sourceforge.net/projects/garmin-gps/ * http://sourceforge.net/projects/garmin-gps/
...@@ -51,7 +51,7 @@ static int debug; ...@@ -51,7 +51,7 @@ static int debug;
*/ */
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 33 #define VERSION_MINOR 36
#define _STR(s) #s #define _STR(s) #s
#define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b) #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) ...@@ -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) 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; const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
__le32 *usbdata = (__le32 *) garmin_data_p->inbuffer; __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
...@@ -458,7 +459,9 @@ static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count) ...@@ -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 /* if this was an abort-transfer command, flush all
queued data. */ queued data. */
if (isAbortTrfCmnd(garmin_data_p->inbuffer)) { if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_DROP_DATA; garmin_data_p->flags |= FLAGS_DROP_DATA;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
pkt_clear(garmin_data_p); pkt_clear(garmin_data_p);
} }
...@@ -943,7 +946,7 @@ static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -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); spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->mode = initial_mode; garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0; 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); spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */ /* shutdown any bulk reads that might be going on */
...@@ -1178,7 +1181,8 @@ static int garmin_write_room(struct tty_struct *tty) ...@@ -1178,7 +1181,8 @@ static int garmin_write_room(struct tty_struct *tty)
static void garmin_read_process(struct garmin_data *garmin_data_p, 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; unsigned long flags;
...@@ -1193,7 +1197,8 @@ static void garmin_read_process(struct garmin_data *garmin_data_p, ...@@ -1193,7 +1197,8 @@ static void garmin_read_process(struct garmin_data *garmin_data_p,
send it directly to the tty port */ send it directly to the tty port */
if (garmin_data_p->flags & FLAGS_QUEUING) { if (garmin_data_p->flags & FLAGS_QUEUING) {
pkt_add(garmin_data_p, data, data_length); 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); spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= APP_RESP_SEEN; garmin_data_p->flags |= APP_RESP_SEEN;
...@@ -1237,7 +1242,7 @@ static void garmin_read_bulk_callback(struct urb *urb) ...@@ -1237,7 +1242,7 @@ static void garmin_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, usb_serial_debug_data(debug, &port->dev,
__func__, urb->actual_length, data); __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 && if (urb->actual_length == 0 &&
0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) { 0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) {
...@@ -1346,7 +1351,7 @@ static void garmin_read_int_callback(struct urb *urb) ...@@ -1346,7 +1351,7 @@ static void garmin_read_int_callback(struct urb *urb)
__func__, garmin_data_p->serial_num); __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; port->interrupt_in_urb->dev = port->serial->dev;
retval = usb_submit_urb(urb, GFP_ATOMIC); retval = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -1461,6 +1466,7 @@ static int garmin_attach(struct usb_serial *serial) ...@@ -1461,6 +1466,7 @@ static int garmin_attach(struct usb_serial *serial)
garmin_data_p->timer.function = timeout_handler; garmin_data_p->timer.function = timeout_handler;
garmin_data_p->port = port; garmin_data_p->port = port;
garmin_data_p->state = 0; garmin_data_p->state = 0;
garmin_data_p->flags = 0;
garmin_data_p->count = 0; garmin_data_p->count = 0;
usb_set_serial_port_data(port, garmin_data_p); usb_set_serial_port_data(port, garmin_data_p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment