xref: /haiku/src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp (revision 68d37cfb3a755a7270d772b505ee15c8b18aa5e0)
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, &notify_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