Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.39-rc6 395 lines 9.7 kB view raw
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 <raja_mani@ti.com> 9 * Pavan Savoy <pavan_savoy@ti.com> 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 */ 51struct 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) */ 59static 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 */ 85static 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 */ 97static 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 */ 126static 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 */ 151static 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 215done: 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 */ 235static 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 255static 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 293static 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 301static 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 344static 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 365static 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 ------ */ 375static 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 382static void __exit btwilink_exit(void) 383{ 384 platform_driver_unregister(&btwilink_driver); 385} 386 387module_init(btwilink_init); 388module_exit(btwilink_exit); 389 390/* ------ Module Info ------ */ 391 392MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>"); 393MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); 394MODULE_VERSION(VERSION); 395MODULE_LICENSE("GPL");