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