hci_sysfs.c revision c4028958b6ecad064b1a6303a6a5906d4fe48d73
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(struct work_struct *work) 241{ 242 struct hci_conn *conn = container_of(work, struct hci_conn, work); 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.bus = &bt_bus; 263 conn->dev.parent = &hdev->dev; 264 265 conn->dev.release = bt_release; 266 267 snprintf(conn->dev.bus_id, BUS_ID_SIZE, 268 "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", 269 conn->type == ACL_LINK ? "acl" : "sco", 270 ba->b[5], ba->b[4], ba->b[3], 271 ba->b[2], ba->b[1], ba->b[0]); 272 273 dev_set_drvdata(&conn->dev, conn); 274 275 INIT_WORK(&conn->work, add_conn); 276 277 schedule_work(&conn->work); 278} 279 280static void del_conn(struct work_struct *work) 281{ 282 struct hci_conn *conn = container_of(work, struct hci_conn, work); 283 device_del(&conn->dev); 284} 285 286void hci_conn_del_sysfs(struct hci_conn *conn) 287{ 288 BT_DBG("conn %p", conn); 289 290 INIT_WORK(&conn->work, del_conn); 291 292 schedule_work(&conn->work); 293} 294 295int hci_register_sysfs(struct hci_dev *hdev) 296{ 297 struct device *dev = &hdev->dev; 298 unsigned int i; 299 int err; 300 301 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 302 303 dev->class = bt_class; 304 dev->parent = hdev->parent; 305 306 strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); 307 308 dev->release = bt_release; 309 310 dev_set_drvdata(dev, hdev); 311 312 err = device_register(dev); 313 if (err < 0) 314 return err; 315 316 for (i = 0; bt_attrs[i]; i++) 317 if (device_create_file(dev, bt_attrs[i]) < 0) 318 BT_ERR("Failed to create device attribute"); 319 320 return 0; 321} 322 323void hci_unregister_sysfs(struct hci_dev *hdev) 324{ 325 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 326 327 device_del(&hdev->dev); 328} 329 330int __init bt_sysfs_init(void) 331{ 332 int err; 333 334 bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); 335 if (IS_ERR(bt_platform)) 336 return PTR_ERR(bt_platform); 337 338 err = bus_register(&bt_bus); 339 if (err < 0) { 340 platform_device_unregister(bt_platform); 341 return err; 342 } 343 344 bt_class = class_create(THIS_MODULE, "bluetooth"); 345 if (IS_ERR(bt_class)) { 346 bus_unregister(&bt_bus); 347 platform_device_unregister(bt_platform); 348 return PTR_ERR(bt_class); 349 } 350 351 return 0; 352} 353 354void bt_sysfs_cleanup(void) 355{ 356 class_destroy(bt_class); 357 358 bus_unregister(&bt_bus); 359 360 platform_device_unregister(bt_platform); 361} 362