diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/stex.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index de6c30e37463..c4eb5c1cc1bc 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -292,11 +292,15 @@ struct st_hba { | |||
292 | struct st_ccb *wait_ccb; | 292 | struct st_ccb *wait_ccb; |
293 | 293 | ||
294 | unsigned int mu_status; | 294 | unsigned int mu_status; |
295 | int out_req_cnt; | ||
296 | |||
297 | unsigned int cardtype; | 295 | unsigned int cardtype; |
296 | int msi_enabled; | ||
297 | int out_req_cnt; | ||
298 | }; | 298 | }; |
299 | 299 | ||
300 | static int msi; | ||
301 | module_param(msi, int, 0); | ||
302 | MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)"); | ||
303 | |||
300 | static const char console_inq_page[] = | 304 | static const char console_inq_page[] = |
301 | { | 305 | { |
302 | 0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30, | 306 | 0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30, |
@@ -1041,6 +1045,40 @@ static int stex_set_dma_mask(struct pci_dev * pdev) | |||
1041 | return ret; | 1045 | return ret; |
1042 | } | 1046 | } |
1043 | 1047 | ||
1048 | static int stex_request_irq(struct st_hba *hba) | ||
1049 | { | ||
1050 | struct pci_dev *pdev = hba->pdev; | ||
1051 | int status; | ||
1052 | |||
1053 | if (msi) { | ||
1054 | status = pci_enable_msi(pdev); | ||
1055 | if (status != 0) | ||
1056 | printk(KERN_ERR DRV_NAME | ||
1057 | "(%s): error %d setting up MSI\n", | ||
1058 | pci_name(pdev), status); | ||
1059 | else | ||
1060 | hba->msi_enabled = 1; | ||
1061 | } else | ||
1062 | hba->msi_enabled = 0; | ||
1063 | |||
1064 | status = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba); | ||
1065 | |||
1066 | if (status != 0) { | ||
1067 | if (hba->msi_enabled) | ||
1068 | pci_disable_msi(pdev); | ||
1069 | } | ||
1070 | return status; | ||
1071 | } | ||
1072 | |||
1073 | static void stex_free_irq(struct st_hba *hba) | ||
1074 | { | ||
1075 | struct pci_dev *pdev = hba->pdev; | ||
1076 | |||
1077 | free_irq(pdev->irq, hba); | ||
1078 | if (hba->msi_enabled) | ||
1079 | pci_disable_msi(pdev); | ||
1080 | } | ||
1081 | |||
1044 | static int __devinit | 1082 | static int __devinit |
1045 | stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 1083 | stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
1046 | { | 1084 | { |
@@ -1125,7 +1163,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1125 | hba->host = host; | 1163 | hba->host = host; |
1126 | hba->pdev = pdev; | 1164 | hba->pdev = pdev; |
1127 | 1165 | ||
1128 | err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba); | 1166 | err = stex_request_irq(hba); |
1129 | if (err) { | 1167 | if (err) { |
1130 | printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", | 1168 | printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", |
1131 | pci_name(pdev)); | 1169 | pci_name(pdev)); |
@@ -1157,7 +1195,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1157 | return 0; | 1195 | return 0; |
1158 | 1196 | ||
1159 | out_free_irq: | 1197 | out_free_irq: |
1160 | free_irq(pdev->irq, hba); | 1198 | stex_free_irq(hba); |
1161 | out_pci_free: | 1199 | out_pci_free: |
1162 | dma_free_coherent(&pdev->dev, hba->dma_size, | 1200 | dma_free_coherent(&pdev->dev, hba->dma_size, |
1163 | hba->dma_mem, hba->dma_handle); | 1201 | hba->dma_mem, hba->dma_handle); |
@@ -1216,7 +1254,7 @@ static void stex_hba_stop(struct st_hba *hba) | |||
1216 | 1254 | ||
1217 | static void stex_hba_free(struct st_hba *hba) | 1255 | static void stex_hba_free(struct st_hba *hba) |
1218 | { | 1256 | { |
1219 | free_irq(hba->pdev->irq, hba); | 1257 | stex_free_irq(hba); |
1220 | 1258 | ||
1221 | iounmap(hba->mmio_base); | 1259 | iounmap(hba->mmio_base); |
1222 | 1260 | ||