Skip to content

Commit

Permalink
USB: gamin_gps: Fix for data transfer problems in native mode
Browse files Browse the repository at this point in the history
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 <herkne@gmx.de>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Hermann Kneissel authored and Greg Kroah-Hartman committed Apr 30, 2011
1 parent 7701846 commit b4026c4
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions drivers/usb/serial/garmin_gps.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* 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
* http://sourceforge.net/projects/garmin-gps/
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit b4026c4

Please sign in to comment.