Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Mar 2018 19:04:40 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r330938 - in stable/10/sys: dev/acpica dev/cardbus dev/pci powerpc/ofw sparc64/pci
Message-ID:  <201803141904.w2EJ4eRM017948@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Mar 14 19:04:40 2018
New Revision: 330938
URL: https://svnweb.freebsd.org/changeset/base/330938

Log:
  Convert pci_delete_child() to a bus_child_deleted() method.
  
  Instead of providing a wrapper around device_delete_child() that the PCI
  bus and child bus drivers must call explicitly, move the bulk of the logic
  from pci_delete_child() into a bus_child_deleted() method
  (pci_child_deleted()).  This allows PCI devices to be safely deleted via
  device_delete_child().
  - Add a bus_child_deleted method to the ACPI PCI bus which clears the
    device_t associated with the corresponding ACPI handle in addition to
    the normal PCI bus cleanup.
  - Change cardbus_detach_card to call device_delete_children() and move
    CardBus-specific delete logic into a new cardbus_child_deleted() method.
  - Use device_delete_child() instead of pci_delete_child() in the SRIOV code.
  - Add a bus_child_deleted method to the OpenFirmware PCI bus drivers which
    frees the OpenFirmware device info for each PCI device.
  
  To preserve KBI, a pci_delete_child() function is left in place that
  just calls device_delete_child().
  
  PR:		226562
  Requested by:	dexuan

Modified:
  stable/10/sys/dev/acpica/acpi_pci.c
  stable/10/sys/dev/cardbus/cardbus.c
  stable/10/sys/dev/pci/pci.c
  stable/10/sys/dev/pci/pci_private.h
  stable/10/sys/powerpc/ofw/ofw_pcibus.c
  stable/10/sys/sparc64/pci/ofw_pcibus.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/acpica/acpi_pci.c
==============================================================================
--- stable/10/sys/dev/acpica/acpi_pci.c	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/dev/acpica/acpi_pci.c	Wed Mar 14 19:04:40 2018	(r330938)
@@ -70,6 +70,7 @@ CTASSERT(ACPI_STATE_D2 == PCI_POWERSTATE_D2);
 CTASSERT(ACPI_STATE_D3 == PCI_POWERSTATE_D3);
 
 static int	acpi_pci_attach(device_t dev);
+static void	acpi_pci_child_deleted(device_t dev, device_t child);
 static int	acpi_pci_child_location_str_method(device_t cbdev,
 		    device_t child, char *buf, size_t buflen);
 static int	acpi_pci_probe(device_t dev);
@@ -92,6 +93,7 @@ static device_method_t acpi_pci_methods[] = {
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	acpi_pci_read_ivar),
 	DEVMETHOD(bus_write_ivar,	acpi_pci_write_ivar),
+	DEVMETHOD(bus_child_deleted,	acpi_pci_child_deleted),
 	DEVMETHOD(bus_child_location_str, acpi_pci_child_location_str_method),
 	DEVMETHOD(bus_get_dma_tag,	acpi_pci_get_dma_tag),
 	DEVMETHOD(bus_get_domain,	acpi_get_domain),
@@ -143,6 +145,16 @@ acpi_pci_write_ivar(device_t dev, device_t child, int 
 	return (0);
     }
     return (pci_write_ivar(dev, child, which, value));
+}
+
+static void
+acpi_pci_child_deleted(device_t dev, device_t child)
+{
+	struct acpi_pci_devinfo *dinfo = device_get_ivars(child);
+
+	if (acpi_get_device(dinfo->ap_handle) == child)
+		AcpiDetachData(dinfo->ap_handle, acpi_fake_objhandler);
+	pci_child_deleted(dev, child);
 }
 
 static int

Modified: stable/10/sys/dev/cardbus/cardbus.c
==============================================================================
--- stable/10/sys/dev/cardbus/cardbus.c	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/dev/cardbus/cardbus.c	Wed Mar 14 19:04:40 2018	(r330938)
@@ -226,31 +226,30 @@ cardbus_attach_card(device_t cbdev)
 	return (ENOENT);
 }
 
