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