[PATCH][NETLINK] devup command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Marcel,

Here is the modified netlink patch.
Let me know what needs to be changed.

-Alok.
From 52e109b77150a9e29d8861794a2dde2b99a94cc8 Mon Sep 17 00:00:00 2001
From: Alok Barsode <alokbarsode@xxxxxxxxx>
Date: Wed, 14 Jan 2009 18:34:55 +0530
Subject: [PATCH] Adding netlink support to bluetooth.
 Adding files netlink.c and netlink.h to net/bluetooth for netlink support.
 Adding support for DEVUP.
 Redefining hci_req_lock to use down_trylock

Signed-off-by: Alok Barsode <alokbarsode@xxxxxxxxx>
---
 include/net/bluetooth/bluetooth.h |    3 +
 include/net/bluetooth/hci_core.h  |    4 +-
 net/bluetooth/Makefile            |    2 +-
 net/bluetooth/af_bluetooth.c      |    6 ++
 net/bluetooth/hci_core.c          |    6 ++
 net/bluetooth/netlink.c           |  168 +++++++++++++++++++++++++++++++++++++
 net/bluetooth/netlink.h           |   28 ++++++
 7 files changed, 215 insertions(+), 2 deletions(-)
 create mode 100644 net/bluetooth/netlink.c
 create mode 100644 net/bluetooth/netlink.h

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 624da4d..ac5e40e 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -189,4 +189,7 @@ extern void bt_sysfs_cleanup(void);
 
 extern struct class *bt_class;
 
+extern int bluetooth_netlink_init(void);
+extern void bluetooth_netlink_cleanup(void);
+
 #endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4b14972..744146e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -675,9 +675,11 @@ struct hci_sec_filter {
 #define HCI_REQ_PEND	  1
 #define HCI_REQ_CANCELED  2
 
-#define hci_req_lock(d)		down(&d->req_lock)
+#define hci_req_lock(d)		down_trylock(&d->req_lock)
 #define hci_req_unlock(d)	up(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
 
+/* FIXME: This is temporarily added to export __hci_request and hci_init_req */
+int hci_init_request(struct hci_dev *hdev);
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index d1e433f..f014d48 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP)	+= bnep/
 obj-$(CONFIG_BT_CMTP)	+= cmtp/
 obj-$(CONFIG_BT_HIDP)	+= hidp/
 
-bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o
+bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o netlink.o
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 744ed3f..b778a0e 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -425,6 +425,10 @@ static int __init bt_init(void)
 	if (err < 0)
 		return err;
 
+	err = bluetooth_netlink_init();
+	if (err < 0)
+		return err;
+
 	err = sock_register(&bt_sock_family_ops);
 	if (err < 0) {
 		bt_sysfs_cleanup();
@@ -445,6 +449,8 @@ static void __exit bt_exit(void)
 	sock_unregister(PF_BLUETOOTH);
 
 	bt_sysfs_cleanup();
+
+	bluetooth_netlink_cleanup();
 }
 
 subsys_initcall(bt_init);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ba78cc1..2a8fb7a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -251,6 +251,12 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 	hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
 }
 
