bluetooth: Refactor debugging and trace calls

* The old debug system was too complex and made
  troubleshooring difficult. (it also was unique
  like a snowflake... which we don't want)
* Move to the classic TRACE / ERROR a large majority
  of the code has changed to.
* I like trace statements, but drop some obvious ones
* Fix style issues along the way
This commit is contained in:
Alexander von Gluck IV
2016-04-09 23:40:54 -05:00
parent a4a85baea1
commit 1f2fa6cd09
10 changed files with 200 additions and 215 deletions
+12 -42
View File
@@ -1,52 +1,22 @@
/*
* Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
*
* All rights reserved. Distributed under the terms of the MIT License.
* Copyright 2015-2016 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
*/
#ifndef _BTDEBUG_H
#define _BTDEBUG_H
#ifdef BT_DEBUG_THIS_MODULE
#ifndef MODULE_NAME
//#warning MODULE_NAME not defined for Haiku BT debugging tools
#define MODULE_NAME "BT"
#endif
#ifndef SUBMODULE_NAME
//#warning SUBMODULE_NAME not defined for Haiku BT debugging tools
#define SUBMODULE_NAME ""
#endif
#ifndef SUBMODULE_COLOR
//#warning SUBMODULE_COLOR not defined for Haiku BT debugging tools
#define SUBMODULE_COLOR 38
#endif
#define debugf(a,param...) dprintf("\x1b[%dm" MODULE_NAME " " SUBMODULE_NAME " " "%s\x1b[0m: " a,SUBMODULE_COLOR,__FUNCTION__, param);
#define flowf(a) dprintf("\x1b[%dm" MODULE_NAME " " SUBMODULE_NAME " " "%s\x1b[0m: " a,SUBMODULE_COLOR,__FUNCTION__);
// XXX: Remove once things get "better"
#define DEBUG
#ifdef DEBUG
# define TRACE(x...) dprintf("bt: " x)
#else
#define debugf(a,param...)
#define flowf(a,param...)
#endif
#undef BT_DEBUG_THIS_MODULE
#define TOUCH(x) ((void)(x))
/* */
#if 0
#pragma mark - Kernel Auxiliary Stuff -
# define TRACE(x...) ;
#endif
static inline uint32 TEST_AND_SET(uint32 *byte, uint32 bit_mask) {
#define ERROR(x...) dprintf("bt: " x)
#define CALLED(x...) TRACE("bt: CALLED %s\n", __PRETTY_FUNCTION__)
uint32 val = (*byte&bit_mask)!=0;
*byte |= bit_mask;
return val;
}
static inline uint32 TEST_AND_CLEAR(uint32* byte, uint32 bit_mask) {
uint32 val = (*byte&bit_mask)!=0;
*byte &= ~bit_mask;
return val;
}
#endif /* _BTDEBUG_H */
@@ -114,7 +114,8 @@ PostEvent(bluetooth_device* ndev, void* event, size_t size)
if (conn == NULL)
panic("no mem for conn desc");
conn->ndevice = ndev;
debugf("Registered connection handle=%#x\n",data->handle);
TRACE("%s: Registered connection handle=%#x\n", __func__,
data->handle);
break;
}
@@ -126,7 +127,8 @@ PostEvent(bluetooth_device* ndev, void* event, size_t size)
(outgoingEvent + 1);
RemoveConnection(data->handle, ndev->index);
debugf("unRegistered connection handle=%#x\n",data->handle);
TRACE("%s: unRegistered connection handle=%#x\n", __func__,
data->handle);
break;
}
@@ -140,10 +142,10 @@ PostEvent(bluetooth_device* ndev, void* event, size_t size)
event, size, B_TIMEOUT, 1 * 1000 * 1000);
if (err != B_OK)
debugf("Error posting userland %s\n", strerror(err));
ERROR("%s: Error posting userland %s\n", __func__, strerror(err));
} else {
flowf("ERROR:bluetooth_server not found for posting\n");
ERROR("%s: bluetooth_server not found for posting!\n", __func__);
err = B_NAME_NOT_FOUND;
}
@@ -36,7 +36,7 @@ uint16
ChannelAllocateCid(HciConnection* conn)
{
uint16 cid = conn->lastCid;
debugf("Starting search cid %d\n",cid);
TRACE("%s: Starting search cid %d\n", __func__, cid);
do {
cid = (cid == L2CAP_LAST_CID) ? L2CAP_FIRST_CID : cid + 1;
@@ -81,7 +81,7 @@ AddChannel(HciConnection* conn, uint16 psm)
L2capChannel* channel = new (std::nothrow) L2capChannel;
if (channel == NULL) {
flowf ("no mem for channel");
ERROR("%s: Unable to allocate memory for channel!\n", __func__);
return NULL;
}
@@ -96,7 +96,7 @@ AddChannel(HciConnection* conn, uint16 psm)
channel->cfgState = 0;
channel->endpoint = NULL;
// the last assigned CID should be the last in the list
// the last assigned CID should be the last in the list
// Think if keeping an ordered list will improve the search method
// as it is called in every reception
conn->ChannelList.Add(channel);
@@ -105,7 +105,7 @@ AddChannel(HciConnection* conn, uint16 psm)
// Any constance of the new channel created ...? ng_l2cap_con_ref(con);
} else {
flowf("no CID available\n");
ERROR("%s: no CID available\n", __func__);
delete channel;
channel = NULL;
}
+23 -17
View File
@@ -40,7 +40,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
// Check ACL data packet. Driver should ensure report complete ACL packets
if (nbuf->size < sizeof(struct hci_acl_header)) {
debugf("Invalid ACL data packet, small length=%ld\n", nbuf->size);
ERROR("%s: Invalid ACL data packet, small length=%" B_PRIu32 "\n",
__func__, nbuf->size);
gBufferModule->free(nbuf);
return (EMSGSIZE);
}
@@ -63,7 +64,7 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
aclHeader.Remove();
debugf("ACL data packet, handle=%#x, PB=%#x, length=%d\n",
TRACE("%s: ACL data packet, handle=%#x, PB=%#x, length=%d\n", __func__,
con_handle, pb, length);
// a) Ensure there is HCI connection
@@ -72,13 +73,15 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
HciConnection* conn = btCoreData->ConnectionByHandle(con_handle, hid);
if (conn == NULL) {
debugf("Uexpected handle=%#x does not exist!\n", con_handle);
ERROR("%s: expected handle=%#x does not exist!\n", __func__,
con_handle);
conn = btCoreData->AddConnection(con_handle, BT_ACL, BDADDR_NULL, hid);
}
// Verify connection state
if (conn->status!= HCI_CONN_OPEN) {
flowf("unexpected ACL data packet. Connection not open\n");
ERROR("%s: unexpected ACL data packet. Connection not open\n",
__func__);
gBufferModule->free(nbuf);
return EHOSTDOWN;
}
@@ -87,8 +90,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
// Process packet
if (pb == HCI_ACL_PACKET_START) {
if (conn->currentRxPacket != NULL) {
debugf("Dropping incomplete L2CAP packet, got %ld want %d \n",
conn->currentRxPacket->size, length );
TRACE("%s: Dropping incomplete L2CAP packet, got %" B_PRIu32
" want %d \n", __func__, conn->currentRxPacket->size, length );
gBufferModule->free(conn->currentRxPacket);
conn->currentRxPacket = NULL;
conn->currentRxExpectedLength = 0;
@@ -96,8 +99,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
// Get L2CAP header, ACL header was dimissed
if (nbuf->size < sizeof(l2cap_hdr_t)) {
debugf("Invalid L2CAP start fragment, small, length=%ld\n",
nbuf->size);
TRACE("%s: Invalid L2CAP start fragment, small, length=%" B_PRIu32
"\n", __func__, nbuf->size);
gBufferModule->free(nbuf);
return (EMSGSIZE);
}
@@ -113,7 +116,7 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
l2capHeader->length = le16toh(l2capHeader->length);
l2capHeader->dcid = le16toh(l2capHeader->dcid);
debugf("New L2CAP, handle=%#x length=%d\n", con_handle,
TRACE("%s: New L2CAP, handle=%#x length=%d\n", __func__, con_handle,
le16toh(l2capHeader->length));
// Start new L2CAP packet
@@ -131,7 +134,8 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
gBufferModule->merge(conn->currentRxPacket, nbuf, true);
} else {
debugf("invalid ACL data packet. Invalid PB flag=%#x\n", pb);
ERROR("%s: invalid ACL data packet. Invalid PB flag=%#x\n", __func__,
pb);
gBufferModule->free(nbuf);
return (EINVAL);
}
@@ -140,9 +144,9 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
conn->currentRxExpectedLength -= length;
if (conn->currentRxExpectedLength < 0) {
debugf("Mismatch. Got %ld, expected %ld\n",
conn->currentRxPacket->size, conn->currentRxExpectedLength);
TRACE("%s: Mismatch. Got %" B_PRIu32 ", expected %" B_PRIuSIZE "\n",
__func__, conn->currentRxPacket->size,
conn->currentRxExpectedLength);
gBufferModule->free(conn->currentRxPacket);
conn->currentRxPacket = NULL;
@@ -150,13 +154,14 @@ AclAssembly(net_buffer* nbuf, hci_id hid)
} else if (conn->currentRxExpectedLength == 0) {
// OK, we have got complete L2CAP packet, so process it
debugf("L2cap packet ready %ld bytes\n", conn->currentRxPacket->size);
TRACE("%s: L2cap packet ready %" B_PRIu32 " bytes\n", __func__,
conn->currentRxPacket->size);
error = PostToUpper(conn, conn->currentRxPacket);
// clean
conn->currentRxPacket = NULL;
conn->currentRxExpectedLength = 0;
} else {
debugf("Expected %ld current adds %d\n",
TRACE("%s: Expected %ld current adds %d\n", __func__,
conn->currentRxExpectedLength, length);
}
@@ -169,8 +174,9 @@ PostToUpper(HciConnection* conn, net_buffer* buf)
{
if (L2cap == NULL)
if (get_module(NET_BLUETOOTH_L2CAP_NAME,(module_info**)&L2cap) != B_OK) {
debugf("cannot get module \"%s\"\n", NET_BLUETOOTH_L2CAP_NAME);
if (get_module(NET_BLUETOOTH_L2CAP_NAME, (module_info**)&L2cap) != B_OK) {
ERROR("%s: cannot get module \"%s\"\n", __func__,
NET_BLUETOOTH_L2CAP_NAME);
return B_ERROR;
} // TODO: someone put it
+24 -27
View File
@@ -119,7 +119,7 @@ Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data,
if (count >= bluetoothDevice->fExpectedPacketSize[type]) {
// the whole packet is here so it can be already posted.
flowf("EVENT posted in HCI!!!\n");
ERROR("%s: EVENT posted in HCI!!!\n", __func__);
btCoreData->PostEvent(bluetoothDevice, data,
bluetoothDevice->fExpectedPacketSize[type]);
@@ -188,7 +188,7 @@ Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data,
case BT_ACL:
// TODO: device descriptor has been fetched better not
// pass id again
flowf("ACL parsed in ACL!\n");
TRACE("%s: ACL parsed in ACL!\n", __func__);
AclAssembly(nbuf, bluetoothDevice->index);
break;
default:
@@ -199,13 +199,11 @@ Assemble(bluetooth_device* bluetoothDevice, bt_packet_t type, void* data,
bluetoothDevice->fBuffersRx[type] = nbuf = NULL;
bluetoothDevice->fExpectedPacketSize[type] = 0;
} else {
#if DEBUG_ACL
if (type == BT_ACL) {
debugf("ACL Packet not filled size=%" B_PRIuSIZE
" expected=%" B_PRIuSIZE "\n", nbuf->size,
TRACE("%s: ACL Packet not filled size %" B_PRIu32
" expected=%" B_PRIuSIZE "\n", __func__, nbuf->size,
bluetoothDevice->fExpectedPacketSize[type]);
}
#endif
}
}
@@ -225,14 +223,15 @@ HciPacketHandler(void* data, int32 code, size_t size)
bluetooth_device* bluetoothDevice = FindDeviceByID(deviceId);
debugf("to assemble %" B_PRIuSIZE " bytes of 0x%" B_PRIx32 "\n", size,
deviceId);
TRACE("%s: to assemble %" B_PRIuSIZE " bytes of 0x%" B_PRIx32 "\n",
__func__, size, deviceId);
if (bluetoothDevice != NULL)
if (bluetoothDevice != NULL) {
return Assemble(bluetoothDevice, Bluetooth::CodeHandler::Protocol(code),
data, size);
else {
debugf("Device 0x%" B_PRIx32 " could not be matched\n", deviceId);
} else {
ERROR("%s: Device 0x%" B_PRIx32 " could not be matched\n", __func__,
deviceId);
}
return B_ERROR;
@@ -267,12 +266,12 @@ RegisterDriver(bt_hci_transport_hooks* hooks, bluetooth_device** _device)
device->index = HCI_DEVICE_INDEX_OFFSET; // REVIEW: dev index
else {
device->index = (sDeviceList.Tail())->index + 1; // REVIEW!
flowf("List not empty\n");
TRACE("%s: List not empty\n", __func__);
}
sDeviceList.Add(device);
debugf("Device %" B_PRIx32 "\n", device->index);
TRACE("%s: Device %" B_PRIx32 "\n", __func__, device->index);
*_device = device;
@@ -315,13 +314,13 @@ PostACL(hci_id hciId, net_buffer* buffer)
bluetooth_device* device = FindDeviceByID(hciId);
if (device == NULL) {
debugf("No device 0x%" B_PRIx32 "\n", hciId);
ERROR("%s: No device 0x%" B_PRIx32 "\n", __func__, hciId);
return B_ERROR;
}
debugf("index 0x%" B_PRIx32 " try to send bt packet of %" B_PRIu32
" bytes (flags 0x%" B_PRIx32 "):\n", device->index, buffer->size,
buffer->flags);
TRACE("%s: index 0x%" B_PRIx32 " try to send bt packet of %" B_PRIu32
" bytes (flags 0x%" B_PRIx32 "):\n", __func__, device->index,
buffer->size, buffer->flags);
// TODO: ATOMIC! any other thread should stop here
do {
@@ -350,7 +349,7 @@ PostACL(hci_id hciId, net_buffer* buffer)
// Send to driver
curr_frame->protocol = BT_ACL;
debugf("Tolower nbuf %p!\n", curr_frame);
TRACE("%s: Tolower nbuf %p!\n", __func__, curr_frame);
// We could pass a cookie and avoid the driver fetch the Id
device->hooks->SendACL(device->index, curr_frame);
flag = HCI_ACL_PACKET_FRAGMENT;
@@ -396,9 +395,6 @@ dump_bluetooth_devices(int argc, char** argv)
static status_t
bluetooth_std_ops(int32 op, ...)
{
flowf("\n");
switch (op) {
case B_MODULE_INIT:
{
@@ -412,9 +408,10 @@ bluetooth_std_ops(int32 op, ...)
return status;
}
status = get_module(BT_CORE_DATA_MODULE_NAME,(module_info**)&btCoreData);
status = get_module(BT_CORE_DATA_MODULE_NAME,
(module_info**)&btCoreData);
if (status < B_OK) {
flowf("problem getting datacore\n");
ERROR("%s: problem getting bt core data module\n", __func__);
return status;
}
@@ -425,23 +422,23 @@ bluetooth_std_ops(int32 op, ...)
(BluetoothRawDataPort::port_listener_func)&HciPacketHandler);
if (BluetoothRXPort->Launch() != B_OK) {
flowf("RX thread creation failed!\n");
ERROR("%s: RX thread creation failed!\n", __func__);
// we Cannot do much here ... avoid registering
} else {
flowf("RX thread launched!\n");
TRACE("%s: RX thread launched!\n", __func__);
}
sLinkChangeSemaphore = create_sem(0, "bt sem");
if (sLinkChangeSemaphore < B_OK) {
put_module(NET_STACK_MODULE_NAME);
flowf("sem failed\n");
ERROR("%s: Link change semaphore failed\n", __func__);
return sLinkChangeSemaphore;
}
mutex_init(&sListLock, "bluetooth devices");
// status = InitializeAclConnectionThread();
debugf("%s: Connection Thread error\n", __func__);
ERROR("%s: Connection Thread error\n", __func__);
add_debugger_command("btLocalDevices", &dump_bluetooth_devices,
"Lists Bluetooth LocalDevices registered in the Stack");
@@ -29,6 +29,7 @@
#include "h2cfg.h"
int32 api_version = B_CUR_DRIVER_API_VERSION;
// Modules
@@ -83,22 +84,22 @@ spawn_device(usb_device* usb_dev)
#endif
{
CALLED();
int32 i;
status_t err = B_OK;
bt_usb_dev* new_bt_dev = NULL;
flowf("add_device()\n");
// 16 usb dongles...
if (dev_count >= MAX_BT_GENERIC_USB_DEVICES) {
flowf("device table full\n");
ERROR("%s: Device table full\n", __func__);
goto exit;
}
// try the allocation
new_bt_dev = (bt_usb_dev*)malloc(sizeof(bt_usb_dev));
if (new_bt_dev == NULL) {
flowf("no memory\n");
ERROR("%s: Unable to malloc new bt device\n", __func__);
goto exit;
}
memset(new_bt_dev, 0, sizeof(bt_usb_dev));
@@ -126,8 +127,8 @@ spawn_device(usb_device* usb_dev)
sprintf(new_bt_dev->name, "%s/%" B_PRId32,
BLUETOOTH_DEVICE_PATH, i);
new_bt_dev->num = i;
debugf("added device %p %" B_PRId32 " %s\n", bt_usb_devices[i],
new_bt_dev->num, new_bt_dev->name);
TRACE("%s: added device %p %" B_PRId32 " %s\n", __func__,
bt_usb_devices[i], new_bt_dev->num, new_bt_dev->name);
break;
}
}
@@ -135,7 +136,7 @@ spawn_device(usb_device* usb_dev)
// In the case we cannot us
if (bt_usb_devices[i] != new_bt_dev) {
flowf("Device could not be added\n");
ERROR("%s: Device could not be added\n", __func__);
goto bail2;
}
@@ -162,7 +163,7 @@ static void
kill_device(bt_usb_dev* bdev)
{
if (bdev != NULL) {
debugf("(%p)\n", bdev);
TRACE("%s: (%p)\n", __func__, bdev);
delete_sem(bdev->lock);
delete_sem(bdev->cmd_complete);
@@ -181,7 +182,7 @@ fetch_device(bt_usb_dev* dev, hci_id hid)
{
int i;
// debugf("(%p) or %d\n", dev, hid);
// TRACE("%s: (%p) or %d\n", __func__, dev, hid);
acquire_sem(dev_table_sem);
if (dev != NULL) {
@@ -228,10 +229,10 @@ device_added(usb_device* dev, void** cookie)
bt_usb_dev* new_bt_dev = spawn_device(dev);
int e;
debugf("device_added(%p)\n", new_bt_dev);
TRACE("%s: device_added(%p)\n", __func__, new_bt_dev);
if (new_bt_dev == NULL) {
flowf("Couldn't allocate device record.\n");
ERROR("%s: Couldn't allocate device record.\n", __func__);
err = ENOMEM;
goto bail_no_mem;
}
@@ -240,12 +241,12 @@ device_added(usb_device* dev, void** cookie)
config = usb->get_nth_configuration(dev, 0);
// dump_usb_configuration_info(config);
if (config == NULL) {
flowf("couldn't get default config.\n");
ERROR("%s: Couldn't get default USB config.\n", __func__);
err = B_ERROR;
goto bail;
}
debugf("found %" B_PRIuSIZE " alt interfaces.\n",
TRACE("%s: found %" B_PRIuSIZE " alt interfaces.\n", __func__,
config->interface->alt_count);
// set first interface
@@ -253,14 +254,14 @@ device_added(usb_device* dev, void** cookie)
err = usb->set_alt_interface(new_bt_dev->dev, interface);
if (err != B_OK) {
debugf("%s: set_alt_interface() error.\n", __func__);
ERROR("%s: set_alt_interface() error.\n", __func__);
goto bail;
}
// call set_configuration() only after calling set_alt_interface()
err = usb->set_configuration(dev, config);
if (err != B_OK) {
debugf("%s: set_configuration() error.\n", __func__);
ERROR("%s: set_configuration() error.\n", __func__);
goto bail;
}
@@ -290,13 +291,13 @@ device_added(usb_device* dev, void** cookie)
// security check
if (config->interface->active->descr->interface_number > 0) {
debugf("Strange condition happened %d\n",
ERROR("%s: Strange condition happened %d\n", __func__,
config->interface->active->descr->interface_number);
err = B_ERROR;
goto bail;
}
debugf("Found %" B_PRIuSIZE " interfaces. Expected 3\n",
TRACE("%s: Found %" B_PRIuSIZE " interfaces. Expected 3\n", __func__,
config->interface_count);
// Find endpoints that we need
@@ -309,22 +310,25 @@ device_added(usb_device* dev, void** cookie)
if (ep->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
{
new_bt_dev->intr_in_ep = ep;
new_bt_dev->max_packet_size_intr_in = ep->descr->max_packet_size;
flowf("INT in\n");
new_bt_dev->max_packet_size_intr_in
= ep->descr->max_packet_size;
TRACE("%s: INT in\n", __func__);
} else {
flowf("INT out\n");
TRACE("%s: INT out\n", __func__);
}
break;
case USB_ENDPOINT_ATTR_BULK:
if (ep->descr->endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) {
new_bt_dev->bulk_in_ep = ep;
new_bt_dev->max_packet_size_bulk_in = ep->descr->max_packet_size;
flowf("BULK int\n");
new_bt_dev->max_packet_size_bulk_in
= ep->descr->max_packet_size;
TRACE("%s: BULK int\n", __func__);
} else {
new_bt_dev->bulk_out_ep = ep;
new_bt_dev->max_packet_size_bulk_out = ep->descr->max_packet_size;
flowf("BULK out\n");
new_bt_dev->max_packet_size_bulk_out
= ep->descr->max_packet_size;
TRACE("%s: BULK out\n", __func__);
}
break;
}
@@ -332,7 +336,7 @@ device_added(usb_device* dev, void** cookie)
if (!new_bt_dev->bulk_in_ep || !new_bt_dev->bulk_out_ep
|| !new_bt_dev->intr_in_ep) {
flowf("Minimal # endpoints for BT not found\n");
ERROR("%s: Minimal # endpoints for BT not found\n", __func__);
goto bail;
}
@@ -347,7 +351,7 @@ device_added(usb_device* dev, void** cookie)
// set the cookie that will be passed to other USB
// hook functions (currently device_removed() is the only other)
*cookie = new_bt_dev;
debugf("Ok %p\n", new_bt_dev);
TRACE("%s: Ok %p\n", __func__, new_bt_dev);
return B_OK;
bail:
@@ -365,31 +369,23 @@ device_removed(void* cookie)
{
bt_usb_dev* bdev = fetch_device((bt_usb_dev*)cookie, 0);
debugf("device_removed(%p)\n", bdev);
TRACE("%s: device_removed(%p)\n", __func__, bdev);
if (bdev == NULL) {
flowf(" not present in driver?\n");
ERROR("%s: Device not present in driver.\n", __func__);
return B_ERROR;
}
if (!TEST_AND_CLEAR(&bdev->state, RUNNING))
flowf("wasnt running?\n");
ERROR("%s: wasnt running?\n", __func__);
flowf("Cancelling queues...\n");
if (bdev->intr_in_ep != NULL) {
TRACE("%s: Cancelling queues...\n", __func__);
if (bdev->intr_in_ep != NULL)
usb->cancel_queued_transfers(bdev->intr_in_ep->handle);
flowf("Cancelling possible EVENTS\n");
}
if (bdev->bulk_in_ep!=NULL) {
if (bdev->bulk_in_ep != NULL)
usb->cancel_queued_transfers(bdev->bulk_in_ep->handle);
flowf("Cancelling possible ACL in\n");
}
if (bdev->bulk_out_ep!=NULL) {
if (bdev->bulk_out_ep != NULL)
usb->cancel_queued_transfers(bdev->bulk_out_ep->handle);
flowf("Cancelling possible ACL out\n");
}
bdev->connected = false;
@@ -423,7 +419,8 @@ submit_nbuffer(hci_id hid, net_buffer* nbuf)
bdev = fetch_device(NULL, hid);
debugf("index=%" B_PRId32 " nbuf=%p bdev=%p\n", hid, nbuf, bdev);
TRACE("%s: index=%" B_PRId32 " nbuf=%p bdev=%p\n", __func__, hid,
nbuf, bdev);
if (bdev != NULL) {
switch (nbuf->protocol) {
@@ -451,13 +448,13 @@ submit_nbuffer(hci_id hid, net_buffer* nbuf)
static status_t
device_open(const char* name, uint32 flags, void **cookie)
{
CALLED();
status_t err = ENODEV;
bt_usb_dev* bdev = NULL;
hci_id hdev;
int i;
flowf("device_open()\n");
acquire_sem(dev_table_sem);
for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) {
if (bt_usb_devices[i] && !strcmp(name, bt_usb_devices[i]->name)) {
@@ -468,14 +465,14 @@ device_open(const char* name, uint32 flags, void **cookie)
release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE);
if (bdev == NULL) {
flowf("Device not found in the open list!");
ERROR("%s: Device not found in the open list!", __func__);
*cookie = NULL;
return B_ERROR;
}
// Set RUNNING
if (TEST_AND_SET(&bdev->state, RUNNING)) {
flowf("dev already running! - reOpened device!\n");
ERROR("%s: dev already running! - reOpened device!\n", __func__);
return B_ERROR;
}
@@ -509,9 +506,9 @@ device_open(const char* name, uint32 flags, void **cookie)
bdev->hdev = hdev = ndev->index; // Get the index
bdev->ndev = ndev; // Get the net_device
} else {
} else {
hdev = bdev->num; // XXX: Lets try to go on
}
}
} else {
hdev = bdev->num; // XXX: Lets try to go on
}
@@ -521,7 +518,6 @@ device_open(const char* name, uint32 flags, void **cookie)
*cookie = bdev;
release_sem(bdev->lock);
flowf(" successful\n");
return B_OK;
}
@@ -533,6 +529,8 @@ device_open(const char* name, uint32 flags, void **cookie)
static status_t
device_close(void* cookie)
{
CALLED();
int32 i;
void* item;
bt_usb_dev* bdev = (bt_usb_dev*)cookie;
@@ -540,26 +538,19 @@ device_close(void* cookie)
if (bdev == NULL)
panic("bad cookie");
debugf("%s: device_close() called\n", __func__);
// Clean queues
if (bdev->connected == true) {
flowf("Cancelling queues...\n");
if (bdev->intr_in_ep != NULL) {
TRACE("%s: Cancelling queues...\n", __func__);
if (bdev->intr_in_ep != NULL)
usb->cancel_queued_transfers(bdev->intr_in_ep->handle);
flowf("Cancelling possible EVENTS\n");
}
if (bdev->bulk_in_ep!=NULL) {
if (bdev->bulk_in_ep!=NULL)
usb->cancel_queued_transfers(bdev->bulk_in_ep->handle);
flowf("Cancelling possible ACL in\n");
}
if (bdev->bulk_out_ep!=NULL) {
if (bdev->bulk_out_ep!=NULL)
usb->cancel_queued_transfers(bdev->bulk_out_ep->handle);
flowf("Cancelling possible ACL out\n");
}
}
// TX
@@ -587,7 +578,7 @@ device_close(void* cookie)
// unSet RUNNING
if (TEST_AND_CLEAR(&bdev->state, RUNNING)) {
debugf(" %s not running?\n", bdev->name);
ERROR("%s: %s not running?\n", __func__, bdev->name);
return B_ERROR;
}
@@ -599,15 +590,13 @@ device_close(void* cookie)
static status_t
device_free(void* cookie)
{
CALLED();
status_t err = B_OK;
bt_usb_dev* bdev = (bt_usb_dev*)cookie;
debugf("device_free() called on %s \n", BLUETOOTH_DEVICE_PATH);
if (!bdev->connected) {
flowf("Device not present can be killed\n");
if (!bdev->connected)
kill_device(bdev);
}
return err;
}
@@ -625,15 +614,16 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
#endif
TOUCH(size);
debugf("ioctl() opcode %" B_PRId32 " size %" B_PRIuSIZE ".\n", msg, size);
TRACE("%s: ioctl() opcode %" B_PRId32 " size %" B_PRIuSIZE ".\n", __func__,
msg, size);
if (bdev == NULL) {
flowf("Bad cookie\n");
TRACE("%s: Bad cookie\n", __func__);
return B_BAD_VALUE;
}
if (params == NULL) {
flowf("Invalid pointer control\n");
TRACE("%s: Invalid pointer control\n", __func__);
return B_BAD_VALUE;
}
@@ -643,7 +633,7 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
case ISSUE_BT_COMMAND:
#ifdef BT_IOCTLS_PASS_SIZE
if (size == 0) {
flowf("Invalid size control\n");
TRACE("%s: Invalid size control\n", __func__);
err = B_BAD_VALUE;
break;
}
@@ -658,7 +648,7 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
snb_put(snbuf, params, size);
err = submit_tx_command(bdev, snbuf);
debugf("%s: command launched\n", __func__);
TRACE("%s: command launched\n", __func__);
break;
case BT_UP:
@@ -667,7 +657,7 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
err = submit_rx_event(bdev);
if (err != B_OK) {
bdev->state = CLEAR_BIT(bdev->state, ANCILLYANT);
flowf("Queuing failed device stops running\n");
ERROR("%s: Queuing failed device stops running\n", __func__);
break;
}
@@ -677,7 +667,8 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
if (err != B_OK && i == 0) {
bdev->state = CLEAR_BIT(bdev->state, ANCILLYANT);
// Set the flaq in the HCI world
flowf("Queuing failed device stops running\n");
ERROR("%s: Queuing failed device stops running\n",
__func__);
break;
}
}
@@ -688,7 +679,8 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
#if BT_DRIVER_SUPPORTS_SCO
// TODO: SCO / eSCO
#endif
flowf("device launched\n");
ERROR("%s: Device online\n", __func__);
break;
case GET_STATS:
@@ -703,7 +695,7 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
default:
debugf("%s: Invalid opcode.\n", __func__);
ERROR("%s: Invalid opcode.\n", __func__);
err = B_DEV_INVALID_IOCTL;
break;
}
@@ -717,7 +709,7 @@ device_control(void* cookie, uint32 msg, void* params, size_t size)
static status_t
device_read(void* cookie, off_t pos, void* buffer, size_t* count)
{
debugf("Reading... count = %" B_PRIuSIZE "\n", *count);
TRACE("%s: Reading... count = %" B_PRIuSIZE "\n", __func__, *count);
*count = 0;
return B_OK;
@@ -728,7 +720,7 @@ device_read(void* cookie, off_t pos, void* buffer, size_t* count)
static status_t
device_write(void* cookie, off_t pos, const void* buffer, size_t* count)
{
flowf("device_write()\n");
CALLED();
return B_ERROR;
}
@@ -768,48 +760,42 @@ dump_driver(int argc, char** argv)
status_t
init_driver(void)
{
CALLED();
int j;
flowf("init_driver()\n");
if (get_module(BT_CORE_DATA_MODULE_NAME,
(module_info**)&btCoreData) != B_OK) {
debugf("cannot get module \"%s\"\n", BT_CORE_DATA_MODULE_NAME);
ERROR("%s: cannot get module '%s'\n", __func__,
BT_CORE_DATA_MODULE_NAME);
return B_ERROR;
} else
debugf("btCoreData module at %p\n", btCoreData);
}
// BT devices MODULE INITS
if (get_module(btDevices_name, (module_info**)&btDevices) != B_OK) {
debugf("cannot get module \"%s\"\n", btDevices_name);
ERROR("%s: cannot get module '%s'\n", __func__, btDevices_name);
goto err_release3;
} else
debugf("btDevices module at %p\n", btDevices);
}
// HCI MODULE INITS
if (get_module(hci_name, (module_info**)&hci) != B_OK) {
debugf("cannot get module \"%s\"\n", hci_name);
ERROR("%s: cannot get module '%s'\n", __func__, hci_name);
#ifndef BT_SURVIVE_WITHOUT_HCI
goto err_release2;
#endif
} else {
debugf("hci module at %p\n", hci);
}
// USB MODULE INITS
if (get_module(usb_name, (module_info**)&usb) != B_OK) {
debugf("cannot get module \"%s\"\n", usb_name);
ERROR("%s: cannot get module '%s'\n", __func__, usb_name);
goto err_release1;
} else {
debugf("usb module at %p\n", usb);
}
if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&nb) != B_OK) {
debugf("cannot get module \"%s\"\n", NET_BUFFER_MODULE_NAME);
ERROR("%s: cannot get module '%s'\n", __func__,
NET_BUFFER_MODULE_NAME);
#ifndef BT_SURVIVE_WITHOUT_NET_BUFFERS
goto err_release;
#endif
} else {
debugf("nb module at %p\n", nb);
}
// GENERAL INITS
@@ -852,9 +838,9 @@ err_release3:
void
uninit_driver(void)
{
int32 j;
CALLED();
flowf("uninit_driver()\n");
int32 j;
for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) {
@@ -865,7 +851,7 @@ uninit_driver(void)
// if (connected_dev != NULL) {
// debugf("Device %p still exists.\n", connected_dev);
// }
debugf("%s still present?\n", bt_usb_devices[j]->name);
ERROR("%s: %s still present?\n", __func__, bt_usb_devices[j]->name);
kill_device(bt_usb_devices[j]);
}
}
@@ -886,13 +872,12 @@ uninit_driver(void)
const char**
publish_devices(void)
{
CALLED();
int32 j;
int32 i = 0;
char* str;
flowf("publish_devices()\n");
for (j = 0; j < MAX_BT_GENERIC_USB_DEVICES; j++) {
if (publish_names[j]) {
free(publish_names[j]);
@@ -906,14 +891,14 @@ publish_devices(void)
str = strdup(bt_usb_devices[j]->name);
if (str) {
publish_names[i++] = str;
debugf("publishing %s\n", bt_usb_devices[j]->name);
TRACE("%s: publishing %s\n", __func__, bt_usb_devices[j]->name);
}
}
}
release_sem_etc(dev_table_sem, 1, B_DO_NOT_RESCHEDULE);
publish_names[i] = NULL;
debugf("published %" B_PRId32 " devices\n", i);
TRACE("%s: published %" B_PRId32 " devices\n", __func__, i);
// TODO: this method might make better memory use
// dev_names = (char**)malloc(sizeof(char*) * (dev_count + 1));
@@ -947,7 +932,7 @@ static device_hooks hooks = {
device_hooks*
find_device(const char* name)
{
debugf("find_device(%s)\n", name);
CALLED();
return &hooks;
}
@@ -4,7 +4,6 @@
* All rights reserved. Distributed under the terms of the MIT License.
*
*/
#ifndef _H2GENERIC_H_
#define _H2GENERIC_H_
@@ -39,6 +38,7 @@
#define USB_TYPE_CLASS (0x01 << 5) /// Check if it is in some other header
#define USB_TYPE_VENDOR (0x02 << 5)
#define TOUCH(x) ((void)(x))
// Expecting nobody is gonna have 16 USB-BT dongles connected in their system
#define MAX_BT_GENERIC_USB_DEVICES 16
@@ -118,4 +118,23 @@ struct bt_usb_dev {
bt_usb_dev* fetch_device(bt_usb_dev* dev, hci_id hid);
static inline uint32
TEST_AND_SET(uint32 *byte, uint32 bit_mask)
{
uint32 val = (*byte&bit_mask)!=0;
*byte |= bit_mask;
return val;
}
static inline uint32
TEST_AND_CLEAR(uint32* byte, uint32 bit_mask)
{
uint32 val = (*byte&bit_mask)!=0;
*byte &= ~bit_mask;
return val;
}
#endif
@@ -63,7 +63,7 @@ event_complete(void* cookie, status_t status, void* data, size_t actual_len)
// bt_usb_dev* bdev = fetch_device(cookie, 0); -> safer / slower option
status_t error;
debugf("cookie@%p status=%s len=%" B_PRIuSIZE "\n", cookie,
TRACE("%s: cookie@%p status=%s len=%" B_PRIuSIZE "\n", __func__, cookie,
strerror(status), actual_len);
if (bdev == NULL)
@@ -84,12 +84,14 @@ event_complete(void* cookie, status_t status, void* data, size_t actual_len)
resubmit:
error = usb->queue_interrupt(bdev->intr_in_ep->handle, data,
max_c(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in), event_complete, bdev);
max_c(HCI_MAX_EVENT_SIZE, bdev->max_packet_size_intr_in),
event_complete, bdev);
if (error != B_OK) {
reuse_room(&bdev->eventRoom, data);
bdev->stat.rejectedRX++;
debugf("RX event resubmittion failed %s\n", strerror(error));
ERROR("%s: RX event resubmittion failed %s\n", __func__,
strerror(error));
} else {
bdev->stat.acceptedRX++;
}
@@ -131,7 +133,7 @@ resubmit:
if (error != B_OK) {
reuse_room(&bdev->aclRoom, data);
bdev->stat.rejectedRX++;
debugf("RX acl resubmittion failed %s\n", strerror(error));
ERROR("%s: RX acl resubmittion failed %s\n", __func__, strerror(error));
} else {
bdev->stat.acceptedRX++;
}
@@ -160,7 +162,7 @@ submit_rx_event(bt_usb_dev* bdev)
bdev->stat.rejectedRX++;
} else {
bdev->stat.acceptedRX++;
debugf("Accepted RX Event %d\n", bdev->stat.acceptedRX);
TRACE("%s: Accepted RX Event %d\n", __func__, bdev->stat.acceptedRX);
}
return status;
@@ -213,7 +215,7 @@ command_complete(void* cookie, status_t status, void* data, size_t actual_len)
snet_buffer* snbuf = (snet_buffer*)cookie;
bt_usb_dev* bdev = (bt_usb_dev*)snb_cookie(snbuf);
debugf("len = %" B_PRIuSIZE " @%p\n", actual_len, data);
TRACE("%s: len = %" B_PRIuSIZE " @%p\n", __func__, actual_len, data);
if (status == B_OK) {
bdev->stat.successfulTX++;
@@ -281,7 +283,7 @@ submit_tx_command(bt_usb_dev* bdev, snet_buffer* snbuf)
// set cookie
snb_set_cookie(snbuf, bdev);
debugf("@%p\n", snb_get(snbuf));
TRACE("%s: @%p\n", __func__, snb_get(snbuf));
error = usb->queue_request(bdev->dev, bRequestType, bRequest,
value, wIndex, wLength, snb_get(snbuf),
@@ -27,7 +27,7 @@ sched_tx_processing(bt_usb_dev* bdev)
snet_buffer* snbuf;
status_t err;
debugf("(%p)\n", bdev)
TRACE("%s: (%p)\n", __func__, bdev);
if (!TEST_AND_SET(&bdev->state, PROCESSING)) {
// We are not processing in another thread so... START!!
@@ -106,7 +106,7 @@ post_packet_up(bt_usb_dev* bdev, bt_packet_t type, void* buf)
net_buffer* nbuf = (net_buffer*) buf;
// No need to free the buffer at allocation is gonna be reused
btDevices->receive_data(bdev->ndev, &nbuf);
flowf("to net_device\n");
TRACE("to net_device\n");
}
return err;
@@ -134,23 +134,24 @@ send_packet(hci_id hid, bt_packet_t type, net_buffer* nbuf)
case BT_COMMAND:
case BT_ACL:
case BT_SCO:
list_add_item(&bdev->nbuffersTx[type],nbuf);
list_add_item(&bdev->nbuffersTx[type], nbuf);
bdev->nbuffersPendingTx[type]++;
break;
default:
debugf("Unknown packet type for sending %d\n",type);
ERROR("%s: Unknown packet type for sending %d\n", __func__,
type);
// TODO: free the net_buffer -> no, allow upper layer
// handle it with the given error
err = B_BAD_VALUE;
break;
}
} else {
flowf("tx sched provoked");
TRACE("%s: tx sched provoked", __func__);
}
// TODO: check if device is actually ready for this
// TODO: unlock device
// sched in any case even if nbuf is null (provoke re-scheduling)
sched_tx_processing(bdev);
@@ -171,16 +172,16 @@ send_command(hci_id hid, snet_buffer* snbuf)
// TODO: mutex
if (snbuf != NULL) {
list_add_item(&bdev->nbuffersTx[BT_COMMAND],snbuf);
list_add_item(&bdev->nbuffersTx[BT_COMMAND], snbuf);
bdev->nbuffersPendingTx[BT_COMMAND]++;
} else {
err = B_BAD_VALUE;
flowf("tx sched provoked");
TRACE("%s: tx sched provoked", __func__);
}
// TODO: check if device is actually ready for this
// TODO: mutex
/* sched in All cases even if nbuf is null (hidden way to provoke
* re-scheduling)
*/
@@ -5,17 +5,20 @@
#ifndef _H2UTIL_H_
#define _H2UTIL_H_
#include <util/list.h>
#include "h2generic.h"
/* net buffer utils for ACL, to be reviewed */
#define DEVICEFIELD type
#define SET_DEVICE(nbuf, hid) \
(nbuf->DEVICEFIELD=(nbuf->DEVICEFIELD & 0xFFFFFF00) | (hid & 0xFF))
#define GET_DEVICE(nbuf) fetch_device(NULL,(nbuf->DEVICEFIELD&0xFF))
#define GET_DEVICE(nbuf) fetch_device(NULL, (nbuf->DEVICEFIELD&0xFF))
#define COOKIEFIELD flags
#define COOKIEFIELD flags
void* nb_get_whole_buffer(net_buffer* nbuf);
void nb_destroy(net_buffer* nbuf);
size_t get_expected_size(net_buffer* nbuf);