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.17-rc1 350 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 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 /* Forward skb to HCI core layer */ 111 err = hci_recv_frame(lhst->hdev, skb); 112 if (err < 0) { 113 BT_ERR("Unable to push skb to HCI core(%d)", err); 114 return err; 115 } 116 117 lhst->hdev->stat.byte_rx += skb->len; 118 119 return 0; 120} 121 122/* ------- Interfaces to HCI layer ------ */ 123/* protocol structure registered with shared transport */ 124static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { 125 { 126 .chnl_id = HCI_EVENT_PKT, /* HCI Events */ 127 .hdr_len = sizeof(struct hci_event_hdr), 128 .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), 129 .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ 130 .reserve = 8, 131 }, 132 { 133 .chnl_id = HCI_ACLDATA_PKT, /* ACL */ 134 .hdr_len = sizeof(struct hci_acl_hdr), 135 .offset_len_in_hdr = offsetof(struct hci_acl_hdr, dlen), 136 .len_size = 2, /* sizeof(dlen) in struct hci_acl_hdr */ 137 .reserve = 8, 138 }, 139 { 140 .chnl_id = HCI_SCODATA_PKT, /* SCO */ 141 .hdr_len = sizeof(struct hci_sco_hdr), 142 .offset_len_in_hdr = offsetof(struct hci_sco_hdr, dlen), 143 .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ 144 .reserve = 8, 145 }, 146}; 147 148/* Called from HCI core to initialize the device */ 149static int ti_st_open(struct hci_dev *hdev) 150{ 151 unsigned long timeleft; 152 struct ti_st *hst; 153 int err, i; 154 155 BT_DBG("%s %p", hdev->name, hdev); 156 157 /* provide contexts for callbacks from ST */ 158 hst = hci_get_drvdata(hdev); 159 160 for (i = 0; i < MAX_BT_CHNL_IDS; i++) { 161 ti_st_proto[i].priv_data = hst; 162 ti_st_proto[i].max_frame_size = HCI_MAX_FRAME_SIZE; 163 ti_st_proto[i].recv = st_receive; 164 ti_st_proto[i].reg_complete_cb = st_reg_completion_cb; 165 166 /* Prepare wait-for-completion handler */ 167 init_completion(&hst->wait_reg_completion); 168 /* Reset ST registration callback status flag, 169 * this value will be updated in 170 * st_reg_completion_cb() 171 * function whenever it called from ST driver. 172 */ 173 hst->reg_status = -EINPROGRESS; 174 175 err = st_register(&ti_st_proto[i]); 176 if (!err) 177 goto done; 178 179 if (err != -EINPROGRESS) { 180 BT_ERR("st_register failed %d", err); 181 return err; 182 } 183 184 /* ST is busy with either protocol 185 * registration or firmware download. 186 */ 187 BT_DBG("waiting for registration " 188 "completion signal from ST"); 189 timeleft = wait_for_completion_timeout 190 (&hst->wait_reg_completion, 191 msecs_to_jiffies(BT_REGISTER_TIMEOUT)); 192 if (!timeleft) { 193 BT_ERR("Timeout(%d sec),didn't get reg " 194 "completion signal from ST", 195 BT_REGISTER_TIMEOUT / 1000); 196 return -ETIMEDOUT; 197 } 198 199 /* Is ST registration callback 200 * called with ERROR status? 201 */ 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 BT_ERR("ST write failed (%ld)", len); 266 /* Try Again, would only fail if UART has gone bad */ 267 return -EAGAIN; 268 } 269 270 /* ST accepted our skb. So, Go ahead and do rest */ 271 hdev->stat.byte_tx += len; 272 ti_st_tx_complete(hst, pkt_type); 273 274 return 0; 275} 276 277static int bt_ti_probe(struct platform_device *pdev) 278{ 279 struct ti_st *hst; 280 struct hci_dev *hdev; 281 int err; 282 283 hst = devm_kzalloc(&pdev->dev, sizeof(struct ti_st), GFP_KERNEL); 284 if (!hst) 285 return -ENOMEM; 286 287 /* Expose "hciX" device to user space */ 288 hdev = hci_alloc_dev(); 289 if (!hdev) 290 return -ENOMEM; 291 292 BT_DBG("hdev %p", hdev); 293 294 hst->hdev = hdev; 295 hdev->bus = HCI_UART; 296 hci_set_drvdata(hdev, hst); 297 hdev->open = ti_st_open; 298 hdev->close = ti_st_close; 299 hdev->flush = NULL; 300 hdev->send = ti_st_send_frame; 301 302 err = hci_register_dev(hdev); 303 if (err < 0) { 304 BT_ERR("Can't register HCI device error %d", err); 305 hci_free_dev(hdev); 306 return err; 307 } 308 309 BT_DBG("HCI device registered (hdev %p)", hdev); 310 311 dev_set_drvdata(&pdev->dev, hst); 312 return 0; 313} 314 315static int bt_ti_remove(struct platform_device *pdev) 316{ 317 struct hci_dev *hdev; 318 struct ti_st *hst = dev_get_drvdata(&pdev->dev); 319 320 if (!hst) 321 return -EFAULT; 322 323 BT_DBG("%s", hst->hdev->name); 324 325 hdev = hst->hdev; 326 ti_st_close(hdev); 327 hci_unregister_dev(hdev); 328 329 hci_free_dev(hdev); 330 331 dev_set_drvdata(&pdev->dev, NULL); 332 return 0; 333} 334 335static struct platform_driver btwilink_driver = { 336 .probe = bt_ti_probe, 337 .remove = bt_ti_remove, 338 .driver = { 339 .name = "btwilink", 340 }, 341}; 342 343module_platform_driver(btwilink_driver); 344 345/* ------ Module Info ------ */ 346 347MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>"); 348MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); 349MODULE_VERSION(VERSION); 350MODULE_LICENSE("GPL");