diff options
author | Olof Johansson <olof@lixom.net> | 2013-04-18 20:19:26 +0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-04-18 20:21:20 +0400 |
commit | da0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9 (patch) | |
tree | 833778d45f2327702f8abc89d236e71ab3b0e291 /net/nfc/llcp/llcp.c | |
parent | 7fa7ed8e1c93dda575021f177a3f6957dc98b28f (diff) | |
parent | 4b23185ff5e1c2ada2845002a034e8840ab98b63 (diff) | |
download | linux-da0851fe3a8ebc416ab61ce50ef2fb3c3d7375c9.tar.xz |
Merge tag 'imx-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt
From Shawn Guo:
The imx device tree changes for 3.10:
* The huge diff stat is introduced by the pinctrl changes. With DTC
macro support ready, we're moving those huge mount of data about pins
out of pinctrl driver.
* Device tree source updates for GPI, LDB, SRC, cpufreq-cpu0.
* Initial imx6dl device tree support
* Board level DTS changes for some imx27 and imx51 platforms.
* tag 'imx-dt-3.10' of git://git.linaro.org/people/shawnguo/linux-2.6: (605 commits)
ARM: dts: imx6dl-wandboard: Add USB Host support
ARM: dts: imx51 cpu node
ARM: dts: Add missing imx27-phytec-phycore dtb target
ARM: dts: Add NFC support for i.MX27 Phytec PCM038 module
ARM: i.MX51: Add PATA support
ARM: dts: Add initial support for Wandboard Dual-Lite
ARM: dts: imx: add initial imx6dl-sabreauto support
ARM: dts: imx: add initial imx6dl-sabresd support
ARM: dts: imx: make sabreauto and sabresd common
pinctrl: add pinctrl driver for imx6sl
pinctrl: add pinctrl driver for imx6dl
ARM: dts: imx53: fix SD2_DATA1 pad AUDMUX_AUD4 configuration
ARM: dts: MicroSys sbc6x support (i.MX6)
ARM i.MX5: Add System Reset Controller (SRC) support for i.MX51 and i.MX53
ARM i.MX5: Add system reset controller (SRC) to i.MX51 and i.MX53 device tree
ARM i.MX6q: Link system reset controller (SRC) to IPU in DT
ARM i.MX6q: Add LDB device to device tree
ARM: imx5 DT init cpufreq-cpu0 device
ARM: imx27 DT init cpufreq-cpu0 device
ARM i.MX53: Add LDB device to device tree
...
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'net/nfc/llcp/llcp.c')
-rw-r--r-- | net/nfc/llcp/llcp.c | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 7f8266dd14cb..b530afadd76c 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock) } } -static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) +static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, + int err) { struct sock *sk; struct hlist_node *tmp; @@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) nfc_llcp_accept_unlink(accept_sk); + if (err) + accept_sk->sk_err = err; accept_sk->sk_state = LLCP_CLOSED; + accept_sk->sk_state_change(sk); bh_unlock_sock(accept_sk); @@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) continue; } + if (err) + sk->sk_err = err; sk->sk_state = LLCP_CLOSED; + sk->sk_state_change(sk); bh_unlock_sock(sk); @@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen) } write_unlock(&local->sockets.lock); + + /* + * If we want to keep the listening sockets alive, + * we don't touch the RAW ones. + */ + if (listen == true) + return; + + write_lock(&local->raw_sockets.lock); + + sk_for_each_safe(sk, tmp, &local->raw_sockets.head) { + llcp_sock = nfc_llcp_sock(sk); + + bh_lock_sock(sk); + + nfc_llcp_socket_purge(llcp_sock); + + if (err) + sk->sk_err = err; + sk->sk_state = LLCP_CLOSED; + sk->sk_state_change(sk); + + bh_unlock_sock(sk); + + sock_orphan(sk); + + sk_del_node_init(sk); + } + + write_unlock(&local->raw_sockets.lock); } struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) @@ -142,20 +179,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) return local; } -static void local_release(struct kref *ref) +static void local_cleanup(struct nfc_llcp_local *local, bool listen) { - struct nfc_llcp_local *local; - - local = container_of(ref, struct nfc_llcp_local, ref); - - list_del(&local->list); - nfc_llcp_socket_release(local, false); + nfc_llcp_socket_release(local, listen, ENXIO); del_timer_sync(&local->link_timer); skb_queue_purge(&local->tx_queue); cancel_work_sync(&local->tx_work); cancel_work_sync(&local->rx_work); cancel_work_sync(&local->timeout_work); kfree_skb(local->rx_pending); +} + +static void local_release(struct kref *ref) +{ + struct nfc_llcp_local *local; + + local = container_of(ref, struct nfc_llcp_local, ref); + + list_del(&local->list); + local_cleanup(local, false); kfree(local); } @@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev) return; /* Close and purge all existing sockets */ - nfc_llcp_socket_release(local, true); + nfc_llcp_socket_release(local, true, 0); } void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx, @@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) return; } + local_cleanup(local, false); + nfc_llcp_local_put(local); } |