示例#1
0
/* NOTE: enable the keyboard port but disable the keyboard 
 * interrupt before calling "reset_kbd()".
 */
int
reset_kbd(KBDC p)
{
    int retry = KBD_MAXRETRY;
    int again = KBD_MAXWAIT;
    int c = KBD_RESEND;		/* keep the compiler happy */

    while (retry-- > 0) {
        empty_both_buffers(p, 10);
        if (!write_kbd_command(p, KBDC_RESET_KBD))
	    continue;
	emptyq(&kbdcp(p)->kbd);
        c = read_controller_data(p);
	if (verbose || bootverbose)
            log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
        if (c == KBD_ACK)	/* keyboard has agreed to reset itself... */
    	    break;
    }
    if (retry < 0)
        return FALSE;

    while (again-- > 0) {
        /* wait awhile, well, in fact we must wait quite loooooooooooong */
        DELAY(KBD_RESETDELAY*1000);
        c = read_controller_data(p);	/* RESET_DONE/RESET_FAIL */
        if (c != -1) 	/* wait again if the controller is not ready */
    	    break;
    }
    if (verbose || bootverbose)
        log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
    if (c != KBD_RESET_DONE)
        return FALSE;
    return TRUE;
}
示例#2
0
int
test_aux_port(KBDC p)
{
    int retry = KBD_MAXRETRY;
    int again = KBD_MAXWAIT;
    int c = -1;

    while (retry-- > 0) {
        empty_both_buffers(p, 10);
        if (write_controller_command(p, KBDC_TEST_AUX_PORT))
    	    break;
    }
    if (retry < 0)
        return FALSE;

    emptyq(&kbdcp(p)->kbd);
    while (again-- > 0) {
        c = read_controller_data(p);
        if (c != -1) 	/* try again if the controller is not ready */
    	    break;
    }
    if (verbose || bootverbose)
        log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
    return c;
}
示例#3
0
int
test_controller(KBDC p)
{
    int retry = KBD_MAXRETRY;
    int again = KBD_MAXWAIT;
    int c = KBD_DIAG_FAIL;

    while (retry-- > 0) {
        empty_both_buffers(p, 10);
        if (write_controller_command(p, KBDC_DIAGNOSE))
    	    break;
    }
    if (retry < 0)
        return FALSE;

    emptyq(&kbdcp(p)->kbd);
    while (again-- > 0) {
        /* wait awhile */
        DELAY(KBD_RESETDELAY*1000);
        c = read_controller_data(p);	/* DIAG_DONE/DIAG_FAIL */
        if (c != -1) 	/* wait again if the controller is not ready */
    	    break;
    }
    if (verbose || bootverbose)
        log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
    return (c == KBD_DIAG_DONE);
}
示例#4
0
static void
devlist(int argc, char *argv[])
{
	struct nvme_controller_data	cdata;
	struct nvme_namespace_data	nsdata;
	struct stat			devstat;
	char				name[64], path[64];
	uint32_t			i;
	int				ch, ctrlr, exit_code, fd, found;

	exit_code = EX_OK;

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch ((char)ch) {
		default:
			usage();
		}
	}

	ctrlr = -1;
	found = 0;

	while (1) {
		ctrlr++;
		sprintf(name, "nvme%d", ctrlr);
		sprintf(path, "/dev/%s", name);

		if (stat(path, &devstat) != 0)
			break;

		found++;

		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;
		}

		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);
			read_namespace_data(fd, i+1, &nsdata);
			printf("  %10s (%lldGB)\n",
				name,
				nsdata.nsze *
				(long long)ns_get_sector_size(&nsdata) /
				1024 / 1024 / 1024);
		}
	}

	if (found == 0)
		printf("No NVMe controllers found.\n");

	exit(exit_code);
}
示例#5
0
文件: devlist.c 项目: ryo/netbsd-src
void
devlist(int argc, char *argv[])
{
	struct nvm_identify_controller	cdata;
	struct nvm_identify_namespace	nsdata;
	char				name[64];
	uint8_t				mn[64];
	uint32_t			i;
	int				ch, ctrlr, fd, found, ret;

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch (ch) {
		default:
			devlist_usage();
		}
	}

	ctrlr = -1;
	found = 0;

	while (1) {
		ctrlr++;
		sprintf(name, "%s%d", NVME_CTRLR_PREFIX, ctrlr);

		ret = open_dev(name, &fd, 0, 0);

		if (ret != 0) {
			if (ret == EACCES) {
				warnx("could not open "_PATH_DEV"%s\n", name);
				continue;
			} else
				break;
		}

		found++;
		read_controller_data(fd, &cdata);
		nvme_strvis(mn, sizeof(mn), cdata.mn, sizeof(cdata.mn));
		printf("%6s: %s\n", name, mn);

		for (i = 0; i < cdata.nn; i++) {
			sprintf(name, "%s%d%s%d", NVME_CTRLR_PREFIX, ctrlr,
			    NVME_NS_PREFIX, i+1);
			read_namespace_data(fd, i+1, &nsdata);
			printf("  %10s (%lldMB)\n",
				name,
				nsdata.nsze *
				(long long)ns_get_sector_size(&nsdata) /
				1024 / 1024);
		}

		close(fd);
	}

	if (found == 0)
		printf("No NVMe controllers found.\n");

	exit(1);
}
示例#6
0
static void
identify_ctrlr(int argc, char *argv[])
{
	struct nvme_controller_data	cdata;
	struct stat			devstat;
	char				path[64];
	int				ch, fd, hexflag = 0, hexlength;
	int				verboseflag = 0;

	while ((ch = getopt(argc, argv, "vx")) != -1) {
		switch ((char)ch) {
		case 'v':
			verboseflag = 1;
			break;
		case 'x':
			hexflag = 1;
			break;
		default:
			usage();
		}
	}

	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);
	}

	fd = open(path, O_RDWR);
	if (fd < 0) {
		printf("Could not open %s. errno=%d (%s)\n", path, errno,
		    strerror(errno));
		exit(EX_NOPERM);
	}

	read_controller_data(fd, &cdata);

	if (hexflag == 1) {
		if (verboseflag == 1)
			hexlength = sizeof(struct nvme_controller_data);
		else
			hexlength = offsetof(struct nvme_controller_data,
			    reserved5);
		print_controller_hex(&cdata, hexlength);
		exit(EX_OK);
	}

	if (verboseflag == 1) {
		printf("-v not currently supported without -x.\n");
		usage();
	}

	print_controller(&cdata);
	exit(EX_OK);
}
示例#7
0
int
get_controller_command_byte(KBDC p)
{
    if (kbdcp(p)->command_byte != -1)
	return kbdcp(p)->command_byte;
    if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
	return -1;
    emptyq(&kbdcp(p)->kbd);
    kbdcp(p)->command_byte = read_controller_data(p);
    return kbdcp(p)->command_byte;
}
示例#8
0
static void
identify_ctrlr(int argc, char *argv[])
{
	struct nvme_controller_data	cdata;
	int				ch, fd, hexflag = 0, hexlength;
	int				verboseflag = 0;

	while ((ch = getopt(argc, argv, "vx")) != -1) {
		switch ((char)ch) {
		case 'v':
			verboseflag = 1;
			break;
		case 'x':
			hexflag = 1;
			break;
		default:
			identify_usage();
		}
	}

	/* Check that a controller was specified. */
	if (optind >= argc)
		identify_usage();

	open_dev(argv[optind], &fd, 1, 1);
	read_controller_data(fd, &cdata);
	close(fd);

	if (hexflag == 1) {
		if (verboseflag == 1)
			hexlength = sizeof(struct nvme_controller_data);
		else
			hexlength = offsetof(struct nvme_controller_data,
			    reserved5);
		print_hex(&cdata, hexlength);
		exit(0);
	}

	if (verboseflag == 1) {
		fprintf(stderr, "-v not currently supported without -x\n");
		identify_usage();
	}

	print_controller(&cdata);
	exit(0);
}
示例#9
0
void
logpage(int argc, char *argv[])
{
	int				fd, nsid;
	int				log_page = 0, pageflag = false;
	int				hexflag = false, ns_specified;
	char				ch, *p;
	char				cname[64];
	uint32_t			size;
	void				*buf;
	const char			*vendor = NULL;
	struct logpage_function		*f;
	struct nvme_controller_data	cdata;
	print_fn_t			print_fn;

	while ((ch = getopt(argc, argv, "p:xv:")) != -1) {
		switch (ch) {
		case 'p':
			/* TODO: Add human-readable ASCII page IDs */
			log_page = strtol(optarg, &p, 0);
			if (p != NULL && *p != '\0') {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			}
			pageflag = true;
			break;
		case 'x':
			hexflag = true;
			break;
		case 'v':
			vendor = optarg;
			break;
		}
	}

	if (!pageflag) {
		printf("Missing page_id (-p).\n");
		logpage_usage();
	}

	/* Check that a controller and/or namespace was specified. */
	if (optind >= argc)
		logpage_usage();

	if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
		ns_specified = true;
		parse_ns_str(argv[optind], cname, &nsid);
		open_dev(cname, &fd, 1, 1);
	} else {
		ns_specified = false;
		nsid = NVME_GLOBAL_NAMESPACE_TAG;
		open_dev(argv[optind], &fd, 1, 1);
	}

	read_controller_data(fd, &cdata);

	/*
	 * The log page attribtues indicate whether or not the controller
	 * supports the SMART/Health information log page on a per
	 * namespace basis.
	 */
	if (ns_specified) {
		if (log_page != NVME_LOG_HEALTH_INFORMATION)
			errx(1, "log page %d valid only at controller level",
			    log_page);
		if (cdata.lpa.ns_smart == 0)
			errx(1,
			    "controller does not support per namespace "
			    "smart/health information");
	}

	print_fn = print_hex;
	size = DEFAULT_SIZE;
	if (!hexflag) {
		/*
		 * See if there is a pretty print function for the specified log
		 * page.  If one isn't found, we just revert to the default
		 * (print_hex). If there was a vendor specified bt the user, and
		 * the page is vendor specific, don't match the print function
		 * unless the vendors match.
		 */
		for (f = logfuncs; f->log_page > 0; f++) {
			if (f->vendor != NULL && vendor != NULL &&
			    strcmp(f->vendor, vendor) != 0)
				continue;
			if (log_page != f->log_page)
				continue;
			print_fn = f->print_fn;
			size = f->size;
			break;
		}
	}

	if (log_page == NVME_LOG_ERROR) {
		size = sizeof(struct nvme_error_information_entry);
		size *= (cdata.elpe + 1);
	}

	/* Read the log page */
	buf = get_log_buffer(size);
	read_logpage(fd, log_page, nsid, buf, size);
	print_fn(buf, size);

	close(fd);
	exit(0);
}
示例#10
0
文件: logpage.c 项目: ryo/netbsd-src
void
logpage(int argc, char *argv[])
{
	int				fd, nsid;
	int				log_page = 0, pageflag = false;
	int				hexflag = false, ns_specified;
	int				ch;
	char				*p;
	char				cname[64];
	uint32_t			size;
	void				*buf;
	struct logpage_function		*f;
	struct nvm_identify_controller	cdata;
	print_fn_t			print_fn;

	while ((ch = getopt(argc, argv, "p:x")) != -1) {
		switch (ch) {
		case 'p':
			/* TODO: Add human-readable ASCII page IDs */
			log_page = strtol(optarg, &p, 0);
			if (p != NULL && *p != '\0') {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			/* TODO: Define valid log page id ranges in nvme.h? */
			} else if (log_page == 0 ||
				   (log_page >= 0x04 && log_page <= 0x7F) ||
				   (log_page >= 0x80 && log_page <= 0xBF)) {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			}
			pageflag = true;
			break;
		case 'x':
			hexflag = true;
			break;
		}
	}

	if (!pageflag) {
		printf("Missing page_id (-p).\n");
		logpage_usage();
	}

	/* Check that a controller and/or namespace was specified. */
	if (optind >= argc)
		logpage_usage();

	if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
		ns_specified = true;
		parse_ns_str(argv[optind], cname, &nsid);
		open_dev(cname, &fd, 1, 1);
	} else {
		ns_specified = false;
		nsid = 0xffffffff;
		open_dev(argv[optind], &fd, 1, 1);
	}

	read_controller_data(fd, &cdata);

	/*
	 * The log page attribtues indicate whether or not the controller
	 * supports the SMART/Health information log page on a per
	 * namespace basis.
	 */
	if (ns_specified) {
		if (log_page != NVME_LOG_HEALTH_INFORMATION)
			errx(1, "log page %d valid only at controller level",
			    log_page);
		if (!(cdata.lpa & NVME_ID_CTRLR_LPA_NS_SMART))
			errx(1,
			    "controller does not support per namespace "
			    "smart/health information");
	}

	print_fn = print_hex;
	if (!hexflag) {
		/*
		 * See if there is a pretty print function for the
		 *  specified log page.  If one isn't found, we
		 *  just revert to the default (print_hex).
		 */
		f = logfuncs;
		while (f->log_page > 0) {
			if (log_page == f->log_page) {
				print_fn = f->fn;
				break;
			}
			f++;
		}
	}

	/* Read the log page */
	switch (log_page) {
	case NVME_LOG_ERROR:
		size = sizeof(struct nvme_error_information_entry);
		size *= (cdata.elpe + 1);
		break;
	case NVME_LOG_HEALTH_INFORMATION:
		size = sizeof(struct nvme_health_information_page);
		break;
	case NVME_LOG_FIRMWARE_SLOT:
		size = sizeof(struct nvme_firmware_page);
		break;
	default:
		size = DEFAULT_SIZE;
		break;
	}

	buf = get_log_buffer(size);
	read_logpage(fd, log_page, nsid, buf, size);
	print_fn(buf, size);

	close(fd);
	exit(0);
}
示例#11
0
void
logpage(int argc, char *argv[])
{
	int				fd, nsid, len;
	int				log_page = 0, pageflag = false;
	int				hexflag = false;
	int				allow_ns = false;
	char				ch, *p, *nsloc = NULL;
	char				*cname = NULL;
	size_t				size;
	void				*buf;
	struct logpage_function		*f;
	struct nvme_controller_data	cdata;
	print_fn_t			print_fn;

	while ((ch = getopt(argc, argv, "p:x")) != -1) {
		switch (ch) {
		case 'p':
			/* TODO: Add human-readable ASCII page IDs */
			log_page = strtol(optarg, &p, 0);
			if (p != NULL && *p != '\0') {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			/* TODO: Define valid log page id ranges in nvme.h? */
			} else if (log_page == 0 ||
				   (log_page >= 0x04 && log_page <= 0x7F) ||
				   (log_page >= 0x80 && log_page <= 0xBF)) {
				fprintf(stderr,
				    "\"%s\" not valid log page id.\n",
				    optarg);
				logpage_usage();
			}
			pageflag = true;
			break;
		case 'x':
			hexflag = true;
			break;
		}
	}

	if (!pageflag) {
		printf("Missing page_id (-p).\n");
		logpage_usage();
	}

	/* Check that a controller and/or namespace was specified. */
	if (optind >= argc)
		logpage_usage();

	/*
	 * The log page attribtues indicate whether or not the controller
	 * supports the SMART/Health information log page on a per
	 * namespace basis.
	 */
	cname = malloc(strlen(NVME_CTRLR_PREFIX) + 2);
	len = strlen(NVME_CTRLR_PREFIX) + 1;
	cname = strncpy(cname, argv[optind], len);
	open_dev(cname, &fd, 1, 1);
	read_controller_data(fd, &cdata);

	if (log_page == NVME_LOG_HEALTH_INFORMATION && cdata.lpa.ns_smart != 0)
		allow_ns = true;

	/* If a namespace id was specified, validate it's use */
	if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
		if (!allow_ns) {
			if (log_page != NVME_LOG_HEALTH_INFORMATION) {
				fprintf(stderr,
				    "Namespace ID not valid for log page %d.\n",
				    log_page);
			} else if (cdata.lpa.ns_smart == 0) {
				fprintf(stderr,
				    "Controller does not support per "
				    "namespace SMART/Health information.\n");
			}
			close(fd);
			exit(EX_IOERR);
		}
		nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
		if (nsloc != NULL)
			nsid = strtol(nsloc + 2, NULL, 10);
		if (nsloc == NULL || (nsid == 0 && errno != 0)) {
			fprintf(stderr,
			    "Invalid namespace ID %s.\n",
			    argv[optind]);
			close(fd);
			exit(EX_IOERR);
		}

		/*
		 * User is asking for per namespace log page information
		 * so close the controller and open up the namespace.
		 */
		close(fd);
		open_dev(argv[optind], &fd, 1, 1);
	} else
		nsid = NVME_GLOBAL_NAMESPACE_TAG;

	print_fn = print_hex;
	if (!hexflag) {
		/*
		 * See if there is a pretty print function for the
		 *  specified log page.  If one isn't found, we
		 *  just revert to the default (print_hex).
		 */
		f = logfuncs;
		while (f->log_page > 0) {
			if (log_page == f->log_page) {
				print_fn = f->fn;
				break;
			}
			f++;
		}
	}

	/* Read the log page */
	switch (log_page) {
	case NVME_LOG_ERROR:
		size = sizeof(struct nvme_error_information_entry);
		size *= (cdata.elpe + 1);
		break;
	case NVME_LOG_HEALTH_INFORMATION:
		size = sizeof(struct nvme_health_information_page);
		break;
	case NVME_LOG_FIRMWARE_SLOT:
		size = sizeof(struct nvme_firmware_page);
		break;
	default:
		size = DEFAULT_SIZE;
		break;
	}

	buf = get_log_buffer(size);
	read_logpage(fd, log_page, nsid, buf, size);
	print_fn(buf, size);

	close(fd);
	exit(EX_OK);
}
示例#12
0
文件: firmware.c 项目: coyizumi/cs111
void
firmware(int argc, char *argv[])
{
	int				fd = -1, slot = 0;
	int				a_flag, s_flag, f_flag;
	int				activate_action, reboot_required;
	char				ch, *p, *image = NULL;
	char				*controller = NULL, prompt[64];
	void				*buf = NULL;
	int32_t				size = 0;
	struct nvme_controller_data	cdata;

	a_flag = s_flag = f_flag = false;

	while ((ch = getopt(argc, argv, "af:s:")) != -1) {
		switch (ch) {
		case 'a':
			a_flag = true;
			break;
		case 's':
			slot = strtol(optarg, &p, 0);
			if (p != NULL && *p != '\0') {
				fprintf(stderr,
				    "\"%s\" not valid slot.\n",
				    optarg);
				firmware_usage();
			} else if (slot == 0) {
				fprintf(stderr,
				    "0 is not a valid slot number. "
				    "Slot numbers start at 1.\n");
				firmware_usage();
			} else if (slot > 7) {
				fprintf(stderr,
				    "Slot number %s specified which is "
				    "greater than max allowed slot number of "
				    "7.\n", optarg);
				firmware_usage();
			}
			s_flag = true;
			break;
		case 'f':
			image = optarg;
			f_flag = true;
			break;
		}
	}

	/* Check that a controller (and not a namespace) was specified. */
	if (optind >= argc || strstr(argv[optind], NVME_NS_PREFIX) != NULL)
		firmware_usage();

	if (!f_flag && !a_flag) {
		fprintf(stderr,
		    "Neither a replace ([-f path_to_firmware]) nor "
		    "activate ([-a]) firmware image action\n"
		    "was specified.\n");
		firmware_usage();
	}

	if (!f_flag && a_flag && slot == 0) {
		fprintf(stderr,
		    "Slot number to activate not specified.\n");
		firmware_usage();
	}

	controller = argv[optind];
	open_dev(controller, &fd, 1, 1);
	read_controller_data(fd, &cdata);

	if (cdata.oacs.firmware == 0)
		errx(1,
		    "controller does not support firmware activate/download");

	if (f_flag && slot == 1 && cdata.frmw.slot1_ro)
		errx(1, "slot %d is marked as read only", slot);

	if (slot > cdata.frmw.num_slots)
		errx(1,
		    "slot %d specified but controller only supports %d slots",
		    slot, cdata.frmw.num_slots);

	if (a_flag && !f_flag && !slot_has_valid_firmware(fd, slot))
		errx(1,
		    "slot %d does not contain valid firmware,\n"
		    "try 'nvmecontrol logpage -p 3 %s' to get a list "
		    "of available images\n",
		    slot, controller);

	if (f_flag)
		read_image_file(image, &buf, &size);

	if (f_flag && a_flag)
		printf("You are about to download and activate "
		       "firmware image (%s) to controller %s.\n"
		       "This may damage your controller and/or "
		       "overwrite an existing firmware image.\n",
		       image, controller);
	else if (a_flag)
		printf("You are about to activate a new firmware "
		       "image on controller %s.\n"
		       "This may damage your controller.\n",
		       controller);
	else if (f_flag)
		printf("You are about to download firmware image "
		       "(%s) to controller %s.\n"
		       "This may damage your controller and/or "
		       "overwrite an existing firmware image.\n",
		       image, controller);

	printf("Are you sure you want to continue? (yes/no) ");
	while (1) {
		fgets(prompt, sizeof(prompt), stdin);
		if (strncasecmp(prompt, "yes", 3) == 0)
			break;
		if (strncasecmp(prompt, "no", 2) == 0)
			exit(1);
		printf("Please answer \"yes\" or \"no\". ");
	}

	if (f_flag) {
		update_firmware(fd, buf, size);
		if (a_flag)
			activate_action = NVME_AA_REPLACE_ACTIVATE;
		else
			activate_action = NVME_AA_REPLACE_NO_ACTIVATE;
	} else {
		activate_action = NVME_AA_ACTIVATE;
	}

	reboot_required = activate_firmware(fd, slot, activate_action);

	if (a_flag) {
		if (reboot_required) {
			printf("New firmware image activated but requires "
			       "conventional reset (i.e. reboot) to "
			       "complete activation.\n");
		} else {
			printf("New firmware image activated and will take "
			       "effect after next controller reset.\n"
			       "Controller reset can be initiated via "
			       "'nvmecontrol reset %s'\n",
			       controller);
		}
	}

	close(fd);
	exit(0);
}