diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-11 11:18:45 -0200 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-11 11:18:45 -0200 |
| commit | 9374020a78fce13a1cf2edf3d26f6dd7231b5c3d (patch) | |
| tree | 50c8629e6c6222c5b9681506b52afbde818c5e56 /drivers/usb/serial/metro-usb.c | |
| parent | d2a0db1ee01aea154ccc460e45a16857e32c4427 (diff) | |
| parent | 29594404d7fe73cd80eaa4ee8c43dcc53970c60e (diff) | |
Merge tag 'v3.7' into v4l_for_linus
Linux 3.7
* tag 'v3.7': (1545 commits)
Linux 3.7
Input: matrix-keymap - provide proper module license
Revert "revert "Revert "mm: remove __GFP_NO_KSWAPD""" and associated damage
ipv4: ip_check_defrag must not modify skb before unsharing
Revert "mm: avoid waking kswapd for THP allocations when compaction is deferred or contended"
inet_diag: validate port comparison byte code to prevent unsafe reads
inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run()
inet_diag: validate byte code to prevent oops in inet_diag_bc_run()
inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state
mm: vmscan: fix inappropriate zone congestion clearing
vfs: fix O_DIRECT read past end of block device
net: gro: fix possible panic in skb_gro_receive()
tcp: bug fix Fast Open client retransmission
tmpfs: fix shared mempolicy leak
mm: vmscan: do not keep kswapd looping forever due to individual uncompactable zones
mm: compaction: validate pfn range passed to isolate_freepages_block
mmc: sh-mmcif: avoid oops on spurious interrupts (second try)
Revert misapplied "mmc: sh-mmcif: avoid oops on spurious interrupts"
mmc: sdhci-s3c: fix missing clock for gpio card-detect
lib/Makefile: Fix oid_registry build dependency
...
Diffstat (limited to 'drivers/usb/serial/metro-usb.c')
| -rw-r--r-- | drivers/usb/serial/metro-usb.c | 65 |
1 files changed, 19 insertions, 46 deletions
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 0b257ddffbd..6f29c74eb76 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) { dev_dbg(&port->dev, "%s\n", __func__); - if (port->serial->dev) { - /* Shutdown any interrupt in urbs. */ - if (port->interrupt_in_urb) { - usb_unlink_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_in_urb); - } - - /* Send deactivate cmd to device */ + usb_unlink_urb(port->interrupt_in_urb); + usb_kill_urb(port->interrupt_in_urb); + + mutex_lock(&port->serial->disc_mutex); + if (!port->serial->disconnected) metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); - } + mutex_unlock(&port->serial->disc_mutex); } static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -271,51 +268,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr return retval; } -static void metrousb_shutdown(struct usb_serial *serial) +static int metrousb_port_probe(struct usb_serial_port *port) { - int i = 0; + struct metrousb_private *metro_priv; - dev_dbg(&serial->dev->dev, "%s\n", __func__); + metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); + if (!metro_priv) + return -ENOMEM; - /* Stop reading and writing on all ports. */ - for (i = 0; i < serial->num_ports; ++i) { - /* Close any open urbs. */ - metrousb_cleanup(serial->port[i]); + spin_lock_init(&metro_priv->lock); - /* Free memory. */ - kfree(usb_get_serial_port_data(serial->port[i])); - usb_set_serial_port_data(serial->port[i], NULL); + usb_set_serial_port_data(port, metro_priv); - dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", - __func__, serial->port[i]->number); - } + return 0; } -static int metrousb_startup(struct usb_serial *serial) +static int metrousb_port_remove(struct usb_serial_port *port) { struct metrousb_private *metro_priv; - struct usb_serial_port *port; - int i = 0; - dev_dbg(&serial->dev->dev, "%s\n", __func__); - - /* Loop through the serial ports setting up the private structures. - * Currently we only use one port. */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - - /* Declare memory. */ - metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); - if (!metro_priv) - return -ENOMEM; - - /* Initialize memory. */ - spin_lock_init(&metro_priv->lock); - usb_set_serial_port_data(port, metro_priv); - - dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", - __func__, port->number); - } + metro_priv = usb_get_serial_port_data(port); + kfree(metro_priv); return 0; } @@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = { .close = metrousb_cleanup, .read_int_callback = metrousb_read_int_callback, .write_int_callback = metrousb_write_int_callback, - .attach = metrousb_startup, - .release = metrousb_shutdown, + .port_probe = metrousb_port_probe, + .port_remove = metrousb_port_remove, .throttle = metrousb_throttle, .unthrottle = metrousb_unthrottle, .tiocmget = metrousb_tiocmget, |
