]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/scsi/aacraid/linit.c
scsi: aacraid: Add task management functionality
[mirror_ubuntu-zesty-kernel.git] / drivers / scsi / aacraid / linit.c
index 3ecbf20ca29f96b970cd4b14c38eb3fdbb3b1511..68a5d2d1e65518a8edceaed9ee78d7dd997c43b1 100644 (file)
@@ -401,61 +401,89 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
 static int aac_slave_configure(struct scsi_device *sdev)
 {
        struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
+       int chn, tid;
+       unsigned int depth = 0;
+       unsigned int set_timeout = 0;
+
+       chn = aac_logical_to_phys(sdev_channel(sdev));
+       tid = sdev_id(sdev);
+       if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
+               aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
+               depth = aac->hba_map[chn][tid].qd_limit;
+               set_timeout = 1;
+               goto common_config;
+       }
+
+
        if (aac->jbod && (sdev->type == TYPE_DISK))
                sdev->removable = 1;
-       if ((sdev->type == TYPE_DISK) &&
-                       (sdev_channel(sdev) != CONTAINER_CHANNEL) &&
-                       (!aac->jbod || sdev->inq_periph_qual) &&
-                       (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) {
+
+       if (sdev->type == TYPE_DISK
+        && sdev_channel(sdev) != CONTAINER_CHANNEL
+        && (!aac->jbod || sdev->inq_periph_qual)
+        && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) {
+
                if (expose_physicals == 0)
                        return -ENXIO;
+
                if (expose_physicals < 0)
                        sdev->no_uld_attach = 1;
        }
-       if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
-                       (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) &&
-                       !sdev->no_uld_attach) {
+
+       if (sdev->tagged_supported
+        &&  sdev->type == TYPE_DISK
+        &&  (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
+        && !sdev->no_uld_attach) {
+
                struct scsi_device * dev;
                struct Scsi_Host *host = sdev->host;
                unsigned num_lsu = 0;
                unsigned num_one = 0;
-               unsigned depth;
                unsigned cid;
 
-               /*
-                * Firmware has an individual device recovery time typically
-                * of 35 seconds, give us a margin.
-                */
-               if (sdev->request_queue->rq_timeout < (45 * HZ))
-                       blk_queue_rq_timeout(sdev->request_queue, 45*HZ);
+               set_timeout = 1;
+
                for (cid = 0; cid < aac->maximum_num_containers; ++cid)
                        if (aac->fsa_dev[cid].valid)
                                ++num_lsu;
+
                __shost_for_each_device(dev, host) {
-                       if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
-                                       (!aac->raid_scsi_mode ||
-                                               (sdev_channel(sdev) != 2)) &&
-                                       !dev->no_uld_attach) {
+                       if (dev->tagged_supported
+                        && dev->type == TYPE_DISK
+                        && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
+                        && !dev->no_uld_attach) {
                                if ((sdev_channel(dev) != CONTAINER_CHANNEL)
-                                || !aac->fsa_dev[sdev_id(dev)].valid)
+                                || !aac->fsa_dev[sdev_id(dev)].valid) {
                                        ++num_lsu;
-                       } else
+                               }
+                       } else {
                                ++num_one;
+                       }
                }
+
                if (num_lsu == 0)
                        ++num_lsu;
-               depth = (host->can_queue - num_one) / num_lsu;
-               if (depth > 256)
-                       depth = 256;
-               else if (depth < 2)
-                       depth = 2;
-               scsi_change_queue_depth(sdev, depth);
-       } else {
-               scsi_change_queue_depth(sdev, 1);
 
-               sdev->tagged_supported = 1;
+               depth = (host->can_queue - num_one) / num_lsu;
        }
 
+common_config:
+       /*
+        * Firmware has an individual device recovery time typically
+        * of 35 seconds, give us a margin.
+        */
+       if (set_timeout && sdev->request_queue->rq_timeout < (45 * HZ))
+               blk_queue_rq_timeout(sdev->request_queue, 45*HZ);
+
+       if (depth > 256)
+               depth = 256;
+       else if (depth < 1)
+               depth = 1;
+
+       scsi_change_queue_depth(sdev, depth);
+
+       sdev->tagged_supported = 1;
+
        return 0;
 }
 
@@ -470,6 +498,15 @@ static int aac_slave_configure(struct scsi_device *sdev)
 
 static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
 {
+       struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
+       int chn, tid, is_native_device = 0;
+
+       chn = aac_logical_to_phys(sdev_channel(sdev));
+       tid = sdev_id(sdev);
+       if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
+               aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW)
+               is_native_device = 1;
+
        if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
            (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
                struct scsi_device * dev;
@@ -491,9 +528,12 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
                else if (depth < 2)
                        depth = 2;
                return scsi_change_queue_depth(sdev, depth);
+       } else if (is_native_device) {
+               scsi_change_queue_depth(sdev, aac->hba_map[chn][tid].qd_limit);
+       } else {
+               scsi_change_queue_depth(sdev, 1);
        }
-
-       return scsi_change_queue_depth(sdev, 1);
+       return sdev->queue_depth;
 }
 
 static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1070,6 +1110,7 @@ static void __aac_shutdown(struct aac_dev * aac)
 {
        int i;
 
+       aac->adapter_shutdown = 1;
        aac_send_shutdown(aac);
 
        if (aac->aif_thread) {
@@ -1285,7 +1326,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        else
                shost->this_id = shost->max_id;
 
-       if (aac_drivers[index].quirks & AAC_QUIRK_SRC)
+       if (!aac->sa_firmware && aac_drivers[index].quirks & AAC_QUIRK_SRC)
                aac_intr_normal(aac, 0, 2, 0, NULL);
 
        /*
@@ -1327,35 +1368,12 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
 static void aac_release_resources(struct aac_dev *aac)
 {
-       int i;
-
        aac_adapter_disable_int(aac);
-       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++)
-                               free_irq(pci_irq_vector(aac->pdev, i),
-                                       &(aac->aac_msix[i]));
-               } 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);
-       else if (aac->max_msix > 1)
-               pci_disable_msix(aac->pdev);
-
+       aac_free_irq(aac);
 }
 
 static int aac_acquire_resources(struct aac_dev *dev)
 {
-       int i, j;
-       int instance = dev->id;
-       const char *name = dev->name;
        unsigned long status;
        /*
         *      First clear out all interrupts.  Then enable the one's that we
@@ -1377,37 +1395,8 @@ static int aac_acquire_resources(struct aac_dev *dev)
        if (dev->msi_enabled)
                aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
 
-       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(pci_irq_vector(dev->pdev, i),
-                                       dev->a_ops.adapter_intr,
-                                       0, "aacraid", &(dev->aac_msix[i]))) {
-                               printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
-                                               name, instance, i);
-                               for (j = 0 ; j < i ; j++)
-                                       free_irq(pci_irq_vector(dev->pdev, j),
-                                                &(dev->aac_msix[j]));
-                               pci_disable_msix(dev->pdev);
-                               goto error_iounmap;
-                       }
-               }
-       } 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",
-                                       name, instance);
-                       goto error_iounmap;
-               }
-       }
+       if (aac_acquire_irq(dev))
+               goto error_iounmap;
 
        aac_adapter_enable_int(dev);
 
@@ -1420,7 +1409,7 @@ static int aac_acquire_resources(struct aac_dev *dev)
                /* After EEH recovery or suspend resume, max_msix count
                 * may change, therfore updating in init as well.
                 */
-               dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
+               dev->init->r7.no_of_msix_vectors = cpu_to_le32(dev->max_msix);
                aac_adapter_start(dev);
        }
        return 0;