These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / scsi / aacraid / commsup.c
index 4da5749..a1f90fe 100644 (file)
@@ -1270,13 +1270,12 @@ retry_next:
 static int _aac_reset_adapter(struct aac_dev *aac, int forced)
 {
        int index, quirks;
-       int retval, i;
+       int retval;
        struct Scsi_Host *host;
        struct scsi_device *dev;
        struct scsi_cmnd *command;
        struct scsi_cmnd *command_list;
        int jafo = 0;
-       int cpu;
 
        /*
         * Assumptions:
@@ -1339,35 +1338,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
        aac->comm_phys = 0;
        kfree(aac->queues);
        aac->queues = NULL;
-       cpu = cpumask_first(cpu_online_mask);
-       if (aac->pdev->device == PMC_DEVICE_S6 ||
-           aac->pdev->device == PMC_DEVICE_S7 ||
-           aac->pdev->device == PMC_DEVICE_S8 ||
-           aac->pdev->device == PMC_DEVICE_S9) {
-               if (aac->max_msix > 1) {
-                       for (i = 0; i < aac->max_msix; i++) {
-                               if (irq_set_affinity_hint(
-                                   aac->msixentry[i].vector,
-                                   NULL)) {
-                                       printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n",
-                                               aac->name,
-                                               aac->id,
-                                               cpu);
-                               }
-                               cpu = cpumask_next(cpu,
-                                               cpu_online_mask);
-                               free_irq(aac->msixentry[i].vector,
-                                        &(aac->aac_msix[i]));
-                       }
-                       pci_disable_msix(aac->pdev);
-               } else {
-                       free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
-               }
-       } else {
-               free_irq(aac->pdev->irq, aac);
-       }
-       if (aac->msi)
-               pci_disable_msi(aac->pdev);
+       aac_free_irq(aac);
        kfree(aac->fsa_dev);
        aac->fsa_dev = NULL;
        quirks = aac_get_driver_ident(index)->quirks;
@@ -1978,3 +1949,83 @@ int aac_command_thread(void *data)
        dev->aif_thread = 0;
        return 0;
 }
+
+int aac_acquire_irq(struct aac_dev *dev)
+{
+       int i;
+       int j;
+       int ret = 0;
+       int cpu;
+
+       cpu = cpumask_first(cpu_online_mask);
+       if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+               for (i = 0; i < dev->max_msix; i++) {
+                       dev->aac_msix[i].vector_no = i;
+                       dev->aac_msix[i].dev = dev;
+                       if (request_irq(dev->msixentry[i].vector,
+                                       dev->a_ops.adapter_intr,
+                                       0, "aacraid", &(dev->aac_msix[i]))) {
+                               printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+                                               dev->name, dev->id, i);
+                               for (j = 0 ; j < i ; j++)
+                                       free_irq(dev->msixentry[j].vector,
+                                                &(dev->aac_msix[j]));
+                               pci_disable_msix(dev->pdev);
+                               ret = -1;
+                       }
+                       if (irq_set_affinity_hint(dev->msixentry[i].vector,
+                                                       get_cpu_mask(cpu))) {
+                               printk(KERN_ERR "%s%d: Failed to set IRQ affinity for cpu %d\n",
+                                           dev->name, dev->id, cpu);
+                       }
+                       cpu = cpumask_next(cpu, cpu_online_mask);
+               }
+       } else {
+               dev->aac_msix[0].vector_no = 0;
+               dev->aac_msix[0].dev = dev;
+
+               if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+                       IRQF_SHARED, "aacraid",
+                       &(dev->aac_msix[0])) < 0) {
+                       if (dev->msi)
+                               pci_disable_msi(dev->pdev);
+                       printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+                                       dev->name, dev->id);
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
+void aac_free_irq(struct aac_dev *dev)
+{
+       int i;
+       int cpu;
+
+       cpu = cpumask_first(cpu_online_mask);
+       if (dev->pdev->device == PMC_DEVICE_S6 ||
+           dev->pdev->device == PMC_DEVICE_S7 ||
+           dev->pdev->device == PMC_DEVICE_S8 ||
+           dev->pdev->device == PMC_DEVICE_S9) {
+               if (dev->max_msix > 1) {
+                       for (i = 0; i < dev->max_msix; i++) {
+                               if (irq_set_affinity_hint(
+                                       dev->msixentry[i].vector, NULL)) {
+                                       printk(KERN_ERR "%s%d: Failed to reset IRQ affinity for cpu %d\n",
+                                           dev->name, dev->id, cpu);
+                               }
+                               cpu = cpumask_next(cpu, cpu_online_mask);
+                               free_irq(dev->msixentry[i].vector,
+                                               &(dev->aac_msix[i]));
+                       }
+               } else {
+                       free_irq(dev->pdev->irq, &(dev->aac_msix[0]));
+               }
+       } else {
+               free_irq(dev->pdev->irq, dev);
+       }
+       if (dev->msi)
+               pci_disable_msi(dev->pdev);
+       else if (dev->max_msix > 1)
+               pci_disable_msix(dev->pdev);
+}