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