Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167598507
D6018.id15662.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D6018.id15662.diff
View Options
Index: head/sys/dev/cardbus/cardbus.c
===================================================================
--- head/sys/dev/cardbus/cardbus.c
+++ head/sys/dev/cardbus/cardbus.c
@@ -346,6 +346,7 @@
DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag),
DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
DEVMETHOD(bus_driver_added, cardbus_driver_added),
+ DEVMETHOD(bus_rescan, kobj_error_method),
/* Card Interface */
DEVMETHOD(card_attach_card, cardbus_attach_card),
Index: head/sys/dev/pci/pci.c
===================================================================
--- head/sys/dev/pci/pci.c
+++ head/sys/dev/pci/pci.c
@@ -168,6 +168,7 @@
DEVMETHOD(bus_remap_intr, pci_remap_intr_method),
DEVMETHOD(bus_suspend_child, pci_suspend_child),
DEVMETHOD(bus_resume_child, pci_resume_child),
+ DEVMETHOD(bus_rescan, pci_rescan_method),
/* PCI interface */
DEVMETHOD(pci_read_config, pci_read_config_method),
@@ -3917,6 +3918,103 @@
#undef REG
}
+int
+pci_rescan_method(device_t dev)
+{
+#define REG(n, w) PCIB_READ_CONFIG(pcib, busno, s, f, n, w)
+ device_t pcib = device_get_parent(dev);
+ struct pci_softc *sc;
+ device_t child, *devlist, *unchanged;
+ int devcount, error, i, j, maxslots, oldcount;
+ int busno, domain, s, f, pcifunchigh;
+ uint8_t hdrtype;
+
+ /* No need to check for ARI on a rescan. */
+ error = device_get_children(dev, &devlist, &devcount);
+ if (error)
+ return (error);
+ if (devcount != 0) {
+ unchanged = malloc(devcount * sizeof(device_t), M_TEMP,
+ M_NOWAIT | M_ZERO);
+ if (unchanged == NULL) {
+ free(devlist, M_TEMP);
+ return (ENOMEM);
+ }
+ } else
+ unchanged = NULL;
+
+ sc = device_get_softc(dev);
+ domain = pcib_get_domain(dev);
+ busno = pcib_get_bus(dev);
+ maxslots = PCIB_MAXSLOTS(pcib);
+ for (s = 0; s <= maxslots; s++) {
+ /* If function 0 is not present, skip to the next slot. */
+ f = 0;
+ if (REG(PCIR_VENDOR, 2) == 0xffff)
+ continue;
+ pcifunchigh = 0;
+ hdrtype = REG(PCIR_HDRTYPE, 1);
+ if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
+ continue;
+ if (hdrtype & PCIM_MFDEV)
+ pcifunchigh = PCIB_MAXFUNCS(pcib);
+ for (f = 0; f <= pcifunchigh; f++) {
+ if (REG(PCIR_VENDOR, 2) == 0xfff)
+ continue;
+
+ /*
+ * Found a valid function. Check if a
+ * device_t for this device already exists.
+ */
+ for (i = 0; i < devcount; i++) {
+ child = devlist[i];
+ if (child == NULL)
+ continue;
+ if (pci_get_slot(child) == s &&
+ pci_get_function(child) == f) {
+ unchanged[i] = child;
+ goto next_func;
+ }
+ }
+
+ pci_identify_function(pcib, dev, domain, busno, s, f);
+ next_func:;
+ }
+ }
+
+ /* Remove devices that are no longer present. */
+ for (i = 0; i < devcount; i++) {
+ if (unchanged[i] != NULL)
+ continue;
+ device_delete_child(dev, devlist[i]);
+ }
+
+ free(devlist, M_TEMP);
+ oldcount = devcount;
+
+ /* Try to attach the devices just added. */
+ error = device_get_children(dev, &devlist, &devcount);
+ if (error) {
+ free(unchanged, M_TEMP);
+ return (error);
+ }
+
+ for (i = 0; i < devcount; i++) {
+ for (j = 0; j < oldcount; j++) {
+ if (devlist[i] == unchanged[j])
+ goto next_device;
+ }
+
+ device_probe_and_attach(devlist[i]);
+ next_device:;
+ }
+
+ free(unchanged, M_TEMP);
+ free(devlist, M_TEMP);
+ return (0);
+#undef REG
+}
+
#ifdef PCI_IOV
device_t
pci_add_iov_child(device_t bus, device_t pf, uint16_t rid, uint16_t vid,
Index: head/sys/dev/pci/pci_private.h
===================================================================
--- head/sys/dev/pci/pci_private.h
+++ head/sys/dev/pci/pci_private.h
@@ -57,6 +57,7 @@
void pci_add_resources_ea(device_t bus, device_t dev, int alloc_iov);
struct pci_devinfo *pci_alloc_devinfo_method(device_t dev);
int pci_attach_common(device_t dev);
+int pci_rescan_method(device_t dev);
void pci_driver_added(device_t dev, driver_t *driver);
int pci_ea_is_enabled(device_t dev, int rid);
int pci_print_child(device_t dev, device_t child);
Index: head/sys/mips/nlm/xlp_pci.c
===================================================================
--- head/sys/mips/nlm/xlp_pci.c
+++ head/sys/mips/nlm/xlp_pci.c
@@ -154,6 +154,7 @@
/* Device interface */
DEVMETHOD(device_probe, xlp_pci_probe),
DEVMETHOD(device_attach, xlp_pci_attach),
+ DEVMETHOD(bus_rescan, kobj_error_method),
DEVMETHOD_END
};
Index: head/sys/powerpc/ofw/ofw_pcibus.c
===================================================================
--- head/sys/powerpc/ofw/ofw_pcibus.c
+++ head/sys/powerpc/ofw/ofw_pcibus.c
@@ -77,6 +77,7 @@
/* Bus interface */
DEVMETHOD(bus_child_deleted, ofw_pcibus_child_deleted),
DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_child_pnpinfo_str_method),
+ DEVMETHOD(bus_rescan, kobj_error_method),
/* PCI interface */
DEVMETHOD(pci_alloc_devinfo, ofw_pcibus_alloc_devinfo),
Index: head/sys/sparc64/pci/ofw_pcibus.c
===================================================================
--- head/sys/sparc64/pci/ofw_pcibus.c
+++ head/sys/sparc64/pci/ofw_pcibus.c
@@ -81,6 +81,7 @@
/* Bus interface */
DEVMETHOD(bus_child_deleted, ofw_pcibus_child_deleted),
DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_pnpinfo_str),
+ DEVMETHOD(bus_rescan, kobj_error_method),
/* PCI interface */
DEVMETHOD(pci_alloc_devinfo, ofw_pcibus_alloc_devinfo),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Aug 24, 12:26 AM (8 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37167500
Default Alt Text
D6018.id15662.diff (5 KB)
Attached To
Mode
D6018: Implement a PCI bus rescan method.
Attached
Detach File
Event Timeline
Log In to Comment