hci_sysfs.c revision dfb826a8b07f23ca31156979a7effec7b1f1daa8
1/* Bluetooth HCI driver model support. */ 2 3#include <linux/module.h> 4 5#include <net/bluetooth/bluetooth.h> 6#include <net/bluetooth/hci_core.h> 7 8static struct class *bt_class; 9 10static inline char *link_typetostr(int type) 11{ 12 switch (type) { 13 case ACL_LINK: 14 return "ACL"; 15 case SCO_LINK: 16 return "SCO"; 17 case ESCO_LINK: 18 return "eSCO"; 19 case LE_LINK: 20 return "LE"; 21 default: 22 return "UNKNOWN"; 23 } 24} 25 26static ssize_t show_link_type(struct device *dev, 27 struct device_attribute *attr, char *buf) 28{ 29 struct hci_conn *conn = to_hci_conn(dev); 30 return sprintf(buf, "%s\n", link_typetostr(conn->type)); 31} 32 33static ssize_t show_link_address(struct device *dev, 34 struct device_attribute *attr, char *buf) 35{ 36 struct hci_conn *conn = to_hci_conn(dev); 37 return sprintf(buf, "%pMR\n", &conn->dst); 38} 39 40static ssize_t show_link_features(struct device *dev, 41 struct device_attribute *attr, char *buf) 42{ 43 struct hci_conn *conn = to_hci_conn(dev); 44 45 return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", 46 conn->features[0][0], conn->features[0][1], 47 conn->features[0][2], conn->features[0][3], 48 conn->features[0][4], conn->features[0][5], 49 conn->features[0][6], conn->features[0][7]); 50} 51 52#define LINK_ATTR(_name, _mode, _show, _store) \ 53struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) 54 55static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); 56static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); 57static LINK_ATTR(features, S_IRUGO, show_link_features, NULL); 58 59static struct attribute *bt_link_attrs[] = { 60 &link_attr_type.attr, 61 &link_attr_address.attr, 62 &link_attr_features.attr, 63 NULL 64}; 65 66static struct attribute_group bt_link_group = { 67 .attrs = bt_link_attrs, 68}; 69 70static const struct attribute_group *bt_link_groups[] = { 71 &bt_link_group, 72 NULL 73}; 74 75static void bt_link_release(struct device *dev) 76{ 77 struct hci_conn *conn = to_hci_conn(dev); 78 kfree(conn); 79} 80 81static struct device_type bt_link = { 82 .name = "link", 83 .groups = bt_link_groups, 84 .release = bt_link_release, 85}; 86 87/* 88 * The rfcomm tty device will possibly retain even when conn 89 * is down, and sysfs doesn't support move zombie device, 90 * so we should move the device before conn device is destroyed. 91 */ 92static int __match_tty(struct device *dev, void *data) 93{ 94 return !strncmp(dev_name(dev), "rfcomm", 6); 95} 96 97void hci_conn_init_sysfs(struct hci_conn *conn) 98{ 99 struct hci_dev *hdev = conn->hdev; 100 101 BT_DBG("conn %p", conn); 102 103 conn->dev.type = &bt_link; 104 conn->dev.class = bt_class; 105 conn->dev.parent = &hdev->dev; 106 107 device_initialize(&conn->dev); 108} 109 110void hci_conn_add_sysfs(struct hci_conn *conn) 111{ 112 struct hci_dev *hdev = conn->hdev; 113 114 BT_DBG("conn %p", conn); 115 116 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); 117 118 if (device_add(&conn->dev) < 0) { 119 BT_ERR("Failed to register connection device"); 120 return; 121 } 122 123 hci_dev_hold(hdev); 124} 125 126void hci_conn_del_sysfs(struct hci_conn *conn) 127{ 128 struct hci_dev *hdev = conn->hdev; 129 130 if (!device_is_registered(&conn->dev)) 131 return; 132 133 while (1) { 134 struct device *dev; 135 136 dev = device_find_child(&conn->dev, NULL, __match_tty); 137 if (!dev) 138 break; 139 device_move(dev, NULL, DPM_ORDER_DEV_LAST); 140 put_device(dev); 141 } 142 143 device_del(&conn->dev); 144 145 hci_dev_put(hdev); 146} 147 148static inline char *host_bustostr(int bus) 149{ 150 switch (bus) { 151 case HCI_VIRTUAL: 152 return "VIRTUAL"; 153 case HCI_USB: 154 return "USB"; 155 case HCI_PCCARD: 156 return "PCCARD"; 157 case HCI_UART: 158 return "UART"; 159 case HCI_RS232: 160 return "RS232"; 161 case HCI_PCI: 162 return "PCI"; 163 case HCI_SDIO: 164 return "SDIO"; 165 default: 166 return "UNKNOWN"; 167 } 168} 169 170static inline char *host_typetostr(int type) 171{ 172 switch (type) { 173 case HCI_BREDR: 174 return "BR/EDR"; 175 case HCI_AMP: 176 return "AMP"; 177 default: 178 return "UNKNOWN"; 179 } 180} 181 182static ssize_t show_bus(struct device *dev, 183 struct device_attribute *attr, char *buf) 184{ 185 struct hci_dev *hdev = to_hci_dev(dev); 186 return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); 187} 188 189static ssize_t show_type(struct device *dev, 190 struct device_attribute *attr, char *buf) 191{ 192 struct hci_dev *hdev = to_hci_dev(dev); 193 return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); 194} 195 196static ssize_t show_name(struct device *dev, 197 struct device_attribute *attr, char *buf) 198{ 199 struct hci_dev *hdev = to_hci_dev(dev); 200 char name[HCI_MAX_NAME_LENGTH + 1]; 201 int i; 202 203 for (i = 0; i < HCI_MAX_NAME_LENGTH; i++) 204 name[i] = hdev->dev_name[i]; 205 206 name[HCI_MAX_NAME_LENGTH] = '\0'; 207 return sprintf(buf, "%s\n", name); 208} 209 210static ssize_t show_class(struct device *dev, 211 struct device_attribute *attr, char *buf) 212{ 213 struct hci_dev *hdev = to_hci_dev(dev); 214 return sprintf(buf, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], 215 hdev->dev_class[1], hdev->dev_class[0]); 216} 217 218static ssize_t show_address(struct device *dev, 219 struct device_attribute *attr, char *buf) 220{ 221 struct hci_dev *hdev = to_hci_dev(dev); 222 return sprintf(buf, "%pMR\n", &hdev->bdaddr); 223} 224 225static ssize_t show_manufacturer(struct device *dev, 226 struct device_attribute *attr, char *buf) 227{ 228 struct hci_dev *hdev = to_hci_dev(dev); 229 return sprintf(buf, "%d\n", hdev->manufacturer); 230} 231 232static ssize_t show_hci_version(struct device *dev, 233 struct device_attribute *attr, char *buf) 234{ 235 struct hci_dev *hdev = to_hci_dev(dev); 236 return sprintf(buf, "%d\n", hdev->hci_ver); 237} 238 239static ssize_t show_hci_revision(struct device *dev, 240 struct device_attribute *attr, char *buf) 241{ 242 struct hci_dev *hdev = to_hci_dev(dev); 243 return sprintf(buf, "%d\n", hdev->hci_rev); 244} 245 246static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); 247static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); 248static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 249static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); 250static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); 251static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); 252static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); 253static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); 254 255static struct attribute *bt_host_attrs[] = { 256 &dev_attr_bus.attr, 257 &dev_attr_type.attr, 258 &dev_attr_name.attr, 259 &dev_attr_class.attr, 260 &dev_attr_address.attr, 261 &dev_attr_manufacturer.attr, 262 &dev_attr_hci_version.attr, 263 &dev_attr_hci_revision.attr, 264 NULL 265}; 266 267static struct attribute_group bt_host_group = { 268 .attrs = bt_host_attrs, 269}; 270 271static const struct attribute_group *bt_host_groups[] = { 272 &bt_host_group, 273 NULL 274}; 275 276static void bt_host_release(struct device *dev) 277{ 278 struct hci_dev *hdev = to_hci_dev(dev); 279 kfree(hdev); 280 module_put(THIS_MODULE); 281} 282 283static struct device_type bt_host = { 284 .name = "host", 285 .groups = bt_host_groups, 286 .release = bt_host_release, 287}; 288 289void hci_init_sysfs(struct hci_dev *hdev) 290{ 291 struct device *dev = &hdev->dev; 292 293 dev->type = &bt_host; 294 dev->class = bt_class; 295 296 __module_get(THIS_MODULE); 297 device_initialize(dev); 298} 299 300int __init bt_sysfs_init(void) 301{ 302 bt_class = class_create(THIS_MODULE, "bluetooth"); 303 304 return PTR_ERR_OR_ZERO(bt_class); 305} 306 307void bt_sysfs_cleanup(void) 308{ 309 class_destroy(bt_class); 310} 311