static struct class *nvme_class;
 
+static inline bool nvme_req_needs_retry(struct request *req, u16 status)
+{
+       return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
+               (jiffies - req->start_time) < req->timeout &&
+               req->retries < nvme_max_retries;
+}
+
+void nvme_complete_rq(struct request *req)
+{
+       int error = 0;
+
+       if (unlikely(req->errors)) {
+               if (nvme_req_needs_retry(req, req->errors)) {
+                       req->retries++;
+                       blk_mq_requeue_request(req,
+                                       !blk_mq_queue_stopped(req->q));
+                       return;
+               }
+
+               if (blk_rq_is_passthrough(req))
+                       error = req->errors;
+               else
+                       error = nvme_error_status(req->errors);
+       }
+
+       blk_mq_end_request(req, error);
+}
+EXPORT_SYMBOL_GPL(nvme_complete_rq);
+
 void nvme_cancel_request(struct request *req, void *data, bool reserved)
 {
        int status;
        return NULL;
 }
 
-void nvme_requeue_req(struct request *req)
-{
-       blk_mq_requeue_request(req, !blk_mq_queue_stopped(req->q));
-}
-EXPORT_SYMBOL_GPL(nvme_requeue_req);
-
 struct request *nvme_alloc_request(struct request_queue *q,
                struct nvme_command *cmd, unsigned int flags, int qid)
 {
 
 {
        struct nvme_fc_fcp_op *op = blk_mq_rq_to_pdu(rq);
        struct nvme_fc_ctrl *ctrl = op->ctrl;
-       int error = 0, state;
+       int state;
 
        state = atomic_xchg(&op->state, FCPOP_STATE_IDLE);
 
        nvme_cleanup_cmd(rq);
-
        nvme_fc_unmap_data(ctrl, rq, op);
-
-       if (unlikely(rq->errors)) {
-               if (nvme_req_needs_retry(rq, rq->errors)) {
-                       rq->retries++;
-                       nvme_requeue_req(rq);
-                       goto put_ctrl;
-               }
-
-               if (blk_rq_is_passthrough(rq))
-                       error = rq->errors;
-               else
-                       error = nvme_error_status(rq->errors);
-       }
-
-       blk_mq_end_request(rq, error);
-put_ctrl:
+       nvme_complete_rq(rq);
        nvme_fc_ctrl_put(ctrl);
 
 }
 
        }
 }
 
-static inline bool nvme_req_needs_retry(struct request *req, u16 status)
-{
-       return !(status & NVME_SC_DNR || blk_noretry_request(req)) &&
-               (jiffies - req->start_time) < req->timeout &&
-               req->retries < nvme_max_retries;
-}
-
+void nvme_complete_rq(struct request *req);
 void nvme_cancel_request(struct request *req, void *data, bool reserved);
 bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
                enum nvme_ctrl_state new_state);
 #define NVME_QID_ANY -1
 struct request *nvme_alloc_request(struct request_queue *q,
                struct nvme_command *cmd, unsigned int flags, int qid);
-void nvme_requeue_req(struct request *req);
 int nvme_setup_cmd(struct nvme_ns *ns, struct request *req,
                struct nvme_command *cmd);
 int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
 
        return ret;
 }
 
-static void nvme_complete_rq(struct request *req)
+static void nvme_pci_complete_rq(struct request *req)
 {
        struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
-       struct nvme_dev *dev = iod->nvmeq->dev;
-       int error = 0;
 
-       nvme_unmap_data(dev, req);
-
-       if (unlikely(req->errors)) {
-               if (nvme_req_needs_retry(req, req->errors)) {
-                       req->retries++;
-                       nvme_requeue_req(req);
-                       return;
-               }
-
-               if (blk_rq_is_passthrough(req))
-                       error = req->errors;
-               else
-                       error = nvme_error_status(req->errors);
-       }
-
-       if (unlikely(iod->aborted)) {
-               dev_warn(dev->ctrl.device,
-                       "completing aborted command with status: %04x\n",
-                       req->errors);
-       }
-
-       blk_mq_end_request(req, error);
+       nvme_unmap_data(iod->nvmeq->dev, req);
+       nvme_complete_rq(req);
 }
 
 /* We read the CQE phase first to check if the rest of the entry is valid */
 
 static const struct blk_mq_ops nvme_mq_admin_ops = {
        .queue_rq       = nvme_queue_rq,
-       .complete       = nvme_complete_rq,
+       .complete       = nvme_pci_complete_rq,
        .init_hctx      = nvme_admin_init_hctx,
        .exit_hctx      = nvme_admin_exit_hctx,
        .init_request   = nvme_admin_init_request,
 
 static const struct blk_mq_ops nvme_mq_ops = {
        .queue_rq       = nvme_queue_rq,
-       .complete       = nvme_complete_rq,
+       .complete       = nvme_pci_complete_rq,
        .init_hctx      = nvme_init_hctx,
        .init_request   = nvme_init_request,
        .map_queues     = nvme_pci_map_queues,
 
 static void nvme_rdma_complete_rq(struct request *rq)
 {
        struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq);
-       struct nvme_rdma_queue *queue = req->queue;
-       int error = 0;
 
-       nvme_rdma_unmap_data(queue, rq);
-
-       if (unlikely(rq->errors)) {
-               if (nvme_req_needs_retry(rq, rq->errors)) {
-                       rq->retries++;
-                       nvme_requeue_req(rq);
-                       return;
-               }
-
-               if (blk_rq_is_passthrough(rq))
-                       error = rq->errors;
-               else
-                       error = nvme_error_status(rq->errors);
-       }
-
-       blk_mq_end_request(rq, error);
+       nvme_rdma_unmap_data(req->queue, rq);
+       nvme_complete_rq(rq);
 }
 
 static const struct blk_mq_ops nvme_rdma_mq_ops = {
 
 static void nvme_loop_complete_rq(struct request *req)
 {
        struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);
-       int error = 0;
 
        nvme_cleanup_cmd(req);
        sg_free_table_chained(&iod->sg_table, true);
-
-       if (unlikely(req->errors)) {
-               if (nvme_req_needs_retry(req, req->errors)) {
-                       req->retries++;
-                       nvme_requeue_req(req);
-                       return;
-               }
-
-               if (blk_rq_is_passthrough(req))
-                       error = req->errors;
-               else
-                       error = nvme_error_status(req->errors);
-       }
-
-       blk_mq_end_request(req, error);
+       nvme_complete_rq(req);
 }
 
 static struct blk_mq_tags *nvme_loop_tagset(struct nvme_loop_queue *queue)