Add functions to the old-style PCI bus manager to reserve a device from an old-style driver for exclusive use. This should help making OSS and native audio drivers mutually exclusive. Used in es1370 and hda drivers as examples. OSS must still be fixed to use it too though.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32899 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
271b9ad49a
commit
7e26ad5af7
@ -155,6 +155,18 @@ struct pci_module_info {
|
||||
uchar cap_id,
|
||||
uchar *offset
|
||||
);
|
||||
status_t (*reserve_device) (
|
||||
uchar bus,
|
||||
uchar device,
|
||||
uchar function,
|
||||
const char *driver_name,
|
||||
void *cookie);
|
||||
status_t (*unreserve_device) (
|
||||
uchar bus,
|
||||
uchar device,
|
||||
uchar function,
|
||||
const char *driver_name,
|
||||
void *cookie);
|
||||
};
|
||||
|
||||
#define B_PCI_MODULE_NAME "bus_managers/pci/v1"
|
||||
|
@ -86,6 +86,196 @@ pci_find_capability(uchar virtualBus, uchar device, uchar function,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
||||
const char *driverName, void *nodeCookie)
|
||||
{
|
||||
status_t status;
|
||||
uint8 bus;
|
||||
int domain;
|
||||
|
||||
/*
|
||||
* we add 2 nodes to the PCI devices, one with constant attributes,
|
||||
* so adding for another driver fails, and a subnode with the
|
||||
* driver-provided informations.
|
||||
*/
|
||||
|
||||
if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
//TRACE(("%s(%d [%d:%d], %d, %d, %s, %p)\n", __FUNCTION__, virtualBus,
|
||||
// domain, bus, device, function, driverName, nodeCookie));
|
||||
|
||||
device_attr matchPCIRoot[] = {
|
||||
{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "PCI"}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr matchThis[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}},
|
||||
|
||||
// location on PCI bus
|
||||
{B_PCI_DEVICE_DOMAIN, B_UINT32_TYPE, {ui32: domain}},
|
||||
{B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}},
|
||||
{B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: device}},
|
||||
{B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: function}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr legacyAttrs[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}},
|
||||
{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Legacy Driver Reservation"}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr drvAttrs[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}},
|
||||
{"legacy_driver", B_STRING_TYPE, {string: driverName}},
|
||||
{"legacy_driver_cookie", B_UINT64_TYPE, {ui64: (uint64)nodeCookie}},
|
||||
{NULL}
|
||||
};
|
||||
device_node *root, *pci, *node, *legacy;
|
||||
|
||||
status = B_DEVICE_NOT_FOUND;
|
||||
root = gDeviceManager->get_root_node();
|
||||
if (!root)
|
||||
return status;
|
||||
|
||||
pci = NULL;
|
||||
if (gDeviceManager->get_next_child_node(root, matchPCIRoot, &pci) < B_OK)
|
||||
goto err0;
|
||||
|
||||
node = NULL;
|
||||
if (gDeviceManager->get_next_child_node(pci, matchThis, &node) < B_OK)
|
||||
goto err1;
|
||||
|
||||
// common API for all legacy modules ?
|
||||
//status = legacy_driver_register(node, driverName, nodeCookie, PCI_LEGACY_DRIVER_MODULE_NAME);
|
||||
|
||||
status = gDeviceManager->register_node(node, PCI_LEGACY_DRIVER_MODULE_NAME,
|
||||
legacyAttrs, NULL, &legacy);
|
||||
if (status < B_OK)
|
||||
goto err2;
|
||||
|
||||
status = gDeviceManager->register_node(legacy, PCI_LEGACY_DRIVER_MODULE_NAME,
|
||||
drvAttrs, NULL, NULL);
|
||||
if (status < B_OK)
|
||||
goto err3;
|
||||
|
||||
gDeviceManager->put_node(node);
|
||||
gDeviceManager->put_node(pci);
|
||||
gDeviceManager->put_node(root);
|
||||
|
||||
return B_OK;
|
||||
|
||||
err3:
|
||||
gDeviceManager->unregister_node(legacy);
|
||||
err2:
|
||||
gDeviceManager->put_node(node);
|
||||
err1:
|
||||
gDeviceManager->put_node(pci);
|
||||
err0:
|
||||
gDeviceManager->put_node(root);
|
||||
TRACE(("pci_reserve_device for driver %s failed: %s\n", driverName, strerror(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
pci_unreserve_device(uchar virtualBus, uchar device, uchar function,
|
||||
const char *driverName, void *nodeCookie)
|
||||
{
|
||||
status_t status;
|
||||
uint8 bus;
|
||||
int domain;
|
||||
|
||||
if (gPCI->ResolveVirtualBus(virtualBus, &domain, &bus) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
//TRACE(("%s(%d [%d:%d], %d, %d, %s, %p)\n", __FUNCTION__, virtualBus,
|
||||
// domain, bus, device, function, driverName, nodeCookie));
|
||||
|
||||
device_attr matchPCIRoot[] = {
|
||||
{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "PCI"}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr matchThis[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}},
|
||||
|
||||
// location on PCI bus
|
||||
{B_PCI_DEVICE_DOMAIN, B_UINT32_TYPE, {ui32: domain}},
|
||||
{B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}},
|
||||
{B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: device}},
|
||||
{B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: function}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr legacyAttrs[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}},
|
||||
{B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "Legacy Driver Reservation"}},
|
||||
{NULL}
|
||||
};
|
||||
device_attr drvAttrs[] = {
|
||||
// info about device
|
||||
{B_DEVICE_BUS, B_STRING_TYPE, {string: "legacy_driver"}},
|
||||
{"legacy_driver", B_STRING_TYPE, {string: driverName}},
|
||||
{"legacy_driver_cookie", B_UINT64_TYPE, {ui64: (uint64)nodeCookie}},
|
||||
{NULL}
|
||||
};
|
||||
device_node *root, *pci, *node, *legacy, *drv;
|
||||
|
||||
status = B_DEVICE_NOT_FOUND;
|
||||
root = gDeviceManager->get_root_node();
|
||||
if (!root)
|
||||
return status;
|
||||
|
||||
pci = NULL;
|
||||
if (gDeviceManager->get_next_child_node(root, matchPCIRoot, &pci) < B_OK)
|
||||
goto err0;
|
||||
|
||||
node = NULL;
|
||||
if (gDeviceManager->get_next_child_node(pci, matchThis, &node) < B_OK)
|
||||
goto err1;
|
||||
|
||||
// common API for all legacy modules ?
|
||||
//status = legacy_driver_unregister(node, driverName, nodeCookie);
|
||||
|
||||
legacy = NULL;
|
||||
if (gDeviceManager->get_next_child_node(node, legacyAttrs, &legacy) < B_OK)
|
||||
goto err2;
|
||||
|
||||
drv = NULL;
|
||||
if (gDeviceManager->get_next_child_node(legacy, drvAttrs, &drv) < B_OK)
|
||||
goto err3;
|
||||
|
||||
gDeviceManager->put_node(drv);
|
||||
status = gDeviceManager->unregister_node(drv);
|
||||
//dprintf("unreg:drv:%s\n", strerror(status));
|
||||
|
||||
gDeviceManager->put_node(legacy);
|
||||
status = gDeviceManager->unregister_node(legacy);
|
||||
//dprintf("unreg:legacy:%s\n", strerror(status));
|
||||
// we'll get EBUSY here anyway...
|
||||
|
||||
gDeviceManager->put_node(node);
|
||||
gDeviceManager->put_node(pci);
|
||||
gDeviceManager->put_node(root);
|
||||
return B_OK;
|
||||
|
||||
err3:
|
||||
gDeviceManager->put_node(legacy);
|
||||
err2:
|
||||
gDeviceManager->put_node(node);
|
||||
err1:
|
||||
gDeviceManager->put_node(pci);
|
||||
err0:
|
||||
gDeviceManager->put_node(root);
|
||||
TRACE(("pci_unreserve_device for driver %s failed: %s\n", driverName, strerror(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// used by pci_info.cpp print_info_basic()
|
||||
void
|
||||
__pci_resolve_virtual_bus(uint8 virtualBus, int *domain, uint8 *bus)
|
||||
|
@ -64,7 +64,9 @@ static struct pci_module_info sOldPCIModule = {
|
||||
&pci_read_config,
|
||||
&pci_write_config,
|
||||
&pci_ram_address,
|
||||
&pci_find_capability
|
||||
&pci_find_capability,
|
||||
&pci_reserve_device,
|
||||
&pci_unreserve_device
|
||||
};
|
||||
|
||||
module_dependency module_dependencies[] = {
|
||||
@ -72,9 +74,19 @@ module_dependency module_dependencies[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
driver_module_info gPCILegacyDriverModule = {
|
||||
{
|
||||
PCI_LEGACY_DRIVER_MODULE_NAME,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
NULL
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sOldPCIModule,
|
||||
(module_info *)&gPCIRootModule,
|
||||
(module_info *)&gPCIDeviceModule,
|
||||
(module_info *)&gPCILegacyDriverModule,
|
||||
NULL
|
||||
};
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <device_manager.h>
|
||||
#include <bus/PCI.h>
|
||||
|
||||
// name of PCI legacy driver endpoint module
|
||||
#define PCI_LEGACY_DRIVER_MODULE_NAME "bus_managers/pci/legacy_v1"
|
||||
|
||||
// name of PCI device modules
|
||||
#define PCI_DEVICE_MODULE_NAME "bus_managers/pci/driver_v1"
|
||||
@ -46,6 +48,11 @@ void * pci_ram_address(const void *physical_address_in_system_memory);
|
||||
|
||||
status_t pci_find_capability(uchar bus, uchar device, uchar function, uchar cap_id, uchar *offset);
|
||||
|
||||
status_t pci_reserve_device(uchar virtualBus, uchar device, uchar function,
|
||||
const char *driverName, void *nodeCookie);
|
||||
status_t pci_unreserve_device(uchar virtualBus, uchar device, uchar function,
|
||||
const char *driverName, void *nodeCookie);
|
||||
|
||||
status_t pci_io_init(void);
|
||||
uint8 pci_read_io_8(int mapped_io_addr);
|
||||
void pci_write_io_8(int mapped_io_addr, uint8 value);
|
||||
|
@ -501,6 +501,7 @@ init_driver(void)
|
||||
pci_info info;
|
||||
int ix = 0;
|
||||
num_cards = 0;
|
||||
status_t err;
|
||||
|
||||
PRINT(("init_driver()\n"));
|
||||
|
||||
@ -529,7 +530,7 @@ init_driver(void)
|
||||
if (get_module(pci_name, (module_info **) &pci))
|
||||
return ENOSYS;
|
||||
|
||||
while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) {
|
||||
while ((*pci->get_nth_pci_info)(ix++, &info) == B_OK) {
|
||||
if (info.vendor_id == 0x1274
|
||||
&& (info.device_id == 0x5000
|
||||
/*|| info.device_id == 0x1371
|
||||
@ -541,6 +542,14 @@ init_driver(void)
|
||||
}
|
||||
memset(&cards[num_cards], 0, sizeof(es1370_dev));
|
||||
cards[num_cards].info = info;
|
||||
#ifdef __HAIKU__
|
||||
if ((err = (*pci->reserve_device)(info.bus, info.device, info.function,
|
||||
DRIVER_NAME, &cards[num_cards])) < B_OK) {
|
||||
dprintf("es1370: failed to reserve_device(%d, %d, %d,): %s\n",
|
||||
info.bus, info.device, info.function, strerror(err));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (es1370_setup(&cards[num_cards])) {
|
||||
PRINT(("Setup of es1370 %ld failed\n", num_cards+1));
|
||||
}
|
||||
@ -548,7 +557,6 @@ init_driver(void)
|
||||
num_cards++;
|
||||
}
|
||||
}
|
||||
ix++;
|
||||
}
|
||||
if (!num_cards) {
|
||||
PRINT(("no cards\n"));
|
||||
@ -579,8 +587,14 @@ uninit_driver(void)
|
||||
num_cards = 0;
|
||||
|
||||
PRINT(("uninit_driver()\n"));
|
||||
for (ix=0; ix<cnt; ix++)
|
||||
for (ix=0; ix<cnt; ix++) {
|
||||
es1370_shutdown(&cards[ix]);
|
||||
#ifdef __HAIKU__
|
||||
(*pci->unreserve_device)(cards[ix].info.bus,
|
||||
cards[ix].info.device, cards[ix].info.function,
|
||||
DRIVER_NAME, &cards[ix]);
|
||||
#endif
|
||||
}
|
||||
memset(&cards, 0, sizeof(cards));
|
||||
put_module(pci_name);
|
||||
}
|
||||
|
@ -55,6 +55,14 @@ init_driver(void)
|
||||
&& gNumCards < MAX_CARDS; i++) {
|
||||
if (info.class_base == PCI_multimedia
|
||||
&& info.class_sub == PCI_hd_audio) {
|
||||
#ifdef __HAIKU__
|
||||
if ((*gPci->reserve_device)(info.bus, info.device, info.function, "hda",
|
||||
&gCards[gNumCards]) < B_OK) {
|
||||
dprintf("HDA: Failed to reserve PCI:%d:%d:%d\n",
|
||||
info.bus, info.device, info.function);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
memset(&gCards[gNumCards], 0, sizeof(hda_controller));
|
||||
gCards[gNumCards].pci_info = info;
|
||||
gCards[gNumCards].opened = 0;
|
||||
@ -84,6 +92,10 @@ uninit_driver(void)
|
||||
dprintf("IRA: %s\n", __func__);
|
||||
|
||||
for (uint32 i = 0; i < gNumCards; i++) {
|
||||
#ifdef __HAIKU__
|
||||
(*gPci->unreserve_device)(gCards[i].pci_info.bus, gCards[i].pci_info.device,
|
||||
gCards[i].pci_info.function, "hda", &gCards[i]);
|
||||
#endif
|
||||
free((void*)gCards[i].devfs_path);
|
||||
gCards[i].devfs_path = NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user