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