From 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 Mon Sep 17 00:00:00 2001 From: Yunhong Jiang Date: Tue, 4 Aug 2015 12:17:53 -0700 Subject: Add the rt linux 4.1.3-rt3 as base Import the rt linux 4.1.3-rt3 as OPNFV kvm base. It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and the base is: commit 0917f823c59692d751951bf5ea699a2d1e2f26a2 Author: Sebastian Andrzej Siewior Date: Sat Jul 25 12:13:34 2015 +0200 Prepare v4.1.3-rt3 Signed-off-by: Sebastian Andrzej Siewior We lose all the git history this way and it's not good. We should apply another opnfv project repo in future. Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423 Signed-off-by: Yunhong Jiang --- kernel/net/bluetooth/hci_sysfs.c | 214 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 kernel/net/bluetooth/hci_sysfs.c (limited to 'kernel/net/bluetooth/hci_sysfs.c') diff --git a/kernel/net/bluetooth/hci_sysfs.c b/kernel/net/bluetooth/hci_sysfs.c new file mode 100644 index 000000000..555982a78 --- /dev/null +++ b/kernel/net/bluetooth/hci_sysfs.c @@ -0,0 +1,214 @@ +/* Bluetooth HCI driver model support. */ + +#include + +#include +#include + +static struct class *bt_class; + +static inline char *link_typetostr(int type) +{ + switch (type) { + case ACL_LINK: + return "ACL"; + case SCO_LINK: + return "SCO"; + case ESCO_LINK: + return "eSCO"; + case LE_LINK: + return "LE"; + default: + return "UNKNOWN"; + } +} + +static ssize_t show_link_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hci_conn *conn = to_hci_conn(dev); + return sprintf(buf, "%s\n", link_typetostr(conn->type)); +} + +static ssize_t show_link_address(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hci_conn *conn = to_hci_conn(dev); + return sprintf(buf, "%pMR\n", &conn->dst); +} + +#define LINK_ATTR(_name, _mode, _show, _store) \ +struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) + +static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); +static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); + +static struct attribute *bt_link_attrs[] = { + &link_attr_type.attr, + &link_attr_address.attr, + NULL +}; + +ATTRIBUTE_GROUPS(bt_link); + +static void bt_link_release(struct device *dev) +{ + struct hci_conn *conn = to_hci_conn(dev); + kfree(conn); +} + +static struct device_type bt_link = { + .name = "link", + .groups = bt_link_groups, + .release = bt_link_release, +}; + +/* + * The rfcomm tty device will possibly retain even when conn + * is down, and sysfs doesn't support move zombie device, + * so we should move the device before conn device is destroyed. + */ +static int __match_tty(struct device *dev, void *data) +{ + return !strncmp(dev_name(dev), "rfcomm", 6); +} + +void hci_conn_init_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; + + device_initialize(&conn->dev); +} + +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); + + if (device_add(&conn->dev) < 0) { + BT_ERR("Failed to register connection device"); + return; + } + + hci_dev_hold(hdev); +} + +void hci_conn_del_sysfs(struct hci_conn *conn) +{ + struct hci_dev *hdev = conn->hdev; + + if (!device_is_registered(&conn->dev)) + return; + + while (1) { + struct device *dev; + + dev = device_find_child(&conn->dev, NULL, __match_tty); + if (!dev) + break; + device_move(dev, NULL, DPM_ORDER_DEV_LAST); + put_device(dev); + } + + device_del(&conn->dev); + + hci_dev_put(hdev); +} + +static inline char *host_typetostr(int type) +{ + switch (type) { + case HCI_BREDR: + return "BR/EDR"; + case HCI_AMP: + return "AMP"; + default: + return "UNKNOWN"; + } +} + +static ssize_t show_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hci_dev *hdev = to_hci_dev(dev); + return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); +} + +static ssize_t show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hci_dev *hdev = to_hci_dev(dev); + char name[HCI_MAX_NAME_LENGTH + 1]; + int i; + + for (i = 0; i < HCI_MAX_NAME_LENGTH; i++) + name[i] = hdev->dev_name[i]; + + name[HCI_MAX_NAME_LENGTH] = '\0'; + return sprintf(buf, "%s\n", name); +} + +static ssize_t show_address(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hci_dev *hdev = to_hci_dev(dev); + return sprintf(buf, "%pMR\n", &hdev->bdaddr); +} + +static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); +static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); + +static struct attribute *bt_host_attrs[] = { + &dev_attr_type.attr, + &dev_attr_name.attr, + &dev_attr_address.attr, + NULL +}; + +ATTRIBUTE_GROUPS(bt_host); + +static void bt_host_release(struct device *dev) +{ + struct hci_dev *hdev = to_hci_dev(dev); + kfree(hdev); + module_put(THIS_MODULE); +} + +static struct device_type bt_host = { + .name = "host", + .groups = bt_host_groups, + .release = bt_host_release, +}; + +void hci_init_sysfs(struct hci_dev *hdev) +{ + struct device *dev = &hdev->dev; + + dev->type = &bt_host; + dev->class = bt_class; + + __module_get(THIS_MODULE); + device_initialize(dev); +} + +int __init bt_sysfs_init(void) +{ + bt_class = class_create(THIS_MODULE, "bluetooth"); + + return PTR_ERR_OR_ZERO(bt_class); +} + +void bt_sysfs_cleanup(void) +{ + class_destroy(bt_class); +} -- cgit 1.2.3-korg