+int hci_init_request(struct hci_dev *hdev)
+{
+	return __hci_request(hdev, hci_init_req, 0,
+			msecs_to_jiffies(HCI_INIT_TIMEOUT));
+}
+
 static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
 {
 	__u8 scan = opt;
diff --git a/net/bluetooth/netlink.c b/net/bluetooth/netlink.c
new file mode 100644
index 0000000..dc9fb20
--- /dev/null
+++ b/net/bluetooth/netlink.c
@@ -0,0 +1,168 @@
+/*
+ * This is the netlink-based bluetooth interface.
+ *
+ * Copyright 2008 Alok Barsode <alok.barsode@xxxxxxxxxx>
+ */
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <net/genetlink.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "netlink.h"
+
+/* family definition */
+static struct genl_family bluetooth_fam = {
+	.id = GENL_ID_GENERATE,
+	.hdrsize = 0,
+	.name = "bluetooth",
+	.version = VERSION,
+	.maxattr = ATTR_MAX
+};
+
+static struct nla_policy bluetooth_policy[ATTR_MAX + 1] = {
+	[DEVID] = { .type = NLA_U16 },
+	[FLAG]	= { .type = NLA_U16 },
+};
+
+static int bluetooth_devup(struct sk_buff *skb, struct genl_info *info)
+{
+	int ret=0;
+	 __u16 dev;
+	void *hdr;
+	struct sk_buff *msg;
+	struct hci_dev *hdev;
+
+	if (!info->attrs[DEVID])
+		return -EINVAL;
+
+	dev = nla_get_u16(info->attrs[DEVID]);
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+
+	if (!msg)
+		return -ENOBUFS;
+
+	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, &bluetooth_fam, 0, DEVUP);
+
+	if (hdr == NULL){
+		nlmsg_free(msg);
+		return -ENOBUFS;
+	}
+
+	if (!(hdev = hci_dev_get(dev))){
+		nlmsg_free(msg);
+		return -ENODEV;
+	}
+
+	printk("%s %p", hdev->name, hdev);
+
+	if (hci_req_lock(hdev)) {
+		ret = -EBUSY;
+		goto done;
+	}
+
+	if (test_bit(HCI_UP, &hdev->flags)) {
+		ret = -EALREADY;
+		goto done;
+	}
+
+	if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+		set_bit(HCI_RAW, &hdev->flags);
+
+	if (hdev->open(hdev)) {
+		ret = -EIO;
+		goto done;
+	}
+
+	NLA_PUT_U16(msg, DEVID, dev);
+
+	if (!test_bit(HCI_RAW, &hdev->flags)) {
+		atomic_set(&hdev->cmd_cnt, 1);
+		set_bit(HCI_INIT, &hdev->flags);
+
+		//__hci_request(hdev, hci_init_req, 0, HZ);
+		ret = hci_init_request(hdev);
+
+		clear_bit(HCI_INIT, &hdev->flags);
+	}
+
+	if (!ret) {
+		hci_dev_hold(hdev);
+		set_bit(HCI_UP, &hdev->flags);
+		NLA_PUT_U16(msg, FLAG, HCI_DEV_UP);
+	} else {
+		/* Init failed, cleanup */
+		tasklet_kill(&hdev->rx_task);
+		tasklet_kill(&hdev->tx_task);
+		tasklet_kill(&hdev->cmd_task);
+
+		skb_queue_purge(&hdev->cmd_q);
+		skb_queue_purge(&hdev->rx_q);
+
+		if (hdev->flush)
+			hdev->flush(hdev);
+
+		if (hdev->sent_cmd) {
+			kfree_skb(hdev->sent_cmd);
+			hdev->sent_cmd = NULL;
+		}
+
+		hdev->close(hdev);
+		hdev->flags = 0;
+		NLA_PUT_U16(msg, FLAG, HCI_DEV_DOWN);
+	}
+
+	genlmsg_end(msg, hdr);
+ done:
+	hci_req_unlock(hdev);
+	hci_dev_put(hdev);
+	if (ret < 0)
+		return ret;
+
+	return genlmsg_unicast(msg, info->snd_pid);
+
+ nla_put_failure:
+        genlmsg_cancel(msg, hdr);
+        return -EMSGSIZE;
+}
+
+static struct genl_ops bluetooth_ops = {
+		.cmd = DEVUP,
+		.policy = bluetooth_policy,
+		.doit = bluetooth_devup,
+		.flags = GENL_ADMIN_PERM,
+		.dumpit = NULL,
+};
+
+
+/* initialisation/exit functions */
+int __init bluetooth_netlink_init(void)
+{
+	int err;
+
+	err = genl_register_family(&bluetooth_fam);
+	if (err)
+		return err;
+
+	err = genl_register_ops(&bluetooth_fam, &bluetooth_ops);
+	if (err)
+		goto err_out;
+
+	return 0;
+
+err_out:
+	genl_unregister_family(&bluetooth_fam);
+	return err;
+}
+
+void bluetooth_netlink_cleanup(void)
+{
+	genl_unregister_family(&bluetooth_fam);
+}
diff --git a/net/bluetooth/netlink.h b/net/bluetooth/netlink.h
new file mode 100644
index 0000000..0484bb4
--- /dev/null
+++ b/net/bluetooth/netlink.h
@@ -0,0 +1,28 @@
+/*
+ * This is the netlink-based bluetooth interface.
+ *
+ * Copyright 2008 Alok Barsode <alok.barsode@xxxxxxxxxx>
+ */
+#ifndef __NETLINK_H
+#define __NETLINK_H
+
+#define VERSION 1
+
+enum bluetooth_attr {
+	ATTR_UNSPEC,
+	DEVID,
+	FLAG,
+	/* Add attributes here */
+	__ATTR_MAX,
+	ATTR_MAX  =  __ATTR_MAX - 1
+};
+
+enum bluetooth_cmds {
+	CMD_UNSPEC,
+	DEVUP,
+	/* Add command here */
+	__CMD_MAX,
+	CMD_MAX  = __CMD_MAX - 1
+};
+
+#endif /* __NETLINK_H */
-- 
1.5.6.3


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux