From: Brian King <brking@linux.vnet.ibm.com>
To: Wayne Boyer <wayneb@linux.vnet.ibm.com>
Cc: linux-scsi <linux-scsi@vger.kernel.org>
Subject: Re: [PATCH 1/2] ipr: add test for MSI interrupt support
Date: Wed, 17 Jun 2009 10:39:12 -0500 [thread overview]
Message-ID: <4A390E20.7060006@linux.vnet.ibm.com> (raw)
In-Reply-To: <4A381908.8090000@linux.vnet.ibm.com>
Acked-by: Brian King <brking@linux.vnet.ibm.com>
Wayne Boyer wrote:
> The return value from pci_enable_msi() can not always be trusted. This patch
> adds code to generate an interrupt after MSI has been enabled and tests
> whether or not we can receive and process it. If the tests fails, then fall
> back to LSI.
>
> Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com>
> ---
>
> drivers/scsi/ipr.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++----
> drivers/scsi/ipr.h | 6 +-
> 2 files changed, 105 insertions(+), 9 deletions(-)
>
> Index: b/drivers/scsi/ipr.c
> ===================================================================
> --- a/drivers/scsi/ipr.c 2009-06-03 16:04:14.000000000 -0700
> +++ b/drivers/scsi/ipr.c 2009-06-15 16:36:36.000000000 -0700
> @@ -7366,6 +7366,7 @@
> INIT_LIST_HEAD(&ioa_cfg->used_res_q);
> INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
> init_waitqueue_head(&ioa_cfg->reset_wait_q);
> + init_waitqueue_head(&ioa_cfg->msi_wait_q);
> ioa_cfg->sdt_state = INACTIVE;
> if (ipr_enable_cache)
> ioa_cfg->cache_state = CACHE_ENABLED;
> @@ -7416,6 +7417,89 @@
> }
>
> /**
> + * ipr_test_intr - Handle the interrupt generated in ipr_test_msi().
> + * @pdev: PCI device struct
> + *
> + * Description: Simply set the msi_received flag to 1 indicating that
> + * Message Signaled Interrupts are supported.
> + *
> + * Return value:
> + * 0 on success / non-zero on failure
> + **/
> +static irqreturn_t __devinit ipr_test_intr(int irq, void *devp)
> +{
> + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
> + unsigned long lock_flags = 0;
> + irqreturn_t rc = IRQ_HANDLED;
> +
> + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
> +
> + ioa_cfg->msi_received = 1;
> + wake_up(&ioa_cfg->msi_wait_q);
> +
> + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
> + return rc;
> +}
> +
> +/**
> + * ipr_test_msi - Test for Message Signaled Interrupt (MSI) support.
> + * @pdev: PCI device struct
> + *
> + * Description: The return value from pci_enable_msi() can not always be
> + * trusted. This routine sets up and initiates a test interrupt to determine
> + * if the interrupt is received via the ipr_test_intr() service routine.
> + * If the tests fails, the driver will fall back to LSI.
> + *
> + * Return value:
> + * 0 on success / non-zero on failure
> + **/
> +static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg,
> + struct pci_dev *pdev)
> +{
> + int rc;
> + volatile u32 int_reg;
> + unsigned long lock_flags = 0;
> +
> + ENTER;
> +
> + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
> + init_waitqueue_head(&ioa_cfg->msi_wait_q);
> + ioa_cfg->msi_received = 0;
> + ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
> + writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg);
> + int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
> + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
> +
> + rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg);
> + if (rc) {
> + dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq);
> + return rc;
> + } else if (ipr_debug)
> + dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq);
> +
> + writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg);
> + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
> + wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ);
> + ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
> +
> + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
> + if (!ioa_cfg->msi_received) {
> + /* MSI test failed */
> + dev_info(&pdev->dev, "MSI test failed. Falling back to LSI.\n");
> + rc = -EOPNOTSUPP;
> + } else if (ipr_debug)
> + dev_info(&pdev->dev, "MSI test succeeded.\n");
> +
> + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
> +
> + free_irq(pdev->irq, ioa_cfg);
> +
> + LEAVE;
> +
> + return rc;
> +}
> +
> +/**
> * ipr_probe_ioa - Allocates memory and does first stage of initialization
> * @pdev: PCI device struct
> * @dev_id: PCI device id struct
> @@ -7440,11 +7524,6 @@
> goto out;
> }
>
> - if (!(rc = pci_enable_msi(pdev)))
> - dev_info(&pdev->dev, "MSI enabled\n");
> - else if (ipr_debug)
> - dev_info(&pdev->dev, "Cannot enable MSI\n");
> -
> dev_info(&pdev->dev, "Found IOA with IRQ: %d\n", pdev->irq);
>
> host = scsi_host_alloc(&driver_template, sizeof(*ioa_cfg));
> @@ -7518,6 +7597,18 @@
> goto cleanup_nomem;
> }
>
> + /* Enable MSI style interrupts if they are supported. */
> + if (!(rc = pci_enable_msi(pdev))) {
> + rc = ipr_test_msi(ioa_cfg, pdev);
> + if (rc == -EOPNOTSUPP)
> + pci_disable_msi(pdev);
> + else if (rc)
> + goto out_msi_disable;
> + else
> + dev_info(&pdev->dev, "MSI enabled with IRQ: %d\n", pdev->irq);
> + } else if (ipr_debug)
> + dev_info(&pdev->dev, "Cannot enable MSI.\n");
> +
> /* Save away PCI config space for use following IOA reset */
> rc = pci_save_state(pdev);
>
> @@ -7555,7 +7646,9 @@
> ioa_cfg->ioa_unit_checked = 1;
>
> ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
> - rc = request_irq(pdev->irq, ipr_isr, IRQF_SHARED, IPR_NAME, ioa_cfg);
> + rc = request_irq(pdev->irq, ipr_isr,
> + ioa_cfg->msi_received ? 0 : IRQF_SHARED,
> + IPR_NAME, ioa_cfg);
>
> if (rc) {
> dev_err(&pdev->dev, "Couldn't register IRQ %d! rc=%d\n",
> @@ -7582,12 +7675,13 @@
> ipr_free_mem(ioa_cfg);
> cleanup_nomem:
> iounmap(ipr_regs);
> +out_msi_disable:
> + pci_disable_msi(pdev);
> out_release_regions:
> pci_release_regions(pdev);
> out_scsi_host_put:
> scsi_host_put(host);
> out_disable:
> - pci_disable_msi(pdev);
> pci_disable_device(pdev);
> goto out;
> }
> Index: b/drivers/scsi/ipr.h
> ===================================================================
> --- a/drivers/scsi/ipr.h 2009-06-03 16:04:15.000000000 -0700
> +++ b/drivers/scsi/ipr.h 2009-06-15 16:35:43.000000000 -0700
> @@ -37,8 +37,8 @@
> /*
> * Literals
> */
> -#define IPR_DRIVER_VERSION "2.4.2"
> -#define IPR_DRIVER_DATE "(January 21, 2009)"
> +#define IPR_DRIVER_VERSION "2.4.3"
> +#define IPR_DRIVER_DATE "(June 10, 2009)"
>
> /*
> * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
> @@ -1094,6 +1094,7 @@
> u8 needs_hard_reset:1;
> u8 dual_raid:1;
> u8 needs_warm_reset:1;
> + u8 msi_received:1;
>
> u8 revid;
>
> @@ -1179,6 +1180,7 @@
> struct work_struct work_q;
>
> wait_queue_head_t reset_wait_q;
> + wait_queue_head_t msi_wait_q;
>
> struct ipr_dump *dump;
> enum ipr_sdt_state sdt_state;
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Brian King
Linux on Power Virtualization
IBM Linux Technology Center
next prev parent reply other threads:[~2009-06-17 15:39 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20090616220853.799518360@linux.vnet.ibm.com>
2009-06-16 22:13 ` [PATCH 1/2] ipr: add test for MSI interrupt support Wayne Boyer
2009-06-17 15:39 ` Brian King [this message]
2009-06-16 22:13 ` [PATCH 2/2] ipr: differentiate pci-x and pci-e based adapters Wayne Boyer
2009-06-17 15:41 ` Brian King
2009-06-17 16:55 ` Wayne Boyer
2009-06-17 17:19 ` Brian King
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=4A390E20.7060006@linux.vnet.ibm.com \
--to=brking@linux.vnet.ibm.com \
--cc=linux-scsi@vger.kernel.org \
--cc=wayneb@linux.vnet.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).