diff options
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 113 |
1 files changed, 82 insertions, 31 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 4da574925284..a1f90fe849c9 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -1270,13 +1270,12 @@ retry_next: | |||
1270 | static int _aac_reset_adapter(struct aac_dev *aac, int forced) | 1270 | static int _aac_reset_adapter(struct aac_dev *aac, int forced) |
1271 | { | 1271 | { |
1272 | int index, quirks; | 1272 | int index, quirks; |
1273 | int retval, i; | 1273 | int retval; |
1274 | struct Scsi_Host *host; | 1274 | struct Scsi_Host *host; |
1275 | struct scsi_device *dev; | 1275 | struct scsi_device *dev; |
1276 | struct scsi_cmnd *command; | 1276 | struct scsi_cmnd *command; |
1277 | struct scsi_cmnd *command_list; | 1277 | struct scsi_cmnd *command_list; |
1278 | int jafo = 0; | 1278 | int jafo = 0; |
1279 | int cpu; | ||
1280 | 1279 | ||
1281 | /* | 1280 | /* |
1282 | * Assumptions: | 1281 | * Assumptions: |
@@ -1339,35 +1338,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) | |||
1339 | aac->comm_phys = 0; | 1338 | aac->comm_phys = 0; |
1340 | kfree(aac->queues); | 1339 | kfree(aac->queues); |
1341 | aac->queues = NULL; | 1340 | aac->queues = NULL; |
1342 | cpu = cpumask_first(cpu_online_mask); | 1341 | aac_free_irq(aac); |
1343 | if (aac->pdev->device == PMC_DEVICE_S6 || | ||
1344 | aac->pdev->device == PMC_DEVICE_S7 || | ||
1345 | aac->pdev->device == PMC_DEVICE_S8 || | ||
1346 | aac->pdev->device == PMC_DEVICE_S9) { | ||
1347 | if (aac->max_msix > 1) { | ||
1348 | for (i = 0; i < aac->max_msix; i++) { | ||
1349 | if (irq_set_affinity_hint( | ||
1350 | aac->msixentry[i].vector, | ||
1351 | NULL)) { | ||
1352 | printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n", | ||
1353 | aac->name, | ||
1354 | aac->id, | ||
1355 | cpu); | ||
1356 | } | ||
1357 | cpu = cpumask_next(cpu, | ||
1358 | cpu_online_mask); | ||
1359 | free_irq(aac->msixentry[i].vector, | ||
1360 | &(aac->aac_msix[i])); | ||
1361 | } | ||
1362 | pci_disable_msix(aac->pdev); | ||
1363 | } else { | ||
1364 | free_irq(aac->pdev->irq, &(aac->aac_msix[0])); | ||
1365 | } | ||
1366 | } else { | ||
1367 | free_irq(aac->pdev->irq, aac); | ||
1368 | } | ||
1369 | if (aac->msi) | ||
1370 | pci_disable_msi(aac->pdev); | ||
1371 | kfree(aac->fsa_dev); | 1342 | kfree(aac->fsa_dev); |
1372 | aac->fsa_dev = NULL; | 1343 | aac->fsa_dev = NULL; |
1373 | quirks = aac_get_driver_ident(index)->quirks; | 1344 | quirks = aac_get_driver_ident(index)->quirks; |
@@ -1978,3 +1949,83 @@ int aac_command_thread(void *data) | |||
1978 | dev->aif_thread = 0; | 1949 | dev->aif_thread = 0; |
1979 | return 0; | 1950 | return 0; |
1980 | } | 1951 | } |
1952 | |||
1953 | int aac_acquire_irq(struct aac_dev *dev) | ||
1954 | { | ||
1955 | int i; | ||
1956 | int j; | ||
1957 | int ret = 0; | ||
1958 | int cpu; | ||
1959 | |||
1960 | cpu = cpumask_first(cpu_online_mask); | ||
1961 | if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) { | ||
1962 | for (i = 0; i < dev->max_msix; i++) { | ||
1963 | dev->aac_msix[i].vector_no = i; | ||
1964 | dev->aac_msix[i].dev = dev; | ||
1965 | if (request_irq(dev->msixentry[i].vector, | ||
1966 | dev->a_ops.adapter_intr, | ||
1967 | 0, "aacraid", &(dev->aac_msix[i]))) { | ||
1968 | printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n", | ||
1969 | dev->name, dev->id, i); | ||
1970 | for (j = 0 ; j < i ; j++) | ||
1971 | free_irq(dev->msixentry[j].vector, | ||
1972 | &(dev->aac_msix[j])); | ||
1973 | pci_disable_msix(dev->pdev); | ||
1974 | ret = -1; | ||
1975 | } | ||
1976 | if (irq_set_affinity_hint(dev->msixentry[i].vector, | ||
1977 | get_cpu_mask(cpu))) { | ||
1978 | printk(KERN_ERR "%s%d: Failed to set IRQ affinity for cpu %d\n", | ||
1979 | dev->name, dev->id, cpu); | ||
1980 | } | ||
1981 | cpu = cpumask_next(cpu, cpu_online_mask); | ||
1982 | } | ||
1983 | } else { | ||
1984 | dev->aac_msix[0].vector_no = 0; | ||
1985 | dev->aac_msix[0].dev = dev; | ||
1986 | |||
1987 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, | ||
1988 | IRQF_SHARED, "aacraid", | ||
1989 | &(dev->aac_msix[0])) < 0) { | ||
1990 | if (dev->msi) | ||
1991 | pci_disable_msi(dev->pdev); | ||
1992 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", | ||
1993 | dev->name, dev->id); | ||
1994 | ret = -1; | ||
1995 | } | ||
1996 | } | ||
1997 | return ret; | ||
1998 | } | ||
1999 | |||
2000 | void aac_free_irq(struct aac_dev *dev) | ||
2001 | { | ||
2002 | int i; | ||
2003 | int cpu; | ||
2004 | |||
2005 | cpu = cpumask_first(cpu_online_mask); | ||
2006 | if (dev->pdev->device == PMC_DEVICE_S6 || | ||
2007 | dev->pdev->device == PMC_DEVICE_S7 || | ||
2008 | dev->pdev->device == PMC_DEVICE_S8 || | ||
2009 | dev->pdev->device == PMC_DEVICE_S9) { | ||
2010 | if (dev->max_msix > 1) { | ||
2011 | for (i = 0; i < dev->max_msix; i++) { | ||
2012 | if (irq_set_affinity_hint( | ||
2013 | dev->msixentry[i].vector, NULL)) { | ||
2014 | printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n", | ||
2015 | dev->name, dev->id, cpu); | ||
2016 | } | ||
2017 | cpu = cpumask_next(cpu, cpu_online_mask); | ||
2018 | free_irq(dev->msixentry[i].vector, | ||
2019 | &(dev->aac_msix[i])); | ||
2020 | } | ||
2021 | } else { | ||
2022 | free_irq(dev->pdev->irq, &(dev->aac_msix[0])); | ||
2023 | } | ||
2024 | } else { | ||
2025 | free_irq(dev->pdev->irq, dev); | ||
2026 | } | ||
2027 | if (dev->msi) | ||
2028 | pci_disable_msi(dev->pdev); | ||
2029 | else if (dev->max_msix > 1) | ||
2030 | pci_disable_msix(dev->pdev); | ||
2031 | } | ||