Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/bluetooth/btwilink.c
15109 views
1
/*
2
* Texas Instrument's Bluetooth Driver For Shared Transport.
3
*
4
* Bluetooth Driver acts as interface between HCI core and
5
* TI Shared Transport Layer.
6
*
7
* Copyright (C) 2009-2010 Texas Instruments
8
* Author: Raja Mani <[email protected]>
9
* Pavan Savoy <[email protected]>
10
*
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License version 2 as
13
* published by the Free Software Foundation.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*
24
*/
25
#define DEBUG
26
#include <linux/platform_device.h>
27
#include <net/bluetooth/bluetooth.h>
28
#include <net/bluetooth/hci_core.h>
29
#include <net/bluetooth/hci.h>
30
31
#include <linux/ti_wilink_st.h>
32
33
/* Bluetooth Driver Version */
34
#define VERSION "1.0"
35
#define MAX_BT_CHNL_IDS 3
36
37
/* Number of seconds to wait for registration completion
38
* when ST returns PENDING status.
39
*/
40
#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */
41
42
/**
43
* struct ti_st - driver operation structure
44
* @hdev: hci device pointer which binds to bt driver
45
* @reg_status: ST registration callback status
46
* @st_write: write function provided by the ST driver
47
* to be used by the driver during send_frame.
48
* @wait_reg_completion - completion sync between ti_st_open
49
* and st_reg_completion_cb.
50
*/
51
struct ti_st {
52
struct hci_dev *hdev;
53
char reg_status;
54
long (*st_write) (struct sk_buff *);
55
struct completion wait_reg_completion;
56
};
57
58
/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
59
static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
60
{
61
struct hci_dev *hdev = hst->hdev;
62
63
/* Update HCI stat counters */
64
switch (pkt_type) {
65
case HCI_COMMAND_PKT:
66
hdev->stat.cmd_tx++;
67
break;
68
69
case HCI_ACLDATA_PKT:
70
hdev->stat.acl_tx++;
71
break;
72
73
case HCI_SCODATA_PKT:
74
hdev->stat.sco_tx++;
75
break;
76
}
77
}
78
79
/* ------- Interfaces to Shared Transport ------ */
80
81
/* Called by ST layer to indicate protocol registration completion
82
* status.ti_st_open() function will wait for signal from this
83
* API when st_register() function returns ST_PENDING.
84
*/
85
static void st_reg_completion_cb(void *priv_data, char data)
86
{
87
struct ti_st *lhst = priv_data;
88
89
/* Save registration status for use in ti_st_open() */
90
lhst->reg_status = data;
91
/* complete the wait in ti_st_open() */
92
complete(&lhst->wait_reg_completion);
93
}
94
95
/* Called by Shared Transport layer when receive data is
96
* available */
97
static long st_receive(void *priv_data, struct sk_buff *skb)
98
{
99
struct ti_st *lhst = priv_data;
100
int err;
101
102
if (!skb)
103
return -EFAULT;
104
105
if (!lhst) {
106
kfree_skb(skb);
107
return -EFAULT;
108
}
109
110
skb->dev = (void *) lhst->hdev;
111
112
/* Forward skb to HCI core layer */
113
err = hci_recv_frame(skb);
114
if (err < 0) {
115
BT_ERR("Unable to push skb to HCI core(%d)", err);
116
return err;
117
}
118
119
lhst->hdev->stat.byte_rx += skb->len;
120
121
return 0;
122
}
123
124
/* ------- Interfaces to HCI layer ------ */
125
/* protocol structure registered with shared transport */
126
static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = {
127
{
128
.chnl_id = HCI_ACLDATA_PKT, /* ACL */
129
.hdr_len = sizeof(struct hci_acl_hdr),
130
.offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen),
131
.len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */
132
.reserve = 8,
133
},
134
{
135
.chnl_id = HCI_SCODATA_PKT, /* SCO */
136
.hdr_len = sizeof(struct hci_sco_hdr),
137
.offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen),
138
.len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */
139
.reserve = 8,
140
},
141
{
142
.chnl_id = HCI_EVENT_PKT, /* HCI Events */
143
.hdr_len = sizeof(struct hci_event_hdr),
144
.offset_len_in_hdr = offsetof(struct hci_event_hdr, plen),
145
.len_size = 1, /* sizeof(plen) in struct hci_event_hdr */
146
.reserve = 8,
147
},
148
};
149
150
/* Called from HCI core to initialize the device */
151
static int ti_st_open(struct hci_dev *hdev)
152
{
153
unsigned long timeleft;
154
struct ti_st *hst;
155
int err, i;
156
157
BT_DBG("%s %p", hdev->name, hdev);
158
159
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
160
return -EBUSY;
161
162
/* provide contexts for callbacks from ST */
163
hst = hdev->driver_data;
164
165
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
166
ti_st_proto[i].priv_data = hst;
167
ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE;
168
ti_st_proto[i].recv = st_receive;
169
ti_st_proto[i].reg_complete_cb = st_reg_completion_cb;
170
171
/* Prepare wait-for-completion handler */
172
init_completion(&hst->wait_reg_completion);
173
/* Reset ST registration callback status flag,
174
* this value will be updated in
175
* st_reg_completion_cb()
176
* function whenever it called from ST driver.
177
*/
178
hst->reg_status = -EINPROGRESS;
179
180
err = st_register(&ti_st_proto[i]);
181
if (!err)
182
goto done;
183
184
if (err != -EINPROGRESS) {
185
clear_bit(HCI_RUNNING, &hdev->flags);
186
BT_ERR("st_register failed %d", err);
187
return err;
188
}
189
190
/* ST is busy with either protocol
191
* registration or firmware download.
192
*/
193
BT_DBG("waiting for registration "
194
"completion signal from ST");
195
timeleft = wait_for_completion_timeout
196
(&hst->wait_reg_completion,
197
msecs_to_jiffies(BT_REGISTER_TIMEOUT));
198
if (!timeleft) {
199
clear_bit(HCI_RUNNING, &hdev->flags);
200
BT_ERR("Timeout(%d sec),didn't get reg "
201
"completion signal from ST",
202
BT_REGISTER_TIMEOUT / 1000);
203
return -ETIMEDOUT;
204
}
205
206
/* Is ST registration callback
207
* called with ERROR status? */
208
if (hst->reg_status != 0) {
209
clear_bit(HCI_RUNNING, &hdev->flags);
210
BT_ERR("ST registration completed with invalid "
211
"status %d", hst->reg_status);
212
return -EAGAIN;
213
}
214
215
done:
216
hst->st_write = ti_st_proto[i].write;
217
if (!hst->st_write) {
218
BT_ERR("undefined ST write function");
219
clear_bit(HCI_RUNNING, &hdev->flags);
220
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
221
/* Undo registration with ST */
222
err = st_unregister(&ti_st_proto[i]);
223
if (err)
224
BT_ERR("st_unregister() failed with "
225
"error %d", err);
226
hst->st_write = NULL;
227
}
228
return -EIO;
229
}
230
}
231
return 0;
232
}
233
234
/* Close device */
235
static int ti_st_close(struct hci_dev *hdev)
236
{
237
int err, i;
238
struct ti_st *hst = hdev->driver_data;
239
240
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
241
return 0;
242
243
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
244
err = st_unregister(&ti_st_proto[i]);
245
if (err)
246
BT_ERR("st_unregister(%d) failed with error %d",
247
ti_st_proto[i].chnl_id, err);
248
}
249
250
hst->st_write = NULL;
251
252
return err;
253
}
254
255
static int ti_st_send_frame(struct sk_buff *skb)
256
{
257
struct hci_dev *hdev;
258
struct ti_st *hst;
259
long len;
260
261
hdev = (struct hci_dev *)skb->dev;
262
263
if (!test_bit(HCI_RUNNING, &hdev->flags))
264
return -EBUSY;
265
266
hst = hdev->driver_data;
267
268
/* Prepend skb with frame type */
269
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
270
271
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
272
skb->len);
273
274
/* Insert skb to shared transport layer's transmit queue.
275
* Freeing skb memory is taken care in shared transport layer,
276
* so don't free skb memory here.
277
*/
278
len = hst->st_write(skb);
279
if (len < 0) {
280
kfree_skb(skb);
281
BT_ERR("ST write failed (%ld)", len);
282
/* Try Again, would only fail if UART has gone bad */
283
return -EAGAIN;
284
}
285
286
/* ST accepted our skb. So, Go ahead and do rest */
287
hdev->stat.byte_tx += len;
288
ti_st_tx_complete(hst, bt_cb(skb)->pkt_type);
289
290
return 0;
291
}
292
293
static void ti_st_destruct(struct hci_dev *hdev)
294
{
295
BT_DBG("%s", hdev->name);
296
/* do nothing here, since platform remove
297
* would free the hdev->driver_data
298
*/
299
}
300
301
static int bt_ti_probe(struct platform_device *pdev)
302
{
303
static struct ti_st *hst;
304
struct hci_dev *hdev;
305
int err;
306
307
hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL);
308
if (!hst)
309
return -ENOMEM;
310
311
/* Expose "hciX" device to user space */
312
hdev = hci_alloc_dev();
313
if (!hdev) {
314
kfree(hst);
315
return -ENOMEM;
316
}
317
318
BT_DBG("hdev %p", hdev);
319
320
hst->hdev = hdev;
321
hdev->bus = HCI_UART;
322
hdev->driver_data = hst;
323
hdev->open = ti_st_open;
324
hdev->close = ti_st_close;
325
hdev->flush = NULL;
326
hdev->send = ti_st_send_frame;
327
hdev->destruct = ti_st_destruct;
328
hdev->owner = THIS_MODULE;
329
330
err = hci_register_dev(hdev);
331
if (err < 0) {
332
BT_ERR("Can't register HCI device error %d", err);
333
kfree(hst);
334
hci_free_dev(hdev);
335
return err;
336
}
337
338
BT_DBG("HCI device registered (hdev %p)", hdev);
339
340
dev_set_drvdata(&pdev->dev, hst);
341
return err;
342
}
343
344
static int bt_ti_remove(struct platform_device *pdev)
345
{
346
struct hci_dev *hdev;
347
struct ti_st *hst = dev_get_drvdata(&pdev->dev);
348
349
if (!hst)
350
return -EFAULT;
351
352
BT_DBG("%s", hst->hdev->name);
353
354
hdev = hst->hdev;
355
ti_st_close(hdev);
356
hci_unregister_dev(hdev);
357
358
hci_free_dev(hdev);
359
kfree(hst);
360
361
dev_set_drvdata(&pdev->dev, NULL);
362
return 0;
363
}
364
365
static struct platform_driver btwilink_driver = {
366
.probe = bt_ti_probe,
367
.remove = bt_ti_remove,
368
.driver = {
369
.name = "btwilink",
370
.owner = THIS_MODULE,
371
},
372
};
373
374
/* ------- Module Init/Exit interfaces ------ */
375
static int __init btwilink_init(void)
376
{
377
BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION);
378
379
return platform_driver_register(&btwilink_driver);
380
}
381
382
static void __exit btwilink_exit(void)
383
{
384
platform_driver_unregister(&btwilink_driver);
385
}
386
387
module_init(btwilink_init);
388
module_exit(btwilink_exit);
389
390
/* ------ Module Info ------ */
391
392
MODULE_AUTHOR("Raja Mani <[email protected]>");
393
MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
394
MODULE_VERSION(VERSION);
395
MODULE_LICENSE("GPL");
396
397