diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 22:22:33 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 22:22:33 -0400 |
| commit | f09cc910fe3af7e63298105bc0482653eb534c3c (patch) | |
| tree | a09dca8a3d033352edff6cb1d911f3cd0e980f1f /net/bluetooth/rfcomm | |
| parent | 8b0eaccab4584ace24d233214bfee3cb50e49a60 (diff) | |
| parent | ea2c47b42f12dadbad9d879fb6df102b9003ab82 (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (30 commits)
[IPSEC] IPV6: Fix to add tunnel mode SA correctly.
[NET]: Cut off the queue_mapping field from sk_buff
[NET]: Hide the queue_mapping field inside netif_subqueue_stopped
[NET]: Make and use skb_get_queue_mapping
[NET]: Use the skb_set_queue_mapping where appropriate
[INET]: Use MODULE_ALIAS_NET_PF_PROTO_TYPE where possible.
[INET]: Let inet_diag and friends autoload
[NIU]: Cleanup PAGE_SIZE checks a bit
[NET]: Fix SKB_WITH_OVERHEAD calculation
[ATM]: Fix clip module reload crash.
[TG3]: Update version to 3.85
[TG3]: PCI command adjustment
[TG3]: Add management FW version to ethtool report
[TG3]: Add 5723 support
[Bluetooth] Convert RFCOMM to use kthread API
[Bluetooth] Add constant for Bluetooth socket options level
[Bluetooth] Add support for handling simple eSCO links
[Bluetooth] Add address and channel attribute to RFCOMM TTY device
[Bluetooth] Fix wrong argument in debug code of HIDP
[Bluetooth] Add generic driver for Bluetooth USB devices
...
Diffstat (limited to 'net/bluetooth/rfcomm')
| -rw-r--r-- | net/bluetooth/rfcomm/core.c | 60 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/tty.c | 25 |
2 files changed, 46 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(); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 22a832098d44..e447651a2dbe 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -189,6 +189,23 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) | |||
| 189 | return conn ? &conn->dev : NULL; | 189 | return conn ? &conn->dev : NULL; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) | ||
| 193 | { | ||
| 194 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); | ||
| 195 | bdaddr_t bdaddr; | ||
| 196 | baswap(&bdaddr, &dev->dst); | ||
| 197 | return sprintf(buf, "%s\n", batostr(&bdaddr)); | ||
| 198 | } | ||
| 199 | |||
| 200 | static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf) | ||
| 201 | { | ||
| 202 | struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); | ||
| 203 | return sprintf(buf, "%d\n", dev->channel); | ||
| 204 | } | ||
| 205 | |||
| 206 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | ||
| 207 | static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | ||
| 208 | |||
| 192 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) | 209 | static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc) |
| 193 | { | 210 | { |
| 194 | struct rfcomm_dev *dev; | 211 | struct rfcomm_dev *dev; |
| @@ -281,6 +298,14 @@ out: | |||
| 281 | return err; | 298 | return err; |
| 282 | } | 299 | } |
| 283 | 300 | ||
| 301 | dev_set_drvdata(dev->tty_dev, dev); | ||
| 302 | |||
| 303 | if (device_create_file(dev->tty_dev, &dev_attr_address) < 0) | ||
| 304 | BT_ERR("Failed to create address attribute"); | ||
| 305 | |||
| 306 | if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0) | ||
| 307 | BT_ERR("Failed to create channel attribute"); | ||
| 308 | |||
| 284 | return dev->id; | 309 | return dev->id; |
| 285 | } | 310 | } |
| 286 | 311 | ||
