1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/nvme.h" 9 #include "spdk/env.h" 10 #include "spdk/env_dpdk.h" 11 #include <rte_config.h> 12 #include <rte_eal.h> 13 14 #define MAX_DEVS 64 15 16 struct dev { 17 struct spdk_nvme_ctrlr *ctrlr; 18 struct spdk_nvme_ns *ns; 19 struct spdk_nvme_qpair *qpair; 20 char name[SPDK_NVMF_TRADDR_MAX_LEN + 1]; 21 }; 22 23 static struct dev g_nvme_devs[MAX_DEVS]; 24 static int g_num_devs = 0; 25 static int g_failed = 0; 26 27 static bool 28 probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 29 struct spdk_nvme_ctrlr_opts *opts) 30 { 31 printf("Attaching to %s\n", trid->traddr); 32 33 return true; 34 } 35 36 static void 37 attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 38 struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts) 39 { 40 struct dev *dev; 41 uint32_t nsid; 42 43 /* add to dev list */ 44 dev = &g_nvme_devs[g_num_devs++]; 45 if (g_num_devs >= MAX_DEVS) { 46 return; 47 } 48 49 dev->ctrlr = ctrlr; 50 nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr); 51 dev->ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid); 52 53 dev->qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, NULL, 0); 54 if (dev->qpair == NULL) { 55 g_failed = 1; 56 return; 57 } 58 59 snprintf(dev->name, sizeof(dev->name), "%s", 60 trid->traddr); 61 62 printf("Attached to %s\n", dev->name); 63 } 64 65 int 66 main(int argc, char **argv) 67 { 68 int ret; 69 int i; 70 struct spdk_nvme_detach_ctx *detach_ctx = NULL; 71 72 printf("Starting DPDK initialization...\n"); 73 ret = rte_eal_init(argc, argv); 74 if (ret < 0) { 75 fprintf(stderr, "Failed to initialize DPDK\n"); 76 return -1; 77 } 78 79 printf("Starting SPDK post initialization...\n"); 80 ret = spdk_env_dpdk_post_init(false); 81 if (ret < 0) { 82 fprintf(stderr, "Failed to initialize SPDK\n"); 83 return -1; 84 } 85 86 printf("SPDK NVMe probe\n"); 87 if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) { 88 fprintf(stderr, "spdk_nvme_probe() failed\n"); 89 return 1; 90 } 91 92 printf("Cleaning up...\n"); 93 for (i = 0; i < g_num_devs; i++) { 94 struct dev *dev = &g_nvme_devs[i]; 95 spdk_nvme_detach_async(dev->ctrlr, &detach_ctx); 96 } 97 98 if (detach_ctx) { 99 spdk_nvme_detach_poll(detach_ctx); 100 } 101 102 return g_failed; 103 } 104