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 ATTRIBUTE_GROUPS(bt_link
);
54 static void bt_link_release(struct device
*dev
)
56 struct hci_conn
*conn
= to_hci_conn(dev
);
60 static struct device_type bt_link
= {
62 .groups
= bt_link_groups
,
63 .release
= bt_link_release
,
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.
71 static int __match_tty(struct device
*dev
, void *data
)
73 return !strncmp(dev_name(dev
), "rfcomm", 6);
76 void hci_conn_init_sysfs(struct hci_conn
*conn
)
78 struct hci_dev
*hdev
= conn
->hdev
;
80 BT_DBG("conn %p", conn
);
82 conn
->dev
.type
= &bt_link
;
83 conn
->dev
.class = bt_class
;
84 conn
->dev
.parent
= &hdev
->dev
;
86 device_initialize(&conn
->dev
);
89 void hci_conn_add_sysfs(struct hci_conn
*conn
)
91 struct hci_dev
*hdev
= conn
->hdev
;
93 BT_DBG("conn %p", conn
);
95 dev_set_name(&conn
->dev
, "%s:%d", hdev
->name
, conn
->handle
);
97 if (device_add(&conn
->dev
) < 0) {
98 BT_ERR("Failed to register connection device");
105 void hci_conn_del_sysfs(struct hci_conn
*conn
)
107 struct hci_dev
*hdev
= conn
->hdev
;
109 if (!device_is_registered(&conn
->dev
))
115 dev
= device_find_child(&conn
->dev
, NULL
, __match_tty
);
118 device_move(dev
, NULL
, DPM_ORDER_DEV_LAST
);
122 device_del(&conn
->dev
);
127 static inline char *host_typetostr(int type
)
139 static ssize_t
show_type(struct device
*dev
,
140 struct device_attribute
*attr
, char *buf
)
142 struct hci_dev
*hdev
= to_hci_dev(dev
);
143 return sprintf(buf
, "%s\n", host_typetostr(hdev
->dev_type
));
146 static ssize_t
show_name(struct device
*dev
,
147 struct device_attribute
*attr
, char *buf
)
149 struct hci_dev
*hdev
= to_hci_dev(dev
);
150 char name
[HCI_MAX_NAME_LENGTH
+ 1];
153 for (i
= 0; i
< HCI_MAX_NAME_LENGTH
; i
++)
154 name
[i
] = hdev
->dev_name
[i
];
156 name
[HCI_MAX_NAME_LENGTH
] = '\0';
157 return sprintf(buf
, "%s\n", name
);
160 static ssize_t
show_address(struct device
*dev
,
161 struct device_attribute
*attr
, char *buf
)
163 struct hci_dev
*hdev
= to_hci_dev(dev
);
164 return sprintf(buf
, "%pMR\n", &hdev
->bdaddr
);
167 static DEVICE_ATTR(type
, S_IRUGO
, show_type
, NULL
);
168 static DEVICE_ATTR(name
, S_IRUGO
, show_name
, NULL
);
169 static DEVICE_ATTR(address
, S_IRUGO
, show_address
, NULL
);
171 static struct attribute
*bt_host_attrs
[] = {
174 &dev_attr_address
.attr
,
178 ATTRIBUTE_GROUPS(bt_host
);
180 static void bt_host_release(struct device
*dev
)
182 struct hci_dev
*hdev
= to_hci_dev(dev
);
184 module_put(THIS_MODULE
);
187 static struct device_type bt_host
= {
189 .groups
= bt_host_groups
,
190 .release
= bt_host_release
,
193 void hci_init_sysfs(struct hci_dev
*hdev
)
195 struct device
*dev
= &hdev
->dev
;
197 dev
->type
= &bt_host
;
198 dev
->class = bt_class
;
200 __module_get(THIS_MODULE
);
201 device_initialize(dev
);
204 int __init
bt_sysfs_init(void)
206 bt_class
= class_create(THIS_MODULE
, "bluetooth");
208 return PTR_ERR_OR_ZERO(bt_class
);
211 void bt_sysfs_cleanup(void)
213 class_destroy(bt_class
);