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