Commit 8f876a61 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme_manage: display available LBA formats



Add a helper function, get_lba_format(), to print available LBA formats,
and use it in Create Namespace as well as Format NVM.

Change-Id: I4bfa4db0aa5a083f51b8da6b5103acf64f1da788
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent ddb59105
Loading
Loading
Loading
Loading
+80 −26
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ struct dev {
	struct spdk_pci_device			*pci_dev;
	struct spdk_nvme_ctrlr 			*ctrlr;
	const struct spdk_nvme_ctrlr_data	*cdata;
	struct spdk_nvme_ns_data		*common_ns_data;
	int					outstanding_admin_cmds;
};

static struct dev devs[MAX_DEVS];
@@ -115,16 +117,58 @@ probe_cb(void *cb_ctx, struct spdk_pci_device *dev, struct spdk_nvme_ctrlr_opts
	return true;
}

static void
identify_common_ns_cb(void *cb_arg, const struct spdk_nvme_cpl *cpl)
{
	struct dev *dev = cb_arg;

	if (cpl->status.sc != SPDK_NVME_SC_SUCCESS) {
		/* Identify Namespace for NSID = FFFFFFFFh is optional, so failure is not fatal. */
		rte_free(dev->common_ns_data);
		dev->common_ns_data = NULL;
	}

	dev->outstanding_admin_cmds--;
}

static void
attach_cb(void *cb_ctx, struct spdk_pci_device *pci_dev, struct spdk_nvme_ctrlr *ctrlr,
	  const struct spdk_nvme_ctrlr_opts *opts)
{
	struct dev *dev;
	struct spdk_nvme_cmd cmd;

	/* add to dev list */
	dev = &devs[num_devs++];
	dev->pci_dev = pci_dev;
	dev->ctrlr = ctrlr;

	/* Retrieve controller data */
	dev->cdata = spdk_nvme_ctrlr_get_data(dev->ctrlr);

	dev->common_ns_data = rte_zmalloc("common_ns_data", sizeof(struct spdk_nvme_ns_data), 4096);
	if (dev->common_ns_data == NULL) {
		fprintf(stderr, "common_ns_data allocation failure\n");
		return;
	}

	/* Identify Namespace with NSID set to FFFFFFFFh to get common namespace capabilities. */
	memset(&cmd, 0, sizeof(cmd));
	cmd.opc = SPDK_NVME_OPC_IDENTIFY;
	cmd.cdw10 = 0; /* CNS = 0 (Identify Namespace) */
	cmd.nsid = SPDK_NVME_GLOBAL_NS_TAG;

	dev->outstanding_admin_cmds++;
	if (spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, dev->common_ns_data,
					  sizeof(struct spdk_nvme_ns_data), identify_common_ns_cb, dev) != 0) {
		dev->outstanding_admin_cmds--;
		rte_free(dev->common_ns_data);
		dev->common_ns_data = NULL;
	}

	while (dev->outstanding_admin_cmds) {
		spdk_nvme_ctrlr_process_admin_completions(ctrlr);
	}
}

static const char *ealargs[] = {
@@ -295,7 +339,6 @@ get_controller(void)
	char					*p;
	int					ch;
	struct dev				*iter;
	const struct spdk_nvme_ctrlr_data	*cdata;

	memset(address, 0, sizeof(address));

@@ -335,14 +378,34 @@ get_controller(void)

	foreach_dev(iter) {
		if (pci_addr == get_pci_addr(iter->pci_dev)) {
			cdata = spdk_nvme_ctrlr_get_data(iter->ctrlr);
			iter->cdata = cdata;
			return iter;
		}
	}
	return NULL;
}

static int
get_lba_format(const struct spdk_nvme_ns_data *ns_data)
{
	int lbaf, i;

	printf("\nSupported LBA formats:\n");
	for (i = 0; i <= ns_data->nlbaf; i++) {
		printf("%2d: %d data bytes", i, 1 << ns_data->lbaf[i].lbads);
		if (ns_data->lbaf[i].ms) {
			printf(" + %d metadata bytes", ns_data->lbaf[i].ms);
		}
		printf("\n");
	}

	printf("Please input LBA format index (0 - %d):\n", ns_data->nlbaf);
	if (scanf("%d", &lbaf) != 1 || lbaf > ns_data->nlbaf) {
		return -1;
	}

	return lbaf;
}

static void
ns_attach(struct dev *device, int attachment_op, int ctrlr_id, int ns_id)
{
@@ -463,7 +526,7 @@ add_ns(void)
{
	uint64_t	ns_size		= 0;
	uint64_t	ns_capacity	= 0;
	int		ns_lbasize	= 0;
	int		ns_lbasize;
	int 		ns_dps_type  	= 0;
	int 		ns_dps_location = 0;
	int	 	ns_nmic 	= 0;
@@ -480,6 +543,17 @@ add_ns(void)
		return;
	}

	if (!ctrlr->common_ns_data) {
		printf("Controller did not return common namespace capabilities\n");
		return;
	}

	ns_lbasize = get_lba_format(ctrlr->common_ns_data);
	if (ns_lbasize < 0) {
		printf("Invalid LBA format number\n");
		return;
	}

	printf("Please Input Namespace Size (in LBAs): \n");
	if (!scanf("%" SCNi64, &ns_size)) {
		printf("Invalid Namespace Size\n");
@@ -494,13 +568,6 @@ add_ns(void)
		return;
	}

	printf("Please Input LBA Format Number (0 - 15): \n");
	if (!scanf("%d", &ns_lbasize)) {
		printf("Invalid LBA format size\n");
		while (getchar() != '\n');
		return;
	}

	printf("Please Input Data Protection Type (0 - 3): \n");
	if (!scanf("%d", &ns_dps_type)) {
		printf("Invalid Data Protection Type\n");
@@ -558,7 +625,6 @@ delete_ns(void)
static void
format_nvm(void)
{
	int					i;
	int 					ns_id;
	int					ses;
	int					pil;
@@ -617,21 +683,9 @@ format_nvm(void)
		return;
	}

	for (i = 0; i <= nsdata->nlbaf; i++) {
		printf("LBA Format #%02d: Data Size: %5d  Metadata Size: %5d\n",
		       i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms);
	}

	printf("Please Input LBA Format Number (0 - %d): \n", nsdata->nlbaf);
	if (!scanf("%d", &lbaf)) {
		printf("Invalid LBA format size\n");
		while (getchar() != '\n');
		return;
	}

	if (lbaf > nsdata->nlbaf) {
	lbaf = get_lba_format(nsdata);
	if (lbaf < 0) {
		printf("Invalid LBA format number\n");
		while (getchar() != '\n');
		return;
	}