+static void
+cardbus_child_deleted(device_t cbdev, device_t child)
+{
+	struct cardbus_devinfo *dinfo = device_get_ivars(child);
+
+	if (dinfo->pci.cfg.dev != child)
+		device_printf(cbdev, "devinfo dev mismatch\n");
+	cardbus_device_destroy(dinfo);
+	pci_child_deleted(cbdev, child);
+}
+
 static int
 cardbus_detach_card(device_t cbdev)
 {
-	int numdevs;
-	device_t *devlist;
-	int tmp;
 	int err = 0;
 
-	if (device_get_children(cbdev, &devlist, &numdevs) != 0)
-		return (ENOENT);
-	if (numdevs == 0) {
-		free(devlist, M_TEMP);
-		return (ENOENT);
-	}
+	err = bus_generic_detach(cbdev);
+	if (err)
+		return (err);
+	err = device_delete_children(cbdev);
+	if (err)
+		return (err);
 
-	for (tmp = 0; tmp < numdevs; tmp++) {
-		struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]);
-
-		if (dinfo->pci.cfg.dev != devlist[tmp])
-			device_printf(cbdev, "devinfo dev mismatch\n");
-		cardbus_device_destroy(dinfo);
-		pci_delete_child(cbdev, devlist[tmp]);
-	}
 	POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
-	free(devlist, M_TEMP);
 	return (err);
 }
 
@@ -335,6 +334,7 @@ static device_method_t cardbus_methods[] = {
 	DEVMETHOD(device_resume,	cardbus_resume),
 
 	/* Bus interface */
+	DEVMETHOD(bus_child_deleted,	cardbus_child_deleted),
 	DEVMETHOD(bus_get_dma_tag,	bus_generic_get_dma_tag),
 	DEVMETHOD(bus_read_ivar,	cardbus_read_ivar),
 	DEVMETHOD(bus_driver_added,	cardbus_driver_added),

Modified: stable/10/sys/dev/pci/pci.c
==============================================================================
--- stable/10/sys/dev/pci/pci.c	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/dev/pci/pci.c	Wed Mar 14 19:04:40 2018	(r330938)
@@ -154,6 +154,7 @@ static device_method_t pci_methods[] = {
 	DEVMETHOD(bus_release_resource,	pci_release_resource),
 	DEVMETHOD(bus_activate_resource, pci_activate_resource),
 	DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
+	DEVMETHOD(bus_child_deleted,	pci_child_deleted),
 	DEVMETHOD(bus_child_detached,	pci_child_detached),
 	DEVMETHOD(bus_child_pnpinfo_str, pci_child_pnpinfo_str_method),
 	DEVMETHOD(bus_child_location_str, pci_child_location_str_method),
@@ -4883,7 +4884,7 @@ pci_deactivate_resource(device_t dev, device_t child, 
 }
 
 void
-pci_delete_child(device_t dev, device_t child)
+pci_child_deleted(device_t dev, device_t child)
 {
 	struct resource_list_entry *rle;
 	struct resource_list *rl;
@@ -4892,13 +4893,14 @@ pci_delete_child(device_t dev, device_t child)
 	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);
+	if (bus_child_present(child) != 0) {
+		pci_write_config(child, PCIR_COMMAND, pci_read_config(child,
+		    PCIR_COMMAND, 2) & ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN), 2);
 
+		pci_disable_busmaster(child);
+	}
+
 	/* Free all allocated resources */
 	STAILQ_FOREACH(rle, rl, link) {
 		if (rle->res) {
@@ -4918,8 +4920,17 @@ pci_delete_child(device_t dev, device_t child)
 	}
 	resource_list_free(rl);
 
-	device_delete_child(dev, child);
 	pci_freecfg(dinfo);
+}
+
+/* KBI compatability shim. */
+extern void pci_delete_child(device_t dev, device_t child);
+
+void
+pci_delete_child(device_t dev, device_t child)
+{
+
+	device_delete_child (dev, child);
 }
 
 void

Modified: stable/10/sys/dev/pci/pci_private.h
==============================================================================
--- stable/10/sys/dev/pci/pci_private.h	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/dev/pci/pci_private.h	Wed Mar 14 19:04:40 2018	(r330938)
@@ -54,7 +54,6 @@ void		pci_add_child(device_t bus, struct pci_devinfo *
 void		pci_add_resources(device_t bus, device_t dev, int force,
 		    uint32_t prefetchmask);
 int		pci_attach_common(device_t dev);
-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);
@@ -118,6 +117,7 @@ struct pci_devinfo *pci_read_device(device_t pcib, int
 		    size_t size);
 void		pci_print_verbose(struct pci_devinfo *dinfo);
 int		pci_freecfg(struct pci_devinfo *dinfo);
+void		pci_child_deleted(device_t dev, device_t child);
 void		pci_child_detached(device_t dev, device_t child);
 int		pci_child_location_str_method(device_t cbdev, device_t child,
 		    char *buf, size_t buflen);

Modified: stable/10/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- stable/10/sys/powerpc/ofw/ofw_pcibus.c	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/powerpc/ofw/ofw_pcibus.c	Wed Mar 14 19:04:40 2018	(r330938)
@@ -61,6 +61,7 @@ static device_probe_t ofw_pcibus_probe;
 static device_attach_t ofw_pcibus_attach;
 static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
 static ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
+static bus_child_deleted_t ofw_pcibus_child_deleted;
 static int ofw_pcibus_child_pnpinfo_str_method(device_t cbdev, device_t child,
     char *buf, size_t buflen);
 
@@ -73,6 +74,7 @@ static device_method_t ofw_pcibus_methods[] = {
 	DEVMETHOD(device_attach,	ofw_pcibus_attach),
 
 	/* Bus interface */
+	DEVMETHOD(bus_child_deleted,	ofw_pcibus_child_deleted),
 	DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_child_pnpinfo_str_method),
 
 	/* PCI interface */
@@ -265,6 +267,16 @@ ofw_pcibus_enum_bus(device_t dev, u_int domain, u_int 
 			pci_add_child(dev, (struct pci_devinfo *)dinfo);
 		}
 	}
