msi/pci: Pass cpuid to pcib_release_msi method
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 24 Dec 2011 14:11:10 +0000 (22:11 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 27 Dec 2011 05:44:42 +0000 (13:44 +0800)
sys/bus/pci/pci.c
sys/bus/pci/pci_pci.c
sys/bus/pci/pcib_if.m
sys/bus/pci/pcib_private.h

index 1fbe006..360534b 100644 (file)
@@ -2179,7 +2179,7 @@ pci_release_msi_method(device_t dev, device_t child)
        struct pci_devinfo *dinfo = device_get_ivars(child);
        struct pcicfg_msi *msi = &dinfo->cfg.msi;
        struct resource_list_entry *rle;
-       int error, i, irqs[32];
+       int error, i, irqs[32], cpuid = -1;
 
        /* Try MSI-X first. */
        error = pci_release_msix(dev, child);
@@ -2199,6 +2199,15 @@ pci_release_msi_method(device_t dev, device_t child)
                KASSERT(rle != NULL, ("missing MSI resource"));
                if (rle->res != NULL)
                        return (EBUSY);
+               if (i == 0) {
+                       cpuid = rle->cpuid;
+                       KASSERT(cpuid >= 0 && cpuid < ncpus,
+                           ("invalid MSI target cpuid %d\n", cpuid));
+               } else {
+                       KASSERT(rle->cpuid == cpuid,
+                           ("MSI targets different cpus, "
+                            "was cpu%d, now cpu%d", cpuid, rle->cpuid));
+               }
                irqs[i] = rle->start;
        }
 
@@ -2210,7 +2219,8 @@ pci_release_msi_method(device_t dev, device_t child)
            msi->msi_ctrl, 2);
 
        /* Release the messages. */
-       PCIB_RELEASE_MSI(device_get_parent(dev), child, msi->msi_alloc, irqs);
+       PCIB_RELEASE_MSI(device_get_parent(dev), child, msi->msi_alloc, irqs,
+           cpuid);
        for (i = 0; i < msi->msi_alloc; i++)
                resource_list_delete(&dinfo->resources, SYS_RES_IRQ, i + 1);
 
index e5f69e0..a10baa8 100644 (file)
@@ -609,12 +609,13 @@ pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount,
 
 /* Pass request to release MSI/MSI-X messages up to the parent bridge. */
 int
-pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs)
+pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs, int cpuid)
 {
        device_t bus;
 
        bus = device_get_parent(pcib);
-       return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs));
+       return (PCIB_RELEASE_MSI(device_get_parent(bus), dev, count, irqs,
+           cpuid));
 }
 
 /* Pass request to alloc an MSI-X message up to the parent bridge. */
index 4af4d7d..f2e1e20 100644 (file)
@@ -114,6 +114,7 @@ METHOD int release_msi {
        device_t        dev;
        int             count;
        int             *irqs;
+       int             cpuid;
 };
 
 #
index 7d37ffa..aab5807 100644 (file)
@@ -78,7 +78,7 @@ uint32_t      pcib_read_config(device_t dev, int b, int s, int f, int reg, int width)
 void           pcib_write_config(device_t dev, int b, int s, int f, int reg, uint32_t val, int width);
 int            pcib_route_interrupt(device_t pcib, device_t dev, int pin);
 int            pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs, int cpuid);
-int            pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs);
+int            pcib_release_msi(device_t pcib, device_t dev, int count, int *irqs, int cpuid);
 int            pcib_alloc_msix(device_t pcib, device_t dev, int *irq);
 int            pcib_release_msix(device_t pcib, device_t dev, int irq);
 int            pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);