The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/nvme/nvme_ctrlr_cmd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (C) 2012-2013 Intel Corporation
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "nvme_private.h"
   33 
   34 void
   35 nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr, void *payload,
   36         nvme_cb_fn_t cb_fn, void *cb_arg)
   37 {
   38         struct nvme_request *req;
   39         struct nvme_command *cmd;
   40 
   41         req = nvme_allocate_request_vaddr(payload,
   42             sizeof(struct nvme_controller_data), cb_fn, cb_arg);
   43 
   44         cmd = &req->cmd;
   45         cmd->opc = NVME_OPC_IDENTIFY;
   46 
   47         /*
   48          * TODO: create an identify command data structure, which
   49          *  includes this CNS bit in cdw10.
   50          */
   51         cmd->cdw10 = htole32(1);
   52 
   53         nvme_ctrlr_submit_admin_request(ctrlr, req);
   54 }
   55 
   56 void
   57 nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr, uint32_t nsid,
   58         void *payload, nvme_cb_fn_t cb_fn, void *cb_arg)
   59 {
   60         struct nvme_request *req;
   61         struct nvme_command *cmd;
   62 
   63         req = nvme_allocate_request_vaddr(payload,
   64             sizeof(struct nvme_namespace_data), cb_fn, cb_arg);
   65 
   66         cmd = &req->cmd;
   67         cmd->opc = NVME_OPC_IDENTIFY;
   68 
   69         /*
   70          * TODO: create an identify command data structure
   71          */
   72         cmd->nsid = htole32(nsid);
   73 
   74         nvme_ctrlr_submit_admin_request(ctrlr, req);
   75 }
   76 
   77 void
   78 nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
   79     struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
   80 {
   81         struct nvme_request *req;
   82         struct nvme_command *cmd;
   83 
   84         req = nvme_allocate_request_null(cb_fn, cb_arg);
   85 
   86         cmd = &req->cmd;
   87         cmd->opc = NVME_OPC_CREATE_IO_CQ;
   88 
   89         /*
   90          * TODO: create a create io completion queue command data
   91          *  structure.
   92          */
   93         cmd->cdw10 = htole32(((io_que->num_entries-1) << 16) | io_que->id);
   94         /* 0x3 = interrupts enabled | physically contiguous */
   95         cmd->cdw11 = htole32((io_que->vector << 16) | 0x3);
   96         cmd->prp1 = htole64(io_que->cpl_bus_addr);
   97 
   98         nvme_ctrlr_submit_admin_request(ctrlr, req);
   99 }
  100 
  101 void
  102 nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
  103     struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
  104 {
  105         struct nvme_request *req;
  106         struct nvme_command *cmd;
  107 
  108         req = nvme_allocate_request_null(cb_fn, cb_arg);
  109 
  110         cmd = &req->cmd;
  111         cmd->opc = NVME_OPC_CREATE_IO_SQ;
  112 
  113         /*
  114          * TODO: create a create io submission queue command data
  115          *  structure.
  116          */
  117         cmd->cdw10 = htole32(((io_que->num_entries-1) << 16) | io_que->id);
  118         /* 0x1 = physically contiguous */
  119         cmd->cdw11 = htole32((io_que->id << 16) | 0x1);
  120         cmd->prp1 = htole64(io_que->cmd_bus_addr);
  121 
  122         nvme_ctrlr_submit_admin_request(ctrlr, req);
  123 }
  124 
  125 void
  126 nvme_ctrlr_cmd_delete_io_cq(struct nvme_controller *ctrlr,
  127     struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
  128 {
  129         struct nvme_request *req;
  130         struct nvme_command *cmd;
  131 
  132         req = nvme_allocate_request_null(cb_fn, cb_arg);
  133 
  134         cmd = &req->cmd;
  135         cmd->opc = NVME_OPC_DELETE_IO_CQ;
  136 
  137         /*
  138          * TODO: create a delete io completion queue command data
  139          *  structure.
  140          */
  141         cmd->cdw10 = htole32(io_que->id);
  142 
  143         nvme_ctrlr_submit_admin_request(ctrlr, req);
  144 }
  145 
  146 void
  147 nvme_ctrlr_cmd_delete_io_sq(struct nvme_controller *ctrlr,
  148     struct nvme_qpair *io_que, nvme_cb_fn_t cb_fn, void *cb_arg)
  149 {
  150         struct nvme_request *req;
  151         struct nvme_command *cmd;
  152 
  153         req = nvme_allocate_request_null(cb_fn, cb_arg);
  154 
  155         cmd = &req->cmd;
  156         cmd->opc = NVME_OPC_DELETE_IO_SQ;
  157 
  158         /*
  159          * TODO: create a delete io submission queue command data
  160          *  structure.
  161          */
  162         cmd->cdw10 = htole32(io_que->id);
  163 
  164         nvme_ctrlr_submit_admin_request(ctrlr, req);
  165 }
  166 
  167 void
  168 nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr, uint8_t feature,
  169     uint32_t cdw11, uint32_t cdw12, uint32_t cdw13, uint32_t cdw14,
  170     uint32_t cdw15, void *payload, uint32_t payload_size,
  171     nvme_cb_fn_t cb_fn, void *cb_arg)
  172 {
  173         struct nvme_request *req;
  174         struct nvme_command *cmd;
  175 
  176         req = nvme_allocate_request_null(cb_fn, cb_arg);
  177 
  178         cmd = &req->cmd;
  179         cmd->opc = NVME_OPC_SET_FEATURES;
  180         cmd->cdw10 = htole32(feature);
  181         cmd->cdw11 = htole32(cdw11);
  182         cmd->cdw12 = htole32(cdw12);
  183         cmd->cdw13 = htole32(cdw13);
  184         cmd->cdw14 = htole32(cdw14);
  185         cmd->cdw15 = htole32(cdw15);
  186 
  187         nvme_ctrlr_submit_admin_request(ctrlr, req);
  188 }
  189 
  190 void
  191 nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr, uint8_t feature,
  192     uint32_t cdw11, void *payload, uint32_t payload_size,
  193     nvme_cb_fn_t cb_fn, void *cb_arg)
  194 {
  195         struct nvme_request *req;
  196         struct nvme_command *cmd;
  197 
  198         req = nvme_allocate_request_null(cb_fn, cb_arg);
  199 
  200         cmd = &req->cmd;
  201         cmd->opc = NVME_OPC_GET_FEATURES;
  202         cmd->cdw10 = htole32(feature);
  203         cmd->cdw11 = htole32(cdw11);
  204 
  205         nvme_ctrlr_submit_admin_request(ctrlr, req);
  206 }
  207 
  208 void
  209 nvme_ctrlr_cmd_set_num_queues(struct nvme_controller *ctrlr,
  210     uint32_t num_queues, nvme_cb_fn_t cb_fn, void *cb_arg)
  211 {
  212         uint32_t cdw11;
  213 
  214         cdw11 = ((num_queues - 1) << 16) | (num_queues - 1);
  215         nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_NUMBER_OF_QUEUES, cdw11,
  216             0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
  217 }
  218 
  219 void
  220 nvme_ctrlr_cmd_set_async_event_config(struct nvme_controller *ctrlr,
  221     uint32_t state, nvme_cb_fn_t cb_fn, void *cb_arg)
  222 {
  223         uint32_t cdw11;
  224 
  225         cdw11 = state;
  226         nvme_ctrlr_cmd_set_feature(ctrlr,
  227             NVME_FEAT_ASYNC_EVENT_CONFIGURATION, cdw11, 0, 0, 0, 0, NULL, 0,
  228             cb_fn, cb_arg);
  229 }
  230 
  231 void
  232 nvme_ctrlr_cmd_set_interrupt_coalescing(struct nvme_controller *ctrlr,
  233     uint32_t microseconds, uint32_t threshold, nvme_cb_fn_t cb_fn, void *cb_arg)
  234 {
  235         uint32_t cdw11;
  236 
  237         if ((microseconds/100) >= 0x100) {
  238                 nvme_printf(ctrlr, "invalid coal time %d, disabling\n",
  239                     microseconds);
  240                 microseconds = 0;
  241                 threshold = 0;
  242         }
  243 
  244         if (threshold >= 0x100) {
  245                 nvme_printf(ctrlr, "invalid threshold %d, disabling\n",
  246                     threshold);
  247                 threshold = 0;
  248                 microseconds = 0;
  249         }
  250 
  251         cdw11 = ((microseconds/100) << 8) | threshold;
  252         nvme_ctrlr_cmd_set_feature(ctrlr, NVME_FEAT_INTERRUPT_COALESCING, cdw11,
  253             0, 0, 0, 0, NULL, 0, cb_fn, cb_arg);
  254 }
  255 
  256 void
  257 nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr, uint8_t log_page,
  258     uint32_t nsid, void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn,
  259     void *cb_arg)
  260 {
  261         struct nvme_request *req;
  262         struct nvme_command *cmd;
  263 
  264         req = nvme_allocate_request_vaddr(payload, payload_size, cb_fn, cb_arg);
  265 
  266         cmd = &req->cmd;
  267         cmd->opc = NVME_OPC_GET_LOG_PAGE;
  268         cmd->nsid = htole32(nsid);
  269         cmd->cdw10 = ((payload_size/sizeof(uint32_t)) - 1) << 16;
  270         cmd->cdw10 |= log_page;
  271         cmd->cdw10 = htole32(cmd->cdw10);
  272 
  273         nvme_ctrlr_submit_admin_request(ctrlr, req);
  274 }
  275 
  276 void
  277 nvme_ctrlr_cmd_get_error_page(struct nvme_controller *ctrlr,
  278     struct nvme_error_information_entry *payload, uint32_t num_entries,
  279     nvme_cb_fn_t cb_fn, void *cb_arg)
  280 {
  281 
  282         KASSERT(num_entries > 0, ("%s called with num_entries==0\n", __func__));
  283 
  284         /* Controller's error log page entries is 0-based. */
  285         KASSERT(num_entries <= (ctrlr->cdata.elpe + 1),
  286             ("%s called with num_entries=%d but (elpe+1)=%d\n", __func__,
  287             num_entries, ctrlr->cdata.elpe + 1));
  288 
  289         if (num_entries > (ctrlr->cdata.elpe + 1))
  290                 num_entries = ctrlr->cdata.elpe + 1;
  291 
  292         nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_ERROR,
  293             NVME_GLOBAL_NAMESPACE_TAG, payload, sizeof(*payload) * num_entries,
  294             cb_fn, cb_arg);
  295 }
  296 
  297 void
  298 nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr,
  299     uint32_t nsid, struct nvme_health_information_page *payload,
  300     nvme_cb_fn_t cb_fn, void *cb_arg)
  301 {
  302 
  303         nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_HEALTH_INFORMATION,
  304             nsid, payload, sizeof(*payload), cb_fn, cb_arg);
  305 }
  306 
  307 void
  308 nvme_ctrlr_cmd_get_firmware_page(struct nvme_controller *ctrlr,
  309     struct nvme_firmware_page *payload, nvme_cb_fn_t cb_fn, void *cb_arg)
  310 {
  311 
  312         nvme_ctrlr_cmd_get_log_page(ctrlr, NVME_LOG_FIRMWARE_SLOT, 
  313             NVME_GLOBAL_NAMESPACE_TAG, payload, sizeof(*payload), cb_fn,
  314             cb_arg);
  315 }
  316 
  317 void
  318 nvme_ctrlr_cmd_abort(struct nvme_controller *ctrlr, uint16_t cid,
  319     uint16_t sqid, nvme_cb_fn_t cb_fn, void *cb_arg)
  320 {
  321         struct nvme_request *req;
  322         struct nvme_command *cmd;
  323 
  324         req = nvme_allocate_request_null(cb_fn, cb_arg);
  325 
  326         cmd = &req->cmd;
  327         cmd->opc = NVME_OPC_ABORT;
  328         cmd->cdw10 = htole32((cid << 16) | sqid);
  329 
  330         nvme_ctrlr_submit_admin_request(ctrlr, req);
  331 }

Cache object: 1a1d43a7463fb8b78c80d8b09491d62a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.