diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 08:14:07 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 08:14:07 +0300 |
commit | 894025f24bd028942da3e602b87d9f7223109b14 (patch) | |
tree | 57f23d2bcdd59aaa6a3e7e26e175e678bfa9a5f4 /drivers/usb/serial/garmin_gps.c | |
parent | fb0255fb2941ef6f21742b2bc146d6b9aef4fedc (diff) | |
parent | cdafb6d8b8da7fde266f79b3287ac221aa841879 (diff) | |
download | linux-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.c | 82 |
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); |