1 /* Bluetooth HCI driver model support. */
3 #include <linux/module.h>
5 #include <net/bluetooth/bluetooth.h>
6 #include <net/bluetooth/hci_core.h>
8 static struct class *bt_class
;
10 static inline char *link_typetostr(int type
)
26 static ssize_t
show_link_type(struct device
*dev
,
27 struct device_attribute
*attr
, char *buf
)
29 struct hci_conn
*conn
= to_hci_conn(dev
);
30 return sprintf(buf
, "%s\n", link_typetostr(conn
->type
));
33 static ssize_t
show_link_address(struct device
*dev
,
34 struct device_attribute
*attr
, char *buf
)
36 struct hci_conn
*conn
= to_hci_conn(dev
);
37 return sprintf(buf
, "%pMR\n", &conn
->dst
);
40 #define LINK_ATTR(_name, _mode, _show, _store) \
41 struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store)
43 static LINK_ATTR(type
, S_IRUGO
, show_link_type
, NULL
);
44 static LINK_ATTR(address
, S_IRUGO
, show_link_address
, NULL
);
46 static struct attribute
*bt_link_attrs
[] = {
48 &link_attr_address
.attr
,
52 static struct attribute_group bt_link_group
= {
53 .attrs
= bt_link_attrs
,
56 static const struct attribute_group
*bt_link_groups
[] = {
61 static void bt_link_release(struct device
*dev
)
63 struct hci_conn
*conn
= to_hci_conn(dev
);
67 static struct device_type bt_link
= {
69 .groups
= bt_link_groups
,
70 .release
= bt_link_release
,
74 * The rfcomm tty device will possibly retain even when conn
75 * is down, and sysfs doesn't support move zombie device,
76 * so we should move the device before conn device is destroyed.
78 static int __match_tty(struct device
*dev
, void *data
)
80 return !strncmp(dev_name(dev
), "rfcomm", 6);
83 void hci_conn_init_sysfs(struct hci_conn
*conn
)
85 struct hci_dev
*hdev
= conn
->hdev
;
87 BT_DBG("conn %p", conn
);
89 conn
->dev
.type
= &bt_link
;
90 conn
->dev
.class = bt_class
;
91 conn
->dev
.parent
= &hdev
->dev
;
93 device_initialize(&conn
->dev
);
96 void hci_conn_add_sysfs(struct hci_conn
*conn
)
98 struct hci_dev
*hdev
= conn
->hdev
;
100 BT_DBG("conn %p", conn
);
102 dev_set_name(&conn
->dev
, "%s:%d", hdev
->name
, conn
->handle
);
104 if (device_add(&conn
->dev
) < 0) {
105 BT_ERR("Failed to register connection device");
112 void hci_conn_del_sysfs(struct hci_conn
*conn
)
114 struct hci_dev
*hdev
= conn
->hdev
;
116 if (!device_is_registered(&conn
->dev
))
122 dev
= device_find_child(&conn
->dev
, NULL
, __match_tty
);
125 device_move(dev
, NULL
, DPM_ORDER_DEV_LAST
);
129 device_del(&conn
->dev
);
134 static inline char *host_typetostr(int type
)
146 static ssize_t
show_type(struct device
*dev
,
147 struct device_attribute
*attr
, char *buf
)
149 struct hci_dev
*hdev
= to_hci_dev(dev
);
150 return sprintf(buf
, "%s\n", host_typetostr(hdev
->dev_type
));
153 static ssize_t
show_name(struct device
*dev
,
154 struct device_attribute
*attr
, char *buf
)
156 struct hci_dev
*hdev
= to_hci_dev(dev
);
157 char name
[HCI_MAX_NAME_LENGTH
+ 1];
160 for (i
= 0; i
< HCI_MAX_NAME_LENGTH
; i
++)
161 name
[i
] = hdev
->dev_name
[i
];
163 name
[HCI_MAX_NAME_LENGTH
] = '\0';
164 return sprintf(buf
, "%s\n", name
);
167 static ssize_t
show_address(struct device
*dev
,
168 struct device_attribute
*attr
, char *buf
)
170 struct hci_dev
*hdev
= to_hci_dev(dev
);
171 return sprintf(buf
, "%pMR\n", &hdev
->bdaddr
);
174 static DEVICE_ATTR(type
, S_IRUGO
, show_type
, NULL
);
175 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
176 static DEVICE_ATTR(address
, S_IRUGO
, show_address
, NULL
);
178 static struct attribute
*bt_host_attrs
[] = {
181 &dev_attr_address
.attr
,
185 static struct attribute_group bt_host_group
= {
186 .attrs
= bt_host_attrs
,
189 static const struct attribute_group
*bt_host_groups
[] = {
194 static void bt_host_release(struct device
*dev
)
196 struct hci_dev
*hdev
= to_hci_dev(dev
);
198 module_put(THIS_MODULE
);
201 static struct device_type bt_host
= {
203 .groups
= bt_host_groups
,
204 .release
= bt_host_release
,
207 void hci_init_sysfs(struct hci_dev
*hdev
)
209 struct device
*dev
= &hdev
->dev
;
211 dev
->type
= &bt_host
;
212 dev
->class = bt_class
;
214 __module_get(THIS_MODULE
);
215 device_initialize(dev
);
218 int __init
bt_sysfs_init(void)
220 bt_class
= class_create(THIS_MODULE
, "bluetooth");
222 return PTR_ERR_OR_ZERO(bt_class
);
225 void bt_sysfs_cleanup(void)
227 class_destroy(bt_class
);