struct workqueue_struct *pm8001_wq;
 
+static int pm8001_map_queues(struct Scsi_Host *shost)
+{
+       struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+       struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+       struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT];
+
+       if (pm8001_ha->number_of_intr > 1)
+               blk_mq_pci_map_queues(qmap, pm8001_ha->pdev, 1);
+
+       return blk_mq_map_queues(qmap);
+}
+
 /*
  * The main structure which LLDD must register for scsi core.
  */
        .shost_groups           = pm8001_host_groups,
        .track_queue_depth      = 1,
        .cmd_per_lun            = 32,
+       .map_queues             = pm8001_map_queues,
 };
 
 /*
  */
 static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
 {
-       u32 number_of_intr;
-       int rc, cpu_online_count;
        unsigned int allocated_irq_vectors;
+       int rc;
 
        /* SPCv controllers supports 64 msi-x */
        if (pm8001_ha->chip_id == chip_8001) {
-               number_of_intr = 1;
+               rc = pci_alloc_irq_vectors(pm8001_ha->pdev, 1, 1,
+                                          PCI_IRQ_MSIX);
        } else {
-               number_of_intr = PM8001_MAX_MSIX_VEC;
+               /*
+                * Queue index #0 is used always for housekeeping, so don't
+                * include in the affinity spreading.
+                */
+               struct irq_affinity desc = {
+                       .pre_vectors = 1,
+               };
+               rc = pci_alloc_irq_vectors_affinity(
+                               pm8001_ha->pdev, 2, PM8001_MAX_MSIX_VEC,
+                               PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc);
        }
 
-       cpu_online_count = num_online_cpus();
-       number_of_intr = min_t(int, cpu_online_count, number_of_intr);
-       rc = pci_alloc_irq_vectors(pm8001_ha->pdev, number_of_intr,
-                       number_of_intr, PCI_IRQ_MSIX);
        allocated_irq_vectors = rc;
        if (rc < 0)
                return rc;
 
        /* Assigns the number of interrupts */
-       number_of_intr = min_t(int, allocated_irq_vectors, number_of_intr);
-       pm8001_ha->number_of_intr = number_of_intr;
+       pm8001_ha->number_of_intr = allocated_irq_vectors;
 
        /* Maximum queue number updating in HBA structure */
-       pm8001_ha->max_q_num = number_of_intr;
+       pm8001_ha->max_q_num = allocated_irq_vectors;
 
        pm8001_dbg(pm8001_ha, INIT,
                   "pci_alloc_irq_vectors request ret:%d no of intr %d\n",
        if (rc)
                goto err_out_enable;
 
+
        PM8001_CHIP_DISP->chip_post_init(pm8001_ha);
 
+       if (pm8001_ha->number_of_intr > 1) {
+               shost->nr_hw_queues = pm8001_ha->number_of_intr - 1;
+               /*
+                * For now, ensure we're not sent too many commands by setting
+                * host_tagset. This is also required if we start using request
+                * tag.
+                */
+               shost->host_tagset = 1;
+       }
+
        rc = scsi_add_host(shost, &pdev->dev);
        if (rc)
                goto err_out_ha_free;
 
        return ret;
 }
 
+static u32 pm80xx_chip_get_q_index(struct sas_task *task)
+{
+       struct scsi_cmnd *scmd = NULL;
+       u32 blk_tag;
+
+       if (task->uldd_task) {
+               struct ata_queued_cmd *qc;
+
+               if (dev_is_sata(task->dev)) {
+                       qc = task->uldd_task;
+                       scmd = qc->scsicmd;
+               } else {
+                       scmd = task->uldd_task;
+               }
+       }
+
+       if (!scmd)
+               return 0;
+
+       blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));
+       return blk_mq_unique_tag_to_hwq(blk_tag);
+}
+
 /**
  * pm80xx_chip_ssp_io_req - send an SSP task to FW
  * @pm8001_ha: our hba card information.
        u32 tag = ccb->ccb_tag;
        u64 phys_addr, end_addr;
        u32 end_addr_high, end_addr_low;
-       u32 q_index, cpu_id;
+       u32 q_index;
        u32 opc = OPC_INB_SSPINIIOSTART;
 
        memset(&ssp_cmd, 0, sizeof(ssp_cmd));
        ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
        memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
                       task->ssp_task.cmd->cmd_len);
-       cpu_id = smp_processor_id();
-       q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
+       q_index = pm80xx_chip_get_q_index(task);
 
        /* Check if encryption is set */
        if (pm8001_ha->chip->encrypt &&
        struct domain_device *dev = task->dev;
        struct pm8001_device *pm8001_ha_dev = dev->lldd_dev;
        struct ata_queued_cmd *qc = task->uldd_task;
-       u32 tag = ccb->ccb_tag;
-       u32 q_index, cpu_id;
+       u32 tag = ccb->ccb_tag, q_index;
        struct sata_start_req sata_cmd;
        u32 hdr_tag, ncg_tag = 0;
        u64 phys_addr, end_addr;
        unsigned long flags;
        u32 opc = OPC_INB_SATA_HOST_OPSTART;
        memset(&sata_cmd, 0, sizeof(sata_cmd));
-       cpu_id = smp_processor_id();
-       q_index = (u32) (cpu_id) % (pm8001_ha->max_q_num);
+
+       q_index = pm80xx_chip_get_q_index(task);
 
        if (task->data_dir == DMA_NONE && !task->ata_task.use_ncq) {
                ATAP = 0x04; /* no data*/