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