Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a524eccc authored by Marcel Holtmann's avatar Marcel Holtmann Committed by David S. Miller
Browse files

[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: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 2cb3377a
Loading
Loading
Loading
Loading
+21 −39
Original line number Diff line number Diff line
@@ -33,11 +33,11 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/freezer.h>
#include <linux/wait.h>
#include <linux/device.h>
#include <linux/net.h>
#include <linux/mutex.h>
#include <linux/kthread.h>

#include <net/sock.h>
#include <asm/uaccess.h>
@@ -68,7 +68,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
static unsigned long rfcomm_event;

static LIST_HEAD(session_list);
static atomic_t terminate, running;

static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
@@ -1850,26 +1849,6 @@ static inline void rfcomm_process_sessions(void)
	rfcomm_unlock();
}

static void rfcomm_worker(void)
{
	BT_DBG("");

	while (!atomic_read(&terminate)) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
			/* No pending events. Let's sleep.
			 * Incoming connections and data will wake us up. */
			schedule();
		}
		set_current_state(TASK_RUNNING);

		/* Process stuff */
		clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
		rfcomm_process_sessions();
	}
	return;
}

static int rfcomm_add_listener(bdaddr_t *ba)
{
	struct sockaddr_l2 addr;
@@ -1935,22 +1914,28 @@ static void rfcomm_kill_listener(void)

static int rfcomm_run(void *unused)
{
	rfcomm_thread = current;

	atomic_inc(&running);
	BT_DBG("");

	daemonize("krfcommd");
	set_user_nice(current, -10);

	BT_DBG("");

	rfcomm_add_listener(BDADDR_ANY);

	rfcomm_worker();
	while (!kthread_should_stop()) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
			/* No pending events. Let's sleep.
			 * Incoming connections and data will wake us up. */
			schedule();
		}
		set_current_state(TASK_RUNNING);

		/* Process stuff */
		clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
		rfcomm_process_sessions();
	}

	rfcomm_kill_listener();

	atomic_dec(&running);
	return 0;
}

@@ -2059,7 +2044,11 @@ static int __init rfcomm_init(void)

	hci_register_cb(&rfcomm_cb);

	kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
	rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
	if (IS_ERR(rfcomm_thread)) {
		hci_unregister_cb(&rfcomm_cb);
		return PTR_ERR(rfcomm_thread);
	}

	if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
		BT_ERR("Failed to create RFCOMM info file");
@@ -2081,14 +2070,7 @@ static void __exit rfcomm_exit(void)

	hci_unregister_cb(&rfcomm_cb);

	/* Terminate working thread.
	 * ie. Set terminate flag and wake it up */
	atomic_inc(&terminate);
	rfcomm_schedule(RFCOMM_SCHED_STATE);

	/* Wait until thread is running */
	while (atomic_read(&running))
		schedule();
	kthread_stop(rfcomm_thread);

#ifdef CONFIG_BT_RFCOMM_TTY
	rfcomm_cleanup_ttys();