3ccb4b0b8fc200cd57738bd8fb349c05b51412f8
[pandora-kernel.git] / net / bluetooth / hci_sysfs.c
1 /* Bluetooth HCI driver model support. */
2
3 #include <linux/kernel.h>
4 #include <linux/init.h>
5
6 #include <linux/platform_device.h>
7
8 #include <net/bluetooth/bluetooth.h>
9 #include <net/bluetooth/hci_core.h>
10
11 #ifndef CONFIG_BT_HCI_CORE_DEBUG
12 #undef  BT_DBG
13 #define BT_DBG(D...)
14 #endif
15
16 static inline char *typetostr(int type)
17 {
18         switch (type) {
19         case HCI_VHCI:
20                 return "VIRTUAL";
21         case HCI_USB:
22                 return "USB";
23         case HCI_PCCARD:
24                 return "PCCARD";
25         case HCI_UART:
26                 return "UART";
27         case HCI_RS232:
28                 return "RS232";
29         case HCI_PCI:
30                 return "PCI";
31         default:
32                 return "UNKNOWN";
33         }
34 }
35
36 static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
37 {
38         struct hci_dev *hdev = dev_get_drvdata(dev);
39         return sprintf(buf, "%s\n", typetostr(hdev->type));
40 }
41
42 static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
43 {
44         struct hci_dev *hdev = dev_get_drvdata(dev);
45         bdaddr_t bdaddr;
46         baswap(&bdaddr, &hdev->bdaddr);
47         return sprintf(buf, "%s\n", batostr(&bdaddr));
48 }
49
50 static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf)
51 {
52         struct hci_dev *hdev = dev_get_drvdata(dev);
53         struct inquiry_cache *cache = &hdev->inq_cache;
54         struct inquiry_entry *e;
55         int n = 0;
56
57         hci_dev_lock_bh(hdev);
58
59         for (e = cache->list; e; e = e->next) {
60                 struct inquiry_data *data = &e->data;
61                 bdaddr_t bdaddr;
62                 baswap(&bdaddr, &data->bdaddr);
63                 n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %u\n",
64                                 batostr(&bdaddr),
65                                 data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode,
66                                 data->dev_class[2], data->dev_class[1], data->dev_class[0],
67                                 __le16_to_cpu(data->clock_offset), data->rssi, e->timestamp);
68         }
69
70         hci_dev_unlock_bh(hdev);
71         return n;
72 }
73
74 static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf)
75 {
76         struct hci_dev *hdev = dev_get_drvdata(dev);
77         return sprintf(buf, "%d\n", hdev->idle_timeout);
78 }
79
80 static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
81 {
82         struct hci_dev *hdev = dev_get_drvdata(dev);
83         char *ptr;
84         __u32 val;
85
86         val = simple_strtoul(buf, &ptr, 10);
87         if (ptr == buf)
88                 return -EINVAL;
89
90         if (val != 0 && (val < 500 || val > 3600000))
91                 return -EINVAL;
92
93         hdev->idle_timeout = val;
94
95         return count;
96 }
97
98 static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf)
99 {
100         struct hci_dev *hdev = dev_get_drvdata(dev);
101         return sprintf(buf, "%d\n", hdev->sniff_max_interval);
102 }
103
104 static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
105 {
106         struct hci_dev *hdev = dev_get_drvdata(dev);
107         char *ptr;
108         __u16 val;
109
110         val = simple_strtoul(buf, &ptr, 10);
111         if (ptr == buf)
112                 return -EINVAL;
113
114         if (val < 0x0002 || val > 0xFFFE || val % 2)
115                 return -EINVAL;
116
117         if (val < hdev->sniff_min_interval)
118                 return -EINVAL;
119
120         hdev->sniff_max_interval = val;
121
122         return count;
123 }
124
125 static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf)
126 {
127         struct hci_dev *hdev = dev_get_drvdata(dev);
128         return sprintf(buf, "%d\n", hdev->sniff_min_interval);
129 }
130
131 static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
132 {
133         struct hci_dev *hdev = dev_get_drvdata(dev);
134         char *ptr;
135         __u16 val;
136
137         val = simple_strtoul(buf, &ptr, 10);
138         if (ptr == buf)
139                 return -EINVAL;
140
141         if (val < 0x0002 || val > 0xFFFE || val % 2)
142                 return -EINVAL;
143
144         if (val > hdev->sniff_max_interval)
145                 return -EINVAL;
146
147         hdev->sniff_min_interval = val;
148
149         return count;
150 }
151
152 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
153 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
154 static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL);
155
156 static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR,
157                                 show_idle_timeout, store_idle_timeout);
158 static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
159                                 show_sniff_max_interval, store_sniff_max_interval);
160 static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
161                                 show_sniff_min_interval, store_sniff_min_interval);
162
163 static struct device_attribute *bt_attrs[] = {
164         &dev_attr_type,
165         &dev_attr_address,
166         &dev_attr_inquiry_cache,
167         &dev_attr_idle_timeout,
168         &dev_attr_sniff_max_interval,
169         &dev_attr_sniff_min_interval,
170         NULL
171 };
172
173 struct class *bt_class = NULL;
174 EXPORT_SYMBOL_GPL(bt_class);
175
176 static struct bus_type bt_bus = {
177         .name   = "bluetooth",
178 };
179
180 static struct platform_device *bt_platform;
181
182 static void bt_release(struct device *dev)
183 {
184         struct hci_dev *hdev = dev_get_drvdata(dev);
185         kfree(hdev);
186 }
187
188 int hci_register_sysfs(struct hci_dev *hdev)
189 {
190         struct device *dev = &hdev->dev;
191         unsigned int i;
192         int err;
193
194         BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
195
196         dev->class = bt_class;
197
198         if (hdev->parent)
199                 dev->parent = hdev->parent;
200         else
201                 dev->parent = &bt_platform->dev;
202
203         strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
204
205         dev->release = bt_release;
206
207         dev_set_drvdata(dev, hdev);
208
209         err = device_register(dev);
210         if (err < 0)
211                 return err;
212
213         for (i = 0; bt_attrs[i]; i++)
214                 device_create_file(dev, bt_attrs[i]);
215
216         return 0;
217 }
218
219 void hci_unregister_sysfs(struct hci_dev *hdev)
220 {
221         BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
222
223         device_del(&hdev->dev);
224 }
225
226 int __init bt_sysfs_init(void)
227 {
228         int err;
229
230         bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
231         if (IS_ERR(bt_platform))
232                 return PTR_ERR(bt_platform);
233
234         err = bus_register(&bt_bus);
235         if (err < 0) {
236                 platform_device_unregister(bt_platform);
237                 return err;
238         }
239
240         bt_class = class_create(THIS_MODULE, "bluetooth");
241         if (IS_ERR(bt_class)) {
242                 bus_unregister(&bt_bus);
243                 platform_device_unregister(bt_platform);
244                 return PTR_ERR(bt_class);
245         }
246
247         return 0;
248 }
249
250 void __exit bt_sysfs_cleanup(void)
251 {
252         class_destroy(bt_class);
253
254         bus_unregister(&bt_bus);
255
256         platform_device_unregister(bt_platform);
257 }