All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Garzik <jgarzik@pobox.com>
To: Greg KH <gregkh@suse.de>
Cc: tom.l.nguyen@intel.com, linux-pci@atrey.karlin.mff.cuni.cz,
	linux-kernel@vger.kernel.org, roland@topspin.com,
	davem@davemloft.net, Michael Chan <mchan@broadcom.com>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Re: pci_enable_msi() for everyone?
Date: Fri, 03 Jun 2005 19:16:04 -0400	[thread overview]
Message-ID: <42A0E4B4.3050309@pobox.com> (raw)
In-Reply-To: <20050603224551.GA10014@kroah.com>

[-- Attachment #1: Type: text/plain, Size: 1780 bytes --]

Greg KH wrote:
> In talking with a few people about the MSI kernel code, they asked why
> we can't just do the pci_enable_msi() call for every pci device in the
> system (at somewhere like pci_enable_device() time or so).  That would
> let all drivers and devices get the MSI functionality without changing
> their code, and probably make the api a whole lot simpler.

Agreed.

And now is a good time to make changes, before bunches of drivers start 
using pci_enable_msi().  I am preparing such a change for the AHCI 
driver (see attached), which will be the standard SATA interface on most 
new motherboards.


> Now I know the e1000 driver would have to specifically disable MSI for
> some of their broken versions, and possibly some other drivers might
> need this, but the downside seems quite small.

tg3 needs to deal with some broken system chipsets as well.  See
tg3_test_msi(), which I would eventually prefer to eliminate in favor of 
PCI quirks and such.

An API note of warning though...   IMO eventually different drivers are 
going to want different behavior from pci_enable_device().  IDE already 
hacks around this, as Alan was required to do a while ago (IDE has a 
weird PCI BAR setup sometimes, requiring care during enabling).

Longer term, I think we will need a

	pci_enable(info on what to enable)

so that drivers can specify ahead of time "don't enable PIO, only MMIO", 
"don't enable MMIO, only PIO", "don't use MSI", etc.  and add a 
pci_disable() to undo all of that.

The more we add singleton functions like pci_enable_msi(), 
pci_set_master(), etc. the more I wish for a single function that 
handled all those details at one atomic point.  There is a lot of 
standard patterns that are hand-coded into every PCI driver's probe 
functions.

	Jeff


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 3831 bytes --]

diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ahci"
-#define DRV_VERSION	"1.00"
+#define DRV_VERSION	"1.01"
 
 
 enum {
@@ -153,6 +153,7 @@ struct ahci_sg {
 
 struct ahci_host_priv {
 	unsigned long		flags;
+	unsigned int		have_msi; /* is PCI MSI enabled? */
 	u32			cap;	/* cache of HOST_CAP register */
 	u32			port_map; /* cache of HOST_PORTS_IMPL reg */
 };
@@ -183,6 +184,7 @@ static void ahci_qc_prep(struct ata_queu
 static u8 ahci_check_status(struct ata_port *ap);
 static u8 ahci_check_err(struct ata_port *ap);
 static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+static void ahci_remove_one (struct pci_dev *pdev);
 
 static Scsi_Host_Template ahci_sht = {
 	.module			= THIS_MODULE,
@@ -272,7 +274,7 @@ static struct pci_driver ahci_pci_driver
 	.name			= DRV_NAME,
 	.id_table		= ahci_pci_tbl,
 	.probe			= ahci_init_one,
-	.remove			= ata_pci_remove_one,
+	.remove			= ahci_remove_one,
 };
 
 
@@ -879,15 +881,19 @@ static int ahci_host_init(struct ata_pro
 }
 
 /* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
+static void pci_intx(struct pci_dev *pdev, int enable)
 {
-	u16 pci_command;
+	u16 pci_command, new;
 
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-		pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+
+	if (enable)
+		new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+	else
+		new = pci_command | PCI_COMMAND_INTX_DISABLE;
+
+	if (new != pci_command)
 		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-	}
 }
 
 static void ahci_print_info(struct ata_probe_ent *probe_ent)
@@ -969,7 +975,7 @@ static int ahci_init_one (struct pci_dev
 	unsigned long base;
 	void *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
-	int pci_dev_busy = 0;
+	int have_msi, pci_dev_busy = 0;
 	int rc;
 
 	VPRINTK("ENTER\n");
@@ -987,12 +993,17 @@ static int ahci_init_one (struct pci_dev
 		goto err_out;
 	}
 
-	pci_enable_intx(pdev);
+	if (pci_enable_msi(pdev) == 0)
+		have_msi = 1;
+	else {
+		pci_intx(pdev, 1);
+		have_msi = 0;
+	}
 
 	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
 	if (probe_ent == NULL) {
 		rc = -ENOMEM;
-		goto err_out_regions;
+		goto err_out_msi;
 	}
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
@@ -1025,6 +1036,8 @@ static int ahci_init_one (struct pci_dev
 	probe_ent->mmio_base = mmio_base;
 	probe_ent->private_data = hpriv;
 
+	hpriv->have_msi = have_msi;
+
 	/* initialize adapter */
 	rc = ahci_host_init(probe_ent);
 	if (rc)
@@ -1044,7 +1057,11 @@ err_out_iounmap:
 	iounmap(mmio_base);
 err_out_free_ent:
 	kfree(probe_ent);
-err_out_regions:
+err_out_msi:
+	if (have_msi)
+		pci_disable_msi(pdev);
+	else
+		pci_intx(pdev, 0);
 	pci_release_regions(pdev);
 err_out:
 	if (!pci_dev_busy)
@@ -1052,6 +1069,42 @@ err_out:
 	return rc;
 }
 
+static void ahci_remove_one (struct pci_dev *pdev)
+{
+	struct device *dev = pci_dev_to_dev(pdev);
+	struct ata_host_set *host_set = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host_set->private_data;
+	struct ata_port *ap;
+	unsigned int i;
+	int have_msi;
+
+	for (i = 0; i < host_set->n_ports; i++) {
+		ap = host_set->ports[i];
+
+		scsi_remove_host(ap->host);
+	}
+
+	have_msi = hpriv->have_msi;
+	free_irq(host_set->irq, host_set);
+
+	for (i = 0; i < host_set->n_ports; i++) {
+		ap = host_set->ports[i];
+
+		ata_scsi_release(ap->host);
+		scsi_host_put(ap->host);
+	}
+
+	host_set->ops->host_stop(host_set);
+	kfree(host_set);
+
+	if (have_msi)
+		pci_disable_msi(pdev);
+	else
+		pci_intx(pdev, 0);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	dev_set_drvdata(dev, NULL);
+}
 
 static int __init ahci_init(void)
 {

  reply	other threads:[~2005-06-03 23:16 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-03 22:45 pci_enable_msi() for everyone? Greg KH
2005-06-03 23:16 ` Jeff Garzik [this message]
2005-06-04  0:01   ` Benjamin Herrenschmidt
2005-06-04  0:08     ` Jeff Garzik
2005-06-04  0:16       ` Benjamin Herrenschmidt
2005-06-04  0:34         ` Jeff Garzik
2005-06-04  6:51   ` Greg KH
2005-06-03 23:36 ` Roland Dreier
2005-06-06 22:58   ` Greg KH
2005-06-07  0:23     ` Roland Dreier
2005-06-07  5:19       ` Greg KH
2005-06-04  1:31 ` Grant Grundler
2005-06-04  6:48   ` Greg KH
2005-06-04  7:05     ` Grant Grundler
2005-06-04  7:18       ` Greg KH
2005-06-04  7:23         ` Dave Jones
2005-06-04 14:58           ` Roland Dreier
2005-06-06 23:01           ` Greg KH
2005-06-07  0:26             ` Roland Dreier
2005-06-07  5:22               ` Greg KH
2005-06-07  5:46                 ` Adam Belay
2005-06-07 17:43                   ` Luben Tuikov
2005-06-05 22:00         ` Benjamin Herrenschmidt
2005-06-06 23:00           ` Greg KH
2005-06-06 23:56             ` Benjamin Herrenschmidt
2005-06-05 19:46 ` David S. Miller
2005-06-06 22:55   ` Greg KH
2005-06-06 22:59     ` David S. Miller
2005-06-06 23:09       ` Greg KH
2005-06-06 23:08     ` Jeff Garzik
2005-06-06 23:10       ` David S. Miller
2005-06-06 23:13       ` Greg KH
2005-06-06 23:53         ` Jeff Garzik
2005-06-06 23:56           ` Greg KH
2005-06-06 23:58           ` David S. Miller
2005-06-07  4:24       ` Grant Grundler
2005-06-07  0:18     ` Roland Dreier
2005-06-07  5:21       ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2005-06-07 22:33 Nguyen, Tom L

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42A0E4B4.3050309@pobox.com \
    --to=jgarzik@pobox.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=davem@davemloft.net \
    --cc=gregkh@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@atrey.karlin.mff.cuni.cz \
    --cc=mchan@broadcom.com \
    --cc=roland@topspin.com \
    --cc=tom.l.nguyen@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.