aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/garmin_gps.c93
1 files changed, 47 insertions, 46 deletions
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 04bd3b7a2985..f1c90cfe7251 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Garmin GPS driver 2 * Garmin GPS driver
3 * 3 *
4 * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net 4 * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net
5 * 5 *
6 * The latest version of the driver can be found at 6 * The latest version of the driver can be found at
7 * http://sourceforge.net/projects/garmin-gps/ 7 * http://sourceforge.net/projects/garmin-gps/
@@ -34,6 +34,7 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37#include <asm/atomic.h>
37#include <linux/usb.h> 38#include <linux/usb.h>
38#include <linux/usb/serial.h> 39#include <linux/usb/serial.h>
39 40
@@ -52,7 +53,7 @@ static int debug = 0;
52 */ 53 */
53 54
54#define VERSION_MAJOR 0 55#define VERSION_MAJOR 0
55#define VERSION_MINOR 28 56#define VERSION_MINOR 31
56 57
57#define _STR(s) #s 58#define _STR(s) #s
58#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) 59#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
@@ -141,6 +142,8 @@ struct garmin_data {
141 __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ 142 __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */
142 __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ 143 __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
143 __u8 privpkt[4*6]; 144 __u8 privpkt[4*6];
145 atomic_t req_count;
146 atomic_t resp_count;
144 spinlock_t lock; 147 spinlock_t lock;
145 struct list_head pktlist; 148 struct list_head pktlist;
146}; 149};
@@ -171,8 +174,6 @@ struct garmin_data {
171#define CLEAR_HALT_REQUIRED 0x0001 174#define CLEAR_HALT_REQUIRED 0x0001
172 175
173#define FLAGS_QUEUING 0x0100 176#define FLAGS_QUEUING 0x0100
174#define FLAGS_APP_RESP_SEEN 0x0200
175#define FLAGS_APP_REQ_SEEN 0x0400
176#define FLAGS_DROP_DATA 0x0800 177#define FLAGS_DROP_DATA 0x0800
177 178
178#define FLAGS_GSP_SKIP 0x1000 179#define FLAGS_GSP_SKIP 0x1000
@@ -186,7 +187,8 @@ struct garmin_data {
186/* function prototypes */ 187/* function prototypes */
187static void gsp_next_packet(struct garmin_data * garmin_data_p); 188static void gsp_next_packet(struct garmin_data * garmin_data_p);
188static int garmin_write_bulk(struct usb_serial_port *port, 189static int garmin_write_bulk(struct usb_serial_port *port,
189 const unsigned char *buf, int count); 190 const unsigned char *buf, int count,
191 int dismiss_ack);
190 192
191/* some special packets to be send or received */ 193/* some special packets to be send or received */
192static unsigned char const GARMIN_START_SESSION_REQ[] 194static unsigned char const GARMIN_START_SESSION_REQ[]
@@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = {
233 235
234static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) 236static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
235{ 237{
236 return ((garmin_data_p->flags 238 return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
237 & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
238 == FLAGS_APP_REQ_SEEN);
239} 239}
240 240
241 241
@@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
463 usbdata[2] = __cpu_to_le32(size); 463 usbdata[2] = __cpu_to_le32(size);
464 464
465 garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, 465 garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
466 GARMIN_PKTHDR_LENGTH+size); 466 GARMIN_PKTHDR_LENGTH+size, 0);
467 467
468 /* if this was an abort-transfer command, flush all 468 /* if this was an abort-transfer command, flush all
469 queued data. */ 469 queued data. */
@@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
818 if (garmin_data_p->insize >= len) { 818 if (garmin_data_p->insize >= len) {
819 garmin_write_bulk (garmin_data_p->port, 819 garmin_write_bulk (garmin_data_p->port,
820 garmin_data_p->inbuffer, 820 garmin_data_p->inbuffer,
821 len); 821 len, 0);
822 garmin_data_p->insize = 0; 822 garmin_data_p->insize = 0;
823 823
824 /* if this was an abort-transfer command, 824 /* if this was an abort-transfer command,
@@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p)
893 893
894 struct usb_serial_port *port = garmin_data_p->port; 894 struct usb_serial_port *port = garmin_data_p->port;
895 895
896 if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) { 896 if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
897 /* send a terminate command */ 897 /* send a terminate command */
898 status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, 898 status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
899 sizeof(GARMIN_STOP_TRANSFER_REQ)); 899 sizeof(GARMIN_STOP_TRANSFER_REQ),
900 1);
900 } 901 }
901 902
902 /* flush all queued data */ 903 /* flush all queued data */
@@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port)
939 dbg("%s - starting session ...", __FUNCTION__); 940 dbg("%s - starting session ...", __FUNCTION__);
940 garmin_data_p->state = STATE_ACTIVE; 941 garmin_data_p->state = STATE_ACTIVE;
941 status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, 942 status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
942 sizeof(GARMIN_START_SESSION_REQ)); 943 sizeof(GARMIN_START_SESSION_REQ),
944 0);
943 945
944 if (status >= 0) { 946 if (status >= 0) {
945 947
@@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port)
950 /* not needed, but the win32 driver does it too ... */ 952 /* not needed, but the win32 driver does it too ... */
951 status = garmin_write_bulk(port, 953 status = garmin_write_bulk(port,
952 GARMIN_START_SESSION_REQ2, 954 GARMIN_START_SESSION_REQ2,
953 sizeof(GARMIN_START_SESSION_REQ2)); 955 sizeof(GARMIN_START_SESSION_REQ2),
956 0);
954 if (status >= 0) { 957 if (status >= 0) {
955 status = 0; 958 status = 0;
956 spin_lock_irqsave(&garmin_data_p->lock, flags); 959 spin_lock_irqsave(&garmin_data_p->lock, flags);
@@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
987 garmin_data_p->mode = initial_mode; 990 garmin_data_p->mode = initial_mode;
988 garmin_data_p->count = 0; 991 garmin_data_p->count = 0;
989 garmin_data_p->flags = 0; 992 garmin_data_p->flags = 0;
993 atomic_set(&garmin_data_p->req_count, 0);
994 atomic_set(&garmin_data_p->resp_count, 0);
990 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 995 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
991 996
992 /* shutdown any bulk reads that might be going on */ 997 /* shutdown any bulk reads that might be going on */
@@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb)
1035{ 1040{
1036 unsigned long flags; 1041 unsigned long flags;
1037 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 1042 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
1038 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1039 int status = urb->status; 1043 int status = urb->status;
1040 1044
1041 /* free up the transfer buffer, as usb_free_urb() does not do this */ 1045 if (port) {
1042 kfree (urb->transfer_buffer); 1046 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1043 1047
1044 dbg("%s - port %d", __FUNCTION__, port->number); 1048 dbg("%s - port %d", __FUNCTION__, port->number);
1045 1049
1046 if (status) { 1050 if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
1047 dbg("%s - nonzero write bulk status received: %d", 1051 && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
1048 __FUNCTION__, status); 1052 gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
1049 spin_lock_irqsave(&garmin_data_p->lock, flags); 1053 }
1050 garmin_data_p->flags |= CLEAR_HALT_REQUIRED; 1054
1051 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 1055 if (status) {
1056 dbg("%s - nonzero write bulk status received: %d",
1057 __FUNCTION__, urb->status);
1058 spin_lock_irqsave(&garmin_data_p->lock, flags);
1059 garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
1060 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
1061 }
1062
1063 usb_serial_port_softint(port);
1052 } 1064 }
1053 1065
1054 usb_serial_port_softint(port); 1066 /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
1067
1068 /* free up the transfer buffer, as usb_free_urb() does not do this */
1069 kfree (urb->transfer_buffer);
1055} 1070}
1056 1071
1057 1072
1058static int garmin_write_bulk (struct usb_serial_port *port, 1073static int garmin_write_bulk (struct usb_serial_port *port,
1059 const unsigned char *buf, int count) 1074 const unsigned char *buf, int count,
1075 int dismiss_ack)
1060{ 1076{
1061 unsigned long flags; 1077 unsigned long flags;
1062 struct usb_serial *serial = port->serial; 1078 struct usb_serial *serial = port->serial;
@@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port,
1093 usb_sndbulkpipe (serial->dev, 1109 usb_sndbulkpipe (serial->dev,
1094 port->bulk_out_endpointAddress), 1110 port->bulk_out_endpointAddress),
1095 buffer, count, 1111 buffer, count,
1096 garmin_write_bulk_callback, port); 1112 garmin_write_bulk_callback,
1113 dismiss_ack ? NULL : port);
1097 urb->transfer_flags |= URB_ZERO_PACKET; 1114 urb->transfer_flags |= URB_ZERO_PACKET;
1098 1115
1099 if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { 1116 if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
1100 spin_lock_irqsave(&garmin_data_p->lock, flags); 1117 atomic_inc(&garmin_data_p->req_count);
1101 garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
1102 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
1103 if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { 1118 if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
1104 pkt_clear(garmin_data_p); 1119 pkt_clear(garmin_data_p);
1105 garmin_data_p->state = STATE_GSP_WAIT_DATA; 1120 garmin_data_p->state = STATE_GSP_WAIT_DATA;
@@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
1114 "failed with status = %d\n", 1129 "failed with status = %d\n",
1115 __FUNCTION__, status); 1130 __FUNCTION__, status);
1116 count = status; 1131 count = status;
1117 } else {
1118
1119 if (GARMIN_LAYERID_APPL == getLayerId(buffer)
1120 && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
1121
1122 gsp_send_ack(garmin_data_p, buffer[4]);
1123 }
1124 } 1132 }
1125 1133
1126 /* we are done with this urb, so let the host driver 1134 /* we are done with this urb, so let the host driver
@@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
1135static int garmin_write (struct usb_serial_port *port, 1143static int garmin_write (struct usb_serial_port *port,
1136 const unsigned char *buf, int count) 1144 const unsigned char *buf, int count)
1137{ 1145{
1138 unsigned long flags;
1139 int pktid, pktsiz, len; 1146 int pktid, pktsiz, len;
1140 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); 1147 struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
1141 __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; 1148 __le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
@@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port,
1186 break; 1193 break;
1187 1194
1188 case PRIV_PKTID_RESET_REQ: 1195 case PRIV_PKTID_RESET_REQ:
1189 spin_lock_irqsave(&garmin_data_p->lock, flags); 1196 atomic_inc(&garmin_data_p->req_count);
1190 garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
1191 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
1192 break; 1197 break;
1193 1198
1194 case PRIV_PKTID_SET_DEF_MODE: 1199 case PRIV_PKTID_SET_DEF_MODE:
@@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port)
1241static void garmin_read_process(struct garmin_data * garmin_data_p, 1246static void garmin_read_process(struct garmin_data * garmin_data_p,
1242 unsigned char *data, unsigned data_length) 1247 unsigned char *data, unsigned data_length)
1243{ 1248{
1244 unsigned long flags;
1245
1246 if (garmin_data_p->flags & FLAGS_DROP_DATA) { 1249 if (garmin_data_p->flags & FLAGS_DROP_DATA) {
1247 /* abort-transfer cmd is actice */ 1250 /* abort-transfer cmd is actice */
1248 dbg("%s - pkt dropped", __FUNCTION__); 1251 dbg("%s - pkt dropped", __FUNCTION__);
@@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
1254 the device */ 1257 the device */
1255 if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, 1258 if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
1256 sizeof(GARMIN_APP_LAYER_REPLY))) { 1259 sizeof(GARMIN_APP_LAYER_REPLY))) {
1257 spin_lock_irqsave(&garmin_data_p->lock, flags); 1260 atomic_inc(&garmin_data_p->resp_count);
1258 garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
1259 spin_unlock_irqrestore(&garmin_data_p->lock, flags);
1260 } 1261 }
1261 1262
1262 /* if throttling is active or postprecessing is required 1263 /* if throttling is active or postprecessing is required