summaryrefslogtreecommitdiff
path: root/drivers/usb/serial/garmin_gps.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 08:14:07 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 08:14:07 +0300
commit894025f24bd028942da3e602b87d9f7223109b14 (patch)
tree57f23d2bcdd59aaa6a3e7e26e175e678bfa9a5f4 /drivers/usb/serial/garmin_gps.c
parentfb0255fb2941ef6f21742b2bc146d6b9aef4fedc (diff)
parentcdafb6d8b8da7fde266f79b3287ac221aa841879 (diff)
downloadlinux-894025f24bd028942da3e602b87d9f7223109b14.tar.xz
Merge tag 'usb-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big set of USB and PHY driver updates for 4.15-rc1. There is the usual amount of gadget and xhci driver updates, along with phy and chipidea enhancements. There's also a lot of SPDX tags and license boilerplate cleanups as well, which provide some churn in the diffstat. Other major thing is the typec code that moved out of staging and into the "real" part of the drivers/usb/ tree, which was nice to see happen. All of these have been in linux-next with no reported issues for a while" * tag 'usb-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (263 commits) usb: gadget: f_fs: Fix use-after-free in ffs_free_inst USB: usbfs: compute urb->actual_length for isochronous usb: core: message: remember to reset 'ret' to 0 when necessary USB: typec: Remove remaining redundant license text USB: typec: add SPDX identifiers to some files USB: renesas_usbhs: rcar?.h: add SPDX tags USB: chipidea: ci_hdrc_tegra.c: add SPDX line USB: host: xhci-debugfs: add SPDX lines USB: add SPDX identifiers to all remaining Makefiles usb: host: isp1362-hcd: remove a couple of redundant assignments USB: adutux: remove redundant variable minor usb: core: add a new usb_get_ptm_status() helper usb: core: add a 'type' parameter to usb_get_status() usb: core: introduce a new usb_get_std_status() helper usb: core: rename usb_get_status() 'type' argument to 'recip' usb: core: add Status Type definitions USB: gadget: Remove redundant license text USB: gadget: function: Remove redundant license text USB: gadget: udc: Remove redundant license text USB: gadget: legacy: Remove redundant license text ...
Diffstat (limited to 'drivers/usb/serial/garmin_gps.c')
-rw-r--r--drivers/usb/serial/garmin_gps.c82
1 files changed, 36 insertions, 46 deletions
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index b2f2e87aed94..633550ec3025 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Garmin GPS driver
*
@@ -7,20 +8,6 @@
* http://sourceforge.net/projects/garmin-gps/
*
* This driver has been derived from v2.1 of the visor driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
*/
#include <linux/kernel.h>
@@ -138,6 +125,7 @@ struct garmin_data {
__u8 privpkt[4*6];
spinlock_t lock;
struct list_head pktlist;
+ struct usb_anchor write_urbs;
};
@@ -875,42 +863,38 @@ static int garmin_clear(struct garmin_data *garmin_data_p)
static int garmin_init_session(struct usb_serial_port *port)
{
- struct usb_serial *serial = port->serial;
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
- int status = 0;
- int i = 0;
+ int status;
+ int i;
- if (status == 0) {
- usb_kill_urb(port->interrupt_in_urb);
+ usb_kill_urb(port->interrupt_in_urb);
- dev_dbg(&serial->dev->dev, "%s - adding interrupt input\n", __func__);
- status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
- if (status)
- dev_err(&serial->dev->dev,
- "%s - failed submitting interrupt urb, error %d\n",
- __func__, status);
+ status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+ if (status) {
+ dev_err(&port->dev, "failed to submit interrupt urb: %d\n",
+ status);
+ return status;
}
/*
* using the initialization method from gpsbabel. See comments in
* gpsbabel/jeeps/gpslibusb.c gusb_reset_toggles()
*/
- if (status == 0) {
- dev_dbg(&serial->dev->dev, "%s - starting session ...\n", __func__);
- garmin_data_p->state = STATE_ACTIVE;
+ dev_dbg(&port->dev, "%s - starting session ...\n", __func__);
+ garmin_data_p->state = STATE_ACTIVE;
- for (i = 0; i < 3; i++) {
- status = garmin_write_bulk(port,
- GARMIN_START_SESSION_REQ,
- sizeof(GARMIN_START_SESSION_REQ), 0);
+ for (i = 0; i < 3; i++) {
+ status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
+ sizeof(GARMIN_START_SESSION_REQ), 0);
+ if (status < 0)
+ goto err_kill_urbs;
+ }
- if (status < 0)
- break;
- }
+ return 0;
- if (status > 0)
- status = 0;
- }
+err_kill_urbs:
+ usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
+ usb_kill_urb(port->interrupt_in_urb);
return status;
}
@@ -930,7 +914,6 @@ static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port)
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */
- usb_kill_urb(port->write_urb);
usb_kill_urb(port->read_urb);
if (garmin_data_p->state == STATE_RESET)
@@ -953,7 +936,7 @@ static void garmin_close(struct usb_serial_port *port)
/* shutdown our urbs */
usb_kill_urb(port->read_urb);
- usb_kill_urb(port->write_urb);
+ usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
/* keep reset state so we know that we must start a new session */
if (garmin_data_p->state != STATE_RESET)
@@ -1037,12 +1020,14 @@ static int garmin_write_bulk(struct usb_serial_port *port,
}
/* send it down the pipe */
+ usb_anchor_urb(urb, &garmin_data_p->write_urbs);
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
dev_err(&port->dev,
"%s - usb_submit_urb(write bulk) failed with status = %d\n",
__func__, status);
count = status;
+ usb_unanchor_urb(urb);
kfree(buffer);
}
@@ -1370,9 +1355,9 @@ static void garmin_unthrottle(struct tty_struct *tty)
* the tty in cases where the protocol provides no own handshaking
* to initiate the transfer.
*/
-static void timeout_handler(unsigned long data)
+static void timeout_handler(struct timer_list *t)
{
- struct garmin_data *garmin_data_p = (struct garmin_data *) data;
+ struct garmin_data *garmin_data_p = from_timer(garmin_data_p, t, timer);
/* send the next queued packet to the tty port */
if (garmin_data_p->mode == MODE_NATIVE)
@@ -1391,19 +1376,23 @@ static int garmin_port_probe(struct usb_serial_port *port)
if (!garmin_data_p)
return -ENOMEM;
- init_timer(&garmin_data_p->timer);
+ timer_setup(&garmin_data_p->timer, timeout_handler, 0);
spin_lock_init(&garmin_data_p->lock);
INIT_LIST_HEAD(&garmin_data_p->pktlist);
- /* garmin_data_p->timer.expires = jiffies + session_timeout; */
- garmin_data_p->timer.data = (unsigned long)garmin_data_p;
- 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;
+ init_usb_anchor(&garmin_data_p->write_urbs);
usb_set_serial_port_data(port, garmin_data_p);
status = garmin_init_session(port);
+ if (status)
+ goto err_free;
+
+ return 0;
+err_free:
+ kfree(garmin_data_p);
return status;
}
@@ -1413,6 +1402,7 @@ static int garmin_port_remove(struct usb_serial_port *port)
{
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
+ usb_kill_anchored_urbs(&garmin_data_p->write_urbs);
usb_kill_urb(port->interrupt_in_urb);
del_timer_sync(&garmin_data_p->timer);
kfree(garmin_data_p);