- Reorder and fix the uninitialization of a device.

- Fix some null pointer bugs
- Mark the removed device to avoid killing it twice in the uninit hook (Mika Lindqvist)
* More things might be still missing in the uninit context 



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26382 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Ruiz Dorantes
2008-07-11 18:18:43 +00:00
parent e4f6d30d1c
commit 674e234e11
@@ -22,6 +22,11 @@
#include <bluetooth/HCI/btHCI_module.h> #include <bluetooth/HCI/btHCI_module.h>
#define BT_DEBUG_THIS_MODULE #define BT_DEBUG_THIS_MODULE
#define MODULE_NAME "BT"
#define SUBMODULE_NAME BLUETOOTH_DEVICE_DEVFS_NAME
#define SUBMODULE_COLOR 31
#include <btDebug.h> #include <btDebug.h>
#include "h2generic.h" #include "h2generic.h"
@@ -147,15 +152,20 @@ exit:
/* remove a device from the list of connected devices */ /* remove a device from the list of connected devices */
static void static void
kill_device(bt_usb_dev* dev) kill_device(bt_usb_dev* bdev)
{ {
debugf("remove_device(%p)\n", dev); if (bdev != NULL) {
debugf("(%p)\n", bdev);
delete_sem(dev->lock); delete_sem(bdev->lock);
delete_sem(dev->cmd_complete); delete_sem(bdev->cmd_complete);
free(dev); // mark it free
bt_usb_devices[bdev->num] = NULL;
free(bdev);
dev_count--; dev_count--;
}
} }
@@ -347,47 +357,38 @@ bail_no_mem:
static status_t static status_t
device_removed(void* cookie) device_removed(void* cookie)
{ {
int32 i;
void* item;
bt_usb_dev* bdev = (bt_usb_dev*) fetch_device(cookie, 0); bt_usb_dev* bdev = (bt_usb_dev*) fetch_device(cookie, 0);
debugf("device_removed(%p)\n", bdev); debugf("device_removed(%p)\n", bdev);
if (bdev == NULL) { if (bdev == NULL) {
flowf("Weird condition...\n"); flowf(" not present in driver¿?\n");
return B_ERROR; return B_ERROR;
} }
// TODO: Consider some other place
// TX if (!TEST_AND_CLEAR(&bdev->state, RUNNING) ) {
for (i = 0; i < BT_DRIVER_TXCOVERAGE; i++) { flowf(" wasnt running¿?\n");
if (i == BT_COMMAND)
while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) {
snb_free(item);
}
else
while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) {
nb_destroy(item);
} }
}
// RX
for (i = 0; i < BT_DRIVER_RXCOVERAGE; i++) {
nb_destroy(bdev->nbufferRx[i]);
}
snb_free(bdev->eventRx);
purge_room(&bdev->eventRoom); flowf("Cancelling queues...\n");
purge_room(&bdev->aclRoom); if ( bdev->intr_in_ep != NULL ) {
// TODO: Consider some other place usb->cancel_queued_transfers(bdev->intr_in_ep->handle);
flowf("Cancelling impossible EVENTS\n");
}
if (hci != NULL) if (bdev->bulk_in_ep!=NULL) {
hci->UnregisterDriver(bdev->hdev); usb->cancel_queued_transfers(bdev->bulk_in_ep->handle);
flowf("Cancelling impossible ACL in\n");
}
if (bdev->bulk_out_ep!=NULL) {
usb->cancel_queued_transfers(bdev->bulk_out_ep->handle);
flowf("Cancelling impossible ACL out\n");
}
bdev->connected = false; bdev->connected = false;
/* TODO: maybe we still need this struct for close and free hooks */
kill_device(bdev);
return B_OK; return B_OK;
} }
@@ -487,6 +488,8 @@ device_open(const char *name, uint32 flags, void **cookie)
static status_t static status_t
device_close(void *cookie) device_close(void *cookie)
{ {
int32 i;
void* item;
bt_usb_dev* bdev = (bt_usb_dev*)cookie; bt_usb_dev* bdev = (bt_usb_dev*)cookie;
if (bdev == NULL) if (bdev == NULL)
@@ -494,34 +497,39 @@ device_close(void *cookie)
debugf("device_close() called on %ld\n", bdev->hdev ); debugf("device_close() called on %ld\n", bdev->hdev );
// Clean queues
if (!TEST_AND_CLEAR(&bdev->state, RUNNING) ) { // TX
flowf("Device wasnt running!!!\n"); for (i = 0; i < BT_DRIVER_TXCOVERAGE; i++) {
if (i == BT_COMMAND)
while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) {
snb_free(item);
}
else
while ((item = list_remove_head_item(&bdev->nbuffersTx[i])) != NULL) {
nb_destroy(item);
} }
flowf("Stopping device and cancelling queues...\n");
if ( bdev->intr_in_ep != NULL ) {
usb->cancel_queued_transfers(bdev->intr_in_ep->handle);
} else {
flowf("Cancelling impossible EVENTS\n");
} }
// RX
if (bdev->bulk_in_ep!=NULL) { for (i = 0; i < BT_DRIVER_RXCOVERAGE; i++) {
usb->cancel_queued_transfers(bdev->bulk_in_ep->handle); nb_destroy(bdev->nbufferRx[i]);
} else {
flowf("Cancelling impossible ACL in\n");
} }
snb_free(bdev->eventRx);
if (bdev->bulk_out_ep!=NULL) { purge_room(&bdev->eventRoom);
usb->cancel_queued_transfers(bdev->bulk_out_ep->handle); purge_room(&bdev->aclRoom);
} else {
flowf("Cancelling impossible ACL out\n"); /* Device no longer in our Stack*/
if (hci != NULL)
hci->UnregisterDriver(bdev->hdev);
// unSet RUNNING
if (TEST_AND_CLEAR(&bdev->state, RUNNING)) {
debugf(" %s not running¿?\n",bdev->name);
return B_ERROR;
} }
// TODO: Kill if its not connected?
return B_OK; return B_OK;
} }
@@ -532,12 +540,12 @@ static status_t
device_free (void *cookie) device_free (void *cookie)
{ {
status_t err = B_OK; status_t err = B_OK;
bt_usb_dev* dev = (bt_usb_dev*)cookie; bt_usb_dev* bdev = (bt_usb_dev*)cookie;
debugf("device_free() called on %s \n",BLUETOOTH_DEVICE_PATH); debugf("device_free() called on %s \n",BLUETOOTH_DEVICE_PATH);
if (--dev->open_count == 0) { if (--bdev->open_count == 0) {
/* GotoLowPower */ /* GotoLowPower */
// interesting ..... // interesting .....
@@ -545,10 +553,9 @@ device_free (void *cookie)
else { else {
/* The last client has closed, and the device is no longer /* The last client has closed, and the device is no longer
connected, so remove it from the list. */ connected, so remove it from the list. */
} }
// TODO: Kill if its not connected? kill_device(bdev);
return err; return err;
} }
@@ -747,10 +754,9 @@ uninit_driver(void)
// if (connected_dev != NULL) { // if (connected_dev != NULL) {
// debugf("Device %p still exists.\n", connected_dev); // debugf("Device %p still exists.\n", connected_dev);
// } // }
debugf("%s still present¿?\n",bt_usb_devices[j]->name);
kill_device(bt_usb_devices[j]); kill_device(bt_usb_devices[j]);
bt_usb_devices[j] = NULL;
} }
} }
usb->uninstall_notify(BLUETOOTH_DEVICE_DEVFS_NAME); usb->uninstall_notify(BLUETOOTH_DEVICE_DEVFS_NAME);