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