1 /* 2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "h2generic.h" 9 10 #include <kernel.h> 11 #include <malloc.h> 12 #include <stdio.h> 13 #include <string.h> 14 15 #include <KernelExport.h> 16 #include <ByteOrder.h> 17 #include <Drivers.h> 18 19 #include <btModules.h> 20 21 #include "snet_buffer.h" 22 #include "h2cfg.h" 23 #include "h2debug.h" 24 #include "h2transactions.h" 25 #include "h2util.h" 26 27 28 int32 api_version = B_CUR_DRIVER_API_VERSION; 29 30 // Modules 31 static const char* usb_name = B_USB_MODULE_NAME; 32 static const char* hci_name = BT_HCI_MODULE_NAME; 33 static const char* btDevices_name = BT_HCI_MODULE_NAME; 34 35 36 usb_module_info* usb = NULL; 37 bt_hci_module_info* hci = NULL; // TODO remove / clean 38 struct bt_hci_module_info* btDevices = NULL; 39 struct net_buffer_module_info* nb = NULL; 40 struct bluetooth_core_data_module_info* btCoreData = NULL; 41 42 // Driver Global data 43 static char* publish_names[MAX_BT_GENERIC_USB_DEVICES]; 44 45 int32 dev_count = 0; // number of connected devices 46 static bt_usb_dev* bt_usb_devices[MAX_BT_GENERIC_USB_DEVICES]; 47 sem_id dev_table_sem = -1; // sem to synchronize access to device table 48 49 status_t submit_nbuffer(hci_id hid, net_buffer* nbuf); 50 51 usb_support_descriptor supported_devices[] = { 52 // Generic Bluetooth USB device 53 // Class, SubClass, and Protocol codes that describe a Bluetooth device 54 { UDCLASS_WIRELESS, UDSUBCLASS_RF, UDPROTO_BLUETOOTH, 0, 0 }, 55 56 // Broadcom BCM2035 57 { 0, 0, 0, 0x0a5c, 0x200a }, 58 { 0, 0, 0, 0x0a5c, 0x2009 }, 59 60 // Devices taken from the linux Driver 61 // MediaTek MT76x0E 62 { 0, 0, 0, 0x0e8d, 0x763f }, 63 // Broadcom SoftSailing reporting vendor specific 64 { 0, 0, 0, 0x0a5c, 0x21e1 }, 65 66 // Apple MacBookPro 7,1 67 { 0, 0, 0, 0x05ac, 0x8213 }, 68 // Apple iMac11,1 69 { 0, 0, 0, 0x05ac, 0x8215 }, 70 // Apple MacBookPro6,2 71 { 0, 0, 0, 0x05ac, 0x8218 }, 72 // Apple MacBookAir3,1, MacBookAir3,2 73 { 0, 0, 0, 0x05ac, 0x821b }, 74 // Apple MacBookAir4,1 75 { 0, 0, 0, 0x05ac, 0x821f }, 76 // Apple MacBookPro8,2 77 { 0, 0, 0, 0x05ac, 0x821a }, 78 // Apple MacMini5,1 79 { 0, 0, 0, 0x05ac, 0x8281 }, 80 81 // AVM BlueFRITZ! USB v2.0 82 { 0, 0, 0, 0x057c, 0x3800 }, 83 // Bluetooth Ultraport Module from IBM 84 { 0, 0, 0, 0x04bf, 0x030a }, 85 // ALPS Modules with non-standard id 86 { 0, 0, 0, 0x044e, 0x3001 }, 87 { 0, 0, 0, 0x044e, 0x3002 }, 88 // Ericsson with non-standard id 89 { 0, 0, 0, 0x0bdb, 0x1002 }, 90 91 // Canyon CN-BTU1 with HID interfaces 92 { 0, 0, 0, 0x0c10, 0x0000 }, 93 94 // Broadcom BCM20702A0 95 { 0, 0, 0, 0x413c, 0x8197 }, 96 97 }; 98 99 /* add a device to the list of connected devices */ 100 static bt_usb_dev* 101 spawn_device(usb_device usb_dev) 102 { 103 CALLED(); 104 105 int32 i; 106 status_t err = B_OK; 107 bt_usb_dev* new_bt_dev = NULL; 108 109 // 16 usb dongles... 110 if (dev_count >= MAX_BT_GENERIC_USB_DEVICES) { 111 ERROR("%s: Device table full\n", __func__); 112 goto exit; 113 } 114 115 // try the allocation 116 new_bt_dev = (bt_usb_dev*)malloc(sizeof(bt_usb_dev)); 117 if (new_bt_dev == NULL) { 118 ERROR("%s: Unable to malloc new bt device\n", __func__); 119 goto exit; 120 } 121 memset(new_bt_dev, 0, sizeof(bt_usb_dev)); 122 123 // We will need this sem for some flow control 124 new_bt_dev->cmd_complete = create_sem(1, 125 BLUETOOTH_DEVICE_DEVFS_NAME "cmd_complete"); 126 if (new_bt_dev->cmd_complete < 0) { 127 err = new_bt_dev->cmd_complete; 128 ERROR("%s: Unable to create bt device command semaphore: %" B_PRId32 "\n", __func__, err); 129 goto bail0; 130 } 131 132 // and this for something else 133 new_bt_dev->lock = create_sem(1, BLUETOOTH_DEVICE_DEVFS_NAME "lock"); 134 if (new_bt_dev->lock < 0) { 135 err = new_bt_dev->lock; 136 ERROR("%s: Unable to create bt device lock semaphore: %" B_PRId32 "\n", __func__, err); 137 goto bail1; 138 } 139 140 // find a free slot and fill out the name 141 acquire_sem(dev_table_sem); 142 for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { 143 if (bt_usb_devices[i] == NULL) { 144 bt_usb_devices[i] = new_bt_dev; 145 sprintf(new_bt_dev->name, "%s/%" B_PRId32, 146 BLUETOOTH_DEVICE_PATH, i); 147 new_bt_dev->num = i; 148 TRACE("%s: added device %p %" B_PRId32 " %s\n", __func__, 149 bt_usb_devices[i], new_bt_dev->num, new_bt_dev->name); 150 break; 151 } 152 } 153 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 154 155 // In the case we cannot find a free slot 156 if (i >= MAX_BT_GENERIC_USB_DEVICES) { 157 ERROR("%s: Device could not be added\n", __func__); 158 goto bail2; 159 } 160 161 new_bt_dev->dev = usb_dev; 162 // TODO: currently only server opens 163 new_bt_dev->open_count = 0; 164 165 dev_count++; 166 return new_bt_dev; 167 168 bail2: 169 delete_sem(new_bt_dev->lock); 170 bail1: 171 delete_sem(new_bt_dev->cmd_complete); 172 bail0: 173 free(new_bt_dev); 174 new_bt_dev = NULL; 175 exit: 176 return new_bt_dev; 177 } 178 179 180 // remove a device from the list of connected devices 181 static void 182 kill_device(bt_usb_dev* bdev) 183 { 184 if (bdev != NULL) { 185 TRACE("%s: (%p)\n", __func__, bdev); 186 187 delete_sem(bdev->lock); 188 delete_sem(bdev->cmd_complete); 189 190 // mark it free 191 bt_usb_devices[bdev->num] = NULL; 192 193 free(bdev); 194 dev_count--; 195 } 196 } 197 198 199 bt_usb_dev* 200 fetch_device(bt_usb_dev* dev, hci_id hid) 201 { 202 int i; 203 204 // TRACE("%s: (%p) or %d\n", __func__, dev, hid); 205 206 acquire_sem(dev_table_sem); 207 if (dev != NULL) { 208 for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { 209 if (bt_usb_devices[i] == dev) { 210 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 211 return bt_usb_devices[i]; 212 } 213 } 214 } else { 215 for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { 216 if (bt_usb_devices[i] != NULL && bt_usb_devices[i]->hdev == hid) { 217 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 218 return bt_usb_devices[i]; 219 } 220 } 221 } 222 223 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 224 225 return NULL; 226 } 227 228 229 #if 0 230 #pragma mark - 231 #endif 232 233 // called by USB Manager when device is added to the USB 234 static status_t 235 device_added(usb_device dev, void** cookie) 236 { 237 const usb_interface_info* interface; 238 const usb_device_descriptor* desc; 239 const usb_configuration_info* config; 240 const usb_interface_info* uif; 241 const usb_endpoint_info* ep; 242 243 status_t err = B_ERROR; 244 bt_usb_dev* new_bt_dev = spawn_device(dev); 245 int e; 246 247 TRACE("%s: device_added(%p)\n", __func__, new_bt_dev); 248 249 if (new_bt_dev == NULL) { 250 ERROR("%s: Couldn't allocate device record.\n", __func__); 251 err = ENOMEM; 252 goto bail_no_mem; 253 } 254 255 // we only have 1 configuration number 0 256 config = usb->get_nth_configuration(dev, 0); 257 // dump_usb_configuration_info(config); 258 if (config == NULL) { 259 ERROR("%s: Couldn't get default USB config.\n", __func__); 260 err = B_ERROR; 261 goto bail; 262 } 263 264 TRACE("%s: found %" B_PRIuSIZE " alt interfaces.\n", __func__, 265 config->interface->alt_count); 266 267 // set first interface 268 interface = &config->interface->alt[0]; 269 err = usb->set_alt_interface(new_bt_dev->dev, interface); 270 271 if (err != B_OK) { 272 ERROR("%s: set_alt_interface() error.\n", __func__); 273 goto bail; 274 } 275 276 // call set_configuration() only after calling set_alt_interface() 277 err = usb->set_configuration(dev, config); 278 if (err != B_OK) { 279 ERROR("%s: set_configuration() error.\n", __func__); 280 goto bail; 281 } 282 283 // Place to find out whats our concrete device and set up some special 284 // info to our driver. If this code increases too much reconsider 285 // this implementation 286 desc = usb->get_device_descriptor(dev); 287 if (desc->vendor_id == 0x0a5c 288 && (desc->product_id == 0x200a 289 || desc->product_id == 0x2009 290 || desc->product_id == 0x2035)) { 291 292 new_bt_dev->driver_info = BT_WILL_NEED_A_RESET | BT_SCO_NOT_WORKING; 293 294 } 295 /* 296 else if ( desc->vendor_id == YOUR_VENDOR_HERE 297 && desc->product_id == YOUR_PRODUCT_HERE ) { 298 YOUR_SPECIAL_FLAGS_HERE 299 } 300 */ 301 302 if (new_bt_dev->driver_info & BT_IGNORE_THIS_DEVICE) { 303 err = ENODEV; 304 goto bail; 305 } 306 307 // security check 308 if (config->interface->active->descr->interface_number > 0) { 309 ERROR("%s: Strange condition happened %d\n", __func__, 310 config->interface->active->descr->interface_number); 311 err = B_ERROR; 312 goto bail; 313 } 314 315 TRACE("%s: Found %" B_PRIuSIZE " interfaces. Expected 3\n", __func__, 316 config->interface_count); 317 318 // Find endpoints that we need 319 uif = config->interface->active; 320 for (e = 0; e < uif->descr->num_endpoints; e++) { 321 322 ep = &uif->endpoint[e]; 323 switch (ep->descr->attributes & USB_ENDPOINT_ATTR_MASK) { 324 case USB_ENDPOINT_ATTR_INTERRUPT: 325 if (ep->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) 326 { 327 new_bt_dev->intr_in_ep = ep; 328 new_bt_dev->max_packet_size_intr_in 329 = ep->descr->max_packet_size; 330 TRACE("%s: INT in\n", __func__); 331 } else { 332 TRACE("%s: INT out\n", __func__); 333 } 334 break; 335 336 case USB_ENDPOINT_ATTR_BULK: 337 if (ep->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) { 338 new_bt_dev->bulk_in_ep = ep; 339 new_bt_dev->max_packet_size_bulk_in 340 = ep->descr->max_packet_size; 341 TRACE("%s: BULK int\n", __func__); 342 } else { 343 new_bt_dev->bulk_out_ep = ep; 344 new_bt_dev->max_packet_size_bulk_out 345 = ep->descr->max_packet_size; 346 TRACE("%s: BULK out\n", __func__); 347 } 348 break; 349 } 350 } 351 352 if (!new_bt_dev->bulk_in_ep || !new_bt_dev->bulk_out_ep 353 || !new_bt_dev->intr_in_ep) { 354 ERROR("%s: Minimal # endpoints for BT not found\n", __func__); 355 goto bail; 356 } 357 358 // Look into the devices suported to understand this 359 if (new_bt_dev->driver_info & BT_DIGIANSWER) 360 new_bt_dev->ctrl_req = USB_TYPE_VENDOR; 361 else 362 new_bt_dev->ctrl_req = USB_TYPE_CLASS; 363 364 new_bt_dev->connected = true; 365 366 // set the cookie that will be passed to other USB 367 // hook functions (currently device_removed() is the only other) 368 *cookie = new_bt_dev; 369 TRACE("%s: Ok %p\n", __func__, new_bt_dev); 370 return B_OK; 371 372 bail: 373 kill_device(new_bt_dev); 374 bail_no_mem: 375 *cookie = NULL; 376 377 return err; 378 } 379 380 381 // Called by USB Manager when device is removed from the USB 382 static status_t 383 device_removed(void* cookie) 384 { 385 bt_usb_dev* bdev = fetch_device((bt_usb_dev*)cookie, 0); 386 387 TRACE("%s: device_removed(%p)\n", __func__, bdev); 388 389 if (bdev == NULL) { 390 ERROR("%s: Device not present in driver.\n", __func__); 391 return B_ERROR; 392 } 393 394 if (!TEST_AND_CLEAR(&bdev->state, RUNNING)) 395 ERROR("%s: wasnt running?\n", __func__); 396 397 TRACE("%s: Cancelling queues...\n", __func__); 398 if (bdev->intr_in_ep != NULL) 399 usb->cancel_queued_transfers(bdev->intr_in_ep->handle); 400 if (bdev->bulk_in_ep != NULL) 401 usb->cancel_queued_transfers(bdev->bulk_in_ep->handle); 402 if (bdev->bulk_out_ep != NULL) 403 usb->cancel_queued_transfers(bdev->bulk_out_ep->handle); 404 405 bdev->connected = false; 406 407 return B_OK; 408 } 409 410 411 static bt_hci_transport_hooks bluetooth_hooks = { 412 NULL, 413 &submit_nbuffer, 414 &submit_nbuffer, 415 NULL, 416 NULL, 417 H2 418 }; 419 420 421 static usb_notify_hooks notify_hooks = { 422 &device_added, 423 &device_removed 424 }; 425 426 #if 0 427 #pragma mark - 428 #endif 429 430 status_t 431 submit_nbuffer(hci_id hid, net_buffer* nbuf) 432 { 433 bt_usb_dev* bdev = NULL; 434 435 bdev = fetch_device(NULL, hid); 436 437 TRACE("%s: index=%" B_PRId32 " nbuf=%p bdev=%p\n", __func__, hid, 438 nbuf, bdev); 439 440 if (bdev != NULL) { 441 switch (nbuf->protocol) { 442 case BT_COMMAND: 443 // not issued this way 444 break; 445 446 case BT_ACL: 447 return submit_tx_acl(bdev, nbuf); 448 break; 449 450 default: 451 panic("submit_nbuffer: no protocol"); 452 break; 453 454 } 455 } 456 457 return B_ERROR; 458 459 } 460 461 462 // implements the POSIX open() 463 static status_t 464 device_open(const char* name, uint32 flags, void **cookie) 465 { 466 CALLED(); 467 468 status_t err = ENODEV; 469 bt_usb_dev* bdev = NULL; 470 hci_id hdev; 471 int i; 472 473 acquire_sem(dev_table_sem); 474 for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { 475 if (bt_usb_devices[i] && !strcmp(name, bt_usb_devices[i]->name)) { 476 bdev = bt_usb_devices[i]; 477 break; 478 } 479 } 480 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 481 482 if (bdev == NULL) { 483 ERROR("%s: Device not found in the open list!", __func__); 484 *cookie = NULL; 485 return B_ERROR; 486 } 487 488 // Set RUNNING 489 if (TEST_AND_SET(&bdev->state, RUNNING)) { 490 ERROR("%s: dev already running! - reOpened device!\n", __func__); 491 return B_ERROR; 492 } 493 494 acquire_sem(bdev->lock); 495 // TX structures 496 for (i = 0; i < BT_DRIVER_TXCOVERAGE; i++) { 497 list_init(&bdev->nbuffersTx[i]); 498 bdev->nbuffersPendingTx[i] = 0; 499 } 500 501 // RX structures 502 bdev->eventRx = NULL; 503 for (i = 0; i < BT_DRIVER_RXCOVERAGE; i++) { 504 bdev->nbufferRx[i] = NULL; 505 } 506 507 // dumping the USB frames 508 init_room(&bdev->eventRoom); 509 init_room(&bdev->aclRoom); 510 // init_room(new_bt_dev->scoRoom); 511 512 list_init(&bdev->snetBufferRecycleTrash); 513 514 // Allocate set and register the HCI device 515 if (btDevices != NULL) { 516 bluetooth_device* ndev; 517 // TODO: Fill the transport descriptor 518 err = btDevices->RegisterDriver(&bluetooth_hooks, &ndev); 519 520 if (err == B_OK) { 521 bdev->hdev = hdev = ndev->index; // Get the index 522 bdev->ndev = ndev; // Get the net_device 523 524 } else { 525 hdev = bdev->num; // XXX: Lets try to go on 526 } 527 } else { 528 hdev = bdev->num; // XXX: Lets try to go on 529 } 530 531 bdev->hdev = hdev; 532 533 *cookie = bdev; 534 release_sem(bdev->lock); 535 536 return B_OK; 537 538 } 539 540 541 /* called when a client calls POSIX close() on the driver, but I/O 542 * requests may still be pending 543 */ 544 static status_t 545 device_close(void* cookie) 546 { 547 CALLED(); 548 549 int32 i; 550 void* item; 551 bt_usb_dev* bdev = (bt_usb_dev*)cookie; 552 553 if (bdev == NULL) 554 panic("bad cookie"); 555 556 // Clean queues 557 558 if (bdev->connected == true) { 559 TRACE("%s: Cancelling queues...\n", __func__); 560 561 if (bdev->intr_in_ep != NULL) 562 usb->cancel_queued_transfers(bdev->intr_in_ep->handle); 563 564 if (bdev->bulk_in_ep!=NULL) 565 usb->cancel_queued_transfers(bdev->bulk_in_ep->handle); 566 567 if (bdev->bulk_out_ep!=NULL) 568 usb->cancel_queued_transfers(bdev->bulk_out_ep->handle); 569 } 570 571 // TX 572 for (i = 0; i < BT_DRIVER_TXCOVERAGE; i++) { 573 if (i == BT_COMMAND) { 574 while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) 575 snb_free((snet_buffer*)item); 576 } else { 577 while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) 578 nb_destroy((net_buffer*)item); 579 } 580 } 581 // RX 582 for (i = 0; i < BT_DRIVER_RXCOVERAGE; i++) { 583 nb_destroy(bdev->nbufferRx[i]); 584 } 585 snb_free(bdev->eventRx); 586 587 purge_room(&bdev->eventRoom); 588 purge_room(&bdev->aclRoom); 589 590 // Device no longer in our Stack 591 if (btDevices != NULL) 592 btDevices->UnregisterDriver(bdev->hdev); 593 594 // unSet RUNNING 595 if (TEST_AND_CLEAR(&bdev->state, RUNNING)) { 596 ERROR("%s: %s not running?\n", __func__, bdev->name); 597 return B_ERROR; 598 } 599 600 return B_OK; 601 } 602 603 604 // Called after device_close(), when all pending I / O requests have returned 605 static status_t 606 device_free(void* cookie) 607 { 608 CALLED(); 609 610 status_t err = B_OK; 611 bt_usb_dev* bdev = (bt_usb_dev*)cookie; 612 613 if (!bdev->connected) 614 kill_device(bdev); 615 616 return err; 617 } 618 619 620 // implements the POSIX ioctl() 621 static status_t 622 device_control(void* cookie, uint32 msg, void* params, size_t size) 623 { 624 status_t err = B_ERROR; 625 bt_usb_dev* bdev = (bt_usb_dev*)cookie; 626 snet_buffer* snbuf; 627 #if BT_DRIVER_SUPPORTS_ACL // ACL 628 int32 i; 629 #endif 630 631 TOUCH(size); 632 TRACE("%s: ioctl() opcode %" B_PRId32 " size %" B_PRIuSIZE ".\n", __func__, 633 msg, size); 634 635 if (bdev == NULL) { 636 TRACE("%s: Bad cookie\n", __func__); 637 return B_BAD_VALUE; 638 } 639 640 if (params == NULL || !IS_USER_ADDRESS(params)) { 641 TRACE("%s: Invalid pointer control\n", __func__); 642 return B_BAD_VALUE; 643 } 644 645 acquire_sem(bdev->lock); 646 647 switch (msg) { 648 case ISSUE_BT_COMMAND: { 649 if (size == 0) { 650 TRACE("%s: Invalid size control\n", __func__); 651 err = B_BAD_VALUE; 652 break; 653 } 654 655 void* _params = alloca(size); 656 if (user_memcpy(_params, params, size) != B_OK) 657 return B_BAD_ADDRESS; 658 659 // TODO: Reuse from some TXcompleted queue 660 // snbuf = snb_create(size); 661 snbuf = snb_fetch(&bdev->snetBufferRecycleTrash, size); 662 snb_put(snbuf, _params, size); 663 664 err = submit_tx_command(bdev, snbuf); 665 TRACE("%s: command launched\n", __func__); 666 break; 667 } 668 669 case BT_UP: 670 // EVENTS 671 err = submit_rx_event(bdev); 672 if (err != B_OK) { 673 bdev->state = CLEAR_BIT(bdev->state, ANCILLYANT); 674 ERROR("%s: Queuing failed device stops running\n", __func__); 675 break; 676 } 677 678 #if BT_DRIVER_SUPPORTS_ACL // ACL 679 for (i = 0; i < MAX_ACL_IN_WINDOW; i++) { 680 err = submit_rx_acl(bdev); 681 if (err != B_OK && i == 0) { 682 bdev->state = CLEAR_BIT(bdev->state, ANCILLYANT); 683 // Set the flaq in the HCI world 684 ERROR("%s: Queuing failed device stops running\n", 685 __func__); 686 break; 687 } 688 } 689 #endif 690 691 bdev->state = SET_BIT(bdev->state, RUNNING); 692 693 #if BT_DRIVER_SUPPORTS_SCO 694 // TODO: SCO / eSCO 695 #endif 696 697 ERROR("%s: Device online\n", __func__); 698 break; 699 700 case GET_STATS: 701 err = user_memcpy(params, &bdev->stat, sizeof(bt_hci_statistics)); 702 break; 703 704 case GET_HCI_ID: 705 err = user_memcpy(params, &bdev->hdev, sizeof(hci_id)); 706 break; 707 708 709 default: 710 ERROR("%s: Invalid opcode.\n", __func__); 711 err = B_DEV_INVALID_IOCTL; 712 break; 713 } 714 715 release_sem(bdev->lock); 716 return err; 717 } 718 719 720 // implements the POSIX read() 721 static status_t 722 device_read(void* cookie, off_t pos, void* buffer, size_t* count) 723 { 724 TRACE("%s: Reading... count = %" B_PRIuSIZE "\n", __func__, *count); 725 726 *count = 0; 727 return B_OK; 728 } 729 730 731 // implements the POSIX write() 732 static status_t 733 device_write(void* cookie, off_t pos, const void* buffer, size_t* count) 734 { 735 CALLED(); 736 737 return B_ERROR; 738 } 739 740 741 #if 0 742 #pragma mark - 743 #endif 744 745 746 static int 747 dump_driver(int argc, char** argv) 748 { 749 int i; 750 snet_buffer* item = NULL; 751 752 for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) { 753 754 if (bt_usb_devices[i] != NULL) { 755 kprintf("%s : \n", bt_usb_devices[i]->name); 756 kprintf("\taclroom = %d\teventroom = %d\tcommand & events =%d\n", 757 snb_packets(&bt_usb_devices[i]->eventRoom), 758 snb_packets(&bt_usb_devices[i]->aclRoom), 759 snb_packets(&bt_usb_devices[i]->snetBufferRecycleTrash)); 760 761 while ((item = (snet_buffer*)list_get_next_item( 762 &bt_usb_devices[i]->snetBufferRecycleTrash, item)) != NULL) 763 snb_dump(item); 764 } 765 } 766 767 return 0; 768 } 769 770 771 // called each time the driver is loaded by the kernel 772 status_t 773 init_driver(void) 774 { 775 CALLED(); 776 int j; 777 778 if (get_module(BT_CORE_DATA_MODULE_NAME, 779 (module_info**)&btCoreData) != B_OK) { 780 ERROR("%s: cannot get module '%s'\n", __func__, 781 BT_CORE_DATA_MODULE_NAME); 782 return B_ERROR; 783 } 784 785 // BT devices MODULE INITS 786 if (get_module(btDevices_name, (module_info**)&btDevices) != B_OK) { 787 ERROR("%s: cannot get module '%s'\n", __func__, btDevices_name); 788 goto err_release3; 789 } 790 791 // HCI MODULE INITS 792 if (get_module(hci_name, (module_info**)&hci) != B_OK) { 793 ERROR("%s: cannot get module '%s'\n", __func__, hci_name); 794 #ifndef BT_SURVIVE_WITHOUT_HCI 795 goto err_release2; 796 #endif 797 } 798 799 // USB MODULE INITS 800 if (get_module(usb_name, (module_info**)&usb) != B_OK) { 801 ERROR("%s: cannot get module '%s'\n", __func__, usb_name); 802 goto err_release1; 803 } 804 805 if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&nb) != B_OK) { 806 ERROR("%s: cannot get module '%s'\n", __func__, 807 NET_BUFFER_MODULE_NAME); 808 #ifndef BT_SURVIVE_WITHOUT_NET_BUFFERS 809 goto err_release; 810 #endif 811 } 812 813 // GENERAL INITS 814 dev_table_sem = create_sem(1, BLUETOOTH_DEVICE_DEVFS_NAME "dev_table_lock"); 815 if (dev_table_sem < 0) { 816 goto err; 817 } 818 819 for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) { 820 bt_usb_devices[j] = NULL; 821 } 822 823 // Note: After here device_added and publish devices hooks are called 824 usb->register_driver(BLUETOOTH_DEVICE_DEVFS_NAME, supported_devices, 1, NULL); 825 usb->install_notify(BLUETOOTH_DEVICE_DEVFS_NAME, ¬ify_hooks); 826 827 add_debugger_command("bth2generic", &dump_driver, 828 "Lists H2 Transport device info"); 829 830 return B_OK; 831 832 err: // Releasing 833 put_module(NET_BUFFER_MODULE_NAME); 834 err_release: 835 put_module(usb_name); 836 err_release1: 837 put_module(hci_name); 838 #ifndef BT_SURVIVE_WITHOUT_HCI 839 err_release2: 840 #endif 841 put_module(btDevices_name); 842 err_release3: 843 put_module(BT_CORE_DATA_MODULE_NAME); 844 845 return B_ERROR; 846 } 847 848 849 // called just before the kernel unloads the driver 850 void 851 uninit_driver(void) 852 { 853 CALLED(); 854 855 int32 j; 856 857 for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) { 858 859 if (publish_names[j] != NULL) 860 free(publish_names[j]); 861 862 if (bt_usb_devices[j] != NULL) { 863 // if (connected_dev != NULL) { 864 // debugf("Device %p still exists.\n", connected_dev); 865 // } 866 ERROR("%s: %s still present?\n", __func__, bt_usb_devices[j]->name); 867 kill_device(bt_usb_devices[j]); 868 } 869 } 870 871 usb->uninstall_notify(BLUETOOTH_DEVICE_DEVFS_NAME); 872 873 remove_debugger_command("bth2generic", &dump_driver); 874 875 // Releasing modules 876 put_module(usb_name); 877 put_module(hci_name); 878 // TODO: netbuffers 879 880 delete_sem(dev_table_sem); 881 } 882 883 884 const char** 885 publish_devices(void) 886 { 887 CALLED(); 888 int32 j; 889 int32 i = 0; 890 891 char* str; 892 893 for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) { 894 if (publish_names[j]) { 895 free(publish_names[j]); 896 publish_names[j] = NULL; 897 } 898 } 899 900 acquire_sem(dev_table_sem); 901 for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) { 902 if (bt_usb_devices[j] != NULL && bt_usb_devices[j]->connected) { 903 str = strdup(bt_usb_devices[j]->name); 904 if (str) { 905 publish_names[i++] = str; 906 TRACE("%s: publishing %s\n", __func__, bt_usb_devices[j]->name); 907 } 908 } 909 } 910 release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE); 911 912 publish_names[i] = NULL; 913 TRACE("%s: published %" B_PRId32 " devices\n", __func__, i); 914 915 // TODO: this method might make better memory use 916 // dev_names = (char**)malloc(sizeof(char*) * (dev_count + 1)); 917 // if (dev_names) { 918 // for (i = 0; i < MAX_NUM_DEVS; i++) { 919 // if ((dev != NULL) // dev + \n 920 // && (dev_names[i] = (char*)malloc(strlen(DEVICE_PATH) + 2))) { 921 // sprintf(dev_names[i], "%s%ld", DEVICE_PATH, dev->num); 922 // debugf("publishing \"%s\"\n", dev_names[i]); 923 // } 924 // } 925 926 return (const char**)publish_names; 927 } 928 929 930 static device_hooks hooks = { 931 device_open, 932 device_close, 933 device_free, 934 device_control, 935 device_read, 936 device_write, 937 NULL, 938 NULL, 939 NULL, 940 NULL 941 }; 942 943 944 device_hooks* 945 find_device(const char* name) 946 { 947 CALLED(); 948 949 return &hooks; 950 } 951