Bug Summary

File:src/add-ons/kernel/drivers/bluetooth/h2/h2generic/h2generic.cpp
Warning:line 153, column 2
Use of memory after it is freed

Annotated Source Code

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