diff options
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 135 |
1 files changed, 119 insertions, 16 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 3987d167f04e..989b22d9042e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -13,16 +13,32 @@ | |||
13 | #define BT_DBG(D...) | 13 | #define BT_DBG(D...) |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) | 16 | static inline char *typetostr(int type) |
17 | { | 17 | { |
18 | struct hci_dev *hdev = dev_get_drvdata(dev); | 18 | switch (type) { |
19 | return sprintf(buf, "%s\n", hdev->name); | 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 | } | ||
20 | } | 36 | } |
21 | 37 | ||
22 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) | 38 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) |
23 | { | 39 | { |
24 | struct hci_dev *hdev = dev_get_drvdata(dev); | 40 | struct hci_dev *hdev = dev_get_drvdata(dev); |
25 | return sprintf(buf, "%d\n", hdev->type); | 41 | return sprintf(buf, "%s\n", typetostr(hdev->type)); |
26 | } | 42 | } |
27 | 43 | ||
28 | static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) | 44 | static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -33,10 +49,22 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c | |||
33 | return sprintf(buf, "%s\n", batostr(&bdaddr)); | 49 | return sprintf(buf, "%s\n", batostr(&bdaddr)); |
34 | } | 50 | } |
35 | 51 | ||
36 | static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf) | 52 | static 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 | |||
58 | static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) | ||
37 | { | 59 | { |
38 | struct hci_dev *hdev = dev_get_drvdata(dev); | 60 | struct hci_dev *hdev = dev_get_drvdata(dev); |
39 | return sprintf(buf, "0x%lx\n", hdev->flags); | 61 | return sprintf(buf, "%d\n", hdev->hci_ver); |
62 | } | ||
63 | |||
64 | static 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); | ||
40 | } | 68 | } |
41 | 69 | ||
42 | static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) | 70 | static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -141,10 +169,11 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib | |||
141 | return count; | 169 | return count; |
142 | } | 170 | } |
143 | 171 | ||
144 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
145 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | 172 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); |
146 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | 173 | static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); |
147 | static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); | 174 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); |
175 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); | ||
176 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); | ||
148 | static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); | 177 | static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); |
149 | 178 | ||
150 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, | 179 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, |
@@ -155,10 +184,11 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, | |||
155 | show_sniff_min_interval, store_sniff_min_interval); | 184 | show_sniff_min_interval, store_sniff_min_interval); |
156 | 185 | ||
157 | static struct device_attribute *bt_attrs[] = { | 186 | static struct device_attribute *bt_attrs[] = { |
158 | &dev_attr_name, | ||
159 | &dev_attr_type, | 187 | &dev_attr_type, |
160 | &dev_attr_address, | 188 | &dev_attr_address, |
161 | &dev_attr_flags, | 189 | &dev_attr_manufacturer, |
190 | &dev_attr_hci_version, | ||
191 | &dev_attr_hci_revision, | ||
162 | &dev_attr_inquiry_cache, | 192 | &dev_attr_inquiry_cache, |
163 | &dev_attr_idle_timeout, | 193 | &dev_attr_idle_timeout, |
164 | &dev_attr_sniff_max_interval, | 194 | &dev_attr_sniff_max_interval, |
@@ -166,6 +196,32 @@ static struct device_attribute *bt_attrs[] = { | |||
166 | NULL | 196 | NULL |
167 | }; | 197 | }; |
168 | 198 | ||
199 | static 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 | |||
205 | static 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) \ | ||
214 | struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store) | ||
215 | |||
216 | static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL); | ||
217 | static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL); | ||
218 | |||
219 | static struct device_attribute *conn_attrs[] = { | ||
220 | &conn_attr_type, | ||
221 | &conn_attr_address, | ||
222 | NULL | ||
223 | }; | ||
224 | |||
169 | struct class *bt_class = NULL; | 225 | struct class *bt_class = NULL; |
170 | EXPORT_SYMBOL_GPL(bt_class); | 226 | EXPORT_SYMBOL_GPL(bt_class); |
171 | 227 | ||
@@ -177,8 +233,57 @@ static struct platform_device *bt_platform; | |||
177 | 233 | ||
178 | static void bt_release(struct device *dev) | 234 | static void bt_release(struct device *dev) |
179 | { | 235 | { |
180 | struct hci_dev *hdev = dev_get_drvdata(dev); | 236 | void *data = dev_get_drvdata(dev); |
181 | kfree(hdev); | 237 | kfree(data); |
238 | } | ||
239 | |||
240 | static void add_conn(void *data) | ||
241 | { | ||
242 | struct hci_conn *conn = data; | ||
243 | int i; | ||
244 | |||
245 | device_register(&conn->dev); | ||
246 | |||
247 | for (i = 0; conn_attrs[i]; i++) | ||
248 | device_create_file(&conn->dev, conn_attrs[i]); | ||
249 | } | ||
250 | |||
251 | void hci_conn_add_sysfs(struct hci_conn *conn) | ||
252 | { | ||
253 | struct hci_dev *hdev = conn->hdev; | ||
254 | bdaddr_t *ba = &conn->dst; | ||
255 | |||
256 | BT_DBG("conn %p", conn); | ||
257 | |||
258 | conn->dev.parent = &hdev->dev; | ||
259 | conn->dev.release = bt_release; | ||
260 | |||
261 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, | ||
262 | "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", | ||
263 | conn->type == ACL_LINK ? "acl" : "sco", | ||
264 | ba->b[5], ba->b[4], ba->b[3], | ||
265 | ba->b[2], ba->b[1], ba->b[0]); | ||
266 | |||
267 | dev_set_drvdata(&conn->dev, conn); | ||
268 | |||
269 | INIT_WORK(&conn->work, add_conn, (void *) conn); | ||
270 | |||
271 | schedule_work(&conn->work); | ||
272 | } | ||
273 | |||
274 | static void del_conn(void *data) | ||
275 | { | ||
276 | struct hci_conn *conn = data; | ||
277 | device_del(&conn->dev); | ||
278 | } | ||
279 | |||
280 | void hci_conn_del_sysfs(struct hci_conn *conn) | ||
281 | { | ||
282 | BT_DBG("conn %p", conn); | ||
283 | |||
284 | INIT_WORK(&conn->work, del_conn, (void *) conn); | ||
285 | |||
286 | schedule_work(&conn->work); | ||
182 | } | 287 | } |
183 | 288 | ||
184 | int hci_register_sysfs(struct hci_dev *hdev) | 289 | int hci_register_sysfs(struct hci_dev *hdev) |
@@ -214,11 +319,9 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
214 | 319 | ||
215 | void hci_unregister_sysfs(struct hci_dev *hdev) | 320 | void hci_unregister_sysfs(struct hci_dev *hdev) |
216 | { | 321 | { |
217 | struct device *dev = &hdev->dev; | ||
218 | |||
219 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 322 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); |
220 | 323 | ||
221 | device_del(dev); | 324 | device_del(&hdev->dev); |
222 | } | 325 | } |
223 | 326 | ||
224 | int __init bt_sysfs_init(void) | 327 | int __init bt_sysfs_init(void) |
@@ -245,7 +348,7 @@ int __init bt_sysfs_init(void) | |||
245 | return 0; | 348 | return 0; |
246 | } | 349 | } |
247 | 350 | ||
248 | void __exit bt_sysfs_cleanup(void) | 351 | void bt_sysfs_cleanup(void) |
249 | { | 352 | { |
250 | class_destroy(bt_class); | 353 | class_destroy(bt_class); |
251 | 354 | ||