+}
+
+static void
+ofw_pcibus_child_deleted(device_t dev, device_t child)
+{
+	struct ofw_pcibus_devinfo *dinfo;
+
+	dinfo = device_get_ivars(dev);
+	ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);
+	pci_child_deleted(dev, child);
 }
 
 static int

Modified: stable/10/sys/sparc64/pci/ofw_pcibus.c
==============================================================================
--- stable/10/sys/sparc64/pci/ofw_pcibus.c	Wed Mar 14 18:27:06 2018	(r330937)
+++ stable/10/sys/sparc64/pci/ofw_pcibus.c	Wed Mar 14 19:04:40 2018	(r330938)
@@ -65,6 +65,7 @@ static void ofw_pcibus_setup_device(device_t bridge, u
     u_int busno, u_int slot, u_int func);
 
 /* Methods */
+static bus_child_deleted_t ofw_pcibus_child_deleted;
 static bus_child_pnpinfo_str_t ofw_pcibus_pnpinfo_str;
 static device_attach_t ofw_pcibus_attach;
 static device_probe_t ofw_pcibus_probe;
@@ -77,6 +78,7 @@ static device_method_t ofw_pcibus_methods[] = {
 	DEVMETHOD(device_attach,	ofw_pcibus_attach),
 
 	/* Bus interface */
+	DEVMETHOD(bus_child_deleted,	ofw_pcibus_child_deleted),
 	DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_pnpinfo_str),
 
 	/* PCI interface */
@@ -325,6 +327,16 @@ ofw_pcibus_get_devinfo(device_t bus, device_t dev)
 
 	dinfo = device_get_ivars(dev);
 	return (&dinfo->opd_obdinfo);
+}
+
+static void
+ofw_pcibus_child_deleted(device_t dev, device_t child)
+{
+	struct ofw_pcibus_devinfo *dinfo;
+
+	dinfo = device_get_ivars(dev);
+	ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);
+	pci_child_deleted(dev, child);
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803141904.w2EJ4eRM017948>