From owner-svn-src-head@FreeBSD.ORG Tue Jan 5 20:42:25 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6DAED1065692; Tue, 5 Jan 2010 20:42:25 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5CA678FC15; Tue, 5 Jan 2010 20:42:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o05KgP2E007357; Tue, 5 Jan 2010 20:42:25 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o05KgPQ6007353; Tue, 5 Jan 2010 20:42:25 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201001052042.o05KgPQ6007353@svn.freebsd.org> From: John Baldwin Date: Tue, 5 Jan 2010 20:42:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201609 - in head/sys/dev: cardbus pci X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jan 2010 20:42:25 -0000 Author: jhb Date: Tue Jan 5 20:42:25 2010 New Revision: 201609 URL: http://svn.freebsd.org/changeset/base/201609 Log: 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 Modified: head/sys/dev/cardbus/cardbus.c head/sys/dev/pci/pci.c head/sys/dev/pci/pci_private.h Modified: head/sys/dev/cardbus/cardbus.c ============================================================================== --- head/sys/dev/cardbus/cardbus.c Tue Jan 5 20:40:40 2010 (r201608) +++ head/sys/dev/cardbus/cardbus.c Tue Jan 5 20:42:25 2010 (r201609) @@ -80,8 +80,6 @@ static void cardbus_driver_added(device_ 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, dri 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 */ /************************************************************************/ Modified: head/sys/dev/pci/pci.c ============================================================================== --- head/sys/dev/pci/pci.c Tue Jan 5 20:40:40 2010 (r201608) +++ head/sys/dev/pci/pci.c Tue Jan 5 20:42:25 2010 (r201609) @@ -3797,6 +3797,46 @@ pci_deactivate_resource(device_t dev, de } 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) { struct pci_devinfo *dinfo; Modified: head/sys/dev/pci/pci_private.h ============================================================================== --- head/sys/dev/pci/pci_private.h Tue Jan 5 20:40:40 2010 (r201608) +++ head/sys/dev/pci/pci_private.h Tue Jan 5 20:42:25 2010 (r201609) @@ -43,6 +43,7 @@ void pci_add_children(device_t dev, int 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);