Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.33-rc2 400 lines 8.4 kB view raw
1/* 2 * 3 * Generic Bluetooth SDIO driver 4 * 5 * Copyright (C) 2007 Cambridge Silicon Radio Ltd. 6 * Copyright (C) 2007 Marcel Holtmann <marcel@holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25#include <linux/kernel.h> 26#include <linux/module.h> 27#include <linux/init.h> 28#include <linux/slab.h> 29#include <linux/types.h> 30#include <linux/sched.h> 31#include <linux/errno.h> 32#include <linux/skbuff.h> 33 34#include <linux/mmc/sdio_ids.h> 35#include <linux/mmc/sdio_func.h> 36 37#include <net/bluetooth/bluetooth.h> 38#include <net/bluetooth/hci_core.h> 39 40#define VERSION "0.1" 41 42static const struct sdio_device_id btsdio_table[] = { 43 /* Generic Bluetooth Type-A SDIO device */ 44 { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_A) }, 45 46 /* Generic Bluetooth Type-B SDIO device */ 47 { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, 48 49 { } /* Terminating entry */ 50}; 51 52MODULE_DEVICE_TABLE(sdio, btsdio_table); 53 54struct btsdio_data { 55 struct hci_dev *hdev; 56 struct sdio_func *func; 57 58 struct work_struct work; 59 60 struct sk_buff_head txq; 61}; 62 63#define REG_RDAT 0x00 /* Receiver Data */ 64#define REG_TDAT 0x00 /* Transmitter Data */ 65#define REG_PC_RRT 0x10 /* Read Packet Control */ 66#define REG_PC_WRT 0x11 /* Write Packet Control */ 67#define REG_RTC_STAT 0x12 /* Retry Control Status */ 68#define REG_RTC_SET 0x12 /* Retry Control Set */ 69#define REG_INTRD 0x13 /* Interrupt Indication */ 70#define REG_CL_INTRD 0x13 /* Interrupt Clear */ 71#define REG_EN_INTRD 0x14 /* Interrupt Enable */ 72#define REG_MD_STAT 0x20 /* Bluetooth Mode Status */ 73 74static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb) 75{ 76 int err; 77 78 BT_DBG("%s", data->hdev->name); 79 80 /* Prepend Type-A header */ 81 skb_push(skb, 4); 82 skb->data[0] = (skb->len & 0x0000ff); 83 skb->data[1] = (skb->len & 0x00ff00) >> 8; 84 skb->data[2] = (skb->len & 0xff0000) >> 16; 85 skb->data[3] = bt_cb(skb)->pkt_type; 86 87 err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len); 88 if (err < 0) { 89 skb_pull(skb, 4); 90 sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL); 91 return err; 92 } 93 94 data->hdev->stat.byte_tx += skb->len; 95 96 kfree_skb(skb); 97 98 return 0; 99} 100 101static void btsdio_work(struct work_struct *work) 102{ 103 struct btsdio_data *data = container_of(work, struct btsdio_data, work); 104 struct sk_buff *skb; 105 int err; 106 107 BT_DBG("%s", data->hdev->name); 108 109 sdio_claim_host(data->func); 110 111 while ((skb = skb_dequeue(&data->txq))) { 112 err = btsdio_tx_packet(data, skb); 113 if (err < 0) { 114 data->hdev->stat.err_tx++; 115 skb_queue_head(&data->txq, skb); 116 break; 117 } 118 } 119 120 sdio_release_host(data->func); 121} 122 123static int btsdio_rx_packet(struct btsdio_data *data) 124{ 125 u8 hdr[4] __attribute__ ((aligned(4))); 126 struct sk_buff *skb; 127 int err, len; 128 129 BT_DBG("%s", data->hdev->name); 130 131 err = sdio_readsb(data->func, hdr, REG_RDAT, 4); 132 if (err < 0) 133 return err; 134 135 len = hdr[0] | (hdr[1] << 8) | (hdr[2] << 16); 136 if (len < 4 || len > 65543) 137 return -EILSEQ; 138 139 skb = bt_skb_alloc(len - 4, GFP_KERNEL); 140 if (!skb) { 141 /* Out of memory. Prepare a read retry and just 142 * return with the expectation that the next time 143 * we're called we'll have more memory. */ 144 return -ENOMEM; 145 } 146 147 skb_put(skb, len - 4); 148 149 err = sdio_readsb(data->func, skb->data, REG_RDAT, len - 4); 150 if (err < 0) { 151 kfree_skb(skb); 152 return err; 153 } 154 155 data->hdev->stat.byte_rx += len; 156 157 skb->dev = (void *) data->hdev; 158 bt_cb(skb)->pkt_type = hdr[3]; 159 160 err = hci_recv_frame(skb); 161 if (err < 0) 162 return err; 163 164 sdio_writeb(data->func, 0x00, REG_PC_RRT, NULL); 165 166 return 0; 167} 168 169static void btsdio_interrupt(struct sdio_func *func) 170{ 171 struct btsdio_data *data = sdio_get_drvdata(func); 172 int intrd; 173 174 BT_DBG("%s", data->hdev->name); 175 176 intrd = sdio_readb(func, REG_INTRD, NULL); 177 if (intrd & 0x01) { 178 sdio_writeb(func, 0x01, REG_CL_INTRD, NULL); 179 180 if (btsdio_rx_packet(data) < 0) { 181 data->hdev->stat.err_rx++; 182 sdio_writeb(data->func, 0x01, REG_PC_RRT, NULL); 183 } 184 } 185} 186 187static int btsdio_open(struct hci_dev *hdev) 188{ 189 struct btsdio_data *data = hdev->driver_data; 190 int err; 191 192 BT_DBG("%s", hdev->name); 193 194 if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) 195 return 0; 196 197 sdio_claim_host(data->func); 198 199 err = sdio_enable_func(data->func); 200 if (err < 0) { 201 clear_bit(HCI_RUNNING, &hdev->flags); 202 goto release; 203 } 204 205 err = sdio_claim_irq(data->func, btsdio_interrupt); 206 if (err < 0) { 207 sdio_disable_func(data->func); 208 clear_bit(HCI_RUNNING, &hdev->flags); 209 goto release; 210 } 211 212 if (data->func->class == SDIO_CLASS_BT_B) 213 sdio_writeb(data->func, 0x00, REG_MD_STAT, NULL); 214 215 sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL); 216 217release: 218 sdio_release_host(data->func); 219 220 return err; 221} 222 223static int btsdio_close(struct hci_dev *hdev) 224{ 225 struct btsdio_data *data = hdev->driver_data; 226 227 BT_DBG("%s", hdev->name); 228 229 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) 230 return 0; 231 232 sdio_claim_host(data->func); 233 234 sdio_writeb(data->func, 0x00, REG_EN_INTRD, NULL); 235 236 sdio_release_irq(data->func); 237 sdio_disable_func(data->func); 238 239 sdio_release_host(data->func); 240 241 return 0; 242} 243 244static int btsdio_flush(struct hci_dev *hdev) 245{ 246 struct btsdio_data *data = hdev->driver_data; 247 248 BT_DBG("%s", hdev->name); 249 250 skb_queue_purge(&data->txq); 251 252 return 0; 253} 254 255static int btsdio_send_frame(struct sk_buff *skb) 256{ 257 struct hci_dev *hdev = (struct hci_dev *) skb->dev; 258 struct btsdio_data *data = hdev->driver_data; 259 260 BT_DBG("%s", hdev->name); 261 262 if (!test_bit(HCI_RUNNING, &hdev->flags)) 263 return -EBUSY; 264 265 switch (bt_cb(skb)->pkt_type) { 266 case HCI_COMMAND_PKT: 267 hdev->stat.cmd_tx++; 268 break; 269 270 case HCI_ACLDATA_PKT: 271 hdev->stat.acl_tx++; 272 break; 273 274 case HCI_SCODATA_PKT: 275 hdev->stat.sco_tx++; 276 break; 277 278 default: 279 return -EILSEQ; 280 } 281 282 skb_queue_tail(&data->txq, skb); 283 284 schedule_work(&data->work); 285 286 return 0; 287} 288 289static void btsdio_destruct(struct hci_dev *hdev) 290{ 291 struct btsdio_data *data = hdev->driver_data; 292 293 BT_DBG("%s", hdev->name); 294 295 kfree(data); 296} 297 298static int btsdio_probe(struct sdio_func *func, 299 const struct sdio_device_id *id) 300{ 301 struct btsdio_data *data; 302 struct hci_dev *hdev; 303 struct sdio_func_tuple *tuple = func->tuples; 304 int err; 305 306 BT_DBG("func %p id %p class 0x%04x", func, id, func->class); 307 308 while (tuple) { 309 BT_DBG("code 0x%x size %d", tuple->code, tuple->size); 310 tuple = tuple->next; 311 } 312 313 data = kzalloc(sizeof(*data), GFP_KERNEL); 314 if (!data) 315 return -ENOMEM; 316 317 data->func = func; 318 319 INIT_WORK(&data->work, btsdio_work); 320 321 skb_queue_head_init(&data->txq); 322 323 hdev = hci_alloc_dev(); 324 if (!hdev) { 325 kfree(data); 326 return -ENOMEM; 327 } 328 329 hdev->type = HCI_SDIO; 330 hdev->driver_data = data; 331 332 data->hdev = hdev; 333 334 SET_HCIDEV_DEV(hdev, &func->dev); 335 336 hdev->open = btsdio_open; 337 hdev->close = btsdio_close; 338 hdev->flush = btsdio_flush; 339 hdev->send = btsdio_send_frame; 340 hdev->destruct = btsdio_destruct; 341 342 hdev->owner = THIS_MODULE; 343 344 err = hci_register_dev(hdev); 345 if (err < 0) { 346 hci_free_dev(hdev); 347 kfree(data); 348 return err; 349 } 350 351 sdio_set_drvdata(func, data); 352 353 return 0; 354} 355 356static void btsdio_remove(struct sdio_func *func) 357{ 358 struct btsdio_data *data = sdio_get_drvdata(func); 359 struct hci_dev *hdev; 360 361 BT_DBG("func %p", func); 362 363 if (!data) 364 return; 365 366 hdev = data->hdev; 367 368 sdio_set_drvdata(func, NULL); 369 370 hci_unregister_dev(hdev); 371 372 hci_free_dev(hdev); 373} 374 375static struct sdio_driver btsdio_driver = { 376 .name = "btsdio", 377 .probe = btsdio_probe, 378 .remove = btsdio_remove, 379 .id_table = btsdio_table, 380}; 381 382static int __init btsdio_init(void) 383{ 384 BT_INFO("Generic Bluetooth SDIO driver ver %s", VERSION); 385 386 return sdio_register_driver(&btsdio_driver); 387} 388 389static void __exit btsdio_exit(void) 390{ 391 sdio_unregister_driver(&btsdio_driver); 392} 393 394module_init(btsdio_init); 395module_exit(btsdio_exit); 396 397MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 398MODULE_DESCRIPTION("Generic Bluetooth SDIO driver ver " VERSION); 399MODULE_VERSION(VERSION); 400MODULE_LICENSE("GPL");