Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Mar 2009 08:25:05 +0000 (UTC)
From:      Robert Noland <rnoland@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r189569 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb dev/pci
Message-ID:  <200903090825.n298P5RU014944@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rnoland
Date: Mon Mar  9 08:25:05 2009
New Revision: 189569
URL: http://svn.freebsd.org/changeset/base/189569

Log:
  Merge r189367,189447
  
    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.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/dev/pci/pci.c

Modified: stable/7/sys/dev/pci/pci.c
==============================================================================
--- stable/7/sys/dev/pci/pci.c	Mon Mar  9 08:18:40 2009	(r189568)
+++ stable/7/sys/dev/pci/pci.c	Mon Mar  9 08:25:05 2009	(r189569)
@@ -2796,14 +2796,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) {
@@ -2845,7 +2855,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) {
@@ -2867,16 +2878,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)
@@ -2901,11 +2920,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);



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