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 40#define LINK_ATTR(_name, _mode, _show, _store) \ 41struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) 42 43static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); 44static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); 45 46static struct attribute *bt_link_attrs[] = { 47 &link_attr_type.attr, 48 &link_attr_address.attr, 49 NULL 50}; 51 52ATTRIBUTE_GROUPS(bt_link); 53 54static void bt_link_release(struct device *dev) 55{ 56 struct hci_conn *conn = to_hci_conn(dev); 57 kfree(conn); 58} 59 60static struct device_type bt_link = { 61 .name = "link", 62 .groups = bt_link_groups, 63 .release = bt_link_release, 64}; 65 66/* 67 * The rfcomm tty device will possibly retain even when conn 68 * is down, and sysfs doesn't support move zombie device, 69 * so we should move the device before conn device is destroyed. 70 */ 71static int __match_tty(struct device *dev, void *data) 72{ 73 return !strncmp(dev_name(dev), "rfcomm", 6); 74} 75 76void hci_conn_init_sysfs(struct hci_conn *conn) 77{ 78 struct hci_dev *hdev = conn->hdev; 79 80 BT_DBG("conn %p", conn); 81 82 conn->dev.type = &bt_link; 83 conn->dev.class = bt_class; 84 conn->dev.parent = &hdev->dev; 85 86 device_initialize(&conn->dev); 87} 88 89void hci_conn_add_sysfs(struct hci_conn *conn) 90{ 91 struct hci_dev *hdev = conn->hdev; 92 93 BT_DBG("conn %p", conn); 94 95 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); 96 97 if (device_add(&conn->dev) < 0) { 98 BT_ERR("Failed to register connection device"); 99 return; 100 } 101 102 hci_dev_hold(hdev); 103} 104 105void hci_conn_del_sysfs(struct hci_conn *conn) 106{ 107 struct hci_dev *hdev = conn->hdev; 108 109 if (!device_is_registered(&conn->dev)) 110 return; 111 112 while (1) { 113 struct device *dev; 114 115 dev = device_find_child(&conn->dev, NULL, __match_tty); 116 if (!dev) 117 break; 118 device_move(dev, NULL, DPM_ORDER_DEV_LAST); 119 put_device(dev); 120 } 121 122 device_del(&conn->dev); 123 124 hci_dev_put(hdev); 125} 126 127static inline char *host_typetostr(int type) 128{ 129 switch (type) { 130 case HCI_BREDR: 131 return "BR/EDR"; 132 case HCI_AMP: 133 return "AMP"; 134 default: 135 return "UNKNOWN"; 136 } 137} 138 139static ssize_t show_type(struct device *dev, 140 struct device_attribute *attr, char *buf) 141{ 142 struct hci_dev *hdev = to_hci_dev(dev); 143 return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); 144} 145 146static ssize_t show_name(struct device *dev, 147 struct device_attribute *attr, char *buf) 148{ 149 struct hci_dev *hdev = to_hci_dev(dev); 150 char name[HCI_MAX_NAME_LENGTH + 1]; 151 int i; 152 153 for (i = 0; i < HCI_MAX_NAME_LENGTH; i++) 154 name[i] = hdev->dev_name[i]; 155 156 name[HCI_MAX_NAME_LENGTH] = '\0'; 157 return sprintf(buf, "%s\n", name); 158} 159 160static ssize_t show_address(struct device *dev, 161 struct device_attribute *attr, char *buf) 162{ 163 struct hci_dev *hdev = to_hci_dev(dev); 164 return sprintf(buf, "%pMR\n", &hdev->bdaddr); 165} 166 167static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); 168static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 169static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); 170 171static struct attribute *bt_host_attrs[] = { 172 &dev_attr_type.attr, 173 &dev_attr_name.attr, 174 &dev_attr_address.attr, 175 NULL 176}; 177 178ATTRIBUTE_GROUPS(bt_host); 179 180static void bt_host_release(struct device *dev) 181{ 182 struct hci_dev *hdev = to_hci_dev(dev); 183 kfree(hdev); 184 module_put(THIS_MODULE); 185} 186 187static struct device_type bt_host = { 188 .name = "host", 189 .groups = bt_host_groups, 190 .release = bt_host_release, 191}; 192 193void hci_init_sysfs(struct hci_dev *hdev) 194{ 195 struct device *dev = &hdev->dev; 196 197 dev->type = &bt_host; 198 dev->class = bt_class; 199 200 __module_get(THIS_MODULE); 201 device_initialize(dev); 202} 203 204int __init bt_sysfs_init(void) 205{ 206 bt_class = class_create(THIS_MODULE, "bluetooth"); 207 208 return PTR_ERR_OR_ZERO(bt_class); 209} 210 211void bt_sysfs_cleanup(void) 212{ 213 class_destroy(bt_class); 214} 215