busses/usb: Handle getting/putting the PCI modules properly.
Previously it was possible that we put() them twice, leading to assert-failure panics as their ref-counts would go below 0. Now we get() them once for every bus object that we create, as the destructors put() them. Should fix the panic in #15004.
This commit is contained in:
@@ -146,17 +146,20 @@ EHCI::AddTo(Stack *stack)
|
|||||||
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
||||||
item->bus, item->device, item->function);
|
item->bus, item->device, item->function);
|
||||||
EHCI *bus = new(std::nothrow) EHCI(item, stack);
|
EHCI *bus = new(std::nothrow) EHCI(item, stack);
|
||||||
if (!bus) {
|
if (bus == NULL) {
|
||||||
delete item;
|
delete item;
|
||||||
sPCIModule = NULL;
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
if (sPCIx86Module != NULL) {
|
if (sPCIx86Module != NULL)
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The bus will put the PCI modules when it is destroyed, so get
|
||||||
|
// them again to increase their reference count.
|
||||||
|
get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
get_module(B_PCI_X86_MODULE_NAME, (module_info **)&sPCIx86Module);
|
||||||
|
|
||||||
if (bus->InitCheck() != B_OK) {
|
if (bus->InitCheck() != B_OK) {
|
||||||
TRACE_MODULE_ERROR("bus failed init check\n");
|
TRACE_MODULE_ERROR("bus failed init check\n");
|
||||||
delete bus;
|
delete bus;
|
||||||
@@ -174,20 +177,16 @@ EHCI::AddTo(Stack *stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
// The modules will have been gotten again if we successfully
|
||||||
TRACE_MODULE_ERROR("no devices found\n");
|
// initialized a bus, so we should put them here.
|
||||||
delete item;
|
put_module(B_PCI_MODULE_NAME);
|
||||||
sPCIModule = NULL;
|
if (sPCIx86Module != NULL)
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
if (sPCIx86Module != NULL) {
|
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
|
||||||
}
|
|
||||||
return ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
TRACE_MODULE_ERROR("no devices found\n");
|
||||||
delete item;
|
delete item;
|
||||||
return B_OK;
|
return found ? B_OK : ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -690,12 +689,10 @@ EHCI::~EHCI()
|
|||||||
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
||||||
fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->device, fPCIInfo->function);
|
||||||
}
|
}
|
||||||
put_module(B_PCI_MODULE_NAME);
|
|
||||||
|
|
||||||
if (sPCIx86Module != NULL) {
|
put_module(B_PCI_MODULE_NAME);
|
||||||
sPCIx86Module = NULL;
|
if (sPCIx86Module != NULL)
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,19 +97,20 @@ OHCI::AddTo(Stack *stack)
|
|||||||
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
||||||
item->bus, item->device, item->function);
|
item->bus, item->device, item->function);
|
||||||
OHCI *bus = new(std::nothrow) OHCI(item, stack);
|
OHCI *bus = new(std::nothrow) OHCI(item, stack);
|
||||||
if (!bus) {
|
if (bus == NULL) {
|
||||||
delete item;
|
delete item;
|
||||||
sPCIModule = NULL;
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
if (sPCIx86Module != NULL) {
|
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The bus will put the PCI modules when it is destroyed, so get
|
||||||
|
// them again to increase their reference count.
|
||||||
|
get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
get_module(B_PCI_X86_MODULE_NAME, (module_info **)&sPCIx86Module);
|
||||||
|
|
||||||
if (bus->InitCheck() < B_OK) {
|
if (bus->InitCheck() < B_OK) {
|
||||||
TRACE_MODULE_ERROR("bus failed init check\n");
|
TRACE_MODULE_ERROR("bus failed init check\n");
|
||||||
delete bus;
|
delete bus;
|
||||||
@@ -127,22 +128,16 @@ OHCI::AddTo(Stack *stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
// The modules will have been gotten again if we successfully
|
||||||
|
// initialized a bus, so we should put them here.
|
||||||
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
TRACE_MODULE_ERROR("no devices found\n");
|
TRACE_MODULE_ERROR("no devices found\n");
|
||||||
delete item;
|
|
||||||
sPCIModule = NULL;
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
|
||||||
|
|
||||||
if (sPCIx86Module != NULL) {
|
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete item;
|
delete item;
|
||||||
return B_OK;
|
return found ? B_OK : ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -491,11 +486,10 @@ OHCI::~OHCI()
|
|||||||
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
||||||
fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->device, fPCIInfo->function);
|
||||||
}
|
}
|
||||||
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
if (sPCIx86Module != NULL) {
|
if (sPCIx86Module != NULL)
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -336,11 +336,18 @@ UHCI::AddTo(Stack *stack)
|
|||||||
UHCI *bus = new(std::nothrow) UHCI(item, stack);
|
UHCI *bus = new(std::nothrow) UHCI(item, stack);
|
||||||
if (!bus) {
|
if (!bus) {
|
||||||
delete item;
|
delete item;
|
||||||
sPCIModule = NULL;
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The bus will put the PCI modules when it is destroyed, so get
|
||||||
|
// them again to increase their reference count.
|
||||||
|
get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
get_module(B_PCI_X86_MODULE_NAME, (module_info **)&sPCIx86Module);
|
||||||
|
|
||||||
if (bus->InitCheck() < B_OK) {
|
if (bus->InitCheck() < B_OK) {
|
||||||
TRACE_MODULE_ERROR("AddTo(): InitCheck() failed 0x%08" B_PRIx32
|
TRACE_MODULE_ERROR("AddTo(): InitCheck() failed 0x%08" B_PRIx32
|
||||||
"\n", bus->InitCheck());
|
"\n", bus->InitCheck());
|
||||||
@@ -359,16 +366,16 @@ UHCI::AddTo(Stack *stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
// The modules will have been gotten again if we successfully
|
||||||
TRACE_MODULE_ERROR("no devices found\n");
|
// initialized a bus, so we should put them here.
|
||||||
delete item;
|
put_module(B_PCI_MODULE_NAME);
|
||||||
sPCIModule = NULL;
|
if (sPCIx86Module != NULL)
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
return ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
TRACE_MODULE_ERROR("no devices found\n");
|
||||||
delete item;
|
delete item;
|
||||||
return B_OK;
|
return found ? B_OK : ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -639,11 +646,11 @@ UHCI::~UHCI()
|
|||||||
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
sPCIx86Module->unconfigure_msi(fPCIInfo->bus,
|
||||||
fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->device, fPCIInfo->function);
|
||||||
}
|
}
|
||||||
|
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
if (sPCIx86Module != NULL) {
|
if (sPCIx86Module != NULL)
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ XHCI::AddTo(Stack *stack)
|
|||||||
TRACE_MODULE("searching devices\n");
|
TRACE_MODULE("searching devices\n");
|
||||||
bool found = false;
|
bool found = false;
|
||||||
pci_info *item = new(std::nothrow) pci_info;
|
pci_info *item = new(std::nothrow) pci_info;
|
||||||
if (!item) {
|
if (item == NULL) {
|
||||||
sPCIModule = NULL;
|
sPCIModule = NULL;
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -141,13 +141,21 @@ XHCI::AddTo(Stack *stack)
|
|||||||
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
TRACE_MODULE("found device at PCI:%d:%d:%d\n",
|
||||||
item->bus, item->device, item->function);
|
item->bus, item->device, item->function);
|
||||||
XHCI *bus = new(std::nothrow) XHCI(item, stack);
|
XHCI *bus = new(std::nothrow) XHCI(item, stack);
|
||||||
if (!bus) {
|
if (bus == NULL) {
|
||||||
delete item;
|
delete item;
|
||||||
sPCIModule = NULL;
|
sPCIModule = NULL;
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The bus will put the PCI modules when it is destroyed, so get
|
||||||
|
// them again to increase their reference count.
|
||||||
|
get_module(B_PCI_MODULE_NAME, (module_info **)&sPCIModule);
|
||||||
|
if (sPCIx86Module != NULL)
|
||||||
|
get_module(B_PCI_X86_MODULE_NAME, (module_info **)&sPCIx86Module);
|
||||||
|
|
||||||
if (bus->InitCheck() < B_OK) {
|
if (bus->InitCheck() < B_OK) {
|
||||||
TRACE_MODULE_ERROR("bus failed init check\n");
|
TRACE_MODULE_ERROR("bus failed init check\n");
|
||||||
delete bus;
|
delete bus;
|
||||||
@@ -165,16 +173,16 @@ XHCI::AddTo(Stack *stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
// The modules will have been gotten again if we successfully
|
||||||
TRACE_MODULE_ERROR("no devices found\n");
|
// initialized a bus, so we should put them here.
|
||||||
delete item;
|
put_module(B_PCI_MODULE_NAME);
|
||||||
sPCIModule = NULL;
|
if (sPCIx86Module != NULL)
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
return ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
TRACE_MODULE_ERROR("no devices found\n");
|
||||||
delete item;
|
delete item;
|
||||||
return B_OK;
|
return found ? B_OK : ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -422,10 +430,8 @@ XHCI::~XHCI()
|
|||||||
fPCIInfo->device, fPCIInfo->function);
|
fPCIInfo->device, fPCIInfo->function);
|
||||||
}
|
}
|
||||||
put_module(B_PCI_MODULE_NAME);
|
put_module(B_PCI_MODULE_NAME);
|
||||||
if (sPCIx86Module != NULL) {
|
if (sPCIx86Module != NULL)
|
||||||
sPCIx86Module = NULL;
|
|
||||||
put_module(B_PCI_X86_MODULE_NAME);
|
put_module(B_PCI_X86_MODULE_NAME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user