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