Move the PCI-specific logic of removing a cardbus device into a
pci_delete_child() function called by the cardbus driver. The new function uses resource_list_unreserve() to release the BARs decoded by the device being removed. Reviewed by: imp Tested by: brooks
This commit is contained in:
parent
a0dce5cf22
commit
2dd11a3eaa
@ -80,8 +80,6 @@ static void cardbus_driver_added(device_t cbdev, driver_t *driver);
|
||||
static int cardbus_probe(device_t cbdev);
|
||||
static int cardbus_read_ivar(device_t cbdev, device_t child, int which,
|
||||
uintptr_t *result);
|
||||
static void cardbus_release_all_resources(device_t cbdev,
|
||||
struct cardbus_devinfo *dinfo);
|
||||
|
||||
/************************************************************************/
|
||||
/* Probe/Attach */
|
||||
@ -226,16 +224,11 @@ cardbus_detach_card(device_t cbdev)
|
||||
|
||||
for (tmp = 0; tmp < numdevs; tmp++) {
|
||||
struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
|
||||
int status = device_get_state(devlist[tmp]);
|
||||
|
||||
if (dinfo->pci.cfg.dev != devlist[tmp])
|
||||
device_printf(cbdev, "devinfo dev mismatch\n");
|
||||
if (status == DS_ATTACHED || status == DS_BUSY)
|
||||
device_detach(devlist[tmp]);
|
||||
cardbus_release_all_resources(cbdev, dinfo);
|
||||
cardbus_device_destroy(dinfo);
|
||||
device_delete_child(cbdev, devlist[tmp]);
|
||||
pci_freecfg((struct pci_devinfo *)dinfo);
|
||||
pci_delete_child(cbdev, devlist[tmp]);
|
||||
}
|
||||
POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
|
||||
free(devlist, M_TEMP);
|
||||
@ -283,28 +276,6 @@ cardbus_driver_added(device_t cbdev, driver_t *driver)
|
||||
free(devlist, M_TEMP);
|
||||
}
|
||||
|
||||
static void
|
||||
cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo)
|
||||
{
|
||||
struct resource_list_entry *rle;
|
||||
device_t dev;
|
||||
|
||||
/* Turn off access to resources we're about to free */
|
||||
dev = dinfo->pci.cfg.dev;
|
||||
pci_write_config(dev, PCIR_COMMAND,
|
||||
pci_read_config(dev, PCIR_COMMAND, 2) &
|
||||
~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN), 2);
|
||||
/* Free all allocated resources */
|
||||
STAILQ_FOREACH(rle, &dinfo->pci.resources, link) {
|
||||
if (rle->res) {
|
||||
BUS_RELEASE_RESOURCE(device_get_parent(cbdev),
|
||||
cbdev, rle->type, rle->rid, rle->res);
|
||||
rle->res = NULL;
|
||||
}
|
||||
}
|
||||
resource_list_free(&dinfo->pci.resources);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* Other Bus Methods */
|
||||
/************************************************************************/
|
||||
|
@ -3796,6 +3796,46 @@ pci_deactivate_resource(device_t dev, device_t child, int type,
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pci_delete_child(device_t dev, device_t child)
|
||||
{
|
||||
struct resource_list_entry *rle;
|
||||
struct resource_list *rl;
|
||||
struct pci_devinfo *dinfo;
|
||||
|
||||
dinfo = device_get_ivars(child);
|
||||
rl = &dinfo->resources;
|
||||
|
||||
if (device_is_attached(child))
|
||||
device_detach(child);
|
||||
|
||||
/* Turn off access to resources we're about to free */
|
||||
pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
|
||||
PCIR_COMMAND, 2) & ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN), 2);
|
||||
|
||||
/* Free all allocated resources */
|
||||
STAILQ_FOREACH(rle, rl, link) {
|
||||
if (rle->res) {
|
||||
if (rman_get_flags(rle->res) & RF_ACTIVE ||
|
||||
resource_list_busy(rl, rle->type, rle->rid)) {
|
||||
pci_printf(&dinfo->cfg,
|
||||
"Resource still owned, oops. "
|
||||
"(type=%d, rid=%d, addr=%lx)\n",
|
||||
rle->type, rle->rid,
|
||||
rman_get_start(rle->res));
|
||||
bus_release_resource(child, rle->type, rle->rid,
|
||||
rle->res);
|
||||
}
|
||||
resource_list_unreserve(rl, dev, child, rle->type,
|
||||
rle->rid);
|
||||
}
|
||||
}
|
||||
resource_list_free(rl);
|
||||
|
||||
device_delete_child(dev, child);
|
||||
pci_freecfg(dinfo);
|
||||
}
|
||||
|
||||
void
|
||||
pci_delete_resource(device_t dev, device_t child, int type, int rid)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ void pci_add_children(device_t dev, int domain, int busno,
|
||||
void pci_add_child(device_t bus, struct pci_devinfo *dinfo);
|
||||
void pci_add_resources(device_t bus, device_t dev, int force,
|
||||
uint32_t prefetchmask);
|
||||
void pci_delete_child(device_t dev, device_t child);
|
||||
void pci_driver_added(device_t dev, driver_t *driver);
|
||||
int pci_print_child(device_t dev, device_t child);
|
||||
void pci_probe_nomatch(device_t dev, device_t child);
|
||||
|
Loading…
Reference in New Issue
Block a user