Root/
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 | |
8 | static struct class *bt_class; |
9 | |
10 | static 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 | |
26 | static 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 | |
33 | static 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) \ |
41 | struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) |
42 | |
43 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); |
44 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); |
45 | |
46 | static struct attribute *bt_link_attrs[] = { |
47 | &link_attr_type.attr, |
48 | &link_attr_address.attr, |
49 | NULL |
50 | }; |
51 | |
52 | ATTRIBUTE_GROUPS(bt_link); |
53 | |
54 | static void bt_link_release(struct device *dev) |
55 | { |
56 | struct hci_conn *conn = to_hci_conn(dev); |
57 | kfree(conn); |
58 | } |
59 | |
60 | static 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 | */ |
71 | static int __match_tty(struct device *dev, void *data) |
72 | { |
73 | return !strncmp(dev_name(dev), "rfcomm", 6); |
74 | } |
75 | |
76 | void 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 | |
89 | void 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 | |
105 | void 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 | |
127 | static 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 | |
139 | static 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 | |
146 | static 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 | |
160 | static 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 | |
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); |
170 | |
171 | static struct attribute *bt_host_attrs[] = { |
172 | &dev_attr_type.attr, |
173 | &dev_attr_name.attr, |
174 | &dev_attr_address.attr, |
175 | NULL |
176 | }; |
177 | |
178 | ATTRIBUTE_GROUPS(bt_host); |
179 | |
180 | static 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 | |
187 | static struct device_type bt_host = { |
188 | .name = "host", |
189 | .groups = bt_host_groups, |
190 | .release = bt_host_release, |
191 | }; |
192 | |
193 | void 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 | |
204 | int __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 | |
211 | void bt_sysfs_cleanup(void) |
212 | { |
213 | class_destroy(bt_class); |
214 | } |
215 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9