hci_sysfs.c revision e9c4bec63eac001651d6d30239dd4175cc3698ef
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_address(struct device *dev, struct device_attribute *attr, char *buf) 45{ 46 struct hci_dev *hdev = dev_get_drvdata(dev); 47 bdaddr_t bdaddr; 48 baswap(&bdaddr, &hdev->bdaddr); 49 return sprintf(buf, "%s\n", batostr(&bdaddr)); 50} 51 52static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf) 53{ 54 struct hci_dev *hdev = dev_get_drvdata(dev); 55 return sprintf(buf, "%d\n", hdev->manufacturer); 56} 57 58static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) 59{ 60 struct hci_dev *hdev = dev_get_drvdata(dev); 61 return sprintf(buf, "%d\n", hdev->hci_ver); 62} 63 64static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf) 65{ 66 struct hci_dev *hdev = dev_get_drvdata(dev); 67 return sprintf(buf, "%d\n", hdev->hci_rev); 68} 69 70static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) 71{ 72 struct hci_dev *hdev = dev_get_drvdata(dev); 73 struct inquiry_cache *cache = &hdev->inq_cache; 74 struct inquiry_entry *e; 75 int n = 0; 76 77 hci_dev_lock_bh(hdev); 78 79 for (e = cache->list; e; e = e->next) { 80 struct inquiry_data *data = &e->data; 81 bdaddr_t bdaddr; 82 baswap(&bdaddr, &data->bdaddr); 83 n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %u\n", 84 batostr(&bdaddr), 85 data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode, 86 data->dev_class[2], data->dev_class[1], data->dev_class[0], 87 __le16_to_cpu(data->clock_offset), data->rssi, e->timestamp); 88 } 89 90 hci_dev_unlock_bh(hdev); 91 return n; 92} 93 94static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) 95{ 96 struct hci_dev *hdev = dev_get_drvdata(dev); 97 return sprintf(buf, "%d\n", hdev->idle_timeout); 98} 99 100static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 101{ 102 struct hci_dev *hdev = dev_get_drvdata(dev); 103 char *ptr; 104 __u32 val; 105 106 val = simple_strtoul(buf, &ptr, 10); 107 if (ptr == buf) 108 return -EINVAL; 109 110 if (val != 0 && (val < 500 || val > 3600000)) 111 return -EINVAL; 112 113 hdev->idle_timeout = val; 114 115 return count; 116} 117 118static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf) 119{ 120 struct hci_dev *hdev = dev_get_drvdata(dev); 121 return sprintf(buf, "%d\n", hdev->sniff_max_interval); 122} 123 124static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 125{ 126 struct hci_dev *hdev = dev_get_drvdata(dev); 127 char *ptr; 128 __u16 val; 129 130 val = simple_strtoul(buf, &ptr, 10); 131 if (ptr == buf) 132 return -EINVAL; 133 134 if (val < 0x0002 || val > 0xFFFE || val % 2) 135 return -EINVAL; 136 137 if (val < hdev->sniff_min_interval) 138 return -EINVAL; 139 140 hdev->sniff_max_interval = val; 141 142 return count; 143} 144 145static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf) 146{ 147 struct hci_dev *hdev = dev_get_drvdata(dev); 148 return sprintf(buf, "%d\n", hdev->sniff_min_interval); 149} 150 151static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 152{ 153 struct hci_dev *hdev = dev_get_drvdata(dev); 154 char *ptr; 155 __u16 val; 156 157 val = simple_strtoul(buf, &ptr, 10); 158 if (ptr == buf) 159 return -EINVAL; 160 161 if (val < 0x0002 || val > 0xFFFE || val % 2) 162 return -EINVAL; 163 164 if (val > hdev->sniff_max_interval) 165 return -EINVAL; 166 167 hdev->sniff_min_interval = val; 168 169 return count; 170} 171 172static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); 173static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); 174static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); 175static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); 176static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); 177static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); 178 179static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, 180 show_idle_timeout, store_idle_timeout); 181static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, 182 show_sniff_max_interval, store_sniff_max_interval); 183static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, 184 show_sniff_min_interval, store_sniff_min_interval); 185 186static struct device_attribute *bt_attrs[] = { 187 &dev_attr_type, 188 &dev_attr_address, 189 &dev_attr_manufacturer, 190 &dev_attr_hci_version, 191 &dev_attr_hci_revision, 192 &dev_attr_inquiry_cache, 193 &dev_attr_idle_timeout, 194 &dev_attr_sniff_max_interval, 195 &dev_attr_sniff_min_interval, 196 NULL 197}; 198 199static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf) 200{ 201 struct hci_conn *conn = dev_get_drvdata(dev); 202 return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO"); 203} 204 205static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf) 206{ 207 struct hci_conn *conn = dev_get_drvdata(dev); 208 bdaddr_t bdaddr; 209 baswap(&bdaddr, &conn->dst); 210 return sprintf(buf, "%s\n", batostr(&bdaddr)); 211} 212 213#define CONN_ATTR(_name,_mode,_show,_store) \ 214struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store) 215 216static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL); 217static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL); 218 219static struct device_attribute *conn_attrs[] = { 220 &conn_attr_type, 221 &conn_attr_address, 222 NULL 223}; 224 225struct class *bt_class = NULL; 226EXPORT_SYMBOL_GPL(bt_class); 227 228static struct bus_type bt_bus = { 229 .name = "bluetooth", 230}; 231 232static struct platform_device *bt_platform; 233 234static void bt_release(struct device *dev) 235{ 236 void *data = dev_get_drvdata(dev); 237 kfree(data); 238} 239 240static void add_conn(void *data) 241{ 242 struct hci_conn *conn = data; 243 int i; 244 245 if (device_register(&conn->dev) < 0) { 246 BT_ERR("Failed to register connection device"); 247 return; 248 } 249 250 for (i = 0; conn_attrs[i]; i++) 251 if (device_create_file(&conn->dev, conn_attrs[i]) < 0) 252 BT_ERR("Failed to create connection attribute"); 253} 254 255void hci_conn_add_sysfs(struct hci_conn *conn) 256{ 257 struct hci_dev *hdev = conn->hdev; 258 bdaddr_t *ba = &conn->dst; 259 260 BT_DBG("conn %p", conn); 261 262 conn->dev.parent = &hdev->dev; 263 conn->dev.release = bt_release; 264 265 snprintf(conn->dev.bus_id, BUS_ID_SIZE, 266 "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", 267 conn->type == ACL_LINK ? "acl" : "sco", 268 ba->b[5], ba->b[4], ba->b[3], 269 ba->b[2], ba->b[1], ba->b[0]); 270 271 dev_set_drvdata(&conn->dev, conn); 272 273 INIT_WORK(&conn->work, add_conn, (void *) conn); 274 275 schedule_work(&conn->work); 276} 277 278static void del_conn(void *data) 279{ 280 struct hci_conn *conn = data; 281 device_del(&conn->dev); 282} 283 284void hci_conn_del_sysfs(struct hci_conn *conn) 285{ 286 BT_DBG("conn %p", conn); 287 288 INIT_WORK(&conn->work, del_conn, (void *) conn); 289 290 schedule_work(&conn->work); 291} 292 293int hci_register_sysfs(struct hci_dev *hdev) 294{ 295 struct device *dev = &hdev->dev; 296 unsigned int i; 297 int err; 298 299 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 300 301 dev->class = bt_class; 302 dev->parent = hdev->parent; 303 304 strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); 305 306 dev->release = bt_release; 307 308 dev_set_drvdata(dev, hdev); 309 310 err = device_register(dev); 311 if (err < 0) 312 return err; 313 314 for (i = 0; bt_attrs[i]; i++) 315 if (device_create_file(dev, bt_attrs[i]) < 0) 316 BT_ERR("Failed to create device attribute"); 317 318 return 0; 319} 320 321void hci_unregister_sysfs(struct hci_dev *hdev) 322{ 323 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 324 325 device_del(&hdev->dev); 326} 327 328int __init bt_sysfs_init(void) 329{ 330 int err; 331 332 bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); 333 if (IS_ERR(bt_platform)) 334 return PTR_ERR(bt_platform); 335 336 err = bus_register(&bt_bus); 337 if (err < 0) { 338 platform_device_unregister(bt_platform); 339 return err; 340 } 341 342 bt_class = class_create(THIS_MODULE, "bluetooth"); 343 if (IS_ERR(bt_class)) { 344 bus_unregister(&bt_bus); 345 platform_device_unregister(bt_platform); 346 return PTR_ERR(bt_class); 347 } 348 349 return 0; 350} 351 352void bt_sysfs_cleanup(void) 353{ 354 class_destroy(bt_class); 355 356 bus_unregister(&bt_bus); 357 358 platform_device_unregister(bt_platform); 359} 360