1 // SPDX-License-Identifier: GPL-2.0
2 /* Bluetooth HCI driver model support. */
3
4 #include <linux/module.h>
5
6 #include <net/bluetooth/bluetooth.h>
7 #include <net/bluetooth/hci_core.h>
8
9 static const struct class bt_class = {
10 .name = "bluetooth",
11 };
12
bt_link_release(struct device * dev)13 static void bt_link_release(struct device *dev)
14 {
15 struct hci_conn *conn = to_hci_conn(dev);
16 struct device *parent = dev->parent;
17
18 kfree(conn);
19 put_device(parent);
20 }
21
22 static const struct device_type bt_link = {
23 .name = "link",
24 .release = bt_link_release,
25 };
26
27 /*
28 * The rfcomm tty device will possibly retain even when conn
29 * is down, and sysfs doesn't support move zombie device,
30 * so we should move the device before conn device is destroyed.
31 */
__match_tty(struct device * dev,const void * data)32 static int __match_tty(struct device *dev, const void *data)
33 {
34 return !strncmp(dev_name(dev), "rfcomm", 6);
35 }
36
hci_conn_init_sysfs(struct hci_conn * conn)37 void hci_conn_init_sysfs(struct hci_conn *conn)
38 {
39 struct hci_dev *hdev = conn->hdev;
40
41 bt_dev_dbg(hdev, "conn %p", conn);
42
43 conn->dev.type = &bt_link;
44 conn->dev.class = &bt_class;
45 conn->dev.parent = get_device(&hdev->dev);
46
47 device_initialize(&conn->dev);
48 }
49
hci_conn_add_sysfs(struct hci_conn * conn)50 void hci_conn_add_sysfs(struct hci_conn *conn)
51 {
52 struct hci_dev *hdev = conn->hdev;
53
54 bt_dev_dbg(hdev, "conn %p", conn);
55
56 if (device_is_registered(&conn->dev))
57 return;
58
59 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
60
61 if (device_add(&conn->dev) < 0)
62 bt_dev_err(hdev, "failed to register connection device");
63 }
64
hci_conn_del_sysfs(struct hci_conn * conn)65 void hci_conn_del_sysfs(struct hci_conn *conn)
66 {
67 struct hci_dev *hdev = conn->hdev;
68
69 bt_dev_dbg(hdev, "conn %p", conn);
70
71 if (!device_is_registered(&conn->dev)) {
72 /* If device_add() has *not* succeeded, use *only* put_device()
73 * to drop the reference count.
74 */
75 put_device(&conn->dev);
76 return;
77 }
78
79 /* If there are devices using the connection as parent reset it to NULL
80 * before unregistering the device.
81 */
82 while (1) {
83 struct device *dev;
84
85 dev = device_find_child(&conn->dev, NULL, __match_tty);
86 if (!dev)
87 break;
88 device_move(dev, NULL, DPM_ORDER_DEV_LAST);
89 put_device(dev);
90 }
91
92 device_unregister(&conn->dev);
93 }
94
bt_host_release(struct device * dev)95 static void bt_host_release(struct device *dev)
96 {
97 struct hci_dev *hdev = to_hci_dev(dev);
98
99 if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
100 hci_release_dev(hdev);
101 } else {
102 cleanup_srcu_struct(&hdev->srcu);
103 kfree(hdev);
104 }
105 module_put(THIS_MODULE);
106 }
107
reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)108 static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
109 const char *buf, size_t count)
110 {
111 struct hci_dev *hdev = to_hci_dev(dev);
112
113 if (hdev->reset)
114 hdev->reset(hdev);
115
116 return count;
117 }
118 static DEVICE_ATTR_WO(reset);
119
120 static struct attribute *bt_host_attrs[] = {
121 &dev_attr_reset.attr,
122 NULL,
123 };
124 ATTRIBUTE_GROUPS(bt_host);
125
126 static const struct device_type bt_host = {
127 .name = "host",
128 .release = bt_host_release,
129 .groups = bt_host_groups,
130 };
131
hci_init_sysfs(struct hci_dev * hdev)132 void hci_init_sysfs(struct hci_dev *hdev)
133 {
134 struct device *dev = &hdev->dev;
135
136 dev->type = &bt_host;
137 dev->class = &bt_class;
138
139 __module_get(THIS_MODULE);
140 device_initialize(dev);
141 }
142
bt_sysfs_init(void)143 int __init bt_sysfs_init(void)
144 {
145 return class_register(&bt_class);
146 }
147
bt_sysfs_cleanup(void)148 void bt_sysfs_cleanup(void)
149 {
150 class_unregister(&bt_class);
151 }
152