aboutsummaryrefslogtreecommitdiff
path: root/net/bluetooth/hci_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r--net/bluetooth/hci_sysfs.c135
1 files changed, 119 insertions, 16 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 3987d167f04..989b22d9042 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -13,16 +13,32 @@
#define BT_DBG(D...)
#endif
-static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+static inline char *typetostr(int type)
{
- struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", hdev->name);
+ switch (type) {
+ case HCI_VIRTUAL:
+ return "VIRTUAL";
+ case HCI_USB:
+ return "USB";
+ case HCI_PCCARD:
+ return "PCCARD";
+ case HCI_UART:
+ return "UART";
+ case HCI_RS232:
+ return "RS232";
+ case HCI_PCI:
+ return "PCI";
+ case HCI_SDIO:
+ return "SDIO";
+ default:
+ return "UNKNOWN";
+ }
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", hdev->type);
+ return sprintf(buf, "%s\n", typetostr(hdev->type));
}
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
@@ -33,10 +49,22 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
return sprintf(buf, "%s\n", batostr(&bdaddr));
}
-static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", hdev->manufacturer);
+}
+
+static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
- return sprintf(buf, "0x%lx\n", hdev->flags);
+ return sprintf(buf, "%d\n", hdev->hci_ver);
+}
+
+static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", hdev->hci_rev);
}
static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
@@ -141,10 +169,11 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
return count;
}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
+static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
+static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
+static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
@@ -155,10 +184,11 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
show_sniff_min_interval, store_sniff_min_interval);
static struct device_attribute *bt_attrs[] = {
- &dev_attr_name,
&dev_attr_type,
&dev_attr_address,
- &dev_attr_flags,
+ &dev_attr_manufacturer,
+ &dev_attr_hci_version,
+ &dev_attr_hci_revision,
&dev_attr_inquiry_cache,
&dev_attr_idle_timeout,
&dev_attr_sniff_max_interval,
@@ -166,6 +196,32 @@ static struct device_attribute *bt_attrs[] = {
NULL
};
+static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_conn *conn = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
+}
+
+static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_conn *conn = dev_get_drvdata(dev);
+ bdaddr_t bdaddr;
+ baswap(&bdaddr, &conn->dst);
+ return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+#define CONN_ATTR(_name,_mode,_show,_store) \
+struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
+static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
+
+static struct device_attribute *conn_attrs[] = {
+ &conn_attr_type,
+ &conn_attr_address,
+ NULL
+};
+
struct class *bt_class = NULL;
EXPORT_SYMBOL_GPL(bt_class);
@@ -177,8 +233,57 @@ static struct platform_device *bt_platform;
static void bt_release(struct device *dev)
{
- struct hci_dev *hdev = dev_get_drvdata(dev);
- kfree(hdev);
+ void *data = dev_get_drvdata(dev);
+ kfree(data);
+}
+
+static void add_conn(void *data)
+{
+ struct hci_conn *conn = data;
+ int i;
+
+ device_register(&conn->dev);
+
+ for (i = 0; conn_attrs[i]; i++)
+ device_create_file(&conn->dev, conn_attrs[i]);
+}
+
+void hci_conn_add_sysfs(struct hci_conn *conn)
+{
+ struct hci_dev *hdev = conn->hdev;
+ bdaddr_t *ba = &conn->dst;
+
+ BT_DBG("conn %p", conn);
+
+ conn->dev.parent = &hdev->dev;
+ conn->dev.release = bt_release;
+
+ snprintf(conn->dev.bus_id, BUS_ID_SIZE,
+ "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
+ conn->type == ACL_LINK ? "acl" : "sco",
+ ba->b[5], ba->b[4], ba->b[3],
+ ba->b[2], ba->b[1], ba->b[0]);
+
+ dev_set_drvdata(&conn->dev, conn);
+
+ INIT_WORK(&conn->work, add_conn, (void *) conn);
+
+ schedule_work(&conn->work);
+}
+
+static void del_conn(void *data)
+{
+ struct hci_conn *conn = data;
+ device_del(&conn->dev);
+}
+
+void hci_conn_del_sysfs(struct hci_conn *conn)
+{
+ BT_DBG("conn %p", conn);
+
+ INIT_WORK(&conn->work, del_conn, (void *) conn);
+
+ schedule_work(&conn->work);
}
int hci_register_sysfs(struct hci_dev *hdev)
@@ -214,11 +319,9 @@ int hci_register_sysfs(struct hci_dev *hdev)
void hci_unregister_sysfs(struct hci_dev *hdev)
{
- struct device *dev = &hdev->dev;
-
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
- device_del(dev);
+ device_del(&hdev->dev);
}
int __init bt_sysfs_init(void)
@@ -245,7 +348,7 @@ int __init bt_sysfs_init(void)
return 0;
}
-void __exit bt_sysfs_cleanup(void)
+void bt_sysfs_cleanup(void)
{
class_destroy(bt_class);