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