Author: rnoland
Date: Wed Mar  4 18:23:48 2009
New Revision: 189367
URL: http://svn.freebsd.org/changeset/base/189367

Log:
  Extend the management of PCIM_CMD_INTxDIS.
  
  We now explicitly enable INTx during bus_setup_intr() if it is needed.
  Several of the ata drivers were managing this bit internally.  This is
  better handled in pci and it should work for all drivers now.
  
  We also mask INTx during bus_teardown_intr() by setting this bit.
  
  Reviewed by:  jhb
  MFC after:    3 days

Modified:
  head/sys/dev/pci/pci.c

Modified: head/sys/dev/pci/pci.c
==============================================================================
--- head/sys/dev/pci/pci.c      Wed Mar  4 16:21:00 2009        (r189366)
+++ head/sys/dev/pci/pci.c      Wed Mar  4 18:23:48 2009        (r189367)
@@ -2825,14 +2825,24 @@ pci_setup_intr(device_t dev, device_t ch
        if (error)
                return (error);
 
-       /*
-        * If this is a direct child, check to see if the interrupt is
-        * MSI or MSI-X.  If so, ask our parent to map the MSI and give
-        * us the address and data register values.  If we fail for some
-        * reason, teardown the interrupt handler.
-        */
+       /* If this is not a direct child, just bail out. */
+       if (device_get_parent(child) != dev) {
+               *cookiep = cookie;
+               return(0);
+       }
+
        rid = rman_get_rid(irq);
-       if (device_get_parent(child) == dev && rid > 0) {
+       if (rid == 0) {
+               /* Make sure that INTx is enabled */
+               pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS);
+       } else {
+               /*
+                * Check to see if the interrupt is MSI or MSI-X.
+                * Ask our parent to map the MSI and give
+                * us the address and data register values.
+                * If we fail for some reason, teardown the
+                * interrupt handler.
+                */
                dinfo = device_get_ivars(child);
                if (dinfo->cfg.msi.msi_alloc > 0) {
                        if (dinfo->cfg.msi.msi_addr == 0) {
@@ -2874,7 +2884,8 @@ pci_setup_intr(device_t dev, device_t ch
                        }
                        mte->mte_handlers++;
                }
-               /* Disable INTx if we are using MSI/MSIX */
+
+               /* Make sure that INTx is disabled if we are using MSI/MSIX */
                pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS);
        bad:
                if (error) {
@@ -2896,16 +2907,24 @@ pci_teardown_intr(device_t dev, device_t
        struct pci_devinfo *dinfo;
        int error, rid;
 
-       /*
-        * If this is a direct child, check to see if the interrupt is
-        * MSI or MSI-X.  If so, decrement the appropriate handlers
-        * count and mask the MSI-X message, or disable MSI messages
-        * if the count drops to 0.
-        */
        if (irq == NULL || !(rman_get_flags(irq) & RF_ACTIVE))
                return (EINVAL);
+
+       /* If this isn't a direct child, just bail out */
+       if (device_get_parent(child) != dev)
+               return(bus_generic_teardown_intr(dev, child, irq, cookie));
+
        rid = rman_get_rid(irq);
-       if (device_get_parent(child) == dev && rid > 0) {
+       if (rid > 0) {
+               /* Mask INTx */
+               pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS);
+       } else {
+               /*
+                * Check to see if the interrupt is MSI or MSI-X.  If so,
+                * decrement the appropriate handlers count and mask the
+                * MSI-X message, or disable MSI messages if the count
+                * drops to 0.
+                */
                dinfo = device_get_ivars(child);
                rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, rid);
                if (rle->res != irq)
@@ -2930,11 +2949,9 @@ pci_teardown_intr(device_t dev, device_t
                        if (mte->mte_handlers == 0)
                                pci_mask_msix(child, rid - 1);
                }
-               /* Restore INTx capability for MSI/MSIX */
-               pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS);
        }
        error = bus_generic_teardown_intr(dev, child, irq, cookie);
-       if (device_get_parent(child) == dev && rid > 0)
+       if (rid > 0)
                KASSERT(error == 0,
                    ("%s: generic teardown failed for MSI/MSI-X", __func__));
        return (error);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to