Merge tag 'timers_urgent_for_v5.15_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / nvme / target / passthru.c
index 39b1473..f0efb35 100644 (file)
@@ -20,6 +20,16 @@ MODULE_IMPORT_NS(NVME_TARGET_PASSTHRU);
  */
 static DEFINE_XARRAY(passthru_subsystems);
 
+void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl)
+{
+       /*
+        * Multiple command set support can only be declared if the underlying
+        * controller actually supports it.
+        */
+       if (!nvme_multi_css(ctrl->subsys->passthru_ctrl))
+               ctrl->cap &= ~(1ULL << 43);
+}
+
 static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req)
 {
        struct nvmet_ctrl *ctrl = req->sq->ctrl;
@@ -153,11 +163,10 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
 {
        struct nvmet_req *req = container_of(w, struct nvmet_req, p.work);
        struct request *rq = req->p.rq;
-       u16 status;
+       int status;
 
-       nvme_execute_passthru_rq(rq);
+       status = nvme_execute_passthru_rq(rq);
 
-       status = nvme_req(rq)->status;
        if (status == NVME_SC_SUCCESS &&
            req->cmd->common.opcode == nvme_admin_identify) {
                switch (req->cmd->identify.cns) {
@@ -168,7 +177,8 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
                        nvmet_passthru_override_id_ns(req);
                        break;
                }
-       }
+       } else if (status < 0)
+               status = NVME_SC_INTERNAL;
 
        req->cqe->result = nvme_req(rq)->result;
        nvmet_req_complete(req, status);
@@ -206,8 +216,7 @@ static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq)
        for_each_sg(req->sg, sg, req->sg_cnt, i) {
                if (bio_add_pc_page(rq->q, bio, sg_page(sg), sg->length,
                                    sg->offset) < sg->length) {
-                       if (bio != &req->p.inline_bio)
-                               bio_put(bio);
+                       nvmet_req_bio_put(req, bio);
                        return -EINVAL;
                }
        }
@@ -219,7 +228,7 @@ static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq)
 
 static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
 {
-       struct nvme_ctrl *ctrl = nvmet_req_passthru_ctrl(req);
+       struct nvme_ctrl *ctrl = nvmet_req_subsys(req)->passthru_ctrl;
        struct request_queue *q = ctrl->admin_q;
        struct nvme_ns *ns = NULL;
        struct request *rq = NULL;
@@ -300,7 +309,7 @@ out:
  */
 static void nvmet_passthru_set_host_behaviour(struct nvmet_req *req)
 {
-       struct nvme_ctrl *ctrl = nvmet_req_passthru_ctrl(req);
+       struct nvme_ctrl *ctrl = nvmet_req_subsys(req)->passthru_ctrl;
        struct nvme_feat_host_behavior *host;
        u16 status = NVME_SC_INTERNAL;
        int ret;