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

Commit bc83871e authored by David S. Miller's avatar David S. Miller
Browse files
parents e151a60a a67e899c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -457,6 +457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);

int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
void hci_conn_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn);
void hci_conn_del_sysfs(struct hci_conn *conn);

+2 −0
Original line number Diff line number Diff line
@@ -248,6 +248,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);

	hci_conn_init_sysfs(conn);

	tasklet_enable(&hdev->tx_task);

	return conn;
+40 −34
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
struct class *bt_class = NULL;
EXPORT_SYMBOL_GPL(bt_class);

static struct workqueue_struct *bluetooth;
static struct workqueue_struct *bt_workq;

static inline char *link_typetostr(int type)
{
@@ -89,8 +89,8 @@ static void add_conn(struct work_struct *work)
{
	struct hci_conn *conn = container_of(work, struct hci_conn, work_add);

	/* ensure previous add/del is complete */
	flush_workqueue(bluetooth);
	/* ensure previous del is complete */
	flush_work(&conn->work_del);

	if (device_add(&conn->dev) < 0) {
		BT_ERR("Failed to register connection device");
@@ -98,27 +98,6 @@ static void add_conn(struct work_struct *work)
	}
}

void hci_conn_add_sysfs(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p", conn);

	conn->dev.type = &bt_link;
	conn->dev.class = bt_class;
	conn->dev.parent = &hdev->dev;

	dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);

	dev_set_drvdata(&conn->dev, conn);

	device_initialize(&conn->dev);

	INIT_WORK(&conn->work_add, add_conn);

	queue_work(bluetooth, &conn->work_add);
}

/*
 * The rfcomm tty device will possibly retain even when conn
 * is down, and sysfs doesn't support move zombie device,
@@ -134,8 +113,11 @@ static void del_conn(struct work_struct *work)
	struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
	struct hci_dev *hdev = conn->hdev;

	/* ensure previous add/del is complete */
	flush_workqueue(bluetooth);
	/* ensure previous add is complete */
	flush_work(&conn->work_add);

	if (!device_is_registered(&conn->dev))
		return;

	while (1) {
		struct device *dev;
@@ -152,16 +134,40 @@ static void del_conn(struct work_struct *work)
	hci_dev_put(hdev);
}

void hci_conn_del_sysfs(struct hci_conn *conn)
void hci_conn_init_sysfs(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p", conn);

	if (!device_is_registered(&conn->dev))
		return;
	conn->dev.type = &bt_link;
	conn->dev.class = bt_class;
	conn->dev.parent = &hdev->dev;

	dev_set_drvdata(&conn->dev, conn);

	device_initialize(&conn->dev);

	INIT_WORK(&conn->work_add, add_conn);
	INIT_WORK(&conn->work_del, del_conn);
}

void hci_conn_add_sysfs(struct hci_conn *conn)
{
	struct hci_dev *hdev = conn->hdev;

	BT_DBG("conn %p", conn);

	dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);

	queue_work(bt_workq, &conn->work_add);
}

void hci_conn_del_sysfs(struct hci_conn *conn)
{
	BT_DBG("conn %p", conn);

	queue_work(bluetooth, &conn->work_del);
	queue_work(bt_workq, &conn->work_del);
}

static inline char *host_typetostr(int type)
@@ -438,13 +444,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)

int __init bt_sysfs_init(void)
{
	bluetooth = create_singlethread_workqueue("bluetooth");
	if (!bluetooth)
	bt_workq = create_singlethread_workqueue("bluetooth");
	if (!bt_workq)
		return -ENOMEM;

	bt_class = class_create(THIS_MODULE, "bluetooth");
	if (IS_ERR(bt_class)) {
		destroy_workqueue(bluetooth);
		destroy_workqueue(bt_workq);
		return PTR_ERR(bt_class);
	}

@@ -453,7 +459,7 @@ int __init bt_sysfs_init(void)

void bt_sysfs_cleanup(void)
{
	destroy_workqueue(bluetooth);
	destroy_workqueue(bt_workq);

	class_destroy(bt_class);
}