ufshcd_upiu_wlun_to_scsi_wlun(UFS_UPIU_UFS_DEVICE_WLUN);
 }
 
+/*
+ * Associate the UFS controller queue with the default and poll HCTX types.
+ * Initialize the mq_map[] arrays.
+ */
+static int ufshcd_map_queues(struct Scsi_Host *shost)
+{
+       int i, ret;
+
+       for (i = 0; i < shost->nr_maps; i++) {
+               struct blk_mq_queue_map *map = &shost->tag_set.map[i];
+
+               switch (i) {
+               case HCTX_TYPE_DEFAULT:
+               case HCTX_TYPE_POLL:
+                       map->nr_queues = 1;
+                       break;
+               case HCTX_TYPE_READ:
+                       map->nr_queues = 0;
+                       break;
+               default:
+                       WARN_ON_ONCE(true);
+               }
+               map->queue_offset = 0;
+               ret = blk_mq_map_queues(map);
+               WARN_ON_ONCE(ret);
+       }
+
+       return 0;
+}
+
 static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i)
 {
        struct utp_transfer_cmd_desc *cmd_descp = hba->ucdl_base_addr;
        struct ufshcd_lrb *lrbp;
        int err = 0;
 
-       WARN_ONCE(tag < 0, "Invalid tag %d\n", tag);
+       WARN_ONCE(tag < 0 || tag >= hba->nutrs, "Invalid tag %d\n", tag);
 
        /*
         * Allows the UFS error handler to wait for prior ufshcd_queuecommand()
        }
 }
 
+/*
+ * Returns > 0 if one or more commands have been completed or 0 if no
+ * requests have been completed.
+ */
+static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
+{
+       struct ufs_hba *hba = shost_priv(shost);
+       unsigned long completed_reqs, flags;
+       u32 tr_doorbell;
+
+       spin_lock_irqsave(&hba->outstanding_lock, flags);
+       tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
+       completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
+       WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
+                 "completed: %#lx; outstanding: %#lx\n", completed_reqs,
+                 hba->outstanding_reqs);
+       hba->outstanding_reqs &= ~completed_reqs;
+       spin_unlock_irqrestore(&hba->outstanding_lock, flags);
+
+       if (completed_reqs)
+               __ufshcd_transfer_req_compl(hba, completed_reqs);
+
+       return completed_reqs;
+}
+
 /**
  * ufshcd_transfer_req_compl - handle SCSI and query command completion
  * @hba: per adapter instance
  */
 static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba)
 {
-       unsigned long completed_reqs, flags;
-       u32 tr_doorbell;
-
        /* Resetting interrupt aggregation counters first and reading the
         * DOOR_BELL afterward allows us to handle all the completed requests.
         * In order to prevent other interrupts starvation the DB is read once
        if (ufs_fail_completion())
                return IRQ_HANDLED;
 
-       spin_lock_irqsave(&hba->outstanding_lock, flags);
-       tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
-       completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
-       WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
-                 "completed: %#lx; outstanding: %#lx\n", completed_reqs,
-                 hba->outstanding_reqs);
-       hba->outstanding_reqs &= ~completed_reqs;
-       spin_unlock_irqrestore(&hba->outstanding_lock, flags);
+       /*
+        * Ignore the ufshcd_poll() return value and return IRQ_HANDLED since we
+        * do not want polling to trigger spurious interrupt complaints.
+        */
+       ufshcd_poll(hba->host, 0);
 
-       if (completed_reqs) {
-               __ufshcd_transfer_req_compl(hba, completed_reqs);
-               return IRQ_HANDLED;
-       } else {
-               return IRQ_NONE;
-       }
+       return IRQ_HANDLED;
 }
 
 int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask)
        spin_lock_irqsave(host->host_lock, flags);
 
        task_tag = req->tag;
+       WARN_ONCE(task_tag < 0 || task_tag >= hba->nutmrs, "Invalid tag %d\n",
+                 task_tag);
        hba->tmf_rqs[req->tag] = req;
        treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
 
        .module                 = THIS_MODULE,
        .name                   = UFSHCD,
        .proc_name              = UFSHCD,
+       .map_queues             = ufshcd_map_queues,
        .queuecommand           = ufshcd_queuecommand,
+       .mq_poll                = ufshcd_poll,
        .slave_alloc            = ufshcd_slave_alloc,
        .slave_configure        = ufshcd_slave_configure,
        .slave_destroy          = ufshcd_slave_destroy,
                err = -ENOMEM;
                goto out_error;
        }
+       host->nr_maps = HCTX_TYPE_POLL + 1;
        hba = shost_priv(host);
        hba->host = host;
        hba->dev = dev;