aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/stex.c
diff options
context:
space:
mode:
authorEd Lin <ed.lin@promise.com>2009-03-31 17:30:25 -0800
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 09:23:09 -0500
commit99946f8141f65a8bd5034ac5b1a53237aec8743e (patch)
treed3c2b98039a5d27c664c1e7acae0ccff60f24c10 /drivers/scsi/stex.c
parentf14981616205eedb6fe8b24a09ec103ed976e122 (diff)
[SCSI] stex: add MSI support
This adds the MSI support (default 0=off) Signed-off-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r--drivers/scsi/stex.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index de6c30e3746..c4eb5c1cc1b 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -292,11 +292,15 @@ struct st_hba {
struct st_ccb *wait_ccb;
unsigned int mu_status;
- int out_req_cnt;
-
unsigned int cardtype;
+ int msi_enabled;
+ int out_req_cnt;
};
+static int msi;
+module_param(msi, int, 0);
+MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)");
+
static const char console_inq_page[] =
{
0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30,
@@ -1041,6 +1045,40 @@ static int stex_set_dma_mask(struct pci_dev * pdev)
return ret;
}
+static int stex_request_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+ int status;
+
+ if (msi) {
+ status = pci_enable_msi(pdev);
+ if (status != 0)
+ printk(KERN_ERR DRV_NAME
+ "(%s): error %d setting up MSI\n",
+ pci_name(pdev), status);
+ else
+ hba->msi_enabled = 1;
+ } else
+ hba->msi_enabled = 0;
+
+ status = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba);
+
+ if (status != 0) {
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+ }
+ return status;
+}
+
+static void stex_free_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+
+ free_irq(pdev->irq, hba);
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+}
+
static int __devinit
stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -1125,7 +1163,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hba->host = host;
hba->pdev = pdev;
- err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba);
+ err = stex_request_irq(hba);
if (err) {
printk(KERN_ERR DRV_NAME "(%s): request irq failed\n",
pci_name(pdev));
@@ -1157,7 +1195,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
out_free_irq:
- free_irq(pdev->irq, hba);
+ stex_free_irq(hba);
out_pci_free:
dma_free_coherent(&pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
@@ -1216,7 +1254,7 @@ static void stex_hba_stop(struct st_hba *hba)
static void stex_hba_free(struct st_hba *hba)
{
- free_irq(hba->pdev->irq, hba);
+ stex_free_irq(hba);
iounmap(hba->mmio_base);