Loading drivers/usb/serial/garmin_gps.c +162 −57 Original line number Diff line number Diff line /* * Garmin GPS driver * * Copyright (C) 2004 Hermann Kneissel herkne@users.sourceforge.net * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net * * The latest version of the driver can be found at * http://sourceforge.net/projects/garmin-gps/ Loading Loading @@ -37,6 +37,8 @@ #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/version.h> /* the mode to be set when the port ist opened */ static int initial_mode = 1; Loading @@ -50,7 +52,7 @@ static int debug = 0; */ #define VERSION_MAJOR 0 #define VERSION_MINOR 23 #define VERSION_MINOR 28 #define _STR(s) #s #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) Loading Loading @@ -164,7 +166,8 @@ struct garmin_data { #define FLAGS_SESSION_REPLY1_SEEN 0x0080 #define FLAGS_SESSION_REPLY2_SEEN 0x0040 #define FLAGS_BULK_IN_ACTIVE 0x0020 #define FLAGS_THROTTLED 0x0010 #define FLAGS_BULK_IN_RESTART 0x0010 #define FLAGS_THROTTLED 0x0008 #define CLEAR_HALT_REQUIRED 0x0001 #define FLAGS_QUEUING 0x0100 Loading Loading @@ -296,13 +299,13 @@ static void send_to_tty(struct usb_serial_port *port, static int pkt_add(struct garmin_data * garmin_data_p, unsigned char *data, unsigned int data_length) { int state = 0; int result = 0; unsigned long flags; struct garmin_packet *pkt; /* process only packets containg data ... */ if (data_length) { garmin_data_p->flags |= FLAGS_QUEUING; pkt = kmalloc(sizeof(struct garmin_packet)+data_length, GFP_ATOMIC); if (pkt == NULL) { Loading @@ -313,14 +316,16 @@ static int pkt_add(struct garmin_data * garmin_data_p, memcpy(pkt->data, data, data_length); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_QUEUING; result = list_empty(&garmin_data_p->pktlist); pkt->seq = garmin_data_p->seq_counter++; list_add_tail(&pkt->list, &garmin_data_p->pktlist); state = garmin_data_p->state; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* in serial mode, if someone is waiting for data from the device, iconvert and send the next packet to tty. */ if (result && (garmin_data_p->state == STATE_GSP_WAIT_DATA)) { if (result && (state == STATE_GSP_WAIT_DATA)) { gsp_next_packet(garmin_data_p); } } Loading Loading @@ -493,18 +498,26 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) static int gsp_receive(struct garmin_data * garmin_data_p, const unsigned char *buf, int count) { unsigned long flags; int offs = 0; int ack_or_nak_seen = 0; int i = 0; __u8 *dest = garmin_data_p->inbuffer; int size = garmin_data_p->insize; __u8 *dest; int size; // dleSeen: set if last byte read was a DLE int dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN; int dleSeen; // skip: if set, skip incoming data until possible start of // new packet int skip = garmin_data_p->flags & FLAGS_GSP_SKIP; int skip; __u8 data; spin_lock_irqsave(&garmin_data_p->lock, flags); dest = garmin_data_p->inbuffer; size = garmin_data_p->insize; dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN; skip = garmin_data_p->flags & FLAGS_GSP_SKIP; spin_unlock_irqrestore(&garmin_data_p->lock, flags); dbg("%s - dle=%d skip=%d size=%d count=%d", __FUNCTION__, dleSeen, skip, size, count); Loading Loading @@ -572,6 +585,8 @@ static int gsp_receive(struct garmin_data * garmin_data_p, } } spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->insize = size; // copy flags back to structure Loading @@ -587,6 +602,11 @@ static int gsp_receive(struct garmin_data * garmin_data_p, if (ack_or_nak_seen) { garmin_data_p->state = STATE_GSP_WAIT_DATA; } spin_unlock_irqrestore(&garmin_data_p->lock, flags); if (ack_or_nak_seen) { gsp_next_packet(garmin_data_p); } Loading Loading @@ -757,6 +777,7 @@ static void gsp_next_packet(struct garmin_data * garmin_data_p) static int nat_receive(struct garmin_data * garmin_data_p, const unsigned char *buf, int count) { unsigned long flags; __u8 * dest; int offs = 0; int result = count; Loading Loading @@ -803,7 +824,9 @@ static int nat_receive(struct garmin_data * garmin_data_p, /* 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); } } Loading Loading @@ -839,12 +862,15 @@ static void priv_status_resp(struct usb_serial_port *port) static int process_resetdev_request(struct usb_serial_port *port) { unsigned long flags; int status; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED); garmin_data_p->state = STATE_RESET; garmin_data_p->serial_num = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); usb_kill_urb (port->interrupt_in_urb); dbg("%s - usb_reset_device", __FUNCTION__ ); Loading @@ -862,6 +888,7 @@ static int process_resetdev_request(struct usb_serial_port *port) */ static int garmin_clear(struct garmin_data * garmin_data_p) { unsigned long flags; int status = 0; struct usb_serial_port *port = garmin_data_p->port; Loading @@ -875,8 +902,10 @@ static int garmin_clear(struct garmin_data * garmin_data_p) /* flush all queued data */ pkt_clear(garmin_data_p); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->insize = 0; garmin_data_p->outsize = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); return status; } Loading @@ -888,6 +917,7 @@ static int garmin_clear(struct garmin_data * garmin_data_p) static int garmin_init_session(struct usb_serial_port *port) { unsigned long flags; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status = 0; Loading @@ -913,7 +943,9 @@ static int garmin_init_session(struct usb_serial_port *port) if (status >= 0) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts++; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* not needed, but the win32 driver does it too ... */ status = garmin_write_bulk(port, Loading @@ -921,7 +953,9 @@ static int garmin_init_session(struct usb_serial_port *port) sizeof(GARMIN_START_SESSION_REQ2)); if (status >= 0) { status = 0; spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts++; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } } Loading @@ -935,6 +969,7 @@ static int garmin_init_session(struct usb_serial_port *port) static int garmin_open (struct usb_serial_port *port, struct file *filp) { unsigned long flags; int status = 0; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); Loading @@ -948,9 +983,11 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) if (port->tty) port->tty->low_latency = 1; spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->mode = initial_mode; garmin_data_p->count = 0; garmin_data_p->flags = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* shutdown any bulk reads that might be going on */ usb_kill_urb (port->write_urb); Loading Loading @@ -996,6 +1033,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { 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); Loading @@ -1007,7 +1045,9 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) if (urb->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); Loading @@ -1017,6 +1057,7 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) static int garmin_write_bulk (struct usb_serial_port *port, const unsigned char *buf, int count) { unsigned long flags; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); struct urb *urb; Loading @@ -1026,7 +1067,9 @@ static int garmin_write_bulk (struct usb_serial_port *port, dbg("%s - port %d, state %d", __FUNCTION__, port->number, garmin_data_p->state); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_DROP_DATA; spin_unlock_irqrestore(&garmin_data_p->lock, flags); buffer = kmalloc (count, GFP_ATOMIC); if (!buffer) { Loading @@ -1053,7 +1096,9 @@ static int garmin_write_bulk (struct usb_serial_port *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); if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { pkt_clear(garmin_data_p); garmin_data_p->state = STATE_GSP_WAIT_DATA; Loading Loading @@ -1089,6 +1134,7 @@ 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; Loading Loading @@ -1139,7 +1185,9 @@ 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); break; case PRIV_PKTID_SET_DEF_MODE: Loading @@ -1155,6 +1203,8 @@ static int garmin_write (struct usb_serial_port *port, } } garmin_data_p->ignorePkts = 0; if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { return gsp_receive(garmin_data_p, buf, count); } else { /* MODE_NATIVE */ Loading Loading @@ -1190,6 +1240,8 @@ 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__); Loading @@ -1200,11 +1252,14 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, if a reset is required or not when closing the device */ if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, sizeof(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); } /* if throttling is active or postprecessing is required put the received data in th input queue, otherwise put the received data in the input queue, otherwise send it directly to the tty port */ if (garmin_data_p->flags & FLAGS_QUEUING) { pkt_add(garmin_data_p, data, data_length); Loading @@ -1221,6 +1276,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); Loading @@ -1245,26 +1301,38 @@ static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) garmin_read_process(garmin_data_p, data, urb->actual_length); if (urb->actual_length == 0 && 0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART; spin_unlock_irqrestore(&garmin_data_p->lock, flags); status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } else if (urb->actual_length > 0) { /* Continue trying to read until nothing more is received */ if (urb->actual_length > 0) { usb_fill_bulk_urb (port->read_urb, serial->dev, usb_rcvbulkpipe (serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, garmin_read_bulk_callback, port); if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) { status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } } else { dbg("%s - end of bulk data", __FUNCTION__); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_BULK_IN_ACTIVE; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } return; } static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; int status; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial *serial = port->serial; Loading Loading @@ -1297,6 +1365,8 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) dbg("%s - bulk data available.", __FUNCTION__); if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { /* bulk data available */ usb_fill_bulk_urb (port->read_urb, serial->dev, usb_rcvbulkpipe (serial->dev, Loading @@ -1304,18 +1374,32 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, garmin_read_bulk_callback, port); status = usb_submit_urb(port->read_urb, GFP_KERNEL); status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, status); } else { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; /* do not send this packet to the user */ garmin_data_p->ignorePkts = 1; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } else { /* bulk-in transfer still active */ spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_BULK_IN_RESTART; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY)) && 0 == memcmp(data, GARMIN_START_SESSION_REPLY, sizeof(GARMIN_START_SESSION_REPLY))) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* save the serial number */ garmin_data_p->serial_num Loading @@ -1330,7 +1414,9 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) ignore it. */ dbg("%s - pkt ignored (%d)", __FUNCTION__, garmin_data_p->ignorePkts); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts--; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } else { garmin_read_process(garmin_data_p, data, urb->actual_length); } Loading @@ -1351,18 +1437,20 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) */ static int garmin_flush_queue(struct garmin_data * garmin_data_p) { unsigned long flags; struct garmin_packet *pkt; if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) { pkt = pkt_pop(garmin_data_p); if (pkt != NULL) { send_to_tty(garmin_data_p->port, pkt->data, pkt->size); kfree(pkt); mod_timer(&garmin_data_p->timer, (1)+jiffies); } else { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_QUEUING; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } return 0; Loading @@ -1371,26 +1459,41 @@ static int garmin_flush_queue(struct garmin_data * garmin_data_p) static void garmin_throttle (struct usb_serial_port *port) { unsigned long flags; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); dbg("%s - port %d", __FUNCTION__, port->number); /* set flag, data received will be put into a queue for later processing */ spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } static void garmin_unthrottle (struct usb_serial_port *port) { unsigned long flags; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status; dbg("%s - port %d", __FUNCTION__, port->number); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_THROTTLED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* in native mode send queued data to tty, in serial mode nothing needs to be done here */ if (garmin_data_p->mode == MODE_NATIVE) garmin_flush_queue(garmin_data_p); if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } } Loading Loading @@ -1420,11 +1523,12 @@ static int garmin_attach (struct usb_serial *serial) dbg("%s", __FUNCTION__); garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } memset (garmin_data_p, 0, sizeof(struct garmin_data)); init_timer(&garmin_data_p->timer); spin_lock_init(&garmin_data_p->lock); INIT_LIST_HEAD(&garmin_data_p->pktlist); Loading Loading @@ -1483,6 +1587,7 @@ static struct usb_serial_driver garmin_device = { }; static int __init garmin_init (void) { int retval; Loading Loading
drivers/usb/serial/garmin_gps.c +162 −57 Original line number Diff line number Diff line /* * Garmin GPS driver * * Copyright (C) 2004 Hermann Kneissel herkne@users.sourceforge.net * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net * * The latest version of the driver can be found at * http://sourceforge.net/projects/garmin-gps/ Loading Loading @@ -37,6 +37,8 @@ #include <linux/usb.h> #include <linux/usb/serial.h> #include <linux/version.h> /* the mode to be set when the port ist opened */ static int initial_mode = 1; Loading @@ -50,7 +52,7 @@ static int debug = 0; */ #define VERSION_MAJOR 0 #define VERSION_MINOR 23 #define VERSION_MINOR 28 #define _STR(s) #s #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) Loading Loading @@ -164,7 +166,8 @@ struct garmin_data { #define FLAGS_SESSION_REPLY1_SEEN 0x0080 #define FLAGS_SESSION_REPLY2_SEEN 0x0040 #define FLAGS_BULK_IN_ACTIVE 0x0020 #define FLAGS_THROTTLED 0x0010 #define FLAGS_BULK_IN_RESTART 0x0010 #define FLAGS_THROTTLED 0x0008 #define CLEAR_HALT_REQUIRED 0x0001 #define FLAGS_QUEUING 0x0100 Loading Loading @@ -296,13 +299,13 @@ static void send_to_tty(struct usb_serial_port *port, static int pkt_add(struct garmin_data * garmin_data_p, unsigned char *data, unsigned int data_length) { int state = 0; int result = 0; unsigned long flags; struct garmin_packet *pkt; /* process only packets containg data ... */ if (data_length) { garmin_data_p->flags |= FLAGS_QUEUING; pkt = kmalloc(sizeof(struct garmin_packet)+data_length, GFP_ATOMIC); if (pkt == NULL) { Loading @@ -313,14 +316,16 @@ static int pkt_add(struct garmin_data * garmin_data_p, memcpy(pkt->data, data, data_length); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_QUEUING; result = list_empty(&garmin_data_p->pktlist); pkt->seq = garmin_data_p->seq_counter++; list_add_tail(&pkt->list, &garmin_data_p->pktlist); state = garmin_data_p->state; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* in serial mode, if someone is waiting for data from the device, iconvert and send the next packet to tty. */ if (result && (garmin_data_p->state == STATE_GSP_WAIT_DATA)) { if (result && (state == STATE_GSP_WAIT_DATA)) { gsp_next_packet(garmin_data_p); } } Loading Loading @@ -493,18 +498,26 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) static int gsp_receive(struct garmin_data * garmin_data_p, const unsigned char *buf, int count) { unsigned long flags; int offs = 0; int ack_or_nak_seen = 0; int i = 0; __u8 *dest = garmin_data_p->inbuffer; int size = garmin_data_p->insize; __u8 *dest; int size; // dleSeen: set if last byte read was a DLE int dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN; int dleSeen; // skip: if set, skip incoming data until possible start of // new packet int skip = garmin_data_p->flags & FLAGS_GSP_SKIP; int skip; __u8 data; spin_lock_irqsave(&garmin_data_p->lock, flags); dest = garmin_data_p->inbuffer; size = garmin_data_p->insize; dleSeen = garmin_data_p->flags & FLAGS_GSP_DLESEEN; skip = garmin_data_p->flags & FLAGS_GSP_SKIP; spin_unlock_irqrestore(&garmin_data_p->lock, flags); dbg("%s - dle=%d skip=%d size=%d count=%d", __FUNCTION__, dleSeen, skip, size, count); Loading Loading @@ -572,6 +585,8 @@ static int gsp_receive(struct garmin_data * garmin_data_p, } } spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->insize = size; // copy flags back to structure Loading @@ -587,6 +602,11 @@ static int gsp_receive(struct garmin_data * garmin_data_p, if (ack_or_nak_seen) { garmin_data_p->state = STATE_GSP_WAIT_DATA; } spin_unlock_irqrestore(&garmin_data_p->lock, flags); if (ack_or_nak_seen) { gsp_next_packet(garmin_data_p); } Loading Loading @@ -757,6 +777,7 @@ static void gsp_next_packet(struct garmin_data * garmin_data_p) static int nat_receive(struct garmin_data * garmin_data_p, const unsigned char *buf, int count) { unsigned long flags; __u8 * dest; int offs = 0; int result = count; Loading Loading @@ -803,7 +824,9 @@ static int nat_receive(struct garmin_data * garmin_data_p, /* 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); } } Loading Loading @@ -839,12 +862,15 @@ static void priv_status_resp(struct usb_serial_port *port) static int process_resetdev_request(struct usb_serial_port *port) { unsigned long flags; int status; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED); garmin_data_p->state = STATE_RESET; garmin_data_p->serial_num = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); usb_kill_urb (port->interrupt_in_urb); dbg("%s - usb_reset_device", __FUNCTION__ ); Loading @@ -862,6 +888,7 @@ static int process_resetdev_request(struct usb_serial_port *port) */ static int garmin_clear(struct garmin_data * garmin_data_p) { unsigned long flags; int status = 0; struct usb_serial_port *port = garmin_data_p->port; Loading @@ -875,8 +902,10 @@ static int garmin_clear(struct garmin_data * garmin_data_p) /* flush all queued data */ pkt_clear(garmin_data_p); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->insize = 0; garmin_data_p->outsize = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); return status; } Loading @@ -888,6 +917,7 @@ static int garmin_clear(struct garmin_data * garmin_data_p) static int garmin_init_session(struct usb_serial_port *port) { unsigned long flags; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status = 0; Loading @@ -913,7 +943,9 @@ static int garmin_init_session(struct usb_serial_port *port) if (status >= 0) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts++; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* not needed, but the win32 driver does it too ... */ status = garmin_write_bulk(port, Loading @@ -921,7 +953,9 @@ static int garmin_init_session(struct usb_serial_port *port) sizeof(GARMIN_START_SESSION_REQ2)); if (status >= 0) { status = 0; spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts++; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } } Loading @@ -935,6 +969,7 @@ static int garmin_init_session(struct usb_serial_port *port) static int garmin_open (struct usb_serial_port *port, struct file *filp) { unsigned long flags; int status = 0; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); Loading @@ -948,9 +983,11 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) if (port->tty) port->tty->low_latency = 1; spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->mode = initial_mode; garmin_data_p->count = 0; garmin_data_p->flags = 0; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* shutdown any bulk reads that might be going on */ usb_kill_urb (port->write_urb); Loading Loading @@ -996,6 +1033,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp) static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { 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); Loading @@ -1007,7 +1045,9 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) if (urb->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); Loading @@ -1017,6 +1057,7 @@ static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs) static int garmin_write_bulk (struct usb_serial_port *port, const unsigned char *buf, int count) { unsigned long flags; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); struct urb *urb; Loading @@ -1026,7 +1067,9 @@ static int garmin_write_bulk (struct usb_serial_port *port, dbg("%s - port %d, state %d", __FUNCTION__, port->number, garmin_data_p->state); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_DROP_DATA; spin_unlock_irqrestore(&garmin_data_p->lock, flags); buffer = kmalloc (count, GFP_ATOMIC); if (!buffer) { Loading @@ -1053,7 +1096,9 @@ static int garmin_write_bulk (struct usb_serial_port *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); if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { pkt_clear(garmin_data_p); garmin_data_p->state = STATE_GSP_WAIT_DATA; Loading Loading @@ -1089,6 +1134,7 @@ 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; Loading Loading @@ -1139,7 +1185,9 @@ 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); break; case PRIV_PKTID_SET_DEF_MODE: Loading @@ -1155,6 +1203,8 @@ static int garmin_write (struct usb_serial_port *port, } } garmin_data_p->ignorePkts = 0; if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { return gsp_receive(garmin_data_p, buf, count); } else { /* MODE_NATIVE */ Loading Loading @@ -1190,6 +1240,8 @@ 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__); Loading @@ -1200,11 +1252,14 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, if a reset is required or not when closing the device */ if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, sizeof(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); } /* if throttling is active or postprecessing is required put the received data in th input queue, otherwise put the received data in the input queue, otherwise send it directly to the tty port */ if (garmin_data_p->flags & FLAGS_QUEUING) { pkt_add(garmin_data_p, data, data_length); Loading @@ -1221,6 +1276,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial *serial = port->serial; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); Loading @@ -1245,26 +1301,38 @@ static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs) garmin_read_process(garmin_data_p, data, urb->actual_length); if (urb->actual_length == 0 && 0 != (garmin_data_p->flags & FLAGS_BULK_IN_RESTART)) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_BULK_IN_RESTART; spin_unlock_irqrestore(&garmin_data_p->lock, flags); status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } else if (urb->actual_length > 0) { /* Continue trying to read until nothing more is received */ if (urb->actual_length > 0) { usb_fill_bulk_urb (port->read_urb, serial->dev, usb_rcvbulkpipe (serial->dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, garmin_read_bulk_callback, port); if (0 == (garmin_data_p->flags & FLAGS_THROTTLED)) { status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } } else { dbg("%s - end of bulk data", __FUNCTION__); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_BULK_IN_ACTIVE; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } return; } static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) { unsigned long flags; int status; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct usb_serial *serial = port->serial; Loading Loading @@ -1297,6 +1365,8 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) dbg("%s - bulk data available.", __FUNCTION__); if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { /* bulk data available */ usb_fill_bulk_urb (port->read_urb, serial->dev, usb_rcvbulkpipe (serial->dev, Loading @@ -1304,18 +1374,32 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, garmin_read_bulk_callback, port); status = usb_submit_urb(port->read_urb, GFP_KERNEL); status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) { dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, status); } else { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE; /* do not send this packet to the user */ garmin_data_p->ignorePkts = 1; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } else { /* bulk-in transfer still active */ spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_BULK_IN_RESTART; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY)) && 0 == memcmp(data, GARMIN_START_SESSION_REPLY, sizeof(GARMIN_START_SESSION_REPLY))) { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* save the serial number */ garmin_data_p->serial_num Loading @@ -1330,7 +1414,9 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) ignore it. */ dbg("%s - pkt ignored (%d)", __FUNCTION__, garmin_data_p->ignorePkts); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->ignorePkts--; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } else { garmin_read_process(garmin_data_p, data, urb->actual_length); } Loading @@ -1351,18 +1437,20 @@ static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs) */ static int garmin_flush_queue(struct garmin_data * garmin_data_p) { unsigned long flags; struct garmin_packet *pkt; if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) { pkt = pkt_pop(garmin_data_p); if (pkt != NULL) { send_to_tty(garmin_data_p->port, pkt->data, pkt->size); kfree(pkt); mod_timer(&garmin_data_p->timer, (1)+jiffies); } else { spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_QUEUING; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } } return 0; Loading @@ -1371,26 +1459,41 @@ static int garmin_flush_queue(struct garmin_data * garmin_data_p) static void garmin_throttle (struct usb_serial_port *port) { unsigned long flags; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); dbg("%s - port %d", __FUNCTION__, port->number); /* set flag, data received will be put into a queue for later processing */ spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); } static void garmin_unthrottle (struct usb_serial_port *port) { unsigned long flags; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status; dbg("%s - port %d", __FUNCTION__, port->number); spin_lock_irqsave(&garmin_data_p->lock, flags); garmin_data_p->flags &= ~FLAGS_THROTTLED; spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* in native mode send queued data to tty, in serial mode nothing needs to be done here */ if (garmin_data_p->mode == MODE_NATIVE) garmin_flush_queue(garmin_data_p); if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { status = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (status) dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, status); } } Loading Loading @@ -1420,11 +1523,12 @@ static int garmin_attach (struct usb_serial *serial) dbg("%s", __FUNCTION__); garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); garmin_data_p = kmalloc (sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { dev_err(&port->dev, "%s - Out of memory\n", __FUNCTION__); return -ENOMEM; } memset (garmin_data_p, 0, sizeof(struct garmin_data)); init_timer(&garmin_data_p->timer); spin_lock_init(&garmin_data_p->lock); INIT_LIST_HEAD(&garmin_data_p->pktlist); Loading Loading @@ -1483,6 +1587,7 @@ static struct usb_serial_driver garmin_device = { }; static int __init garmin_init (void) { int retval; Loading