linux/net/bluetooth/hci_sysfs.c
<<
>>
Prefs
   1/* Bluetooth HCI driver model support. */
   2
   3#include <linux/kernel.h>
   4#include <linux/init.h>
   5
   6#include <net/bluetooth/bluetooth.h>
   7#include <net/bluetooth/hci_core.h>
   8
   9struct class *bt_class = NULL;
  10EXPORT_SYMBOL_GPL(bt_class);
  11
  12static struct workqueue_struct *bt_workq;
  13
  14static inline char *link_typetostr(int type)
  15{
  16        switch (type) {
  17        case ACL_LINK:
  18                return "ACL";
  19        case SCO_LINK:
  20                return "SCO";
  21        case ESCO_LINK:
  22                return "eSCO";
  23        default:
  24                return "UNKNOWN";
  25        }
  26}
  27
  28static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
  29{
  30        struct hci_conn *conn = dev_get_drvdata(dev);
  31        return sprintf(buf, "%s\n", link_typetostr(conn->type));
  32}
  33
  34static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
  35{
  36        struct hci_conn *conn = dev_get_drvdata(dev);
  37        bdaddr_t bdaddr;
  38        baswap(&bdaddr, &conn->dst);
  39        return sprintf(buf, "%s\n", batostr(&bdaddr));
  40}
  41
  42static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
  43{
  44        struct hci_conn *conn = dev_get_drvdata(dev);
  45
  46        return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
  47                                conn->features[0], conn->features[1],
  48                                conn->features[2], conn->features[3],
  49                                conn->features[4], conn->features[5],
  50                                conn->features[6], conn->features[7]);
  51}
  52
  53#define LINK_ATTR(_name,_mode,_show,_store) \
  54struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store)
  55
  56static LINK_ATTR(type, S_IRUGO, show_link_type, NULL);
  57static LINK_ATTR(address, S_IRUGO, show_link_address, NULL);
  58static LINK_ATTR(features, S_IRUGO, show_link_features, NULL);
  59
  60static struct attribute *bt_link_attrs[] = {
  61        &link_attr_type.attr,
  62        &link_attr_address.attr,
  63        &link_attr_features.attr,
  64        NULL
  65};
  66
  67static struct attribute_group bt_link_group = {
  68        .attrs = bt_link_attrs,
  69};
  70
  71static const struct attribute_group *bt_link_groups[] = {
  72        &bt_link_group,
  73        NULL
  74};
  75
  76static void bt_link_release(struct device *dev)
  77{
  78        void *data = dev_get_drvdata(dev);
  79        kfree(data);
  80}
  81
  82static struct device_type bt_link = {
  83        .name    = "link",
  84        .groups  = bt_link_groups,
  85        .release = bt_link_release,
  86};
  87
  88static void add_conn(struct work_struct *work)
  89{
  90        struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
  91        struct hci_dev *hdev = conn->hdev;
  92
  93        dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
  94
  95        dev_set_drvdata(&conn->dev, conn);
  96
  97        if (device_add(&conn->dev) < 0) {
  98                BT_ERR("Failed to register connection device");
  99                return;
 100        }
 101
 102        hci_dev_hold(hdev);
 103}
 104
 105/*
 106 * The rfcomm tty device will possibly retain even when conn
 107 * is down, and sysfs doesn't support move zombie device,
 108 * so we should move the device before conn device is destroyed.
 109 */
 110static int __match_tty(struct device *dev, void *data)
 111{
 112        return !strncmp(dev_name(dev), "rfcomm", 6);
 113}
 114
 115static void del_conn(struct work_struct *work)
 116{
 117        struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
 118        struct hci_dev *hdev = conn->hdev;
 119
 120        if (!device_is_registered(&conn->dev))
 121                return;
 122
 123        while (1) {
 124                struct device *dev;
 125
 126                dev = device_find_child(&conn->dev, NULL, __match_tty);
 127                if (!dev)
 128                        break;
 129                device_move(dev, NULL, DPM_ORDER_DEV_LAST);
 130                put_device(dev);
 131        }
 132
 133        device_del(&conn->dev);
 134        put_device(&conn->dev);
 135
 136        hci_dev_put(hdev);
 137}
 138
 139void hci_conn_init_sysfs(struct hci_conn *conn)
 140{
 141        struct hci_dev *hdev = conn->hdev;
 142
 143        BT_DBG("conn %p", conn);
 144
 145        conn->dev.type = &bt_link;
 146        conn->dev.class = bt_class;
 147        conn->dev.parent = &hdev->dev;
 148
 149        device_initialize(&conn->dev);
 150
 151        INIT_WORK(&conn->work_add, add_conn);
 152        INIT_WORK(&conn->work_del, del_conn);
 153}
 154
 155void hci_conn_add_sysfs(struct hci_conn *conn)
 156{
 157        BT_DBG("conn %p", conn);
 158
 159        queue_work(bt_workq, &conn->work_add);
 160}
 161
 162void hci_conn_del_sysfs(struct hci_conn *conn)
 163{
 164        BT_DBG("conn %p", conn);
 165
 166        queue_work(bt_workq, &conn->work_del);
 167}
 168
 169static inline char *host_typetostr(int type)
 170{
 171        switch (type) {
 172        case HCI_VIRTUAL:
 173                return "VIRTUAL";
 174        case HCI_USB:
 175                return "USB";
 176        case HCI_PCCARD:
 177                return "PCCARD";
 178        case HCI_UART:
 179                return "UART";
 180        case HCI_RS232:
 181                return "RS232";
 182        case HCI_PCI:
 183                return "PCI";
 184        case HCI_SDIO:
 185                return "SDIO";
 186        default:
 187                return "UNKNOWN";
 188        }
 189}
 190
 191static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
 192{
 193        struct hci_dev *hdev = dev_get_drvdata(dev);
 194        return sprintf(buf, "%s\n", host_typetostr(hdev->type));
 195}
 196
 197static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
 198{
 199        struct hci_dev *hdev = dev_get_drvdata(dev);
 200        char name[249];
 201        int i;
 202
 203        for (i = 0; i < 248; i++)
 204                name[i] = hdev->dev_name[i];
 205
 206        name[248] = '\0';
 207        return sprintf(buf, "%s\n", name);
 208}
 209
 210static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
 211{
 212        struct hci_dev *hdev = dev_get_drvdata(dev);
 213        return sprintf(buf, "0x%.2x%.2x%.2x\n",
 214                        hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
 215}
 216
 217static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
 218{
 219        struct hci_dev *hdev = dev_get_drvdata(dev);
 220        bdaddr_t bdaddr;
 221        baswap(&bdaddr, &hdev->bdaddr);
 222        return sprintf(buf, "%s\n", batostr(&bdaddr));
 223}
 224
 225static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
 226{
 227        struct hci_dev *hdev = dev_get_drvdata(dev);
 228
 229        return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
 230                                hdev->features[0], hdev->features[1],
 231                                hdev->features[2], hdev->features[3],
 232                                hdev->features[4], hdev->features[5],
 233                                hdev->features[6], hdev->features[7]);
 234}
 235
 236static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
 237{
 238        struct hci_dev *hdev = dev_get_drvdata(dev);
 239        return sprintf(buf, "%d\n", hdev->manufacturer);
 240}
 241
 242static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf)
 243{
 244        struct hci_dev *hdev = dev_get_drvdata(dev);
 245        return sprintf(buf, "%d\n", hdev->hci_ver);
 246}
 247
 248static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf)
 249{
 250        struct hci_dev *hdev = dev_get_drvdata(dev);
 251        return sprintf(buf, "%d\n", hdev->hci_rev);
 252}
 253
 254static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
 255{
 256        struct hci_dev *hdev = dev_get_drvdata(dev);
 257        struct inquiry_cache *cache = &hdev->inq_cache;
 258        struct inquiry_entry *e;
 259        int n = 0;
 260
 261        hci_dev_lock_bh(hdev);
 262
 263        for (e = cache->list; e; e = e->next) {
 264                struct inquiry_data *data = &e->data;
 265                bdaddr_t bdaddr;
 266                baswap(&bdaddr, &data->bdaddr);
 267                n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
 268                                batostr(&bdaddr),
 269                                data->pscan_rep_mode, data->pscan_period_mode,
 270                                data->pscan_mode, data->dev_class[2],
 271                                data->dev_class[1], data->dev_class[0],
 272                                __le16_to_cpu(data->clock_offset),
 273                                data->rssi, data->ssp_mode, e->timestamp);
 274        }
 275
 276        hci_dev_unlock_bh(hdev);
 277        return n;
 278}
 279
 280static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf)
 281{
 282        struct hci_dev *hdev = dev_get_drvdata(dev);
 283        return sprintf(buf, "%d\n", hdev->idle_timeout);
 284}
 285
 286static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 287{
 288        struct hci_dev *hdev = dev_get_drvdata(dev);
 289        char *ptr;
 290        __u32 val;
 291
 292        val = simple_strtoul(buf, &ptr, 10);
 293        if (ptr == buf)
 294                return -EINVAL;
 295
 296        if (val != 0 && (val < 500 || val > 3600000))
 297                return -EINVAL;
 298
 299        hdev->idle_timeout = val;
 300
 301        return count;
 302}
 303
 304static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf)
 305{
 306        struct hci_dev *hdev = dev_get_drvdata(dev);
 307        return sprintf(buf, "%d\n", hdev->sniff_max_interval);
 308}
 309
 310static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 311{
 312        struct hci_dev *hdev = dev_get_drvdata(dev);
 313        char *ptr;
 314        __u16 val;
 315
 316        val = simple_strtoul(buf, &ptr, 10);
 317        if (ptr == buf)
 318                return -EINVAL;
 319
 320        if (val < 0x0002 || val > 0xFFFE || val % 2)
 321                return -EINVAL;
 322
 323        if (val < hdev->sniff_min_interval)
 324                return -EINVAL;
 325
 326        hdev->sniff_max_interval = val;
 327
 328        return count;
 329}
 330
 331static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf)
 332{
 333        struct hci_dev *hdev = dev_get_drvdata(dev);
 334        return sprintf(buf, "%d\n", hdev->sniff_min_interval);
 335}
 336
 337static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 338{
 339        struct hci_dev *hdev = dev_get_drvdata(dev);
 340        char *ptr;
 341        __u16 val;
 342
 343        val = simple_strtoul(buf, &ptr, 10);
 344        if (ptr == buf)
 345                return -EINVAL;
 346
 347        if (val < 0x0002 || val > 0xFFFE || val % 2)
 348                return -EINVAL;
 349
 350        if (val > hdev->sniff_max_interval)
 351                return -EINVAL;
 352
 353        hdev->sniff_min_interval = val;
 354
 355        return count;
 356}
 357
 358static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 359static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 360static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 361static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
 362static DEVICE_ATTR(features, S_IRUGO, show_features, NULL);
 363static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
 364static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
 365static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
 366static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
 367
 368static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
 369                                show_idle_timeout, store_idle_timeout);
 370static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
 371                                show_sniff_max_interval, store_sniff_max_interval);
 372static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
 373                                show_sniff_min_interval, store_sniff_min_interval);
 374
 375static struct attribute *bt_host_attrs[] = {
 376        &dev_attr_type.attr,
 377        &dev_attr_name.attr,
 378        &dev_attr_class.attr,
 379        &dev_attr_address.attr,
 380        &dev_attr_features.attr,
 381        &dev_attr_manufacturer.attr,
 382        &dev_attr_hci_version.attr,
 383        &dev_attr_hci_revision.attr,
 384        &dev_attr_inquiry_cache.attr,
 385        &dev_attr_idle_timeout.attr,
 386        &dev_attr_sniff_max_interval.attr,
 387        &dev_attr_sniff_min_interval.attr,
 388        NULL
 389};
 390
 391static struct attribute_group bt_host_group = {
 392        .attrs = bt_host_attrs,
 393};
 394
 395static const struct attribute_group *bt_host_groups[] = {
 396        &bt_host_group,
 397        NULL
 398};
 399
 400static void bt_host_release(struct device *dev)
 401{
 402        void *data = dev_get_drvdata(dev);
 403        kfree(data);
 404}
 405
 406static struct device_type bt_host = {
 407        .name    = "host",
 408        .groups  = bt_host_groups,
 409        .release = bt_host_release,
 410};
 411
 412int hci_register_sysfs(struct hci_dev *hdev)
 413{
 414        struct device *dev = &hdev->dev;
 415        int err;
 416
 417        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 418
 419        dev->type = &bt_host;
 420        dev->class = bt_class;
 421        dev->parent = hdev->parent;
 422
 423        dev_set_name(dev, "%s", hdev->name);
 424
 425        dev_set_drvdata(dev, hdev);
 426
 427        err = device_register(dev);
 428        if (err < 0)
 429                return err;
 430
 431        return 0;
 432}
 433
 434void hci_unregister_sysfs(struct hci_dev *hdev)
 435{
 436        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 437
 438        device_del(&hdev->dev);
 439}
 440
 441int __init bt_sysfs_init(void)
 442{
 443        bt_workq = create_singlethread_workqueue("bluetooth");
 444        if (!bt_workq)
 445                return -ENOMEM;
 446
 447        bt_class = class_create(THIS_MODULE, "bluetooth");
 448        if (IS_ERR(bt_class)) {
 449                destroy_workqueue(bt_workq);
 450                return PTR_ERR(bt_class);
 451        }
 452
 453        return 0;
 454}
 455
 456void bt_sysfs_cleanup(void)
 457{
 458        destroy_workqueue(bt_workq);
 459
 460        class_destroy(bt_class);
 461}
 462