1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. All rights reserved. 5 * Copyright (c) 2020 Mellanox Technologies LTD. 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 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/nvmf_spec.h" 35 #include "spdk/string.h" 36 #include "nvme_internal.h" 37 #include "nvme_io_msg.h" 38 #include "nvme_uevent.h" 39 40 #define SPDK_NVME_DRIVER_NAME "spdk_nvme_driver" 41 42 struct nvme_driver *g_spdk_nvme_driver; 43 pid_t g_spdk_nvme_pid; 44 45 /* gross timeout of 180 seconds in milliseconds */ 46 static int g_nvme_driver_timeout_ms = 3 * 60 * 1000; 47 48 /* Per-process attached controller list */ 49 static TAILQ_HEAD(, spdk_nvme_ctrlr) g_nvme_attached_ctrlrs = 50 TAILQ_HEAD_INITIALIZER(g_nvme_attached_ctrlrs); 51 52 /* Returns true if ctrlr should be stored on the multi-process shared_attached_ctrlrs list */ 53 static bool 54 nvme_ctrlr_shared(const struct spdk_nvme_ctrlr *ctrlr) 55 { 56 return ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE; 57 } 58 59 void 60 nvme_ctrlr_connected(struct spdk_nvme_probe_ctx *probe_ctx, 61 struct spdk_nvme_ctrlr *ctrlr) 62 { 63 TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq); 64 } 65 66 int 67 spdk_nvme_detach(struct spdk_nvme_ctrlr *ctrlr) 68 { 69 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 70 71 nvme_ctrlr_proc_put_ref(ctrlr); 72 73 if (nvme_ctrlr_get_ref_count(ctrlr) == 0) { 74 nvme_io_msg_ctrlr_detach(ctrlr); 75 if (nvme_ctrlr_shared(ctrlr)) { 76 TAILQ_REMOVE(&g_spdk_nvme_driver->shared_attached_ctrlrs, ctrlr, tailq); 77 } else { 78 TAILQ_REMOVE(&g_nvme_attached_ctrlrs, ctrlr, tailq); 79 } 80 nvme_ctrlr_destruct(ctrlr); 81 } 82 83 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 84 return 0; 85 } 86 87 void 88 nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl) 89 { 90 struct nvme_completion_poll_status *status = arg; 91 92 if (status->timed_out) { 93 /* There is no routine waiting for the completion of this request, free allocated memory */ 94 free(status); 95 return; 96 } 97 98 /* 99 * Copy status into the argument passed by the caller, so that 100 * the caller can check the status to determine if the 101 * the request passed or failed. 102 */ 103 memcpy(&status->cpl, cpl, sizeof(*cpl)); 104 status->done = true; 105 } 106 107 /** 108 * Poll qpair for completions until a command completes. 109 * 110 * \param qpair queue to poll 111 * \param status completion status. The user must fill this structure with zeroes before calling 112 * this function 113 * \param robust_mutex optional robust mutex to lock while polling qpair 114 * 115 * \return 0 if command completed without error, 116 * -EIO if command completed with error, 117 * -ECANCELED if command is not completed due to transport/device error 118 * 119 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback 120 * and status as the callback argument. 121 */ 122 int 123 nvme_wait_for_completion_robust_lock( 124 struct spdk_nvme_qpair *qpair, 125 struct nvme_completion_poll_status *status, 126 pthread_mutex_t *robust_mutex) 127 { 128 int rc; 129 130 while (status->done == false) { 131 if (robust_mutex) { 132 nvme_robust_mutex_lock(robust_mutex); 133 } 134 135 rc = spdk_nvme_qpair_process_completions(qpair, 0); 136 137 if (robust_mutex) { 138 nvme_robust_mutex_unlock(robust_mutex); 139 } 140 141 if (rc < 0) { 142 status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; 143 status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION; 144 if (status->done == false) { 145 status->timed_out = true; 146 } 147 return -ECANCELED; 148 } 149 } 150 151 return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0; 152 } 153 154 int 155 nvme_wait_for_completion(struct spdk_nvme_qpair *qpair, 156 struct nvme_completion_poll_status *status) 157 { 158 return nvme_wait_for_completion_robust_lock(qpair, status, NULL); 159 } 160 161 /** 162 * Poll qpair for completions until a command completes. 163 * 164 * \param qpair queue to poll 165 * \param status completion status. The user must fill this structure with zeroes before calling 166 * this function 167 * \param timeout_in_secs optional timeout 168 * 169 * \return 0 if command completed without error, 170 * -EIO if command completed with error, 171 * -ECANCELED if command is not completed due to transport/device error or time expired 172 * 173 * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback 174 * and status as the callback argument. 175 */ 176 int 177 nvme_wait_for_completion_timeout(struct spdk_nvme_qpair *qpair, 178 struct nvme_completion_poll_status *status, 179 uint64_t timeout_in_secs) 180 { 181 uint64_t timeout_tsc = 0; 182 int rc = 0; 183 184 if (timeout_in_secs) { 185 timeout_tsc = spdk_get_ticks() + timeout_in_secs * spdk_get_ticks_hz(); 186 } 187 188 while (status->done == false) { 189 rc = spdk_nvme_qpair_process_completions(qpair, 0); 190 191 if (rc < 0) { 192 status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; 193 status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION; 194 break; 195 } 196 if (timeout_tsc && spdk_get_ticks() > timeout_tsc) { 197 break; 198 } 199 } 200 201 if (status->done == false || rc < 0) { 202 if (status->done == false) { 203 status->timed_out = true; 204 } 205 return -ECANCELED; 206 } 207 208 return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0; 209 } 210 211 static void 212 nvme_user_copy_cmd_complete(void *arg, const struct spdk_nvme_cpl *cpl) 213 { 214 struct nvme_request *req = arg; 215 enum spdk_nvme_data_transfer xfer; 216 217 if (req->user_buffer && req->payload_size) { 218 /* Copy back to the user buffer and free the contig buffer */ 219 assert(nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_CONTIG); 220 xfer = spdk_nvme_opc_get_data_transfer(req->cmd.opc); 221 if (xfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST || 222 xfer == SPDK_NVME_DATA_BIDIRECTIONAL) { 223 assert(req->pid == getpid()); 224 memcpy(req->user_buffer, req->payload.contig_or_cb_arg, req->payload_size); 225 } 226 227 spdk_free(req->payload.contig_or_cb_arg); 228 } 229 230 /* Call the user's original callback now that the buffer has been copied */ 231 req->user_cb_fn(req->user_cb_arg, cpl); 232 } 233 234 /** 235 * Allocate a request as well as a DMA-capable buffer to copy to/from the user's buffer. 236 * 237 * This is intended for use in non-fast-path functions (admin commands, reservations, etc.) 238 * where the overhead of a copy is not a problem. 239 */ 240 struct nvme_request * 241 nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair, 242 void *buffer, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, 243 void *cb_arg, bool host_to_controller) 244 { 245 struct nvme_request *req; 246 void *dma_buffer = NULL; 247 248 if (buffer && payload_size) { 249 dma_buffer = spdk_zmalloc(payload_size, 4096, NULL, 250 SPDK_ENV_SOCKET_ID_ANY, SPDK_MALLOC_DMA); 251 if (!dma_buffer) { 252 return NULL; 253 } 254 255 if (host_to_controller) { 256 memcpy(dma_buffer, buffer, payload_size); 257 } 258 } 259 260 req = nvme_allocate_request_contig(qpair, dma_buffer, payload_size, nvme_user_copy_cmd_complete, 261 NULL); 262 if (!req) { 263 spdk_free(dma_buffer); 264 return NULL; 265 } 266 267 req->user_cb_fn = cb_fn; 268 req->user_cb_arg = cb_arg; 269 req->user_buffer = buffer; 270 req->cb_arg = req; 271 272 return req; 273 } 274 275 /** 276 * Check if a request has exceeded the controller timeout. 277 * 278 * \param req request to check for timeout. 279 * \param cid command ID for command submitted by req (will be passed to timeout_cb_fn) 280 * \param active_proc per-process data for the controller associated with req 281 * \param now_tick current time from spdk_get_ticks() 282 * \return 0 if requests submitted more recently than req should still be checked for timeouts, or 283 * 1 if requests newer than req need not be checked. 284 * 285 * The request's timeout callback will be called if needed; the caller is only responsible for 286 * calling this function on each outstanding request. 287 */ 288 int 289 nvme_request_check_timeout(struct nvme_request *req, uint16_t cid, 290 struct spdk_nvme_ctrlr_process *active_proc, 291 uint64_t now_tick) 292 { 293 struct spdk_nvme_qpair *qpair = req->qpair; 294 struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr; 295 296 assert(active_proc->timeout_cb_fn != NULL); 297 298 if (req->timed_out || req->submit_tick == 0) { 299 return 0; 300 } 301 302 if (req->pid != g_spdk_nvme_pid) { 303 return 0; 304 } 305 306 if (nvme_qpair_is_admin_queue(qpair) && 307 req->cmd.opc == SPDK_NVME_OPC_ASYNC_EVENT_REQUEST) { 308 return 0; 309 } 310 311 if (req->submit_tick + active_proc->timeout_ticks > now_tick) { 312 return 1; 313 } 314 315 req->timed_out = true; 316 317 /* 318 * We don't want to expose the admin queue to the user, 319 * so when we're timing out admin commands set the 320 * qpair to NULL. 321 */ 322 active_proc->timeout_cb_fn(active_proc->timeout_cb_arg, ctrlr, 323 nvme_qpair_is_admin_queue(qpair) ? NULL : qpair, 324 cid); 325 return 0; 326 } 327 328 int 329 nvme_robust_mutex_init_shared(pthread_mutex_t *mtx) 330 { 331 int rc = 0; 332 333 #ifdef __FreeBSD__ 334 pthread_mutex_init(mtx, NULL); 335 #else 336 pthread_mutexattr_t attr; 337 338 if (pthread_mutexattr_init(&attr)) { 339 return -1; 340 } 341 if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) || 342 pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) || 343 pthread_mutex_init(mtx, &attr)) { 344 rc = -1; 345 } 346 pthread_mutexattr_destroy(&attr); 347 #endif 348 349 return rc; 350 } 351 352 int 353 nvme_driver_init(void) 354 { 355 static pthread_mutex_t g_init_mutex = PTHREAD_MUTEX_INITIALIZER; 356 int ret = 0; 357 /* Any socket ID */ 358 int socket_id = -1; 359 360 /* Use a special process-private mutex to ensure the global 361 * nvme driver object (g_spdk_nvme_driver) gets initialized by 362 * only one thread. Once that object is established and its 363 * mutex is initialized, we can unlock this mutex and use that 364 * one instead. 365 */ 366 pthread_mutex_lock(&g_init_mutex); 367 368 /* Each process needs its own pid. */ 369 g_spdk_nvme_pid = getpid(); 370 371 /* 372 * Only one thread from one process will do this driver init work. 373 * The primary process will reserve the shared memory and do the 374 * initialization. 375 * The secondary process will lookup the existing reserved memory. 376 */ 377 if (spdk_process_is_primary()) { 378 /* The unique named memzone already reserved. */ 379 if (g_spdk_nvme_driver != NULL) { 380 pthread_mutex_unlock(&g_init_mutex); 381 return 0; 382 } else { 383 g_spdk_nvme_driver = spdk_memzone_reserve(SPDK_NVME_DRIVER_NAME, 384 sizeof(struct nvme_driver), socket_id, 385 SPDK_MEMZONE_NO_IOVA_CONTIG); 386 } 387 388 if (g_spdk_nvme_driver == NULL) { 389 SPDK_ERRLOG("primary process failed to reserve memory\n"); 390 pthread_mutex_unlock(&g_init_mutex); 391 return -1; 392 } 393 } else { 394 g_spdk_nvme_driver = spdk_memzone_lookup(SPDK_NVME_DRIVER_NAME); 395 396 /* The unique named memzone already reserved by the primary process. */ 397 if (g_spdk_nvme_driver != NULL) { 398 int ms_waited = 0; 399 400 /* Wait the nvme driver to get initialized. */ 401 while ((g_spdk_nvme_driver->initialized == false) && 402 (ms_waited < g_nvme_driver_timeout_ms)) { 403 ms_waited++; 404 nvme_delay(1000); /* delay 1ms */ 405 } 406 if (g_spdk_nvme_driver->initialized == false) { 407 SPDK_ERRLOG("timeout waiting for primary process to init\n"); 408 pthread_mutex_unlock(&g_init_mutex); 409 return -1; 410 } 411 } else { 412 SPDK_ERRLOG("primary process is not started yet\n"); 413 pthread_mutex_unlock(&g_init_mutex); 414 return -1; 415 } 416 417 pthread_mutex_unlock(&g_init_mutex); 418 return 0; 419 } 420 421 /* 422 * At this moment, only one thread from the primary process will do 423 * the g_spdk_nvme_driver initialization 424 */ 425 assert(spdk_process_is_primary()); 426 427 ret = nvme_robust_mutex_init_shared(&g_spdk_nvme_driver->lock); 428 if (ret != 0) { 429 SPDK_ERRLOG("failed to initialize mutex\n"); 430 spdk_memzone_free(SPDK_NVME_DRIVER_NAME); 431 pthread_mutex_unlock(&g_init_mutex); 432 return ret; 433 } 434 435 /* The lock in the shared g_spdk_nvme_driver object is now ready to 436 * be used - so we can unlock the g_init_mutex here. 437 */ 438 pthread_mutex_unlock(&g_init_mutex); 439 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 440 441 g_spdk_nvme_driver->initialized = false; 442 g_spdk_nvme_driver->hotplug_fd = nvme_uevent_connect(); 443 if (g_spdk_nvme_driver->hotplug_fd < 0) { 444 SPDK_DEBUGLOG(SPDK_LOG_NVME, "Failed to open uevent netlink socket\n"); 445 } 446 447 TAILQ_INIT(&g_spdk_nvme_driver->shared_attached_ctrlrs); 448 449 spdk_uuid_generate(&g_spdk_nvme_driver->default_extended_host_id); 450 451 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 452 453 return ret; 454 } 455 456 /* This function must only be called while holding g_spdk_nvme_driver->lock */ 457 int 458 nvme_ctrlr_probe(const struct spdk_nvme_transport_id *trid, 459 struct spdk_nvme_probe_ctx *probe_ctx, void *devhandle) 460 { 461 struct spdk_nvme_ctrlr *ctrlr; 462 struct spdk_nvme_ctrlr_opts opts; 463 464 assert(trid != NULL); 465 466 spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts)); 467 468 if (!probe_ctx->probe_cb || probe_ctx->probe_cb(probe_ctx->cb_ctx, trid, &opts)) { 469 ctrlr = nvme_get_ctrlr_by_trid_unsafe(trid); 470 if (ctrlr) { 471 /* This ctrlr already exists. 472 * Increase the ref count before calling attach_cb() as the user may 473 * call nvme_detach() immediately. */ 474 nvme_ctrlr_proc_get_ref(ctrlr); 475 476 if (probe_ctx->attach_cb) { 477 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 478 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 479 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 480 } 481 return 0; 482 } 483 484 ctrlr = nvme_transport_ctrlr_construct(trid, &opts, devhandle); 485 if (ctrlr == NULL) { 486 SPDK_ERRLOG("Failed to construct NVMe controller for SSD: %s\n", trid->traddr); 487 return -1; 488 } 489 ctrlr->remove_cb = probe_ctx->remove_cb; 490 ctrlr->cb_ctx = probe_ctx->cb_ctx; 491 492 if (ctrlr->quirks & NVME_QUIRK_MINIMUM_IO_QUEUE_SIZE && 493 ctrlr->opts.io_queue_size == DEFAULT_IO_QUEUE_SIZE) { 494 /* If the user specifically set an IO queue size different than the 495 * default, use that value. Otherwise overwrite with the quirked value. 496 * This allows this quirk to be overridden when necessary. 497 * However, cap.mqes still needs to be respected. 498 */ 499 ctrlr->opts.io_queue_size = spdk_min(DEFAULT_IO_QUEUE_SIZE_FOR_QUIRK, ctrlr->cap.bits.mqes + 1u); 500 } 501 502 nvme_qpair_set_state(ctrlr->adminq, NVME_QPAIR_ENABLED); 503 TAILQ_INSERT_TAIL(&probe_ctx->init_ctrlrs, ctrlr, tailq); 504 return 0; 505 } 506 507 return 1; 508 } 509 510 static int 511 nvme_ctrlr_poll_internal(struct spdk_nvme_ctrlr *ctrlr, 512 struct spdk_nvme_probe_ctx *probe_ctx) 513 { 514 int rc = 0; 515 516 rc = nvme_ctrlr_process_init(ctrlr); 517 518 if (rc) { 519 /* Controller failed to initialize. */ 520 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 521 SPDK_ERRLOG("Failed to initialize SSD: %s\n", ctrlr->trid.traddr); 522 nvme_ctrlr_fail(ctrlr, false); 523 nvme_ctrlr_destruct(ctrlr); 524 return rc; 525 } 526 527 if (ctrlr->state != NVME_CTRLR_STATE_READY) { 528 return 0; 529 } 530 531 STAILQ_INIT(&ctrlr->io_producers); 532 533 /* 534 * Controller has been initialized. 535 * Move it to the attached_ctrlrs list. 536 */ 537 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 538 539 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 540 if (nvme_ctrlr_shared(ctrlr)) { 541 TAILQ_INSERT_TAIL(&g_spdk_nvme_driver->shared_attached_ctrlrs, ctrlr, tailq); 542 } else { 543 TAILQ_INSERT_TAIL(&g_nvme_attached_ctrlrs, ctrlr, tailq); 544 } 545 546 /* 547 * Increase the ref count before calling attach_cb() as the user may 548 * call nvme_detach() immediately. 549 */ 550 nvme_ctrlr_proc_get_ref(ctrlr); 551 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 552 553 if (probe_ctx->attach_cb) { 554 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 555 return 0; 556 } 557 558 return 0; 559 } 560 561 static int 562 nvme_init_controllers(struct spdk_nvme_probe_ctx *probe_ctx) 563 { 564 int rc = 0; 565 566 while (true) { 567 rc = spdk_nvme_probe_poll_async(probe_ctx); 568 if (rc != -EAGAIN) { 569 return rc; 570 } 571 } 572 573 return rc; 574 } 575 576 /* This function must not be called while holding g_spdk_nvme_driver->lock */ 577 static struct spdk_nvme_ctrlr * 578 nvme_get_ctrlr_by_trid(const struct spdk_nvme_transport_id *trid) 579 { 580 struct spdk_nvme_ctrlr *ctrlr; 581 582 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 583 ctrlr = nvme_get_ctrlr_by_trid_unsafe(trid); 584 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 585 586 return ctrlr; 587 } 588 589 /* This function must be called while holding g_spdk_nvme_driver->lock */ 590 struct spdk_nvme_ctrlr * 591 nvme_get_ctrlr_by_trid_unsafe(const struct spdk_nvme_transport_id *trid) 592 { 593 struct spdk_nvme_ctrlr *ctrlr; 594 595 /* Search per-process list */ 596 TAILQ_FOREACH(ctrlr, &g_nvme_attached_ctrlrs, tailq) { 597 if (spdk_nvme_transport_id_compare(&ctrlr->trid, trid) == 0) { 598 return ctrlr; 599 } 600 } 601 602 /* Search multi-process shared list */ 603 TAILQ_FOREACH(ctrlr, &g_spdk_nvme_driver->shared_attached_ctrlrs, tailq) { 604 if (spdk_nvme_transport_id_compare(&ctrlr->trid, trid) == 0) { 605 return ctrlr; 606 } 607 } 608 609 return NULL; 610 } 611 612 /* This function must only be called while holding g_spdk_nvme_driver->lock */ 613 static int 614 nvme_probe_internal(struct spdk_nvme_probe_ctx *probe_ctx, 615 bool direct_connect) 616 { 617 int rc; 618 struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp; 619 620 spdk_nvme_trid_populate_transport(&probe_ctx->trid, probe_ctx->trid.trtype); 621 if (!spdk_nvme_transport_available_by_name(probe_ctx->trid.trstring)) { 622 SPDK_ERRLOG("NVMe trtype %u not available\n", probe_ctx->trid.trtype); 623 return -1; 624 } 625 626 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 627 628 rc = nvme_transport_ctrlr_scan(probe_ctx, direct_connect); 629 if (rc != 0) { 630 SPDK_ERRLOG("NVMe ctrlr scan failed\n"); 631 TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) { 632 TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, tailq); 633 nvme_transport_ctrlr_destruct(ctrlr); 634 } 635 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 636 return -1; 637 } 638 639 /* 640 * Probe controllers on the shared_attached_ctrlrs list 641 */ 642 if (!spdk_process_is_primary() && (probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE)) { 643 TAILQ_FOREACH(ctrlr, &g_spdk_nvme_driver->shared_attached_ctrlrs, tailq) { 644 /* Do not attach other ctrlrs if user specify a valid trid */ 645 if ((strlen(probe_ctx->trid.traddr) != 0) && 646 (spdk_nvme_transport_id_compare(&probe_ctx->trid, &ctrlr->trid))) { 647 continue; 648 } 649 650 /* Do not attach if we failed to initialize it in this process */ 651 if (nvme_ctrlr_get_current_process(ctrlr) == NULL) { 652 continue; 653 } 654 655 nvme_ctrlr_proc_get_ref(ctrlr); 656 657 /* 658 * Unlock while calling attach_cb() so the user can call other functions 659 * that may take the driver lock, like nvme_detach(). 660 */ 661 if (probe_ctx->attach_cb) { 662 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 663 probe_ctx->attach_cb(probe_ctx->cb_ctx, &ctrlr->trid, ctrlr, &ctrlr->opts); 664 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 665 } 666 } 667 } 668 669 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 670 671 return 0; 672 } 673 674 static void 675 nvme_probe_ctx_init(struct spdk_nvme_probe_ctx *probe_ctx, 676 const struct spdk_nvme_transport_id *trid, 677 void *cb_ctx, 678 spdk_nvme_probe_cb probe_cb, 679 spdk_nvme_attach_cb attach_cb, 680 spdk_nvme_remove_cb remove_cb) 681 { 682 probe_ctx->trid = *trid; 683 probe_ctx->cb_ctx = cb_ctx; 684 probe_ctx->probe_cb = probe_cb; 685 probe_ctx->attach_cb = attach_cb; 686 probe_ctx->remove_cb = remove_cb; 687 TAILQ_INIT(&probe_ctx->init_ctrlrs); 688 } 689 690 int 691 spdk_nvme_probe(const struct spdk_nvme_transport_id *trid, void *cb_ctx, 692 spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb attach_cb, 693 spdk_nvme_remove_cb remove_cb) 694 { 695 struct spdk_nvme_transport_id trid_pcie; 696 struct spdk_nvme_probe_ctx *probe_ctx; 697 698 if (trid == NULL) { 699 memset(&trid_pcie, 0, sizeof(trid_pcie)); 700 spdk_nvme_trid_populate_transport(&trid_pcie, SPDK_NVME_TRANSPORT_PCIE); 701 trid = &trid_pcie; 702 } 703 704 probe_ctx = spdk_nvme_probe_async(trid, cb_ctx, probe_cb, 705 attach_cb, remove_cb); 706 if (!probe_ctx) { 707 SPDK_ERRLOG("Create probe context failed\n"); 708 return -1; 709 } 710 711 /* 712 * Keep going even if one or more nvme_attach() calls failed, 713 * but maintain the value of rc to signal errors when we return. 714 */ 715 return nvme_init_controllers(probe_ctx); 716 } 717 718 static bool 719 nvme_connect_probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 720 struct spdk_nvme_ctrlr_opts *opts) 721 { 722 struct spdk_nvme_ctrlr_opts *requested_opts = cb_ctx; 723 724 assert(requested_opts); 725 memcpy(opts, requested_opts, sizeof(*opts)); 726 727 return true; 728 } 729 730 static void 731 nvme_ctrlr_opts_init(struct spdk_nvme_ctrlr_opts *opts, 732 const struct spdk_nvme_ctrlr_opts *opts_user, 733 size_t opts_size_user) 734 { 735 assert(opts); 736 assert(opts_user); 737 738 spdk_nvme_ctrlr_get_default_ctrlr_opts(opts, opts_size_user); 739 740 #define FIELD_OK(field) \ 741 offsetof(struct spdk_nvme_ctrlr_opts, field) + sizeof(opts->field) <= (opts->opts_size) 742 743 if (FIELD_OK(num_io_queues)) { 744 opts->num_io_queues = opts_user->num_io_queues; 745 } 746 747 if (FIELD_OK(use_cmb_sqs)) { 748 opts->use_cmb_sqs = opts_user->use_cmb_sqs; 749 } 750 751 if (FIELD_OK(no_shn_notification)) { 752 opts->no_shn_notification = opts_user->no_shn_notification; 753 } 754 755 if (FIELD_OK(arb_mechanism)) { 756 opts->arb_mechanism = opts_user->arb_mechanism; 757 } 758 759 if (FIELD_OK(arbitration_burst)) { 760 opts->arbitration_burst = opts_user->arbitration_burst; 761 } 762 763 if (FIELD_OK(low_priority_weight)) { 764 opts->low_priority_weight = opts_user->low_priority_weight; 765 } 766 767 if (FIELD_OK(medium_priority_weight)) { 768 opts->medium_priority_weight = opts_user->medium_priority_weight; 769 } 770 771 if (FIELD_OK(high_priority_weight)) { 772 opts->high_priority_weight = opts_user->high_priority_weight; 773 } 774 775 if (FIELD_OK(keep_alive_timeout_ms)) { 776 opts->keep_alive_timeout_ms = opts_user->keep_alive_timeout_ms; 777 } 778 779 if (FIELD_OK(transport_retry_count)) { 780 opts->transport_retry_count = opts_user->transport_retry_count; 781 } 782 783 if (FIELD_OK(io_queue_size)) { 784 opts->io_queue_size = opts_user->io_queue_size; 785 } 786 787 if (FIELD_OK(hostnqn)) { 788 memcpy(opts->hostnqn, opts_user->hostnqn, sizeof(opts_user->hostnqn)); 789 } 790 791 if (FIELD_OK(io_queue_requests)) { 792 opts->io_queue_requests = opts_user->io_queue_requests; 793 } 794 795 if (FIELD_OK(src_addr)) { 796 memcpy(opts->src_addr, opts_user->src_addr, sizeof(opts_user->src_addr)); 797 } 798 799 if (FIELD_OK(src_svcid)) { 800 memcpy(opts->src_svcid, opts_user->src_svcid, sizeof(opts_user->src_svcid)); 801 } 802 803 if (FIELD_OK(host_id)) { 804 memcpy(opts->host_id, opts_user->host_id, sizeof(opts_user->host_id)); 805 } 806 if (FIELD_OK(extended_host_id)) { 807 memcpy(opts->extended_host_id, opts_user->extended_host_id, 808 sizeof(opts_user->extended_host_id)); 809 } 810 811 if (FIELD_OK(command_set)) { 812 opts->command_set = opts_user->command_set; 813 } 814 815 if (FIELD_OK(admin_timeout_ms)) { 816 opts->admin_timeout_ms = opts_user->admin_timeout_ms; 817 } 818 819 if (FIELD_OK(header_digest)) { 820 opts->header_digest = opts_user->header_digest; 821 } 822 823 if (FIELD_OK(data_digest)) { 824 opts->data_digest = opts_user->data_digest; 825 } 826 827 if (FIELD_OK(disable_error_logging)) { 828 opts->disable_error_logging = opts_user->disable_error_logging; 829 } 830 831 if (FIELD_OK(transport_ack_timeout)) { 832 opts->transport_ack_timeout = opts_user->transport_ack_timeout; 833 } 834 835 if (FIELD_OK(admin_queue_size)) { 836 opts->admin_queue_size = opts_user->admin_queue_size; 837 } 838 #undef FIELD_OK 839 } 840 841 struct spdk_nvme_ctrlr * 842 spdk_nvme_connect(const struct spdk_nvme_transport_id *trid, 843 const struct spdk_nvme_ctrlr_opts *opts, size_t opts_size) 844 { 845 int rc; 846 struct spdk_nvme_ctrlr *ctrlr = NULL; 847 struct spdk_nvme_probe_ctx *probe_ctx; 848 struct spdk_nvme_ctrlr_opts *opts_local_p = NULL; 849 struct spdk_nvme_ctrlr_opts opts_local; 850 851 if (trid == NULL) { 852 SPDK_ERRLOG("No transport ID specified\n"); 853 return NULL; 854 } 855 856 if (opts) { 857 opts_local_p = &opts_local; 858 nvme_ctrlr_opts_init(opts_local_p, opts, opts_size); 859 } 860 861 probe_ctx = spdk_nvme_connect_async(trid, opts_local_p, NULL); 862 if (!probe_ctx) { 863 SPDK_ERRLOG("Create probe context failed\n"); 864 return NULL; 865 } 866 867 rc = nvme_init_controllers(probe_ctx); 868 if (rc != 0) { 869 return NULL; 870 } 871 872 ctrlr = nvme_get_ctrlr_by_trid(trid); 873 874 return ctrlr; 875 } 876 877 void 878 spdk_nvme_trid_populate_transport(struct spdk_nvme_transport_id *trid, 879 enum spdk_nvme_transport_type trtype) 880 { 881 const char *trstring = ""; 882 883 trid->trtype = trtype; 884 switch (trtype) { 885 case SPDK_NVME_TRANSPORT_FC: 886 trstring = SPDK_NVME_TRANSPORT_NAME_FC; 887 break; 888 case SPDK_NVME_TRANSPORT_PCIE: 889 trstring = SPDK_NVME_TRANSPORT_NAME_PCIE; 890 break; 891 case SPDK_NVME_TRANSPORT_RDMA: 892 trstring = SPDK_NVME_TRANSPORT_NAME_RDMA; 893 break; 894 case SPDK_NVME_TRANSPORT_TCP: 895 trstring = SPDK_NVME_TRANSPORT_NAME_TCP; 896 break; 897 case SPDK_NVME_TRANSPORT_CUSTOM: 898 default: 899 SPDK_ERRLOG("don't use this for custom transports\n"); 900 assert(0); 901 return; 902 } 903 snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring); 904 } 905 906 int 907 spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring) 908 { 909 int len, i, rc; 910 911 if (trstring == NULL) { 912 return -EINVAL; 913 } 914 915 len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN); 916 if (len == SPDK_NVMF_TRSTRING_MAX_LEN) { 917 return -EINVAL; 918 } 919 920 rc = snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", trstring); 921 if (rc < 0) { 922 return rc; 923 } 924 925 /* cast official trstring to uppercase version of input. */ 926 for (i = 0; i < len; i++) { 927 trid->trstring[i] = toupper(trid->trstring[i]); 928 } 929 return 0; 930 } 931 932 int 933 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str) 934 { 935 if (trtype == NULL || str == NULL) { 936 return -EINVAL; 937 } 938 939 if (strcasecmp(str, "PCIe") == 0) { 940 *trtype = SPDK_NVME_TRANSPORT_PCIE; 941 } else if (strcasecmp(str, "RDMA") == 0) { 942 *trtype = SPDK_NVME_TRANSPORT_RDMA; 943 } else if (strcasecmp(str, "FC") == 0) { 944 *trtype = SPDK_NVME_TRANSPORT_FC; 945 } else if (strcasecmp(str, "TCP") == 0) { 946 *trtype = SPDK_NVME_TRANSPORT_TCP; 947 } else { 948 *trtype = SPDK_NVME_TRANSPORT_CUSTOM; 949 } 950 return 0; 951 } 952 953 const char * 954 spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype) 955 { 956 switch (trtype) { 957 case SPDK_NVME_TRANSPORT_PCIE: 958 return "PCIe"; 959 case SPDK_NVME_TRANSPORT_RDMA: 960 return "RDMA"; 961 case SPDK_NVME_TRANSPORT_FC: 962 return "FC"; 963 case SPDK_NVME_TRANSPORT_TCP: 964 return "TCP"; 965 case SPDK_NVME_TRANSPORT_CUSTOM: 966 return "CUSTOM"; 967 default: 968 return NULL; 969 } 970 } 971 972 int 973 spdk_nvme_transport_id_parse_adrfam(enum spdk_nvmf_adrfam *adrfam, const char *str) 974 { 975 if (adrfam == NULL || str == NULL) { 976 return -EINVAL; 977 } 978 979 if (strcasecmp(str, "IPv4") == 0) { 980 *adrfam = SPDK_NVMF_ADRFAM_IPV4; 981 } else if (strcasecmp(str, "IPv6") == 0) { 982 *adrfam = SPDK_NVMF_ADRFAM_IPV6; 983 } else if (strcasecmp(str, "IB") == 0) { 984 *adrfam = SPDK_NVMF_ADRFAM_IB; 985 } else if (strcasecmp(str, "FC") == 0) { 986 *adrfam = SPDK_NVMF_ADRFAM_FC; 987 } else { 988 return -ENOENT; 989 } 990 return 0; 991 } 992 993 const char * 994 spdk_nvme_transport_id_adrfam_str(enum spdk_nvmf_adrfam adrfam) 995 { 996 switch (adrfam) { 997 case SPDK_NVMF_ADRFAM_IPV4: 998 return "IPv4"; 999 case SPDK_NVMF_ADRFAM_IPV6: 1000 return "IPv6"; 1001 case SPDK_NVMF_ADRFAM_IB: 1002 return "IB"; 1003 case SPDK_NVMF_ADRFAM_FC: 1004 return "FC"; 1005 default: 1006 return NULL; 1007 } 1008 } 1009 1010 static size_t 1011 parse_next_key(const char **str, char *key, char *val, size_t key_buf_size, size_t val_buf_size) 1012 { 1013 1014 const char *sep, *sep1; 1015 const char *whitespace = " \t\n"; 1016 size_t key_len, val_len; 1017 1018 *str += strspn(*str, whitespace); 1019 1020 sep = strchr(*str, ':'); 1021 if (!sep) { 1022 sep = strchr(*str, '='); 1023 if (!sep) { 1024 SPDK_ERRLOG("Key without ':' or '=' separator\n"); 1025 return 0; 1026 } 1027 } else { 1028 sep1 = strchr(*str, '='); 1029 if ((sep1 != NULL) && (sep1 < sep)) { 1030 sep = sep1; 1031 } 1032 } 1033 1034 key_len = sep - *str; 1035 if (key_len >= key_buf_size) { 1036 SPDK_ERRLOG("Key length %zu greater than maximum allowed %zu\n", 1037 key_len, key_buf_size - 1); 1038 return 0; 1039 } 1040 1041 memcpy(key, *str, key_len); 1042 key[key_len] = '\0'; 1043 1044 *str += key_len + 1; /* Skip key: */ 1045 val_len = strcspn(*str, whitespace); 1046 if (val_len == 0) { 1047 SPDK_ERRLOG("Key without value\n"); 1048 return 0; 1049 } 1050 1051 if (val_len >= val_buf_size) { 1052 SPDK_ERRLOG("Value length %zu greater than maximum allowed %zu\n", 1053 val_len, val_buf_size - 1); 1054 return 0; 1055 } 1056 1057 memcpy(val, *str, val_len); 1058 val[val_len] = '\0'; 1059 1060 *str += val_len; 1061 1062 return val_len; 1063 } 1064 1065 int 1066 spdk_nvme_transport_id_parse(struct spdk_nvme_transport_id *trid, const char *str) 1067 { 1068 size_t val_len; 1069 char key[32]; 1070 char val[1024]; 1071 1072 if (trid == NULL || str == NULL) { 1073 return -EINVAL; 1074 } 1075 1076 while (*str != '\0') { 1077 1078 val_len = parse_next_key(&str, key, val, sizeof(key), sizeof(val)); 1079 1080 if (val_len == 0) { 1081 SPDK_ERRLOG("Failed to parse transport ID\n"); 1082 return -EINVAL; 1083 } 1084 1085 if (strcasecmp(key, "trtype") == 0) { 1086 if (spdk_nvme_transport_id_populate_trstring(trid, val) != 0) { 1087 SPDK_ERRLOG("invalid transport '%s'\n", val); 1088 return -EINVAL; 1089 } 1090 if (spdk_nvme_transport_id_parse_trtype(&trid->trtype, val) != 0) { 1091 SPDK_ERRLOG("Unknown trtype '%s'\n", val); 1092 return -EINVAL; 1093 } 1094 } else if (strcasecmp(key, "adrfam") == 0) { 1095 if (spdk_nvme_transport_id_parse_adrfam(&trid->adrfam, val) != 0) { 1096 SPDK_ERRLOG("Unknown adrfam '%s'\n", val); 1097 return -EINVAL; 1098 } 1099 } else if (strcasecmp(key, "traddr") == 0) { 1100 if (val_len > SPDK_NVMF_TRADDR_MAX_LEN) { 1101 SPDK_ERRLOG("traddr length %zu greater than maximum allowed %u\n", 1102 val_len, SPDK_NVMF_TRADDR_MAX_LEN); 1103 return -EINVAL; 1104 } 1105 memcpy(trid->traddr, val, val_len + 1); 1106 } else if (strcasecmp(key, "trsvcid") == 0) { 1107 if (val_len > SPDK_NVMF_TRSVCID_MAX_LEN) { 1108 SPDK_ERRLOG("trsvcid length %zu greater than maximum allowed %u\n", 1109 val_len, SPDK_NVMF_TRSVCID_MAX_LEN); 1110 return -EINVAL; 1111 } 1112 memcpy(trid->trsvcid, val, val_len + 1); 1113 } else if (strcasecmp(key, "priority") == 0) { 1114 if (val_len > SPDK_NVMF_PRIORITY_MAX_LEN) { 1115 SPDK_ERRLOG("priority length %zu greater than maximum allowed %u\n", 1116 val_len, SPDK_NVMF_PRIORITY_MAX_LEN); 1117 return -EINVAL; 1118 } 1119 trid->priority = spdk_strtol(val, 10); 1120 } else if (strcasecmp(key, "subnqn") == 0) { 1121 if (val_len > SPDK_NVMF_NQN_MAX_LEN) { 1122 SPDK_ERRLOG("subnqn length %zu greater than maximum allowed %u\n", 1123 val_len, SPDK_NVMF_NQN_MAX_LEN); 1124 return -EINVAL; 1125 } 1126 memcpy(trid->subnqn, val, val_len + 1); 1127 } else if (strcasecmp(key, "hostaddr") == 0) { 1128 continue; 1129 } else if (strcasecmp(key, "hostsvcid") == 0) { 1130 continue; 1131 } else if (strcasecmp(key, "ns") == 0) { 1132 /* 1133 * Special case. The namespace id parameter may 1134 * optionally be passed in the transport id string 1135 * for an SPDK application (e.g. nvme/perf) 1136 * and additionally parsed therein to limit 1137 * targeting a specific namespace. For this 1138 * scenario, just silently ignore this key 1139 * rather than letting it default to logging 1140 * it as an invalid key. 1141 */ 1142 continue; 1143 } else if (strcasecmp(key, "alt_traddr") == 0) { 1144 /* 1145 * Used by applications for enabling transport ID failover. 1146 * Please see the case above for more information on custom parameters. 1147 */ 1148 continue; 1149 } else { 1150 SPDK_ERRLOG("Unknown transport ID key '%s'\n", key); 1151 } 1152 } 1153 1154 return 0; 1155 } 1156 1157 int 1158 spdk_nvme_host_id_parse(struct spdk_nvme_host_id *hostid, const char *str) 1159 { 1160 1161 size_t key_size = 32; 1162 size_t val_size = 1024; 1163 size_t val_len; 1164 char key[key_size]; 1165 char val[val_size]; 1166 1167 if (hostid == NULL || str == NULL) { 1168 return -EINVAL; 1169 } 1170 1171 while (*str != '\0') { 1172 1173 val_len = parse_next_key(&str, key, val, key_size, val_size); 1174 1175 if (val_len == 0) { 1176 SPDK_ERRLOG("Failed to parse host ID\n"); 1177 return val_len; 1178 } 1179 1180 /* Ignore the rest of the options from the transport ID. */ 1181 if (strcasecmp(key, "trtype") == 0) { 1182 continue; 1183 } else if (strcasecmp(key, "adrfam") == 0) { 1184 continue; 1185 } else if (strcasecmp(key, "traddr") == 0) { 1186 continue; 1187 } else if (strcasecmp(key, "trsvcid") == 0) { 1188 continue; 1189 } else if (strcasecmp(key, "subnqn") == 0) { 1190 continue; 1191 } else if (strcasecmp(key, "priority") == 0) { 1192 continue; 1193 } else if (strcasecmp(key, "ns") == 0) { 1194 continue; 1195 } else if (strcasecmp(key, "hostaddr") == 0) { 1196 if (val_len > SPDK_NVMF_TRADDR_MAX_LEN) { 1197 SPDK_ERRLOG("hostaddr length %zu greater than maximum allowed %u\n", 1198 val_len, SPDK_NVMF_TRADDR_MAX_LEN); 1199 return -EINVAL; 1200 } 1201 memcpy(hostid->hostaddr, val, val_len + 1); 1202 1203 } else if (strcasecmp(key, "hostsvcid") == 0) { 1204 if (val_len > SPDK_NVMF_TRSVCID_MAX_LEN) { 1205 SPDK_ERRLOG("trsvcid length %zu greater than maximum allowed %u\n", 1206 val_len, SPDK_NVMF_TRSVCID_MAX_LEN); 1207 return -EINVAL; 1208 } 1209 memcpy(hostid->hostsvcid, val, val_len + 1); 1210 } else { 1211 SPDK_ERRLOG("Unknown transport ID key '%s'\n", key); 1212 } 1213 } 1214 1215 return 0; 1216 } 1217 1218 static int 1219 cmp_int(int a, int b) 1220 { 1221 return a - b; 1222 } 1223 1224 int 1225 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 1226 const struct spdk_nvme_transport_id *trid2) 1227 { 1228 int cmp; 1229 1230 if (trid1->trtype == SPDK_NVME_TRANSPORT_CUSTOM) { 1231 cmp = strcasecmp(trid1->trstring, trid2->trstring); 1232 } else { 1233 cmp = cmp_int(trid1->trtype, trid2->trtype); 1234 } 1235 1236 if (cmp) { 1237 return cmp; 1238 } 1239 1240 if (trid1->trtype == SPDK_NVME_TRANSPORT_PCIE) { 1241 struct spdk_pci_addr pci_addr1 = {}; 1242 struct spdk_pci_addr pci_addr2 = {}; 1243 1244 /* Normalize PCI addresses before comparing */ 1245 if (spdk_pci_addr_parse(&pci_addr1, trid1->traddr) < 0 || 1246 spdk_pci_addr_parse(&pci_addr2, trid2->traddr) < 0) { 1247 return -1; 1248 } 1249 1250 /* PCIe transport ID only uses trtype and traddr */ 1251 return spdk_pci_addr_compare(&pci_addr1, &pci_addr2); 1252 } 1253 1254 cmp = strcasecmp(trid1->traddr, trid2->traddr); 1255 if (cmp) { 1256 return cmp; 1257 } 1258 1259 cmp = cmp_int(trid1->adrfam, trid2->adrfam); 1260 if (cmp) { 1261 return cmp; 1262 } 1263 1264 cmp = strcasecmp(trid1->trsvcid, trid2->trsvcid); 1265 if (cmp) { 1266 return cmp; 1267 } 1268 1269 cmp = strcmp(trid1->subnqn, trid2->subnqn); 1270 if (cmp) { 1271 return cmp; 1272 } 1273 1274 return 0; 1275 } 1276 1277 int 1278 spdk_nvme_prchk_flags_parse(uint32_t *prchk_flags, const char *str) 1279 { 1280 size_t val_len; 1281 char key[32]; 1282 char val[1024]; 1283 1284 if (prchk_flags == NULL || str == NULL) { 1285 return -EINVAL; 1286 } 1287 1288 while (*str != '\0') { 1289 val_len = parse_next_key(&str, key, val, sizeof(key), sizeof(val)); 1290 1291 if (val_len == 0) { 1292 SPDK_ERRLOG("Failed to parse prchk\n"); 1293 return -EINVAL; 1294 } 1295 1296 if (strcasecmp(key, "prchk") == 0) { 1297 if (strcasestr(val, "reftag") != NULL) { 1298 *prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_REFTAG; 1299 } 1300 if (strcasestr(val, "guard") != NULL) { 1301 *prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_GUARD; 1302 } 1303 } else { 1304 SPDK_ERRLOG("Unknown key '%s'\n", key); 1305 return -EINVAL; 1306 } 1307 } 1308 1309 return 0; 1310 } 1311 1312 const char * 1313 spdk_nvme_prchk_flags_str(uint32_t prchk_flags) 1314 { 1315 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_REFTAG) { 1316 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { 1317 return "prchk:reftag|guard"; 1318 } else { 1319 return "prchk:reftag"; 1320 } 1321 } else { 1322 if (prchk_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { 1323 return "prchk:guard"; 1324 } else { 1325 return NULL; 1326 } 1327 } 1328 } 1329 1330 struct spdk_nvme_probe_ctx * 1331 spdk_nvme_probe_async(const struct spdk_nvme_transport_id *trid, 1332 void *cb_ctx, 1333 spdk_nvme_probe_cb probe_cb, 1334 spdk_nvme_attach_cb attach_cb, 1335 spdk_nvme_remove_cb remove_cb) 1336 { 1337 int rc; 1338 struct spdk_nvme_probe_ctx *probe_ctx; 1339 1340 rc = nvme_driver_init(); 1341 if (rc != 0) { 1342 return NULL; 1343 } 1344 1345 probe_ctx = calloc(1, sizeof(*probe_ctx)); 1346 if (!probe_ctx) { 1347 return NULL; 1348 } 1349 1350 nvme_probe_ctx_init(probe_ctx, trid, cb_ctx, probe_cb, attach_cb, remove_cb); 1351 rc = nvme_probe_internal(probe_ctx, false); 1352 if (rc != 0) { 1353 free(probe_ctx); 1354 return NULL; 1355 } 1356 1357 return probe_ctx; 1358 } 1359 1360 int 1361 spdk_nvme_probe_poll_async(struct spdk_nvme_probe_ctx *probe_ctx) 1362 { 1363 int rc = 0; 1364 struct spdk_nvme_ctrlr *ctrlr, *ctrlr_tmp; 1365 1366 if (!spdk_process_is_primary() && probe_ctx->trid.trtype == SPDK_NVME_TRANSPORT_PCIE) { 1367 free(probe_ctx); 1368 return 0; 1369 } 1370 1371 TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, tailq, ctrlr_tmp) { 1372 rc = nvme_ctrlr_poll_internal(ctrlr, probe_ctx); 1373 if (rc != 0) { 1374 rc = -EIO; 1375 break; 1376 } 1377 } 1378 1379 if (rc != 0 || TAILQ_EMPTY(&probe_ctx->init_ctrlrs)) { 1380 nvme_robust_mutex_lock(&g_spdk_nvme_driver->lock); 1381 g_spdk_nvme_driver->initialized = true; 1382 nvme_robust_mutex_unlock(&g_spdk_nvme_driver->lock); 1383 free(probe_ctx); 1384 return rc; 1385 } 1386 1387 return -EAGAIN; 1388 } 1389 1390 struct spdk_nvme_probe_ctx * 1391 spdk_nvme_connect_async(const struct spdk_nvme_transport_id *trid, 1392 const struct spdk_nvme_ctrlr_opts *opts, 1393 spdk_nvme_attach_cb attach_cb) 1394 { 1395 int rc; 1396 spdk_nvme_probe_cb probe_cb = NULL; 1397 struct spdk_nvme_probe_ctx *probe_ctx; 1398 1399 rc = nvme_driver_init(); 1400 if (rc != 0) { 1401 return NULL; 1402 } 1403 1404 probe_ctx = calloc(1, sizeof(*probe_ctx)); 1405 if (!probe_ctx) { 1406 return NULL; 1407 } 1408 1409 if (opts) { 1410 probe_cb = nvme_connect_probe_cb; 1411 } 1412 1413 nvme_probe_ctx_init(probe_ctx, trid, (void *)opts, probe_cb, attach_cb, NULL); 1414 rc = nvme_probe_internal(probe_ctx, true); 1415 if (rc != 0) { 1416 free(probe_ctx); 1417 return NULL; 1418 } 1419 1420 return probe_ctx; 1421 } 1422 1423 SPDK_LOG_REGISTER_COMPONENT("nvme", SPDK_LOG_NVME) 1424