diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2007-10-20 15:37:20 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-22 05:59:49 -0400 |
| commit | a524eccc7307b1d6e79f03fed79f9f34c016ce56 (patch) | |
| tree | ecf52ff4aa025cf860d92af3efede469585d5788 | |
| parent | 2cb3377a295aade1f2e192d4bea948b2196fb162 (diff) | |
[Bluetooth] Convert RFCOMM to use kthread API
This patch does the full kthread conversion for the RFCOMM protocol. It
makes the code slightly simpler and more maintainable.
Based on a patch from Christoph Hellwig <hch@lst.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
| -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(); |
