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 v4.10-rc5 351 lines 8.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 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#include <linux/module.h> 33 34/* Bluetooth Driver Version */ 35#define VERSION "1.0" 36#define MAX_BT_CHNL_IDS 3 37 38/* Number of seconds to wait for registration completion 39 * when ST returns PENDING status. 40 */ 41#define BT_REGISTER_TIMEOUT 6000 /* 6 sec */ 42 43/** 44 * struct ti_st - driver operation structure 45 * @hdev: hci device pointer which binds to bt driver 46 * @reg_status: ST registration callback status 47 * @st_write: write function provided by the ST driver 48 * to be used by the driver during send_frame. 49 * @wait_reg_completion - completion sync between ti_st_open 50 * and st_reg_completion_cb. 51 */ 52struct ti_st { 53 struct hci_dev *hdev; 54 int reg_status; 55 long (*st_write) (struct sk_buff *); 56 struct completion wait_reg_completion; 57}; 58 59/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ 60static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type) 61{ 62 struct hci_dev *hdev = hst->hdev; 63 64 /* Update HCI stat counters */ 65 switch (pkt_type) { 66 case HCI_COMMAND_PKT: 67 hdev->stat.cmd_tx++; 68 break; 69 70 case HCI_ACLDATA_PKT: 71 hdev->stat.acl_tx++; 72 break; 73 74 case HCI_SCODATA_PKT: 75 hdev->stat.sco_tx++; 76 break; 77 } 78} 79 80/* ------- Interfaces to Shared Transport ------ */ 81 82/* Called by ST layer to indicate protocol registration completion 83 * status.ti_st_open() function will wait for signal from this 84 * API when st_register() function returns ST_PENDING. 85 */ 86static void st_reg_completion_cb(void *priv_data, int data) 87{ 88 struct ti_st *lhst = priv_data; 89 90 /* Save registration status for use in ti_st_open() */ 91 lhst->reg_status = data; 92 /* complete the wait in ti_st_open() */ 93 complete(&lhst->wait_reg_completion); 94} 95 96/* Called by Shared Transport layer when receive data is 97 * available */ 98static long st_receive(void *priv_data, struct sk_buff *skb) 99{ 100 struct ti_st *lhst = priv_data; 101 int err; 102 103 if (!skb) 104 return -EFAULT; 105 106 if (!lhst) { 107 kfree_skb(skb); 108 return -EFAULT; 109 } 110 111 /* Forward skb to HCI core layer */ 112 err = hci_recv_frame(lhst->hdev, skb); 113 if (err < 0) { 114 BT_ERR("Unable to push skb to HCI core(%d)", err); 115 return err; 116 } 117 118 lhst->hdev->stat.byte_rx += skb->len; 119 120 return 0; 121} 122 123/* ------- Interfaces to HCI layer ------ */ 124/* protocol structure registered with shared transport */ 125static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { 126 { 127 .chnl_id = HCI_EVENT_PKT, /* HCI Events */ 128 .hdr_len = sizeof(struct hci_event_hdr), 129 .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), 130 .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ 131 .reserve = 8, 132 }, 133 { 134 .chnl_id = HCI_ACLDATA_PKT, /* ACL */ 135 .hdr_len = sizeof(struct hci_acl_hdr), 136 .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen), 137 .len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */ 138 .reserve = 8, 139 }, 140 { 141 .chnl_id = HCI_SCODATA_PKT, /* SCO */ 142 .hdr_len = sizeof(struct hci_sco_hdr), 143 .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen), 144 .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ 145 .reserve = 8, 146 }, 147}; 148 149/* Called from HCI core to initialize the device */ 150static int ti_st_open(struct hci_dev *hdev) 151{ 152 unsigned long timeleft; 153 struct ti_st *hst; 154 int err, i; 155 156 BT_DBG("%s %p", hdev->name, hdev); 157 158 /* provide contexts for callbacks from ST */ 159 hst = hci_get_drvdata(hdev); 160 161 for (i = 0; i < MAX_BT_CHNL_IDS; i++) { 162 ti_st_proto[i].priv_data = hst; 163 ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE; 164 ti_st_proto[i].recv = st_receive; 165 ti_st_proto[i].reg_complete_cb = st_reg_completion_cb; 166 167 /* Prepare wait-for-completion handler */ 168 init_completion(&hst->wait_reg_completion); 169 /* Reset ST registration callback status flag, 170 * this value will be updated in 171 * st_reg_completion_cb() 172 * function whenever it called from ST driver. 173 */ 174 hst->reg_status = -EINPROGRESS; 175 176 err = st_register(&ti_st_proto[i]); 177 if (!err) 178 goto done; 179 180 if (err != -EINPROGRESS) { 181 BT_ERR("st_register failed %d", err); 182 return err; 183 } 184 185 /* ST is busy with either protocol 186 * registration or firmware download. 187 */ 188 BT_DBG("waiting for registration " 189 "completion signal from ST"); 190 timeleft = wait_for_completion_timeout 191 (&hst->wait_reg_completion, 192 msecs_to_jiffies(BT_REGISTER_TIMEOUT)); 193 if (!timeleft) { 194 BT_ERR("Timeout(%d sec),didn't get reg " 195 "completion signal from ST", 196 BT_REGISTER_TIMEOUT / 1000); 197 return -ETIMEDOUT; 198 } 199 200 /* Is ST registration callback 201 * called with ERROR status? */ 202 if (hst->reg_status != 0) { 203 BT_ERR("ST registration completed with invalid " 204 "status %d", hst->reg_status); 205 return -EAGAIN; 206 } 207 208done: 209 hst->st_write = ti_st_proto[i].write; 210 if (!hst->st_write) { 211 BT_ERR("undefined ST write function"); 212 for (i = 0; i < MAX_BT_CHNL_IDS; i++) { 213 /* Undo registration with ST */ 214 err = st_unregister(&ti_st_proto[i]); 215 if (err) 216 BT_ERR("st_unregister() failed with " 217 "error %d", err); 218 hst->st_write = NULL; 219 } 220 return -EIO; 221 } 222 } 223 return 0; 224} 225 226/* Close device */ 227static int ti_st_close(struct hci_dev *hdev) 228{ 229 int err, i; 230 struct ti_st *hst = hci_get_drvdata(hdev); 231 232 for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) { 233 err = st_unregister(&ti_st_proto[i]); 234 if (err) 235 BT_ERR("st_unregister(%d) failed with error %d", 236 ti_st_proto[i].chnl_id, err); 237 } 238 239 hst->st_write = NULL; 240 241 return err; 242} 243 244static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb) 245{ 246 struct ti_st *hst; 247 long len; 248 int pkt_type; 249 250 hst = hci_get_drvdata(hdev); 251 252 /* Prepend skb with frame type */ 253 memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); 254 255 BT_DBG("%s: type %d len %d", hdev->name, hci_skb_pkt_type(skb), 256 skb->len); 257 258 /* Insert skb to shared transport layer's transmit queue. 259 * Freeing skb memory is taken care in shared transport layer, 260 * so don't free skb memory here. 261 */ 262 pkt_type = hci_skb_pkt_type(skb); 263 len = hst->st_write(skb); 264 if (len < 0) { 265 kfree_skb(skb); 266 BT_ERR("ST write failed (%ld)", len); 267 /* Try Again, would only fail if UART has gone bad */ 268 return -EAGAIN; 269 } 270 271 /* ST accepted our skb. So, Go ahead and do rest */ 272 hdev->stat.byte_tx += len; 273 ti_st_tx_complete(hst, pkt_type); 274 275 return 0; 276} 277 278static int bt_ti_probe(struct platform_device *pdev) 279{ 280 static struct ti_st *hst; 281 struct hci_dev *hdev; 282 int err; 283 284 hst = devm_kzalloc(&pdev->dev, sizeof(struct ti_st), GFP_KERNEL); 285 if (!hst) 286 return -ENOMEM; 287 288 /* Expose "hciX" device to user space */ 289 hdev = hci_alloc_dev(); 290 if (!hdev) 291 return -ENOMEM; 292 293 BT_DBG("hdev %p", hdev); 294 295 hst->hdev = hdev; 296 hdev->bus = HCI_UART; 297 hci_set_drvdata(hdev, hst); 298 hdev->open = ti_st_open; 299 hdev->close = ti_st_close; 300 hdev->flush = NULL; 301 hdev->send = ti_st_send_frame; 302 303 err = hci_register_dev(hdev); 304 if (err < 0) { 305 BT_ERR("Can't register HCI device error %d", err); 306 hci_free_dev(hdev); 307 return err; 308 } 309 310 BT_DBG("HCI device registered (hdev %p)", hdev); 311 312 dev_set_drvdata(&pdev->dev, hst); 313 return 0; 314} 315 316static int bt_ti_remove(struct platform_device *pdev) 317{ 318 struct hci_dev *hdev; 319 struct ti_st *hst = dev_get_drvdata(&pdev->dev); 320 321 if (!hst) 322 return -EFAULT; 323 324 BT_DBG("%s", hst->hdev->name); 325 326 hdev = hst->hdev; 327 ti_st_close(hdev); 328 hci_unregister_dev(hdev); 329 330 hci_free_dev(hdev); 331 332 dev_set_drvdata(&pdev->dev, NULL); 333 return 0; 334} 335 336static struct platform_driver btwilink_driver = { 337 .probe = bt_ti_probe, 338 .remove = bt_ti_remove, 339 .driver = { 340 .name = "btwilink", 341 }, 342}; 343 344module_platform_driver(btwilink_driver); 345 346/* ------ Module Info ------ */ 347 348MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>"); 349MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); 350MODULE_VERSION(VERSION); 351MODULE_LICENSE("GPL");