Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24-rc8 411 lines 10 kB view raw
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 void del_conn(struct work_struct *work) 320{ 321 struct hci_conn *conn = container_of(work, struct hci_conn, work); 322 device_del(&conn->dev); 323 put_device(&conn->dev); 324} 325 326void hci_conn_del_sysfs(struct hci_conn *conn) 327{ 328 BT_DBG("conn %p", conn); 329 330 if (!device_is_registered(&conn->dev)) 331 return; 332 333 INIT_WORK(&conn->work, del_conn); 334 335 schedule_work(&conn->work); 336} 337 338int hci_register_sysfs(struct hci_dev *hdev) 339{ 340 struct device *dev = &hdev->dev; 341 unsigned int i; 342 int err; 343 344 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 345 346 dev->bus = &bt_bus; 347 dev->parent = hdev->parent; 348 349 strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE); 350 351 dev->release = bt_release; 352 353 dev_set_drvdata(dev, hdev); 354 355 err = device_register(dev); 356 if (err < 0) 357 return err; 358 359 for (i = 0; bt_attrs[i]; i++) 360 if (device_create_file(dev, bt_attrs[i]) < 0) 361 BT_ERR("Failed to create device attribute"); 362 363 if (sysfs_create_link(&bt_class->subsys.kobj, 364 &dev->kobj, kobject_name(&dev->kobj)) < 0) 365 BT_ERR("Failed to create class symlink"); 366 367 return 0; 368} 369 370void hci_unregister_sysfs(struct hci_dev *hdev) 371{ 372 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 373 374 sysfs_remove_link(&bt_class->subsys.kobj, 375 kobject_name(&hdev->dev.kobj)); 376 377 device_del(&hdev->dev); 378} 379 380int __init bt_sysfs_init(void) 381{ 382 int err; 383 384 bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); 385 if (IS_ERR(bt_platform)) 386 return PTR_ERR(bt_platform); 387 388 err = bus_register(&bt_bus); 389 if (err < 0) { 390 platform_device_unregister(bt_platform); 391 return err; 392 } 393 394 bt_class = class_create(THIS_MODULE, "bluetooth"); 395 if (IS_ERR(bt_class)) { 396 bus_unregister(&bt_bus); 397 platform_device_unregister(bt_platform); 398 return PTR_ERR(bt_class); 399 } 400 401 return 0; 402} 403 404void bt_sysfs_cleanup(void) 405{ 406 class_destroy(bt_class); 407 408 bus_unregister(&bt_bus); 409 410 platform_device_unregister(bt_platform); 411}