diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index bb7220770f2c..e7ac6ba7ecab 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/signal.h> | 34 | #include <linux/signal.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/freezer.h> | ||
37 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
38 | #include <linux/device.h> | 37 | #include <linux/device.h> |
39 | #include <linux/net.h> | 38 | #include <linux/net.h> |
40 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/kthread.h> | ||
41 | 41 | ||
42 | #include <net/sock.h> | 42 | #include <net/sock.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
@@ -68,7 +68,6 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
68 | static unsigned long rfcomm_event; | 68 | static unsigned long rfcomm_event; |
69 | 69 | ||
70 | static LIST_HEAD(session_list); | 70 | static LIST_HEAD(session_list); |
71 | static atomic_t terminate, running; | ||
72 | 71 | ||
73 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len); | 72 | static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len); |
74 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); | 73 | static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci); |
@@ -1850,26 +1849,6 @@ static inline void rfcomm_process_sessions(void) | |||
1850 | rfcomm_unlock(); | 1849 | rfcomm_unlock(); |
1851 | } | 1850 | } |
1852 | 1851 | ||
1853 | static void rfcomm_worker(void) | ||
1854 | { | ||
1855 | BT_DBG(""); | ||
1856 | |||
1857 | while (!atomic_read(&terminate)) { | ||
1858 | set_current_state(TASK_INTERRUPTIBLE); | ||
1859 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | ||
1860 | /* No pending events. Let's sleep. | ||
1861 | * Incoming connections and data will wake us up. */ | ||
1862 | schedule(); | ||
1863 | } | ||
1864 | set_current_state(TASK_RUNNING); | ||
1865 | |||
1866 | /* Process stuff */ | ||
1867 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
1868 | rfcomm_process_sessions(); | ||
1869 | } | ||
1870 | return; | ||
1871 | } | ||
1872 | |||
1873 | static int rfcomm_add_listener(bdaddr_t *ba) | 1852 | static int rfcomm_add_listener(bdaddr_t *ba) |
1874 | { | 1853 | { |
1875 | struct sockaddr_l2 addr; | 1854 | struct sockaddr_l2 addr; |
@@ -1935,22 +1914,28 @@ static void rfcomm_kill_listener(void) | |||
1935 | 1914 | ||
1936 | static int rfcomm_run(void *unused) | 1915 | static int rfcomm_run(void *unused) |
1937 | { | 1916 | { |
1938 | rfcomm_thread = current; | 1917 | BT_DBG(""); |
1939 | |||
1940 | atomic_inc(&running); | ||
1941 | 1918 | ||
1942 | daemonize("krfcommd"); | ||
1943 | set_user_nice(current, -10); | 1919 | set_user_nice(current, -10); |
1944 | 1920 | ||
1945 | BT_DBG(""); | ||
1946 | |||
1947 | rfcomm_add_listener(BDADDR_ANY); | 1921 | rfcomm_add_listener(BDADDR_ANY); |
1948 | 1922 | ||
1949 | rfcomm_worker(); | 1923 | while (!kthread_should_stop()) { |
1924 | set_current_state(TASK_INTERRUPTIBLE); | ||
1925 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | ||
1926 | /* No pending events. Let's sleep. | ||
1927 | * Incoming connections and data will wake us up. */ | ||
1928 | schedule(); | ||
1929 | } | ||
1930 | set_current_state(TASK_RUNNING); | ||
1931 | |||
1932 | /* Process stuff */ | ||
1933 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
1934 | rfcomm_process_sessions(); | ||
1935 | } | ||
1950 | 1936 | ||
1951 | rfcomm_kill_listener(); | 1937 | rfcomm_kill_listener(); |
1952 | 1938 | ||
1953 | atomic_dec(&running); | ||
1954 | return 0; | 1939 | return 0; |
1955 | } | 1940 | } |
1956 | 1941 | ||
@@ -2059,7 +2044,11 @@ static int __init rfcomm_init(void) | |||
2059 | 2044 | ||
2060 | hci_register_cb(&rfcomm_cb); | 2045 | hci_register_cb(&rfcomm_cb); |
2061 | 2046 | ||
2062 | kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); | 2047 | rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd"); |
2048 | if (IS_ERR(rfcomm_thread)) { | ||
2049 | hci_unregister_cb(&rfcomm_cb); | ||
2050 | return PTR_ERR(rfcomm_thread); | ||
2051 | } | ||
2063 | 2052 | ||
2064 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) | 2053 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) |
2065 | BT_ERR("Failed to create RFCOMM info file"); | 2054 | BT_ERR("Failed to create RFCOMM info file"); |
@@ -2081,14 +2070,7 @@ static void __exit rfcomm_exit(void) | |||
2081 | 2070 | ||
2082 | hci_unregister_cb(&rfcomm_cb); | 2071 | hci_unregister_cb(&rfcomm_cb); |
2083 | 2072 | ||
2084 | /* Terminate working thread. | 2073 | kthread_stop(rfcomm_thread); |
2085 | * ie. Set terminate flag and wake it up */ | ||
2086 | atomic_inc(&terminate); | ||
2087 | rfcomm_schedule(RFCOMM_SCHED_STATE); | ||
2088 | |||
2089 | /* Wait until thread is running */ | ||
2090 | while (atomic_read(&running)) | ||
2091 | schedule(); | ||
2092 | 2074 | ||
2093 | #ifdef CONFIG_BT_RFCOMM_TTY | 2075 | #ifdef CONFIG_BT_RFCOMM_TTY |
2094 | rfcomm_cleanup_ttys(); | 2076 | rfcomm_cleanup_ttys(); |