LCOV - code coverage report
Current view: top level - spdk/lib/nvme - nvme_ctrlr_cmd.c (source / functions) Hit Total Coverage
Test: Combined Lines: 383 474 80.8 %
Date: 2024-07-12 16:43:38 Functions: 34 37 91.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 89 178 50.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2015 Intel Corporation. All rights reserved.
       3                 :            :  *   Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "nvme_internal.h"
       7                 :            : #include "spdk/nvme.h"
       8                 :            : 
       9                 :            : int
      10                 :          4 : spdk_nvme_ctrlr_io_cmd_raw_no_payload_build(struct spdk_nvme_ctrlr *ctrlr,
      11                 :            :                 struct spdk_nvme_qpair *qpair,
      12                 :            :                 struct spdk_nvme_cmd *cmd,
      13                 :            :                 spdk_nvme_cmd_cb cb_fn, void *cb_arg)
      14                 :            : {
      15                 :            :         struct nvme_request *req;
      16                 :          4 :         struct nvme_payload payload;
      17                 :            : 
      18         [ +  - ]:          4 :         if (ctrlr->trid.trtype != SPDK_NVME_TRANSPORT_PCIE) {
      19                 :          4 :                 return -EINVAL;
      20                 :            :         }
      21                 :            : 
      22         [ #  # ]:          0 :         memset(&payload, 0, sizeof(payload));
      23                 :          0 :         req = nvme_allocate_request(qpair, &payload, 0, 0, cb_fn, cb_arg);
      24                 :            : 
      25         [ #  # ]:          0 :         if (req == NULL) {
      26                 :          0 :                 return -ENOMEM;
      27                 :            :         }
      28                 :            : 
      29   [ #  #  #  # ]:          0 :         memcpy(&req->cmd, cmd, sizeof(req->cmd));
      30                 :            : 
      31                 :          0 :         return nvme_qpair_submit_request(qpair, req);
      32                 :            : }
      33                 :            : 
      34                 :            : int
      35                 :     651115 : spdk_nvme_ctrlr_cmd_io_raw(struct spdk_nvme_ctrlr *ctrlr,
      36                 :            :                            struct spdk_nvme_qpair *qpair,
      37                 :            :                            struct spdk_nvme_cmd *cmd,
      38                 :            :                            void *buf, uint32_t len,
      39                 :            :                            spdk_nvme_cmd_cb cb_fn, void *cb_arg)
      40                 :            : {
      41                 :            :         struct nvme_request     *req;
      42                 :            : 
      43                 :     651115 :         req = nvme_allocate_request_contig(qpair, buf, len, cb_fn, cb_arg);
      44                 :            : 
      45         [ +  + ]:     651115 :         if (req == NULL) {
      46                 :          4 :                 return -ENOMEM;
      47                 :            :         }
      48                 :            : 
      49   [ -  +  -  + ]:     651111 :         memcpy(&req->cmd, cmd, sizeof(req->cmd));
      50                 :            : 
      51                 :     651111 :         return nvme_qpair_submit_request(qpair, req);
      52                 :            : }
      53                 :            : 
      54                 :            : int
      55                 :          6 : spdk_nvme_ctrlr_cmd_io_raw_with_md(struct spdk_nvme_ctrlr *ctrlr,
      56                 :            :                                    struct spdk_nvme_qpair *qpair,
      57                 :            :                                    struct spdk_nvme_cmd *cmd,
      58                 :            :                                    void *buf, uint32_t len, void *md_buf,
      59                 :            :                                    spdk_nvme_cmd_cb cb_fn, void *cb_arg)
      60                 :            : {
      61                 :            :         struct nvme_request *req;
      62                 :          4 :         struct nvme_payload payload;
      63                 :          6 :         uint32_t md_len = 0;
      64                 :            : 
      65                 :          6 :         payload = NVME_PAYLOAD_CONTIG(buf, md_buf);
      66                 :            : 
      67                 :            :         /* Calculate metadata length */
      68         [ -  + ]:          6 :         if (md_buf) {
      69                 :          0 :                 struct spdk_nvme_ns *ns = spdk_nvme_ctrlr_get_ns(ctrlr, cmd->nsid);
      70                 :            : 
      71         [ #  # ]:          0 :                 assert(ns != NULL);
      72         [ #  # ]:          0 :                 assert(ns->sector_size != 0);
      73         [ #  # ]:          0 :                 md_len =  len / ns->sector_size * ns->md_size;
      74                 :            :         }
      75                 :            : 
      76                 :          6 :         req = nvme_allocate_request(qpair, &payload, len, md_len, cb_fn, cb_arg);
      77         [ +  + ]:          6 :         if (req == NULL) {
      78                 :          4 :                 return -ENOMEM;
      79                 :            :         }
      80                 :            : 
      81   [ -  +  -  + ]:          2 :         memcpy(&req->cmd, cmd, sizeof(req->cmd));
      82                 :            : 
      83                 :          2 :         return nvme_qpair_submit_request(qpair, req);
      84                 :            : }
      85                 :            : 
      86                 :            : int
      87                 :          0 : spdk_nvme_ctrlr_cmd_iov_raw_with_md(struct spdk_nvme_ctrlr *ctrlr,
      88                 :            :                                     struct spdk_nvme_qpair *qpair,
      89                 :            :                                     struct spdk_nvme_cmd *cmd,
      90                 :            :                                     uint32_t len, void *md_buf,
      91                 :            :                                     spdk_nvme_cmd_cb cb_fn, void *cb_arg,
      92                 :            :                                     spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
      93                 :            :                                     spdk_nvme_req_next_sge_cb next_sge_fn)
      94                 :            : {
      95                 :            :         struct nvme_request *req;
      96                 :          0 :         struct nvme_payload payload;
      97                 :          0 :         uint32_t md_len = 0;
      98                 :            : 
      99   [ #  #  #  # ]:          0 :         if (reset_sgl_fn == NULL || next_sge_fn == NULL) {
     100                 :          0 :                 return -EINVAL;
     101                 :            :         }
     102                 :            : 
     103                 :          0 :         payload = NVME_PAYLOAD_SGL(reset_sgl_fn, next_sge_fn, cb_arg, md_buf);
     104                 :            : 
     105                 :            :         /* Calculate metadata length */
     106         [ #  # ]:          0 :         if (md_buf) {
     107                 :          0 :                 struct spdk_nvme_ns *ns = spdk_nvme_ctrlr_get_ns(ctrlr, cmd->nsid);
     108                 :            : 
     109         [ #  # ]:          0 :                 assert(ns != NULL);
     110         [ #  # ]:          0 :                 assert(ns->sector_size != 0);
     111         [ #  # ]:          0 :                 md_len = len / ns->sector_size * ns->md_size;
     112                 :            :         }
     113                 :            : 
     114                 :          0 :         req = nvme_allocate_request(qpair, &payload, len, md_len, cb_fn, cb_arg);
     115         [ #  # ]:          0 :         if (req == NULL) {
     116                 :          0 :                 return -ENOMEM;
     117                 :            :         }
     118                 :            : 
     119   [ #  #  #  # ]:          0 :         memcpy(&req->cmd, cmd, sizeof(req->cmd));
     120                 :            : 
     121                 :          0 :         return nvme_qpair_submit_request(qpair, req);
     122                 :            : }
     123                 :            : 
     124                 :            : int
     125                 :     570788 : spdk_nvme_ctrlr_cmd_admin_raw(struct spdk_nvme_ctrlr *ctrlr,
     126                 :            :                               struct spdk_nvme_cmd *cmd,
     127                 :            :                               void *buf, uint32_t len,
     128                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     129                 :            : {
     130                 :            :         struct nvme_request     *req;
     131                 :            :         int                     rc;
     132                 :            : 
     133                 :     570788 :         nvme_ctrlr_lock(ctrlr);
     134                 :     570788 :         req = nvme_allocate_request_contig(ctrlr->adminq, buf, len, cb_fn, cb_arg);
     135         [ -  + ]:     570788 :         if (req == NULL) {
     136                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     137                 :          0 :                 return -ENOMEM;
     138                 :            :         }
     139                 :            : 
     140   [ -  +  -  + ]:     570788 :         memcpy(&req->cmd, cmd, sizeof(req->cmd));
     141                 :            : 
     142                 :     570788 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     143                 :            : 
     144                 :     570788 :         nvme_ctrlr_unlock(ctrlr);
     145                 :     570788 :         return rc;
     146                 :            : }
     147                 :            : 
     148                 :            : int
     149                 :      10575 : nvme_ctrlr_cmd_identify(struct spdk_nvme_ctrlr *ctrlr, uint8_t cns, uint16_t cntid, uint32_t nsid,
     150                 :            :                         uint8_t csi, void *payload, size_t payload_size,
     151                 :            :                         spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     152                 :            : {
     153                 :            :         struct nvme_request *req;
     154                 :            :         struct spdk_nvme_cmd *cmd;
     155                 :            :         int                  rc;
     156                 :            : 
     157                 :      10575 :         nvme_ctrlr_lock(ctrlr);
     158                 :      10575 :         req = nvme_allocate_request_user_copy(ctrlr->adminq,
     159                 :            :                                               payload, payload_size,
     160                 :            :                                               cb_fn, cb_arg, false);
     161         [ -  + ]:      10575 :         if (req == NULL) {
     162                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     163                 :          0 :                 return -ENOMEM;
     164                 :            :         }
     165                 :            : 
     166                 :      10575 :         cmd = &req->cmd;
     167                 :      10575 :         cmd->opc = SPDK_NVME_OPC_IDENTIFY;
     168                 :      10575 :         cmd->cdw10_bits.identify.cns = cns;
     169                 :      10575 :         cmd->cdw10_bits.identify.cntid = cntid;
     170                 :      10575 :         cmd->cdw11_bits.identify.csi = csi;
     171                 :      10575 :         cmd->nsid = nsid;
     172                 :            : 
     173                 :      10575 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     174                 :            : 
     175                 :      10575 :         nvme_ctrlr_unlock(ctrlr);
     176                 :      10575 :         return rc;
     177                 :            : }
     178                 :            : 
     179                 :            : int
     180                 :          4 : nvme_ctrlr_cmd_attach_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
     181                 :            :                          struct spdk_nvme_ctrlr_list *payload, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     182                 :            : {
     183                 :            :         struct nvme_request                     *req;
     184                 :            :         struct spdk_nvme_cmd                    *cmd;
     185                 :            :         int                                     rc;
     186                 :            : 
     187                 :          4 :         nvme_ctrlr_lock(ctrlr);
     188                 :          4 :         req = nvme_allocate_request_user_copy(ctrlr->adminq,
     189                 :            :                                               payload, sizeof(struct spdk_nvme_ctrlr_list),
     190                 :            :                                               cb_fn, cb_arg, true);
     191         [ -  + ]:          4 :         if (req == NULL) {
     192                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     193                 :          0 :                 return -ENOMEM;
     194                 :            :         }
     195                 :            : 
     196                 :          4 :         cmd = &req->cmd;
     197                 :          4 :         cmd->opc = SPDK_NVME_OPC_NS_ATTACHMENT;
     198                 :          4 :         cmd->nsid = nsid;
     199                 :          4 :         cmd->cdw10_bits.ns_attach.sel = SPDK_NVME_NS_CTRLR_ATTACH;
     200                 :            : 
     201                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     202                 :            : 
     203                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     204                 :          4 :         return rc;
     205                 :            : }
     206                 :            : 
     207                 :            : int
     208                 :          4 : nvme_ctrlr_cmd_detach_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
     209                 :            :                          struct spdk_nvme_ctrlr_list *payload, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     210                 :            : {
     211                 :            :         struct nvme_request                     *req;
     212                 :            :         struct spdk_nvme_cmd                    *cmd;
     213                 :            :         int                                     rc;
     214                 :            : 
     215                 :          4 :         nvme_ctrlr_lock(ctrlr);
     216                 :          4 :         req = nvme_allocate_request_user_copy(ctrlr->adminq,
     217                 :            :                                               payload, sizeof(struct spdk_nvme_ctrlr_list),
     218                 :            :                                               cb_fn, cb_arg, true);
     219         [ -  + ]:          4 :         if (req == NULL) {
     220                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     221                 :          0 :                 return -ENOMEM;
     222                 :            :         }
     223                 :            : 
     224                 :          4 :         cmd = &req->cmd;
     225                 :          4 :         cmd->opc = SPDK_NVME_OPC_NS_ATTACHMENT;
     226                 :          4 :         cmd->nsid = nsid;
     227                 :          4 :         cmd->cdw10_bits.ns_attach.sel = SPDK_NVME_NS_CTRLR_DETACH;
     228                 :            : 
     229                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     230                 :            : 
     231                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     232                 :          4 :         return rc;
     233                 :            : }
     234                 :            : 
     235                 :            : int
     236                 :          4 : nvme_ctrlr_cmd_create_ns(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns_data *payload,
     237                 :            :                          spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     238                 :            : {
     239                 :            :         struct nvme_request                     *req;
     240                 :            :         struct spdk_nvme_cmd                    *cmd;
     241                 :            :         int                                     rc;
     242                 :            : 
     243                 :          4 :         nvme_ctrlr_lock(ctrlr);
     244                 :          4 :         req = nvme_allocate_request_user_copy(ctrlr->adminq,
     245                 :            :                                               payload, sizeof(struct spdk_nvme_ns_data),
     246                 :            :                                               cb_fn, cb_arg, true);
     247         [ -  + ]:          4 :         if (req == NULL) {
     248                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     249                 :          0 :                 return -ENOMEM;
     250                 :            :         }
     251                 :            : 
     252                 :          4 :         cmd = &req->cmd;
     253                 :          4 :         cmd->opc = SPDK_NVME_OPC_NS_MANAGEMENT;
     254                 :          4 :         cmd->cdw10_bits.ns_manage.sel = SPDK_NVME_NS_MANAGEMENT_CREATE;
     255                 :            : 
     256                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     257                 :            : 
     258                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     259                 :          4 :         return rc;
     260                 :            : }
     261                 :            : 
     262                 :            : int
     263                 :          4 : nvme_ctrlr_cmd_delete_ns(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, spdk_nvme_cmd_cb cb_fn,
     264                 :            :                          void *cb_arg)
     265                 :            : {
     266                 :            :         struct nvme_request                     *req;
     267                 :            :         struct spdk_nvme_cmd                    *cmd;
     268                 :            :         int                                     rc;
     269                 :            : 
     270                 :          4 :         nvme_ctrlr_lock(ctrlr);
     271                 :          4 :         req = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     272         [ -  + ]:          4 :         if (req == NULL) {
     273                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     274                 :          0 :                 return -ENOMEM;
     275                 :            :         }
     276                 :            : 
     277                 :          4 :         cmd = &req->cmd;
     278                 :          4 :         cmd->opc = SPDK_NVME_OPC_NS_MANAGEMENT;
     279                 :          4 :         cmd->cdw10_bits.ns_manage.sel = SPDK_NVME_NS_MANAGEMENT_DELETE;
     280                 :          4 :         cmd->nsid = nsid;
     281                 :            : 
     282                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     283                 :            : 
     284                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     285                 :          4 :         return rc;
     286                 :            : }
     287                 :            : 
     288                 :            : int
     289                 :        681 : nvme_ctrlr_cmd_doorbell_buffer_config(struct spdk_nvme_ctrlr *ctrlr, uint64_t prp1, uint64_t prp2,
     290                 :            :                                       spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     291                 :            : {
     292                 :            :         struct nvme_request                     *req;
     293                 :            :         struct spdk_nvme_cmd                    *cmd;
     294                 :            :         int                                     rc;
     295                 :            : 
     296                 :        681 :         nvme_ctrlr_lock(ctrlr);
     297                 :        681 :         req = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     298         [ -  + ]:        681 :         if (req == NULL) {
     299                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     300                 :          0 :                 return -ENOMEM;
     301                 :            :         }
     302                 :            : 
     303                 :        681 :         cmd = &req->cmd;
     304                 :        681 :         cmd->opc = SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG;
     305                 :        681 :         cmd->dptr.prp.prp1 = prp1;
     306                 :        681 :         cmd->dptr.prp.prp2 = prp2;
     307                 :            : 
     308                 :        681 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     309                 :            : 
     310                 :        681 :         nvme_ctrlr_unlock(ctrlr);
     311                 :        681 :         return rc;
     312                 :            : }
     313                 :            : 
     314                 :            : int
     315                 :          4 : nvme_ctrlr_cmd_format(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, struct spdk_nvme_format *format,
     316                 :            :                       spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     317                 :            : {
     318                 :            :         struct nvme_request *req;
     319                 :            :         struct spdk_nvme_cmd *cmd;
     320                 :            :         int rc;
     321                 :            : 
     322                 :          4 :         nvme_ctrlr_lock(ctrlr);
     323                 :          4 :         req = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     324         [ -  + ]:          4 :         if (req == NULL) {
     325                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     326                 :          0 :                 return -ENOMEM;
     327                 :            :         }
     328                 :            : 
     329                 :          4 :         cmd = &req->cmd;
     330                 :          4 :         cmd->opc = SPDK_NVME_OPC_FORMAT_NVM;
     331                 :          4 :         cmd->nsid = nsid;
     332                 :          4 :         memcpy(&cmd->cdw10, format, sizeof(uint32_t));
     333                 :            : 
     334                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     335                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     336                 :            : 
     337                 :          4 :         return rc;
     338                 :            : }
     339                 :            : 
     340                 :            : int
     341                 :       5229 : spdk_nvme_ctrlr_cmd_set_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
     342                 :            :                                 uint32_t cdw11, uint32_t cdw12, void *payload, uint32_t payload_size,
     343                 :            :                                 spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     344                 :            : {
     345                 :            :         struct nvme_request *req;
     346                 :            :         struct spdk_nvme_cmd *cmd;
     347                 :            :         int rc;
     348                 :            : 
     349                 :       5229 :         nvme_ctrlr_lock(ctrlr);
     350                 :       5229 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
     351                 :            :                                               true);
     352         [ -  + ]:       5229 :         if (req == NULL) {
     353                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     354                 :          0 :                 return -ENOMEM;
     355                 :            :         }
     356                 :            : 
     357                 :       5229 :         cmd = &req->cmd;
     358                 :       5229 :         cmd->opc = SPDK_NVME_OPC_SET_FEATURES;
     359                 :       5229 :         cmd->cdw10_bits.set_features.fid = feature;
     360                 :       5229 :         cmd->cdw11 = cdw11;
     361                 :       5229 :         cmd->cdw12 = cdw12;
     362                 :            : 
     363                 :       5229 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     364                 :       5229 :         nvme_ctrlr_unlock(ctrlr);
     365                 :            : 
     366                 :       5229 :         return rc;
     367                 :            : }
     368                 :            : 
     369                 :            : int
     370                 :       1538 : spdk_nvme_ctrlr_cmd_get_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
     371                 :            :                                 uint32_t cdw11, void *payload, uint32_t payload_size,
     372                 :            :                                 spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     373                 :            : {
     374                 :            :         struct nvme_request *req;
     375                 :            :         struct spdk_nvme_cmd *cmd;
     376                 :            :         int rc;
     377                 :            : 
     378                 :       1538 :         nvme_ctrlr_lock(ctrlr);
     379                 :       1538 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
     380                 :            :                                               false);
     381         [ -  + ]:       1538 :         if (req == NULL) {
     382                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     383                 :          0 :                 return -ENOMEM;
     384                 :            :         }
     385                 :            : 
     386                 :       1538 :         cmd = &req->cmd;
     387                 :       1538 :         cmd->opc = SPDK_NVME_OPC_GET_FEATURES;
     388                 :       1538 :         cmd->cdw10_bits.get_features.fid = feature;
     389                 :       1538 :         cmd->cdw11 = cdw11;
     390                 :            : 
     391                 :       1538 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     392                 :       1538 :         nvme_ctrlr_unlock(ctrlr);
     393                 :            : 
     394                 :       1538 :         return rc;
     395                 :            : }
     396                 :            : 
     397                 :            : int
     398                 :          5 : spdk_nvme_ctrlr_cmd_get_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
     399                 :            :                                    uint32_t cdw11, void *payload,
     400                 :            :                                    uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
     401                 :            :                                    void *cb_arg, uint32_t ns_id)
     402                 :            : {
     403                 :            :         struct nvme_request *req;
     404                 :            :         struct spdk_nvme_cmd *cmd;
     405                 :            :         int rc;
     406                 :            : 
     407                 :          5 :         nvme_ctrlr_lock(ctrlr);
     408                 :          5 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
     409                 :            :                                               false);
     410         [ -  + ]:          5 :         if (req == NULL) {
     411                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     412                 :          0 :                 return -ENOMEM;
     413                 :            :         }
     414                 :            : 
     415                 :          5 :         cmd = &req->cmd;
     416                 :          5 :         cmd->opc = SPDK_NVME_OPC_GET_FEATURES;
     417                 :          5 :         cmd->cdw10_bits.get_features.fid = feature;
     418                 :          5 :         cmd->cdw11 = cdw11;
     419                 :          5 :         cmd->nsid = ns_id;
     420                 :            : 
     421                 :          5 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     422                 :          5 :         nvme_ctrlr_unlock(ctrlr);
     423                 :            : 
     424                 :          5 :         return rc;
     425                 :            : }
     426                 :            : 
     427                 :            : int
     428                 :          5 : spdk_nvme_ctrlr_cmd_set_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
     429                 :            :                                    uint32_t cdw11, uint32_t cdw12, void *payload,
     430                 :            :                                    uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
     431                 :            :                                    void *cb_arg, uint32_t ns_id)
     432                 :            : {
     433                 :            :         struct nvme_request *req;
     434                 :            :         struct spdk_nvme_cmd *cmd;
     435                 :            :         int rc;
     436                 :            : 
     437                 :          5 :         nvme_ctrlr_lock(ctrlr);
     438                 :          5 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
     439                 :            :                                               true);
     440         [ -  + ]:          5 :         if (req == NULL) {
     441                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     442                 :          0 :                 return -ENOMEM;
     443                 :            :         }
     444                 :            : 
     445                 :          5 :         cmd = &req->cmd;
     446                 :          5 :         cmd->opc = SPDK_NVME_OPC_SET_FEATURES;
     447                 :          5 :         cmd->cdw10_bits.set_features.fid = feature;
     448                 :          5 :         cmd->cdw11 = cdw11;
     449                 :          5 :         cmd->cdw12 = cdw12;
     450                 :          5 :         cmd->nsid = ns_id;
     451                 :            : 
     452                 :          5 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     453                 :          5 :         nvme_ctrlr_unlock(ctrlr);
     454                 :            : 
     455                 :          5 :         return rc;
     456                 :            : }
     457                 :            : 
     458                 :            : int
     459                 :       2224 : nvme_ctrlr_cmd_set_num_queues(struct spdk_nvme_ctrlr *ctrlr,
     460                 :            :                               uint32_t num_queues, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     461                 :            : {
     462                 :            :         union spdk_nvme_feat_number_of_queues feat_num_queues;
     463                 :            : 
     464                 :       2224 :         feat_num_queues.raw = 0;
     465                 :       2224 :         feat_num_queues.bits.nsqr = num_queues - 1;
     466                 :       2224 :         feat_num_queues.bits.ncqr = num_queues - 1;
     467                 :            : 
     468                 :       2224 :         return spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_NUMBER_OF_QUEUES, feat_num_queues.raw,
     469                 :            :                                                0,
     470                 :            :                                                NULL, 0, cb_fn, cb_arg);
     471                 :            : }
     472                 :            : 
     473                 :            : int
     474                 :          0 : nvme_ctrlr_cmd_get_num_queues(struct spdk_nvme_ctrlr *ctrlr,
     475                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     476                 :            : {
     477                 :          0 :         return spdk_nvme_ctrlr_cmd_get_feature(ctrlr, SPDK_NVME_FEAT_NUMBER_OF_QUEUES, 0, NULL, 0,
     478                 :            :                                                cb_fn, cb_arg);
     479                 :            : }
     480                 :            : 
     481                 :            : int
     482                 :       2316 : nvme_ctrlr_cmd_set_async_event_config(struct spdk_nvme_ctrlr *ctrlr,
     483                 :            :                                       union spdk_nvme_feat_async_event_configuration config, spdk_nvme_cmd_cb cb_fn,
     484                 :            :                                       void *cb_arg)
     485                 :            : {
     486                 :            :         uint32_t cdw11;
     487                 :            : 
     488                 :       2316 :         cdw11 = config.raw;
     489                 :       2316 :         return spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, 0,
     490                 :            :                                                NULL, 0,
     491                 :            :                                                cb_fn, cb_arg);
     492                 :            : }
     493                 :            : 
     494                 :            : int
     495                 :         12 : nvme_ctrlr_cmd_set_host_id(struct spdk_nvme_ctrlr *ctrlr, void *host_id, uint32_t host_id_size,
     496                 :            :                            spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     497                 :            : {
     498                 :            :         union spdk_nvme_feat_host_identifier feat_host_identifier;
     499                 :            : 
     500                 :         12 :         feat_host_identifier.raw = 0;
     501         [ +  + ]:         12 :         if (host_id_size == 16) {
     502                 :            :                 /* 128-bit extended host identifier */
     503                 :          4 :                 feat_host_identifier.bits.exhid = 1;
     504         [ +  + ]:          8 :         } else if (host_id_size == 8) {
     505                 :            :                 /* 64-bit host identifier */
     506                 :          4 :                 feat_host_identifier.bits.exhid = 0;
     507                 :            :         } else {
     508                 :          4 :                 SPDK_ERRLOG("Invalid host ID size %u\n", host_id_size);
     509                 :          4 :                 return -EINVAL;
     510                 :            :         }
     511                 :            : 
     512                 :          8 :         return spdk_nvme_ctrlr_cmd_set_feature(ctrlr, SPDK_NVME_FEAT_HOST_IDENTIFIER,
     513                 :            :                                                feat_host_identifier.raw, 0,
     514                 :            :                                                host_id, host_id_size, cb_fn, cb_arg);
     515                 :            : }
     516                 :            : 
     517                 :            : int
     518                 :       2244 : spdk_nvme_ctrlr_cmd_get_log_page_ext(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page,
     519                 :            :                                      uint32_t nsid, void *payload, uint32_t payload_size,
     520                 :            :                                      uint64_t offset, uint32_t cdw10,
     521                 :            :                                      uint32_t cdw11, uint32_t cdw14,
     522                 :            :                                      spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     523                 :            : {
     524                 :            :         struct nvme_request *req;
     525                 :            :         struct spdk_nvme_cmd *cmd;
     526                 :            :         uint32_t numd, numdl, numdu;
     527                 :            :         uint32_t lpol, lpou;
     528                 :            :         int rc;
     529                 :            : 
     530         [ -  + ]:       2244 :         if (payload_size == 0) {
     531                 :          0 :                 return -EINVAL;
     532                 :            :         }
     533                 :            : 
     534         [ -  + ]:       2244 :         if (offset & 3) {
     535                 :          0 :                 return -EINVAL;
     536                 :            :         }
     537                 :            : 
     538                 :       2244 :         numd = spdk_nvme_bytes_to_numd(payload_size);
     539                 :       2244 :         numdl = numd & 0xFFFFu;
     540                 :       2244 :         numdu = (numd >> 16) & 0xFFFFu;
     541                 :            : 
     542                 :       2244 :         lpol = (uint32_t)offset;
     543                 :       2244 :         lpou = (uint32_t)(offset >> 32);
     544                 :            : 
     545                 :       2244 :         nvme_ctrlr_lock(ctrlr);
     546                 :            : 
     547   [ -  +  -  - ]:       2244 :         if (offset && !ctrlr->cdata.lpa.edlp) {
     548                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     549                 :          0 :                 return -EINVAL;
     550                 :            :         }
     551                 :            : 
     552                 :       2244 :         req = nvme_allocate_request_user_copy(ctrlr->adminq,
     553                 :            :                                               payload, payload_size, cb_fn, cb_arg, false);
     554         [ -  + ]:       2244 :         if (req == NULL) {
     555                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     556                 :          0 :                 return -ENOMEM;
     557                 :            :         }
     558                 :            : 
     559                 :       2244 :         cmd = &req->cmd;
     560                 :       2244 :         cmd->opc = SPDK_NVME_OPC_GET_LOG_PAGE;
     561                 :       2244 :         cmd->nsid = nsid;
     562                 :       2244 :         cmd->cdw10 = cdw10;
     563                 :       2244 :         cmd->cdw10_bits.get_log_page.numdl = numdl;
     564                 :       2244 :         cmd->cdw10_bits.get_log_page.lid = log_page;
     565                 :            : 
     566                 :       2244 :         cmd->cdw11 = cdw11;
     567                 :       2244 :         cmd->cdw11_bits.get_log_page.numdu = numdu;
     568                 :       2244 :         cmd->cdw12 = lpol;
     569                 :       2244 :         cmd->cdw13 = lpou;
     570                 :       2244 :         cmd->cdw14 = cdw14;
     571                 :            : 
     572                 :       2244 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     573                 :       2244 :         nvme_ctrlr_unlock(ctrlr);
     574                 :            : 
     575                 :       2244 :         return rc;
     576                 :            : }
     577                 :            : 
     578                 :            : int
     579                 :       1215 : spdk_nvme_ctrlr_cmd_get_log_page(struct spdk_nvme_ctrlr *ctrlr, uint8_t log_page,
     580                 :            :                                  uint32_t nsid, void *payload, uint32_t payload_size,
     581                 :            :                                  uint64_t offset, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     582                 :            : {
     583                 :       1215 :         return spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, log_page, nsid, payload,
     584                 :            :                         payload_size, offset, 0, 0, 0, cb_fn, cb_arg);
     585                 :            : }
     586                 :            : 
     587                 :            : static void
     588                 :     323207 : nvme_ctrlr_retry_queued_abort(struct spdk_nvme_ctrlr *ctrlr)
     589                 :            : {
     590                 :            :         struct nvme_request     *next, *tmp;
     591                 :            :         int rc;
     592                 :            : 
     593   [ -  +  +  -  :     323207 :         if (ctrlr->is_resetting || ctrlr->is_destructed || ctrlr->is_failed) {
          -  +  +  -  -  
                +  -  + ]
     594                 :            :                 /* Don't resubmit aborts if ctrlr is failing */
     595                 :          0 :                 return;
     596                 :            :         }
     597                 :            : 
     598         [ -  + ]:     323207 :         if (spdk_nvme_ctrlr_get_admin_qp_failure_reason(ctrlr) != SPDK_NVME_QPAIR_FAILURE_NONE) {
     599                 :            :                 /* Don't resubmit aborts if admin qpair is failed */
     600                 :          0 :                 return;
     601                 :            :         }
     602                 :            : 
     603         [ +  + ]:     323207 :         STAILQ_FOREACH_SAFE(next, &ctrlr->queued_aborts, stailq, tmp) {
     604         [ +  + ]:     183544 :                 STAILQ_REMOVE_HEAD(&ctrlr->queued_aborts, stailq);
     605                 :     183544 :                 ctrlr->outstanding_aborts++;
     606                 :     183544 :                 rc = nvme_ctrlr_submit_admin_request(ctrlr, next);
     607         [ -  + ]:     183544 :                 if (rc < 0) {
     608                 :          0 :                         SPDK_ERRLOG("Failed to submit queued abort.\n");
     609         [ #  # ]:          0 :                         memset(&next->cpl, 0, sizeof(next->cpl));
     610                 :          0 :                         next->cpl.status.sct = SPDK_NVME_SCT_GENERIC;
     611                 :          0 :                         next->cpl.status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
     612                 :          0 :                         next->cpl.status.dnr = 1;
     613                 :          0 :                         nvme_complete_request(next->cb_fn, next->cb_arg, next->qpair, next, &next->cpl);
     614                 :            :                 } else {
     615                 :            :                         /* If the first abort succeeds, stop iterating. */
     616                 :     183544 :                         break;
     617                 :            :                 }
     618                 :            :         }
     619                 :            : }
     620                 :            : 
     621                 :            : static int
     622                 :     323215 : _nvme_ctrlr_submit_abort_request(struct spdk_nvme_ctrlr *ctrlr,
     623                 :            :                                  struct nvme_request *req)
     624                 :            : {
     625                 :            :         /* ACL is a 0's based value. */
     626         [ +  + ]:     323215 :         if (ctrlr->outstanding_aborts >= ctrlr->cdata.acl + 1U) {
     627                 :     183544 :                 STAILQ_INSERT_TAIL(&ctrlr->queued_aborts, req, stailq);
     628                 :     183544 :                 return 0;
     629                 :            :         } else {
     630                 :     139671 :                 ctrlr->outstanding_aborts++;
     631                 :     139671 :                 return nvme_ctrlr_submit_admin_request(ctrlr, req);
     632                 :            :         }
     633                 :            : }
     634                 :            : 
     635                 :            : static void
     636                 :          0 : nvme_ctrlr_cmd_abort_cpl(void *ctx, const struct spdk_nvme_cpl *cpl)
     637                 :            : {
     638                 :          0 :         struct nvme_request     *req = ctx;
     639                 :            :         struct spdk_nvme_ctrlr  *ctrlr;
     640                 :            : 
     641                 :          0 :         ctrlr = req->qpair->ctrlr;
     642                 :            : 
     643         [ #  # ]:          0 :         assert(ctrlr->outstanding_aborts > 0);
     644                 :          0 :         ctrlr->outstanding_aborts--;
     645                 :          0 :         nvme_ctrlr_retry_queued_abort(ctrlr);
     646                 :            : 
     647                 :          0 :         req->user_cb_fn(req->user_cb_arg, cpl);
     648                 :          0 : }
     649                 :            : 
     650                 :            : int
     651                 :         12 : spdk_nvme_ctrlr_cmd_abort(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair,
     652                 :            :                           uint16_t cid, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     653                 :            : {
     654                 :            :         int rc;
     655                 :            :         struct nvme_request *req;
     656                 :            :         struct spdk_nvme_cmd *cmd;
     657                 :            : 
     658         [ +  + ]:         12 :         if (qpair == NULL) {
     659                 :          8 :                 qpair = ctrlr->adminq;
     660                 :            :         }
     661                 :            : 
     662                 :         12 :         nvme_ctrlr_lock(ctrlr);
     663                 :         12 :         req = nvme_allocate_request_null(ctrlr->adminq, nvme_ctrlr_cmd_abort_cpl, NULL);
     664         [ +  + ]:         12 :         if (req == NULL) {
     665                 :          4 :                 nvme_ctrlr_unlock(ctrlr);
     666                 :          4 :                 return -ENOMEM;
     667                 :            :         }
     668                 :          8 :         req->cb_arg = req;
     669                 :          8 :         req->user_cb_fn = cb_fn;
     670                 :          8 :         req->user_cb_arg = cb_arg;
     671                 :            : 
     672                 :          8 :         cmd = &req->cmd;
     673                 :          8 :         cmd->opc = SPDK_NVME_OPC_ABORT;
     674                 :          8 :         cmd->cdw10_bits.abort.sqid = qpair->id;
     675                 :          8 :         cmd->cdw10_bits.abort.cid = cid;
     676                 :            : 
     677                 :          8 :         rc = _nvme_ctrlr_submit_abort_request(ctrlr, req);
     678                 :            : 
     679                 :          8 :         nvme_ctrlr_unlock(ctrlr);
     680                 :          8 :         return rc;
     681                 :            : }
     682                 :            : 
     683                 :            : static void
     684                 :     323207 : nvme_complete_abort_request(void *ctx, const struct spdk_nvme_cpl *cpl)
     685                 :            : {
     686                 :     323207 :         struct nvme_request *req = ctx;
     687                 :     323207 :         struct nvme_request *parent = req->parent;
     688                 :            :         struct spdk_nvme_ctrlr *ctrlr;
     689                 :            : 
     690                 :     323207 :         ctrlr = req->qpair->ctrlr;
     691                 :            : 
     692         [ -  + ]:     323207 :         assert(ctrlr->outstanding_aborts > 0);
     693                 :     323207 :         ctrlr->outstanding_aborts--;
     694                 :     323207 :         nvme_ctrlr_retry_queued_abort(ctrlr);
     695                 :            : 
     696                 :     323207 :         nvme_request_remove_child(parent, req);
     697                 :            : 
     698   [ +  -  +  -  :     323207 :         if (!spdk_nvme_cpl_is_abort_success(cpl)) {
                   +  + ]
     699                 :     300035 :                 parent->parent_status.cdw0 |= 1U;
     700                 :            :         }
     701                 :            : 
     702         [ +  - ]:     323207 :         if (parent->num_children == 0) {
     703                 :     323207 :                 nvme_complete_request(parent->cb_fn, parent->cb_arg, parent->qpair,
     704                 :            :                                       parent, &parent->parent_status);
     705                 :            :         }
     706                 :     323207 : }
     707                 :            : 
     708                 :            : static int
     709                 :   20845438 : nvme_request_add_abort(struct nvme_request *req, void *arg)
     710                 :            : {
     711                 :   20845438 :         struct nvme_request *parent = arg;
     712                 :            :         struct nvme_request *child;
     713                 :            :         void *cmd_cb_arg;
     714                 :            : 
     715                 :   20845438 :         cmd_cb_arg = parent->user_cb_arg;
     716                 :            : 
     717         [ +  + ]:   20845438 :         if (req->cb_arg != cmd_cb_arg &&
     718   [ -  +  -  - ]:   20522183 :             (req->parent == NULL || req->parent->cb_arg != cmd_cb_arg)) {
     719                 :   20522183 :                 return 0;
     720                 :            :         }
     721                 :            : 
     722                 :     323255 :         child = nvme_allocate_request_null(parent->qpair->ctrlr->adminq,
     723                 :            :                                            nvme_complete_abort_request, NULL);
     724         [ +  + ]:     323255 :         if (child == NULL) {
     725                 :         44 :                 return -ENOMEM;
     726                 :            :         }
     727                 :            : 
     728                 :     323211 :         child->cb_arg = child;
     729                 :            : 
     730                 :     323211 :         child->cmd.opc = SPDK_NVME_OPC_ABORT;
     731                 :            :         /* Copy SQID from the parent. */
     732                 :     323211 :         child->cmd.cdw10_bits.abort.sqid = parent->cmd.cdw10_bits.abort.sqid;
     733                 :     323211 :         child->cmd.cdw10_bits.abort.cid = req->cmd.cid;
     734                 :            : 
     735                 :     323211 :         child->parent = parent;
     736                 :            : 
     737                 :     323211 :         TAILQ_INSERT_TAIL(&parent->children, child, child_tailq);
     738                 :     323211 :         parent->num_children++;
     739                 :            : 
     740                 :     323211 :         return 0;
     741                 :            : }
     742                 :            : 
     743                 :            : int
     744                 :     896332 : spdk_nvme_ctrlr_cmd_abort_ext(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_qpair *qpair,
     745                 :            :                               void *cmd_cb_arg,
     746                 :            :                               spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     747                 :            : {
     748                 :     896332 :         int rc = 0;
     749                 :            :         struct nvme_request *parent, *child, *tmp;
     750                 :     896332 :         bool child_failed = false;
     751                 :     896332 :         int aborted = 0;
     752                 :            : 
     753         [ -  + ]:     896332 :         if (cmd_cb_arg == NULL) {
     754                 :          0 :                 return -EINVAL;
     755                 :            :         }
     756                 :            : 
     757                 :     896332 :         nvme_ctrlr_lock(ctrlr);
     758                 :            : 
     759         [ -  + ]:     896332 :         if (qpair == NULL) {
     760                 :          0 :                 qpair = ctrlr->adminq;
     761                 :            :         }
     762                 :            : 
     763                 :     896332 :         parent = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     764         [ +  + ]:     896332 :         if (parent == NULL) {
     765                 :     485563 :                 nvme_ctrlr_unlock(ctrlr);
     766                 :            : 
     767                 :     485563 :                 return -ENOMEM;
     768                 :            :         }
     769                 :            : 
     770                 :     410769 :         TAILQ_INIT(&parent->children);
     771                 :     410769 :         parent->num_children = 0;
     772                 :            : 
     773                 :     410769 :         parent->cmd.opc = SPDK_NVME_OPC_ABORT;
     774         [ -  + ]:     410769 :         memset(&parent->parent_status, 0, sizeof(struct spdk_nvme_cpl));
     775                 :            : 
     776                 :            :         /* Hold SQID that the requests to abort are associated with.
     777                 :            :          * This will be copied to the children.
     778                 :            :          *
     779                 :            :          * CID is not set here because the parent is not submitted directly
     780                 :            :          * and CID is not determined until request to abort is found.
     781                 :            :          */
     782                 :     410769 :         parent->cmd.cdw10_bits.abort.sqid = qpair->id;
     783                 :            : 
     784                 :            :         /* This is used to find request to abort. */
     785                 :     410769 :         parent->user_cb_arg = cmd_cb_arg;
     786                 :            : 
     787                 :            :         /* Add an abort request for each outstanding request which has cmd_cb_arg
     788                 :            :          * as its callback context.
     789                 :            :          */
     790                 :     410769 :         rc = nvme_transport_qpair_iterate_requests(qpair, nvme_request_add_abort, parent);
     791         [ +  + ]:     410769 :         if (rc != 0) {
     792                 :            :                 /* Free abort requests already added. */
     793                 :         40 :                 child_failed = true;
     794                 :            :         }
     795                 :            : 
     796         [ +  + ]:     733976 :         TAILQ_FOREACH_SAFE(child, &parent->children, child_tailq, tmp) {
     797         [ +  - ]:     323207 :                 if (spdk_likely(!child_failed)) {
     798                 :     323207 :                         rc = _nvme_ctrlr_submit_abort_request(ctrlr, child);
     799         [ -  + ]:     323207 :                         if (spdk_unlikely(rc != 0)) {
     800                 :          0 :                                 child_failed = true;
     801                 :            :                         }
     802                 :            :                 } else {
     803                 :            :                         /* Free remaining abort requests. */
     804                 :          0 :                         nvme_request_remove_child(parent, child);
     805                 :          0 :                         nvme_free_request(child);
     806                 :            :                 }
     807                 :            :         }
     808                 :            : 
     809         [ +  + ]:     410769 :         if (spdk_likely(!child_failed)) {
     810                 :            :                 /* There is no error so far. Abort requests were submitted successfully
     811                 :            :                  * or there was no outstanding request to abort.
     812                 :            :                  *
     813                 :            :                  * Hence abort queued requests which has cmd_cb_arg as its callback
     814                 :            :                  * context next.
     815                 :            :                  */
     816                 :     410729 :                 aborted = nvme_qpair_abort_queued_reqs_with_cbarg(qpair, cmd_cb_arg);
     817         [ +  + ]:     410729 :                 if (parent->num_children == 0) {
     818                 :            :                         /* There was no outstanding request to abort. */
     819         [ +  - ]:      87522 :                         if (aborted > 0) {
     820                 :            :                                 /* The queued requests were successfully aborted. Hence
     821                 :            :                                  * complete the parent request with success synchronously.
     822                 :            :                                  */
     823                 :      87522 :                                 nvme_complete_request(parent->cb_fn, parent->cb_arg, parent->qpair,
     824                 :            :                                                       parent, &parent->parent_status);
     825                 :            :                         } else {
     826                 :            :                                 /* There was no queued request to abort. */
     827                 :          0 :                                 rc = -ENOENT;
     828                 :            :                         }
     829                 :            :                 }
     830                 :            :         } else {
     831                 :            :                 /* Failed to add or submit abort request. */
     832         [ -  + ]:         40 :                 if (parent->num_children != 0) {
     833                 :            :                         /* Return success since we must wait for those children
     834                 :            :                          * to complete but set the parent request to failure.
     835                 :            :                          */
     836                 :          0 :                         parent->parent_status.cdw0 |= 1U;
     837                 :          0 :                         rc = 0;
     838                 :            :                 }
     839                 :            :         }
     840                 :            : 
     841         [ +  + ]:     410769 :         if (rc != 0) {
     842                 :         40 :                 nvme_free_request(parent);
     843                 :            :         }
     844                 :            : 
     845                 :     410769 :         nvme_ctrlr_unlock(ctrlr);
     846                 :     410769 :         return rc;
     847                 :            : }
     848                 :            : 
     849                 :            : int
     850                 :          4 : nvme_ctrlr_cmd_fw_commit(struct spdk_nvme_ctrlr *ctrlr,
     851                 :            :                          const struct spdk_nvme_fw_commit *fw_commit,
     852                 :            :                          spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     853                 :            : {
     854                 :            :         struct nvme_request *req;
     855                 :            :         struct spdk_nvme_cmd *cmd;
     856                 :            :         int rc;
     857                 :            : 
     858                 :          4 :         nvme_ctrlr_lock(ctrlr);
     859                 :          4 :         req = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     860         [ -  + ]:          4 :         if (req == NULL) {
     861                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     862                 :          0 :                 return -ENOMEM;
     863                 :            :         }
     864                 :            : 
     865                 :          4 :         cmd = &req->cmd;
     866                 :          4 :         cmd->opc = SPDK_NVME_OPC_FIRMWARE_COMMIT;
     867                 :          4 :         memcpy(&cmd->cdw10, fw_commit, sizeof(uint32_t));
     868                 :            : 
     869                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     870                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     871                 :            : 
     872                 :          4 :         return rc;
     873                 :            : 
     874                 :            : }
     875                 :            : 
     876                 :            : int
     877                 :          4 : nvme_ctrlr_cmd_fw_image_download(struct spdk_nvme_ctrlr *ctrlr,
     878                 :            :                                  uint32_t size, uint32_t offset, void *payload,
     879                 :            :                                  spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     880                 :            : {
     881                 :            :         struct nvme_request *req;
     882                 :            :         struct spdk_nvme_cmd *cmd;
     883                 :            :         int rc;
     884                 :            : 
     885                 :          4 :         nvme_ctrlr_lock(ctrlr);
     886                 :          4 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, size, cb_fn, cb_arg, true);
     887         [ -  + ]:          4 :         if (req == NULL) {
     888                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     889                 :          0 :                 return -ENOMEM;
     890                 :            :         }
     891                 :            : 
     892                 :          4 :         cmd = &req->cmd;
     893                 :          4 :         cmd->opc = SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD;
     894                 :          4 :         cmd->cdw10 = spdk_nvme_bytes_to_numd(size);
     895                 :          4 :         cmd->cdw11 = offset >> 2;
     896                 :            : 
     897                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     898                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     899                 :            : 
     900                 :          4 :         return rc;
     901                 :            : }
     902                 :            : 
     903                 :            : int
     904                 :        201 : spdk_nvme_ctrlr_cmd_security_receive(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
     905                 :            :                                      uint16_t spsp, uint8_t nssf, void *payload,
     906                 :            :                                      uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     907                 :            : {
     908                 :            :         struct nvme_request *req;
     909                 :            :         struct spdk_nvme_cmd *cmd;
     910                 :            :         int rc;
     911                 :            : 
     912                 :        201 :         nvme_ctrlr_lock(ctrlr);
     913                 :        201 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size,
     914                 :            :                                               cb_fn, cb_arg, false);
     915         [ +  + ]:        201 :         if (req == NULL) {
     916                 :          4 :                 nvme_ctrlr_unlock(ctrlr);
     917                 :          4 :                 return -ENOMEM;
     918                 :            :         }
     919                 :            : 
     920                 :        197 :         cmd = &req->cmd;
     921                 :        197 :         cmd->opc = SPDK_NVME_OPC_SECURITY_RECEIVE;
     922                 :        197 :         cmd->cdw10_bits.sec_send_recv.nssf = nssf;
     923                 :        197 :         cmd->cdw10_bits.sec_send_recv.spsp0 = (uint8_t)spsp;
     924                 :        197 :         cmd->cdw10_bits.sec_send_recv.spsp1 = (uint8_t)(spsp >> 8);
     925                 :        197 :         cmd->cdw10_bits.sec_send_recv.secp = secp;
     926                 :        197 :         cmd->cdw11 = payload_size;
     927                 :            : 
     928                 :        197 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     929                 :        197 :         nvme_ctrlr_unlock(ctrlr);
     930                 :            : 
     931                 :        197 :         return rc;
     932                 :            : }
     933                 :            : 
     934                 :            : int
     935                 :         10 : spdk_nvme_ctrlr_cmd_security_send(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
     936                 :            :                                   uint16_t spsp, uint8_t nssf, void *payload,
     937                 :            :                                   uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     938                 :            : {
     939                 :            :         struct nvme_request *req;
     940                 :            :         struct spdk_nvme_cmd *cmd;
     941                 :            :         int rc;
     942                 :            : 
     943                 :         10 :         nvme_ctrlr_lock(ctrlr);
     944                 :         10 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size,
     945                 :            :                                               cb_fn, cb_arg, true);
     946         [ +  + ]:         10 :         if (req == NULL) {
     947                 :          4 :                 nvme_ctrlr_unlock(ctrlr);
     948                 :          4 :                 return -ENOMEM;
     949                 :            :         }
     950                 :            : 
     951                 :          6 :         cmd = &req->cmd;
     952                 :          6 :         cmd->opc = SPDK_NVME_OPC_SECURITY_SEND;
     953                 :          6 :         cmd->cdw10_bits.sec_send_recv.nssf = nssf;
     954                 :          6 :         cmd->cdw10_bits.sec_send_recv.spsp0 = (uint8_t)spsp;
     955                 :          6 :         cmd->cdw10_bits.sec_send_recv.spsp1 = (uint8_t)(spsp >> 8);
     956                 :          6 :         cmd->cdw10_bits.sec_send_recv.secp = secp;
     957                 :          6 :         cmd->cdw11 = payload_size;
     958                 :            : 
     959                 :          6 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     960                 :          6 :         nvme_ctrlr_unlock(ctrlr);
     961                 :            : 
     962                 :          6 :         return rc;
     963                 :            : }
     964                 :            : 
     965                 :            : int
     966                 :          4 : nvme_ctrlr_cmd_sanitize(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
     967                 :            :                         struct spdk_nvme_sanitize *sanitize, uint32_t cdw11,
     968                 :            :                         spdk_nvme_cmd_cb cb_fn, void *cb_arg)
     969                 :            : {
     970                 :            :         struct nvme_request *req;
     971                 :            :         struct spdk_nvme_cmd *cmd;
     972                 :            :         int rc;
     973                 :            : 
     974                 :          4 :         nvme_ctrlr_lock(ctrlr);
     975                 :          4 :         req = nvme_allocate_request_null(ctrlr->adminq, cb_fn, cb_arg);
     976         [ -  + ]:          4 :         if (req == NULL) {
     977                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
     978                 :          0 :                 return -ENOMEM;
     979                 :            :         }
     980                 :            : 
     981                 :          4 :         cmd = &req->cmd;
     982                 :          4 :         cmd->opc = SPDK_NVME_OPC_SANITIZE;
     983                 :          4 :         cmd->nsid = nsid;
     984                 :          4 :         cmd->cdw11 = cdw11;
     985                 :          4 :         memcpy(&cmd->cdw10, sanitize, sizeof(cmd->cdw10));
     986                 :            : 
     987                 :          4 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
     988                 :          4 :         nvme_ctrlr_unlock(ctrlr);
     989                 :            : 
     990                 :          4 :         return rc;
     991                 :            : }
     992                 :            : 
     993                 :            : static int
     994                 :          8 : nvme_ctrlr_cmd_directive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
     995                 :            :                          uint32_t doper, uint32_t dtype, uint32_t dspec,
     996                 :            :                          void *payload, uint32_t payload_size, uint32_t cdw12,
     997                 :            :                          uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
     998                 :            :                          uint16_t opc_type, bool host_to_ctrlr)
     999                 :            : {
    1000                 :          8 :         struct nvme_request *req = NULL;
    1001                 :          8 :         struct spdk_nvme_cmd *cmd = NULL;
    1002                 :            :         int rc;
    1003                 :            : 
    1004                 :          8 :         nvme_ctrlr_lock(ctrlr);
    1005                 :          8 :         req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size,
    1006                 :            :                                               cb_fn, cb_arg, host_to_ctrlr);
    1007         [ -  + ]:          8 :         if (req == NULL) {
    1008                 :          0 :                 nvme_ctrlr_unlock(ctrlr);
    1009                 :          0 :                 return -ENOMEM;
    1010                 :            :         }
    1011                 :          8 :         cmd = &req->cmd;
    1012                 :          8 :         cmd->opc = opc_type;
    1013                 :          8 :         cmd->nsid = nsid;
    1014                 :            : 
    1015         [ -  + ]:          8 :         if ((payload_size >> 2) > 0) {
    1016                 :          0 :                 cmd->cdw10 = (payload_size >> 2) - 1;
    1017                 :            :         }
    1018                 :          8 :         cmd->cdw11_bits.directive.doper = doper;
    1019                 :          8 :         cmd->cdw11_bits.directive.dtype = dtype;
    1020                 :          8 :         cmd->cdw11_bits.directive.dspec = dspec;
    1021                 :          8 :         cmd->cdw12 = cdw12;
    1022                 :          8 :         cmd->cdw13 = cdw13;
    1023                 :          8 :         rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
    1024                 :          8 :         nvme_ctrlr_unlock(ctrlr);
    1025                 :            : 
    1026                 :          8 :         return rc;
    1027                 :            : }
    1028                 :            : 
    1029                 :            : int
    1030                 :          4 : spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
    1031                 :            :                                    uint32_t doper, uint32_t dtype, uint32_t dspec,
    1032                 :            :                                    void *payload, uint32_t payload_size, uint32_t cdw12,
    1033                 :            :                                    uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1034                 :            : {
    1035                 :          4 :         return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
    1036                 :            :                                         payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
    1037                 :            :                                         SPDK_NVME_OPC_DIRECTIVE_SEND, true);
    1038                 :            : }
    1039                 :            : 
    1040                 :            : int
    1041                 :          4 : spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
    1042                 :            :                                       uint32_t doper, uint32_t dtype, uint32_t dspec,
    1043                 :            :                                       void *payload, uint32_t payload_size, uint32_t cdw12,
    1044                 :            :                                       uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
    1045                 :            : {
    1046                 :          4 :         return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
    1047                 :            :                                         payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
    1048                 :            :                                         SPDK_NVME_OPC_DIRECTIVE_RECEIVE, false);
    1049                 :            : }

Generated by: LCOV version 1.14