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