Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 64286
b: refs/heads/master
c: 468d136
h: refs/heads/master
v: v3
  • Loading branch information
Hermann Kneissel authored and Greg Kroah-Hartman committed Aug 22, 2007
1 parent 91ed910 commit 9684402
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 47 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c8ba84a0c682068a55a5892d6e12e3f196fd792c
refs/heads/master: 468d13623b6c8d048abab71ed465fa8ad3bf8875
93 changes: 47 additions & 46 deletions trunk/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 Hermann Kneissel herkne@users.sourceforge.net
* Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net
*
* The latest version of the driver can be found at
* http://sourceforge.net/projects/garmin-gps/
Expand Down Expand Up @@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>

Expand All @@ -52,7 +53,7 @@ static int debug = 0;
*/

#define VERSION_MAJOR 0
#define VERSION_MINOR 28
#define VERSION_MINOR 31

#define _STR(s) #s
#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
Expand Down Expand Up @@ -141,6 +142,8 @@ struct garmin_data {
__u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */
__u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
__u8 privpkt[4*6];
atomic_t req_count;
atomic_t resp_count;
spinlock_t lock;
struct list_head pktlist;
};
Expand Down Expand Up @@ -171,8 +174,6 @@ struct garmin_data {
#define CLEAR_HALT_REQUIRED 0x0001

#define FLAGS_QUEUING 0x0100
#define FLAGS_APP_RESP_SEEN 0x0200
#define FLAGS_APP_REQ_SEEN 0x0400
#define FLAGS_DROP_DATA 0x0800

#define FLAGS_GSP_SKIP 0x1000
Expand All @@ -186,7 +187,8 @@ struct garmin_data {
/* function prototypes */
static void gsp_next_packet(struct garmin_data * garmin_data_p);
static int garmin_write_bulk(struct usb_serial_port *port,
const unsigned char *buf, int count);
const unsigned char *buf, int count,
int dismiss_ack);

/* some special packets to be send or received */
static unsigned char const GARMIN_START_SESSION_REQ[]
Expand Down Expand Up @@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = {

static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
{
return ((garmin_data_p->flags
& (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
== FLAGS_APP_REQ_SEEN);
return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
}


Expand Down Expand Up @@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
usbdata[2] = __cpu_to_le32(size);

garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
GARMIN_PKTHDR_LENGTH+size);
GARMIN_PKTHDR_LENGTH+size, 0);

/* if this was an abort-transfer command, flush all
queued data. */
Expand Down Expand Up @@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
if (garmin_data_p->insize >= len) {
garmin_write_bulk (garmin_data_p->port,
garmin_data_p->inbuffer,
len);
len, 0);
garmin_data_p->insize = 0;

/* if this was an abort-transfer command,
Expand Down Expand Up @@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p)

struct usb_serial_port *port = garmin_data_p->port;

if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
/* send a terminate command */
status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
sizeof(GARMIN_STOP_TRANSFER_REQ));
sizeof(GARMIN_STOP_TRANSFER_REQ),
1);
}

/* flush all queued data */
Expand Down Expand Up @@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port)
dbg("%s - starting session ...", __FUNCTION__);
garmin_data_p->state = STATE_ACTIVE;
status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
sizeof(GARMIN_START_SESSION_REQ));
sizeof(GARMIN_START_SESSION_REQ),
0);

if (status >= 0) {

Expand All @@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port)
/* not needed, but the win32 driver does it too ... */
status = garmin_write_bulk(port,
GARMIN_START_SESSION_REQ2,
sizeof(GARMIN_START_SESSION_REQ2));
sizeof(GARMIN_START_SESSION_REQ2),
0);
if (status >= 0) {
status = 0;
spin_lock_irqsave(&garmin_data_p->lock, flags);
Expand Down Expand Up @@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0;
garmin_data_p->flags = 0;
atomic_set(&garmin_data_p->req_count, 0);
atomic_set(&garmin_data_p->resp_count, 0);
spin_unlock_irqrestore(&garmin_data_p->lock, flags);

/* shutdown any bulk reads that might be going on */
Expand Down Expand Up @@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb)
{
unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
int status = urb->status;

/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
if (port) {
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);

dbg("%s - port %d", __FUNCTION__, port->number);
dbg("%s - port %d", __FUNCTION__, port->number);

if (status) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, status);
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
&& (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
}

if (status) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, urb->status);
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
}

usb_serial_port_softint(port);
}

usb_serial_port_softint(port);
/* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */

/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
}


static int garmin_write_bulk (struct usb_serial_port *port,
const unsigned char *buf, int count)
const unsigned char *buf, int count,
int dismiss_ack)
{
unsigned long flags;
struct usb_serial *serial = port->serial;
Expand Down Expand Up @@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port,
usb_sndbulkpipe (serial->dev,
port->bulk_out_endpointAddress),
buffer, count,
garmin_write_bulk_callback, port);
garmin_write_bulk_callback,
dismiss_ack ? NULL : port);
urb->transfer_flags |= URB_ZERO_PACKET;

if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->req_count);
if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
pkt_clear(garmin_data_p);
garmin_data_p->state = STATE_GSP_WAIT_DATA;
Expand All @@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
"failed with status = %d\n",
__FUNCTION__, status);
count = status;
} else {

if (GARMIN_LAYERID_APPL == getLayerId(buffer)
&& (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {

gsp_send_ack(garmin_data_p, buffer[4]);
}
}

/* we are done with this urb, so let the host driver
Expand All @@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
static int garmin_write (struct usb_serial_port *port,
const unsigned char *buf, int count)
{
unsigned long flags;
int pktid, pktsiz, len;
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
Expand Down Expand Up @@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port,
break;

case PRIV_PKTID_RESET_REQ:
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->req_count);
break;

case PRIV_PKTID_SET_DEF_MODE:
Expand Down Expand Up @@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port)
static void garmin_read_process(struct garmin_data * garmin_data_p,
unsigned char *data, unsigned data_length)
{
unsigned long flags;

if (garmin_data_p->flags & FLAGS_DROP_DATA) {
/* abort-transfer cmd is actice */
dbg("%s - pkt dropped", __FUNCTION__);
Expand All @@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
the device */
if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
sizeof(GARMIN_APP_LAYER_REPLY))) {
spin_lock_irqsave(&garmin_data_p->lock, flags);
garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
atomic_inc(&garmin_data_p->resp_count);
}

/* if throttling is active or postprecessing is required
Expand Down

0 comments on commit 9684402

Please sign in to comment.