xref: /spdk/examples/vmd/led/led.c (revision 57fd99b91e71a4baa5543e19ff83958dc99d4dac)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2019 Intel Corporation.
37135856eSKonrad Sztyber  *   All rights reserved.
47135856eSKonrad Sztyber  */
57135856eSKonrad Sztyber 
67135856eSKonrad Sztyber #include "spdk/stdinc.h"
77135856eSKonrad Sztyber #include "spdk/log.h"
87135856eSKonrad Sztyber #include "spdk/likely.h"
97135856eSKonrad Sztyber #include "spdk/env.h"
107135856eSKonrad Sztyber #include "spdk/vmd.h"
117135856eSKonrad Sztyber 
1263b41c72SJim Harris int g_status;
1363b41c72SJim Harris 
147135856eSKonrad Sztyber enum app_action {
157135856eSKonrad Sztyber 	APP_ACTION_SET,
167135856eSKonrad Sztyber 	APP_ACTION_GET,
177135856eSKonrad Sztyber 	APP_ACTION_NOP,
187135856eSKonrad Sztyber };
197135856eSKonrad Sztyber 
207135856eSKonrad Sztyber struct app_opts {
217135856eSKonrad Sztyber 	const char		*app_name;
227135856eSKonrad Sztyber 	struct spdk_pci_addr	pci_addr;
237135856eSKonrad Sztyber 	bool			all_devices;
247135856eSKonrad Sztyber 	enum app_action		action;
257135856eSKonrad Sztyber 	enum spdk_vmd_led_state	led_state;
267135856eSKonrad Sztyber };
277135856eSKonrad Sztyber 
287135856eSKonrad Sztyber struct app_opts g_opts = {
297135856eSKonrad Sztyber 	.all_devices = true,
307135856eSKonrad Sztyber 	.action = APP_ACTION_GET,
317135856eSKonrad Sztyber 	.led_state = SPDK_VMD_LED_STATE_UNKNOWN,
327135856eSKonrad Sztyber };
337135856eSKonrad Sztyber 
347135856eSKonrad Sztyber static const char *g_led_states[] = {
357135856eSKonrad Sztyber 	[SPDK_VMD_LED_STATE_OFF]	= "off",
367135856eSKonrad Sztyber 	[SPDK_VMD_LED_STATE_IDENTIFY]	= "identify",
377135856eSKonrad Sztyber 	[SPDK_VMD_LED_STATE_FAULT]	= "fault",
387135856eSKonrad Sztyber 	[SPDK_VMD_LED_STATE_REBUILD]	= "rebuild",
397135856eSKonrad Sztyber 	[SPDK_VMD_LED_STATE_UNKNOWN]	= "unknown",
407135856eSKonrad Sztyber };
417135856eSKonrad Sztyber 
427135856eSKonrad Sztyber static void
437135856eSKonrad Sztyber usage(void)
447135856eSKonrad Sztyber {
457135856eSKonrad Sztyber 	printf("Usage: %s [-d] [-s STATE] [-r TRADDR]\n", g_opts.app_name);
467135856eSKonrad Sztyber 	printf("\n");
477135856eSKonrad Sztyber 	printf("Options:\n");
487135856eSKonrad Sztyber 	printf("	-d		enables debug logs from the VMD module\n");
497135856eSKonrad Sztyber 	printf("	-s STATE	sets the state of the LEDs. Available states are:\n");
507135856eSKonrad Sztyber 	printf("			off, identify, fault, rebuild\n");
517135856eSKonrad Sztyber 	printf("	-r TRADDR	uses device identified by TRADDR\n");
527135856eSKonrad Sztyber 	printf("	-h		shows this help\n");
537135856eSKonrad Sztyber }
547135856eSKonrad Sztyber 
557135856eSKonrad Sztyber static int
567135856eSKonrad Sztyber parse_args(int argc, char **argv)
577135856eSKonrad Sztyber {
587135856eSKonrad Sztyber 	int led_state;
597135856eSKonrad Sztyber 	int op;
607135856eSKonrad Sztyber 
617135856eSKonrad Sztyber 	g_opts.app_name = argv[0];
627135856eSKonrad Sztyber 
637135856eSKonrad Sztyber 	while ((op = getopt(argc, argv, "dhr:s:")) != -1) {
647135856eSKonrad Sztyber 		switch (op) {
657135856eSKonrad Sztyber 		case 'r':
667135856eSKonrad Sztyber 			if (spdk_pci_addr_parse(&g_opts.pci_addr, optarg)) {
677135856eSKonrad Sztyber 				fprintf(stderr, "Unable to parse PCI address: %s\n", optarg);
687135856eSKonrad Sztyber 				return -EINVAL;
697135856eSKonrad Sztyber 			}
707135856eSKonrad Sztyber 
717135856eSKonrad Sztyber 			g_opts.all_devices = false;
727135856eSKonrad Sztyber 			break;
737135856eSKonrad Sztyber 
747135856eSKonrad Sztyber 		case 'd':
757135856eSKonrad Sztyber #ifdef DEBUG
767135856eSKonrad Sztyber 			spdk_log_set_print_level(SPDK_LOG_DEBUG);
777135856eSKonrad Sztyber 			spdk_log_set_flag("vmd");
787135856eSKonrad Sztyber 			break;
797135856eSKonrad Sztyber #else
807135856eSKonrad Sztyber 			fprintf(stderr, "%s must be rebuilt with --enable-debug for the -d flag\n",
817135856eSKonrad Sztyber 				argv[0]);
827135856eSKonrad Sztyber 			return -EINVAL;
837135856eSKonrad Sztyber #endif
847135856eSKonrad Sztyber 		case 's':
857135856eSKonrad Sztyber 			for (led_state = SPDK_VMD_LED_STATE_OFF;
867135856eSKonrad Sztyber 			     led_state <= SPDK_VMD_LED_STATE_REBUILD;
877135856eSKonrad Sztyber 			     led_state++) {
887135856eSKonrad Sztyber 				if (strcmp(optarg, g_led_states[led_state]) == 0) {
897135856eSKonrad Sztyber 					g_opts.led_state = (enum spdk_vmd_led_state)led_state;
907135856eSKonrad Sztyber 					break;
917135856eSKonrad Sztyber 				}
927135856eSKonrad Sztyber 			}
937135856eSKonrad Sztyber 
947135856eSKonrad Sztyber 			if (g_opts.led_state == SPDK_VMD_LED_STATE_UNKNOWN) {
957135856eSKonrad Sztyber 				fprintf(stderr, "Invalid LED state\n");
967135856eSKonrad Sztyber 				return -EINVAL;
977135856eSKonrad Sztyber 			}
987135856eSKonrad Sztyber 
997135856eSKonrad Sztyber 			g_opts.action = APP_ACTION_SET;
1007135856eSKonrad Sztyber 			break;
1017135856eSKonrad Sztyber 
1027135856eSKonrad Sztyber 		case 'h':
1037135856eSKonrad Sztyber 			g_opts.action = APP_ACTION_NOP;
1047135856eSKonrad Sztyber 			usage();
1057135856eSKonrad Sztyber 			break;
1067135856eSKonrad Sztyber 
1077135856eSKonrad Sztyber 		default:
1087135856eSKonrad Sztyber 			return -EINVAL;
1097135856eSKonrad Sztyber 		}
1107135856eSKonrad Sztyber 	}
1117135856eSKonrad Sztyber 
1127135856eSKonrad Sztyber 	return 0;
1137135856eSKonrad Sztyber }
1147135856eSKonrad Sztyber 
11563b41c72SJim Harris static void
11663b41c72SJim Harris led_device_action(void *ctx, struct spdk_pci_device *pci_device)
11763b41c72SJim Harris {
11863b41c72SJim Harris 	enum spdk_vmd_led_state led_state;
11963b41c72SJim Harris 	char addr_buf[128];
12063b41c72SJim Harris 	int rc;
12163b41c72SJim Harris 
12263b41c72SJim Harris 	if (strcmp(spdk_pci_device_get_type(pci_device), "vmd") != 0) {
12363b41c72SJim Harris 		return;
12463b41c72SJim Harris 	}
12563b41c72SJim Harris 
12663b41c72SJim Harris 	if (!g_opts.all_devices &&
12763b41c72SJim Harris 	    spdk_pci_addr_compare(&g_opts.pci_addr, &pci_device->addr) != 0) {
12863b41c72SJim Harris 		return;
12963b41c72SJim Harris 	}
13063b41c72SJim Harris 
13163b41c72SJim Harris 	rc = spdk_pci_addr_fmt(addr_buf, sizeof(addr_buf), &pci_device->addr);
13263b41c72SJim Harris 	if (rc != 0) {
13363b41c72SJim Harris 		fprintf(stderr, "Failed to format VMD's PCI address\n");
13463b41c72SJim Harris 		g_status = 1;
13563b41c72SJim Harris 		return;
13663b41c72SJim Harris 	}
13763b41c72SJim Harris 
13863b41c72SJim Harris 	if (g_opts.action == APP_ACTION_GET) {
13963b41c72SJim Harris 		rc = spdk_vmd_get_led_state(pci_device, &led_state);
14063b41c72SJim Harris 		if (spdk_unlikely(rc != 0)) {
14163b41c72SJim Harris 			fprintf(stderr, "Failed to retrieve the state of the LED on %s\n",
14263b41c72SJim Harris 				addr_buf);
14363b41c72SJim Harris 			g_status = 1;
14463b41c72SJim Harris 			return;
14563b41c72SJim Harris 		}
14663b41c72SJim Harris 
14763b41c72SJim Harris 		printf("%s: %s\n", addr_buf, g_led_states[led_state]);
14863b41c72SJim Harris 	} else {
14963b41c72SJim Harris 		rc = spdk_vmd_set_led_state(pci_device, g_opts.led_state);
15063b41c72SJim Harris 		if (spdk_unlikely(rc != 0)) {
15163b41c72SJim Harris 			fprintf(stderr, "Failed to set LED state on %s\n", addr_buf);
15263b41c72SJim Harris 			g_status = 1;
15363b41c72SJim Harris 			return;
15463b41c72SJim Harris 		}
15563b41c72SJim Harris 	}
15663b41c72SJim Harris }
15763b41c72SJim Harris 
1587135856eSKonrad Sztyber int
1597135856eSKonrad Sztyber main(int argc, char **argv)
1607135856eSKonrad Sztyber {
1617135856eSKonrad Sztyber 	struct spdk_env_opts opts;
16263b41c72SJim Harris 	int rc;
1637135856eSKonrad Sztyber 
1647135856eSKonrad Sztyber 	if (parse_args(argc, argv) != 0) {
1657135856eSKonrad Sztyber 		usage();
1667135856eSKonrad Sztyber 		return 1;
1677135856eSKonrad Sztyber 	}
1687135856eSKonrad Sztyber 
1697135856eSKonrad Sztyber 	if (g_opts.action == APP_ACTION_NOP) {
1707135856eSKonrad Sztyber 		return 0;
1717135856eSKonrad Sztyber 	}
1727135856eSKonrad Sztyber 
173*57fd99b9SJim Harris 	opts.opts_size = sizeof(opts);
1747135856eSKonrad Sztyber 	spdk_env_opts_init(&opts);
1757135856eSKonrad Sztyber 	opts.name = "led";
1767135856eSKonrad Sztyber 
1777135856eSKonrad Sztyber 	if (spdk_env_init(&opts) < 0) {
1787135856eSKonrad Sztyber 		fprintf(stderr, "Unable to initialize SPDK environment\n");
1797135856eSKonrad Sztyber 		return 1;
1807135856eSKonrad Sztyber 	}
1817135856eSKonrad Sztyber 
1827135856eSKonrad Sztyber 	rc = spdk_vmd_init();
1837135856eSKonrad Sztyber 	if (rc) {
1847135856eSKonrad Sztyber 		fprintf(stderr, "Unable to initialize VMD subsystem\n");
185f2aa5435SChangpeng Liu 		spdk_env_fini();
1867135856eSKonrad Sztyber 		return 1;
1877135856eSKonrad Sztyber 	}
1887135856eSKonrad Sztyber 
18963b41c72SJim Harris 	spdk_pci_for_each_device(NULL, led_device_action);
1907135856eSKonrad Sztyber 
191ce6171d4SKonrad Sztyber 	spdk_vmd_fini();
192ce6171d4SKonrad Sztyber 
193f2aa5435SChangpeng Liu 	spdk_env_fini();
19463b41c72SJim Harris 	return g_status;
1957135856eSKonrad Sztyber }
196