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