aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-07-03 04:02:41 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-07-03 22:54:02 -0400
commita91f2e396f5b32b21d842b4757bc8de5e88eac66 (patch)
tree174b88a20feea87734bf63ec7104eae0b205649a
parent27d35284258c596900e0e41c46932ec4abe6a7b1 (diff)
[Bluetooth] Use real devices for host controllers
This patch converts the Bluetooth class devices into real devices. The Bluetooth class is kept and the driver core provides the appropriate symlinks for backward compatibility. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/bluetooth/hci_core.h6
-rw-r--r--net/bluetooth/hci_core.c4
-rw-r--r--net/bluetooth/hci_sysfs.c152
-rw-r--r--net/bluetooth/l2cap.c4
-rw-r--r--net/bluetooth/rfcomm/core.c4
-rw-r--r--net/bluetooth/rfcomm/sock.c4
-rw-r--r--net/bluetooth/sco.c4
8 files changed, 79 insertions, 101 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 911ceb5cd263..771d17783c18 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -175,6 +175,6 @@ extern int hci_sock_cleanup(void);
175extern int bt_sysfs_init(void); 175extern int bt_sysfs_init(void);
176extern void bt_sysfs_cleanup(void); 176extern void bt_sysfs_cleanup(void);
177 177
178extern struct class bt_class; 178extern struct class *bt_class;
179 179
180#endif /* __BLUETOOTH_H */ 180#endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ae67b36d76dc..d84855fe7336 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -124,8 +124,8 @@ struct hci_dev {
124 124
125 atomic_t promisc; 125 atomic_t promisc;
126 126
127 struct device *dev; 127 struct device *parent;
128 struct class_device class_dev; 128 struct device dev;
129 129
130 struct module *owner; 130 struct module *owner;
131 131
@@ -413,7 +413,7 @@ static inline int hci_recv_frame(struct sk_buff *skb)
413int hci_register_sysfs(struct hci_dev *hdev); 413int hci_register_sysfs(struct hci_dev *hdev);
414void hci_unregister_sysfs(struct hci_dev *hdev); 414void hci_unregister_sysfs(struct hci_dev *hdev);
415 415
416#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->class_dev.dev = (pdev)) 416#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
417 417
418/* ----- LMP capabilities ----- */ 418/* ----- LMP capabilities ----- */
419#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) 419#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3f9f1565bf06..54e8e5ea2154 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -817,8 +817,8 @@ void hci_free_dev(struct hci_dev *hdev)
817{ 817{
818 skb_queue_purge(&hdev->driver_init); 818 skb_queue_purge(&hdev->driver_init);
819 819
820 /* will free via class release */ 820 /* will free via device release */
821 class_device_put(&hdev->class_dev); 821 put_device(&hdev->dev);
822} 822}
823EXPORT_SYMBOL(hci_free_dev); 823EXPORT_SYMBOL(hci_free_dev);
824 824
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 7789e26c84b9..3987d167f04e 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -13,35 +13,35 @@
13#define BT_DBG(D...) 13#define BT_DBG(D...)
14#endif 14#endif
15 15
16static ssize_t show_name(struct class_device *cdev, char *buf) 16static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
17{ 17{
18 struct hci_dev *hdev = class_get_devdata(cdev); 18 struct hci_dev *hdev = dev_get_drvdata(dev);
19 return sprintf(buf, "%s\n", hdev->name); 19 return sprintf(buf, "%s\n", hdev->name);
20} 20}
21 21
22static ssize_t show_type(struct class_device *cdev, char *buf) 22static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
23{ 23{
24 struct hci_dev *hdev = class_get_devdata(cdev); 24 struct hci_dev *hdev = dev_get_drvdata(dev);
25 return sprintf(buf, "%d\n", hdev->type); 25 return sprintf(buf, "%d\n", hdev->type);
26} 26}
27 27
28static ssize_t show_address(struct class_device *cdev, char *buf) 28static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
29{ 29{
30 struct hci_dev *hdev = class_get_devdata(cdev); 30 struct hci_dev *hdev = dev_get_drvdata(dev);
31 bdaddr_t bdaddr; 31 bdaddr_t bdaddr;
32 baswap(&bdaddr, &hdev->bdaddr); 32 baswap(&bdaddr, &hdev->bdaddr);
33 return sprintf(buf, "%s\n", batostr(&bdaddr)); 33 return sprintf(buf, "%s\n", batostr(&bdaddr));
34} 34}
35 35
36static ssize_t show_flags(struct class_device *cdev, char *buf) 36static ssize_t show_flags(struct device *dev, struct device_attribute *attr, char *buf)
37{ 37{
38 struct hci_dev *hdev = class_get_devdata(cdev); 38 struct hci_dev *hdev = dev_get_drvdata(dev);
39 return sprintf(buf, "0x%lx\n", hdev->flags); 39 return sprintf(buf, "0x%lx\n", hdev->flags);
40} 40}
41 41
42static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf) 42static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
43{ 43{
44 struct hci_dev *hdev = class_get_devdata(cdev); 44 struct hci_dev *hdev = dev_get_drvdata(dev);
45 struct inquiry_cache *cache = &hdev->inq_cache; 45 struct inquiry_cache *cache = &hdev->inq_cache;
46 struct inquiry_entry *e; 46 struct inquiry_entry *e;
47 int n = 0; 47 int n = 0;
@@ -63,15 +63,15 @@ static ssize_t show_inquiry_cache(struct class_device *cdev, char *buf)
63 return n; 63 return n;
64} 64}
65 65
66static ssize_t show_idle_timeout(struct class_device *cdev, char *buf) 66static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf)
67{ 67{
68 struct hci_dev *hdev = class_get_devdata(cdev); 68 struct hci_dev *hdev = dev_get_drvdata(dev);
69 return sprintf(buf, "%d\n", hdev->idle_timeout); 69 return sprintf(buf, "%d\n", hdev->idle_timeout);
70} 70}
71 71
72static ssize_t store_idle_timeout(struct class_device *cdev, const char *buf, size_t count) 72static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
73{ 73{
74 struct hci_dev *hdev = class_get_devdata(cdev); 74 struct hci_dev *hdev = dev_get_drvdata(dev);
75 char *ptr; 75 char *ptr;
76 __u32 val; 76 __u32 val;
77 77
@@ -87,15 +87,15 @@ static ssize_t store_idle_timeout(struct class_device *cdev, const char *buf, si
87 return count; 87 return count;
88} 88}
89 89
90static ssize_t show_sniff_max_interval(struct class_device *cdev, char *buf) 90static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf)
91{ 91{
92 struct hci_dev *hdev = class_get_devdata(cdev); 92 struct hci_dev *hdev = dev_get_drvdata(dev);
93 return sprintf(buf, "%d\n", hdev->sniff_max_interval); 93 return sprintf(buf, "%d\n", hdev->sniff_max_interval);
94} 94}
95 95
96static ssize_t store_sniff_max_interval(struct class_device *cdev, const char *buf, size_t count) 96static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
97{ 97{
98 struct hci_dev *hdev = class_get_devdata(cdev); 98 struct hci_dev *hdev = dev_get_drvdata(dev);
99 char *ptr; 99 char *ptr;
100 __u16 val; 100 __u16 val;
101 101
@@ -114,15 +114,15 @@ static ssize_t store_sniff_max_interval(struct class_device *cdev, const char *b
114 return count; 114 return count;
115} 115}
116 116
117static ssize_t show_sniff_min_interval(struct class_device *cdev, char *buf) 117static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf)
118{ 118{
119 struct hci_dev *hdev = class_get_devdata(cdev); 119 struct hci_dev *hdev = dev_get_drvdata(dev);
120 return sprintf(buf, "%d\n", hdev->sniff_min_interval); 120 return sprintf(buf, "%d\n", hdev->sniff_min_interval);
121} 121}
122 122
123static ssize_t store_sniff_min_interval(struct class_device *cdev, const char *buf, size_t count) 123static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
124{ 124{
125 struct hci_dev *hdev = class_get_devdata(cdev); 125 struct hci_dev *hdev = dev_get_drvdata(dev);
126 char *ptr; 126 char *ptr;
127 __u16 val; 127 __u16 val;
128 128
@@ -141,64 +141,32 @@ static ssize_t store_sniff_min_interval(struct class_device *cdev, const char *b
141 return count; 141 return count;
142} 142}
143 143
144static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 144static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
145static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL); 145static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
146static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL); 146static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
147static CLASS_DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); 147static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
148static CLASS_DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); 148static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
149 149
150static CLASS_DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, 150static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
151 show_idle_timeout, store_idle_timeout); 151 show_idle_timeout, store_idle_timeout);
152static CLASS_DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, 152static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
153 show_sniff_max_interval, store_sniff_max_interval); 153 show_sniff_max_interval, store_sniff_max_interval);
154static CLASS_DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, 154static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
155 show_sniff_min_interval, store_sniff_min_interval); 155 show_sniff_min_interval, store_sniff_min_interval);
156 156
157static struct class_device_attribute *bt_attrs[] = { 157static struct device_attribute *bt_attrs[] = {
158 &class_device_attr_name, 158 &dev_attr_name,
159 &class_device_attr_type, 159 &dev_attr_type,
160 &class_device_attr_address, 160 &dev_attr_address,
161 &class_device_attr_flags, 161 &dev_attr_flags,
162 &class_device_attr_inquiry_cache, 162 &dev_attr_inquiry_cache,
163 &class_device_attr_idle_timeout, 163 &dev_attr_idle_timeout,
164 &class_device_attr_sniff_max_interval, 164 &dev_attr_sniff_max_interval,
165 &class_device_attr_sniff_min_interval, 165 &dev_attr_sniff_min_interval,
166 NULL 166 NULL
167}; 167};
168 168
169#ifdef CONFIG_HOTPLUG 169struct class *bt_class = NULL;
170static int bt_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
171{
172 struct hci_dev *hdev = class_get_devdata(cdev);
173 int n, i = 0;
174
175 envp[i++] = buf;
176 n = snprintf(buf, size, "INTERFACE=%s", hdev->name) + 1;
177 buf += n;
178 size -= n;
179
180 if ((size <= 0) || (i >= num_envp))
181 return -ENOMEM;
182
183 envp[i] = NULL;
184 return 0;
185}
186#endif
187
188static void bt_release(struct class_device *cdev)
189{
190 struct hci_dev *hdev = class_get_devdata(cdev);
191
192 kfree(hdev);
193}
194
195struct class bt_class = {
196 .name = "bluetooth",
197 .release = bt_release,
198#ifdef CONFIG_HOTPLUG
199 .uevent = bt_uevent,
200#endif
201};
202EXPORT_SYMBOL_GPL(bt_class); 170EXPORT_SYMBOL_GPL(bt_class);
203 171
204static struct bus_type bt_bus = { 172static struct bus_type bt_bus = {
@@ -207,40 +175,50 @@ static struct bus_type bt_bus = {
207 175
208static struct platform_device *bt_platform; 176static struct platform_device *bt_platform;
209 177
178static void bt_release(struct device *dev)
179{
180 struct hci_dev *hdev = dev_get_drvdata(dev);
181 kfree(hdev);
182}
183
210int hci_register_sysfs(struct hci_dev *hdev) 184int hci_register_sysfs(struct hci_dev *hdev)
211{ 185{
212 struct class_device *cdev = &hdev->class_dev; 186 struct device *dev = &hdev->dev;
213 unsigned int i; 187 unsigned int i;
214 int err; 188 int err;
215 189
216 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 190 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
217 191
218 cdev->class = &bt_class; 192 dev->class = bt_class;
219 class_set_devdata(cdev, hdev); 193
194 if (hdev->parent)
195 dev->parent = hdev->parent;
196 else
197 dev->parent = &bt_platform->dev;
198
199 strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
220 200
221 if (!cdev->dev) 201 dev->release = bt_release;
222 cdev->dev = &bt_platform->dev;
223 202
224 hdev->dev = cdev->dev; 203 dev_set_drvdata(dev, hdev);
225 204
226 strlcpy(cdev->class_id, hdev->name, BUS_ID_SIZE); 205 err = device_register(dev);
227 err = class_device_register(cdev);
228 if (err < 0) 206 if (err < 0)
229 return err; 207 return err;
230 208
231 for (i = 0; bt_attrs[i]; i++) 209 for (i = 0; bt_attrs[i]; i++)
232 class_device_create_file(cdev, bt_attrs[i]); 210 device_create_file(dev, bt_attrs[i]);
233 211
234 return 0; 212 return 0;
235} 213}
236 214
237void hci_unregister_sysfs(struct hci_dev *hdev) 215void hci_unregister_sysfs(struct hci_dev *hdev)
238{ 216{
239 struct class_device * cdev = &hdev->class_dev; 217 struct device *dev = &hdev->dev;
240 218
241 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 219 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
242 220
243 class_device_del(cdev); 221 device_del(dev);
244} 222}
245 223
246int __init bt_sysfs_init(void) 224int __init bt_sysfs_init(void)
@@ -257,11 +235,11 @@ int __init bt_sysfs_init(void)
257 return err; 235 return err;
258 } 236 }
259 237
260 err = class_register(&bt_class); 238 bt_class = class_create(THIS_MODULE, "bluetooth");
261 if (err < 0) { 239 if (IS_ERR(bt_class)) {
262 bus_unregister(&bt_bus); 240 bus_unregister(&bt_bus);
263 platform_device_unregister(bt_platform); 241 platform_device_unregister(bt_platform);
264 return err; 242 return PTR_ERR(bt_class);
265 } 243 }
266 244
267 return 0; 245 return 0;
@@ -269,7 +247,7 @@ int __init bt_sysfs_init(void)
269 247
270void __exit bt_sysfs_cleanup(void) 248void __exit bt_sysfs_cleanup(void)
271{ 249{
272 class_unregister(&bt_class); 250 class_destroy(bt_class);
273 251
274 bus_unregister(&bt_bus); 252 bus_unregister(&bt_bus);
275 253
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 770101177da1..f6501fa0d59f 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2219,7 +2219,7 @@ static int __init l2cap_init(void)
2219 goto error; 2219 goto error;
2220 } 2220 }
2221 2221
2222 class_create_file(&bt_class, &class_attr_l2cap); 2222 class_create_file(bt_class, &class_attr_l2cap);
2223 2223
2224 BT_INFO("L2CAP ver %s", VERSION); 2224 BT_INFO("L2CAP ver %s", VERSION);
2225 BT_INFO("L2CAP socket layer initialized"); 2225 BT_INFO("L2CAP socket layer initialized");
@@ -2233,7 +2233,7 @@ error:
2233 2233
2234static void __exit l2cap_exit(void) 2234static void __exit l2cap_exit(void)
2235{ 2235{
2236 class_remove_file(&bt_class, &class_attr_l2cap); 2236 class_remove_file(bt_class, &class_attr_l2cap);
2237 2237
2238 if (bt_sock_unregister(BTPROTO_L2CAP) < 0) 2238 if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
2239 BT_ERR("L2CAP socket unregistration failed"); 2239 BT_ERR("L2CAP socket unregistration failed");
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index bd46e8927f29..6de33fe7bf5b 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2035,7 +2035,7 @@ static int __init rfcomm_init(void)
2035 2035
2036 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); 2036 kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
2037 2037
2038 class_create_file(&bt_class, &class_attr_rfcomm_dlc); 2038 class_create_file(bt_class, &class_attr_rfcomm_dlc);
2039 2039
2040 rfcomm_init_sockets(); 2040 rfcomm_init_sockets();
2041 2041
@@ -2050,7 +2050,7 @@ static int __init rfcomm_init(void)
2050 2050
2051static void __exit rfcomm_exit(void) 2051static void __exit rfcomm_exit(void)
2052{ 2052{
2053 class_remove_file(&bt_class, &class_attr_rfcomm_dlc); 2053 class_remove_file(bt_class, &class_attr_rfcomm_dlc);
2054 2054
2055 hci_unregister_cb(&rfcomm_cb); 2055 hci_unregister_cb(&rfcomm_cb);
2056 2056
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 4e9962c8cfa6..220fee04e7f2 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -944,7 +944,7 @@ int __init rfcomm_init_sockets(void)
944 if (err < 0) 944 if (err < 0)
945 goto error; 945 goto error;
946 946
947 class_create_file(&bt_class, &class_attr_rfcomm); 947 class_create_file(bt_class, &class_attr_rfcomm);
948 948
949 BT_INFO("RFCOMM socket layer initialized"); 949 BT_INFO("RFCOMM socket layer initialized");
950 950
@@ -958,7 +958,7 @@ error:
958 958
959void __exit rfcomm_cleanup_sockets(void) 959void __exit rfcomm_cleanup_sockets(void)
960{ 960{
961 class_remove_file(&bt_class, &class_attr_rfcomm); 961 class_remove_file(bt_class, &class_attr_rfcomm);
962 962
963 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) 963 if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
964 BT_ERR("RFCOMM socket layer unregistration failed"); 964 BT_ERR("RFCOMM socket layer unregistration failed");
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index a5f1e44db5d3..85defccc0287 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -969,7 +969,7 @@ static int __init sco_init(void)
969 goto error; 969 goto error;
970 } 970 }
971 971
972 class_create_file(&bt_class, &class_attr_sco); 972 class_create_file(bt_class, &class_attr_sco);
973 973
974 BT_INFO("SCO (Voice Link) ver %s", VERSION); 974 BT_INFO("SCO (Voice Link) ver %s", VERSION);
975 BT_INFO("SCO socket layer initialized"); 975 BT_INFO("SCO socket layer initialized");
@@ -983,7 +983,7 @@ error:
983 983
984static void __exit sco_exit(void) 984static void __exit sco_exit(void)
985{ 985{
986 class_remove_file(&bt_class, &class_attr_sco); 986 class_remove_file(bt_class, &class_attr_sco);
987 987
988 if (bt_sock_unregister(BTPROTO_SCO) < 0) 988 if (bt_sock_unregister(BTPROTO_SCO) < 0)
989 BT_ERR("SCO socket unregistration failed"); 989 BT_ERR("SCO socket unregistration failed");