Date: Fri, 12 Apr 2013 17:56:48 +0000 (UTC) From: Jim Harris <jimharris@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249422 - in head: sbin/nvmecontrol sys/dev/nvme Message-ID: <201304121756.r3CHumDp095933@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jimharris Date: Fri Apr 12 17:56:47 2013 New Revision: 249422 URL: http://svnweb.freebsd.org/changeset/base/249422 Log: Remove the NVME_IDENTIFY_CONTROLLER and NVME_IDENTIFY_NAMESPACE IOCTLs and replace them with the NVMe passthrough equivalent. Sponsored by: Intel Modified: head/sbin/nvmecontrol/nvmecontrol.c head/sys/dev/nvme/nvme.h head/sys/dev/nvme/nvme_ctrlr.c head/sys/dev/nvme/nvme_ns.c Modified: head/sbin/nvmecontrol/nvmecontrol.c ============================================================================== --- head/sbin/nvmecontrol/nvmecontrol.c Fri Apr 12 17:52:17 2013 (r249421) +++ head/sbin/nvmecontrol/nvmecontrol.c Fri Apr 12 17:56:47 2013 (r249422) @@ -210,6 +210,53 @@ ns_get_sector_size(struct nvme_namespace return (1 << nsdata->lbaf[0].lbads); } +static void +read_controller_data(int fd, struct nvme_controller_data *cdata) +{ + struct nvme_pt_command pt; + + memset(&pt, 0, sizeof(pt)); + pt.cmd.opc = NVME_OPC_IDENTIFY; + pt.cmd.cdw10 = 1; + pt.buf = cdata; + pt.len = sizeof(*cdata); + pt.is_read = 1; + + if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) { + printf("Identify request failed. errno=%d (%s)\n", + errno, strerror(errno)); + exit(EX_IOERR); + } + + if (nvme_completion_is_error(&pt.cpl)) { + printf("Passthrough command returned error.\n"); + exit(EX_IOERR); + } +} + +static void +read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata) +{ + struct nvme_pt_command pt; + + memset(&pt, 0, sizeof(pt)); + pt.cmd.opc = NVME_OPC_IDENTIFY; + pt.cmd.nsid = nsid; + pt.buf = nsdata; + pt.len = sizeof(*nsdata); + pt.is_read = 1; + + if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) { + printf("Identify request failed. errno=%d (%s)\n", + errno, strerror(errno)); + exit(EX_IOERR); + } + + if (nvme_completion_is_error(&pt.cpl)) { + printf("Passthrough command returned error.\n"); + exit(EX_IOERR); + } +} static void devlist(int argc, char *argv[]) @@ -251,33 +298,12 @@ devlist(int argc, char *argv[]) continue; } - if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) < 0) { - printf("Identify request to %s failed. errno=%d (%s)\n", - path, errno, strerror(errno)); - exit_code = EX_IOERR; - continue; - } - + read_controller_data(fd, &cdata); printf("%6s: %s\n", name, cdata.mn); for (i = 0; i < cdata.nn; i++) { sprintf(name, "nvme%dns%d", ctrlr, i+1); - sprintf(path, "/dev/%s", name); - - fd = open(path, O_RDWR); - if (fd < 0) { - printf("Could not open %s. errno=%d (%s)\n", - path, errno, strerror(errno)); - exit_code = EX_NOPERM; - continue; - } - if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) < 0) { - printf("Identify request to %s failed. " - "errno=%d (%s)\n", path, errno, - strerror(errno)); - exit_code = EX_IOERR; - continue; - } + read_namespace_data(fd, i+1, &nsdata); printf(" %10s (%lldGB)\n", name, nsdata.nsze * @@ -329,11 +355,7 @@ identify_ctrlr(int argc, char *argv[]) exit(EX_NOPERM); } - if (ioctl(fd, NVME_IDENTIFY_CONTROLLER, &cdata) < 0) { - printf("Identify request to %s failed. errno=%d (%s)\n", path, - errno, strerror(errno)); - exit(EX_IOERR); - } + read_controller_data(fd, &cdata); if (hexflag == 1) { if (verboseflag == 1) @@ -360,7 +382,8 @@ identify_ns(int argc, char *argv[]) struct nvme_namespace_data nsdata; struct stat devstat; char path[64]; - int ch, fd, hexflag = 0, hexlength; + char *nsloc; + int ch, fd, hexflag = 0, hexlength, nsid; int verboseflag = 0; while ((ch = getopt(argc, argv, "vx")) != -1) { @@ -376,8 +399,41 @@ identify_ns(int argc, char *argv[]) } } + /* + * Check if the specified device node exists before continuing. + * This is a cleaner check for cases where the correct controller + * is specified, but an invalid namespace on that controller. + */ sprintf(path, "/dev/%s", argv[optind]); + if (stat(path, &devstat) < 0) { + printf("Invalid device node %s. errno=%d (%s)\n", path, errno, + strerror(errno)); + exit(EX_IOERR); + } + nsloc = strstr(argv[optind], "ns"); + if (nsloc == NULL) { + printf("Invalid namepsace %s.\n", argv[optind]); + exit(EX_IOERR); + } + + /* + * Pull the namespace id from the string. +2 skips past the "ns" part + * of the string. + */ + nsid = strtol(nsloc + 2, NULL, 10); + if (nsid == 0 && errno != 0) { + printf("Invalid namespace ID %s.\n", argv[optind]); + exit(EX_IOERR); + } + + /* + * We send IDENTIFY commands to the controller, not the namespace, + * since it is an admin cmd. So the path should only include the + * nvmeX part of the nvmeXnsY string. + */ + sprintf(path, "/dev/"); + strncat(path, argv[optind], nsloc - argv[optind]); if (stat(path, &devstat) < 0) { printf("Invalid device node %s. errno=%d (%s)\n", path, errno, strerror(errno)); @@ -391,11 +447,7 @@ identify_ns(int argc, char *argv[]) exit(EX_NOPERM); } - if (ioctl(fd, NVME_IDENTIFY_NAMESPACE, &nsdata) < 0) { - printf("Identify request to %s failed. errno=%d (%s)\n", path, - errno, strerror(errno)); - exit(EX_IOERR); - } + read_namespace_data(fd, nsid, &nsdata); if (hexflag == 1) { if (verboseflag == 1) Modified: head/sys/dev/nvme/nvme.h ============================================================================== --- head/sys/dev/nvme/nvme.h Fri Apr 12 17:52:17 2013 (r249421) +++ head/sys/dev/nvme/nvme.h Fri Apr 12 17:56:47 2013 (r249422) @@ -33,12 +33,11 @@ #include <sys/types.h> #endif -#define NVME_IDENTIFY_CONTROLLER _IOR('n', 0, struct nvme_controller_data) -#define NVME_IDENTIFY_NAMESPACE _IOR('n', 1, struct nvme_namespace_data) -#define NVME_IO_TEST _IOWR('n', 2, struct nvme_io_test) -#define NVME_BIO_TEST _IOWR('n', 4, struct nvme_io_test) -#define NVME_RESET_CONTROLLER _IO('n', 5) -#define NVME_PASSTHROUGH_CMD _IOWR('n', 6, struct nvme_pt_command) +#define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command) +#define NVME_RESET_CONTROLLER _IO('n', 1) + +#define NVME_IO_TEST _IOWR('n', 100, struct nvme_io_test) +#define NVME_BIO_TEST _IOWR('n', 101, struct nvme_io_test) /* * Use to mark a command to apply to all namespaces, or to retrieve global Modified: head/sys/dev/nvme/nvme_ctrlr.c ============================================================================== --- head/sys/dev/nvme/nvme_ctrlr.c Fri Apr 12 17:52:17 2013 (r249421) +++ head/sys/dev/nvme/nvme_ctrlr.c Fri Apr 12 17:56:47 2013 (r249422) @@ -976,34 +976,12 @@ static int nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, struct thread *td) { - struct nvme_completion_poll_status status; struct nvme_controller *ctrlr; struct nvme_pt_command *pt; ctrlr = cdev->si_drv1; switch (cmd) { - case NVME_IDENTIFY_CONTROLLER: -#ifdef CHATHAM2 - /* - * Don't refresh data on Chatham, since Chatham returns - * garbage on IDENTIFY anyways. - */ - if (pci_get_devid(ctrlr->dev) == CHATHAM_PCI_ID) { - memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); - break; - } -#endif - /* Refresh data before returning to user. */ - status.done = FALSE; - nvme_ctrlr_cmd_identify_controller(ctrlr, &ctrlr->cdata, - nvme_completion_poll_cb, &status); - while (status.done == FALSE) - DELAY(5); - if (nvme_completion_is_error(&status.cpl)) - return (ENXIO); - memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); - break; case NVME_RESET_CONTROLLER: nvme_ctrlr_reset(ctrlr); break; Modified: head/sys/dev/nvme/nvme_ns.c ============================================================================== --- head/sys/dev/nvme/nvme_ns.c Fri Apr 12 17:52:17 2013 (r249421) +++ head/sys/dev/nvme/nvme_ns.c Fri Apr 12 17:56:47 2013 (r249422) @@ -45,7 +45,6 @@ static int nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, struct thread *td) { - struct nvme_completion_poll_status status; struct nvme_namespace *ns; struct nvme_controller *ctrlr; struct nvme_pt_command *pt; @@ -54,27 +53,6 @@ nvme_ns_ioctl(struct cdev *cdev, u_long ctrlr = ns->ctrlr; switch (cmd) { - case NVME_IDENTIFY_NAMESPACE: -#ifdef CHATHAM2 - /* - * Don't refresh data on Chatham, since Chatham returns - * garbage on IDENTIFY anyways. - */ - if (pci_get_devid(ctrlr->dev) == CHATHAM_PCI_ID) { - memcpy(arg, &ns->data, sizeof(ns->data)); - break; - } -#endif - /* Refresh data before returning to user. */ - status.done = FALSE; - nvme_ctrlr_cmd_identify_namespace(ctrlr, ns->id, &ns->data, - nvme_completion_poll_cb, &status); - while (status.done == FALSE) - DELAY(5); - if (nvme_completion_is_error(&status.cpl)) - return (ENXIO); - memcpy(arg, &ns->data, sizeof(ns->data)); - break; case NVME_IO_TEST: case NVME_BIO_TEST: nvme_ns_test(ns, cmd, arg);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304121756.r3CHumDp095933>