Skip to content
Snippets Groups Projects
fmc-slot-eeprom.c 2.82 KiB
Newer Older
/*
 * SPDX-License-Identifier: LGPL-3.0-or-later
 * Copyright (C) 2020 CERN (www.cern.ch)
 * Author: Federico Vaga <federico.vaga@cern.ch>
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <getopt.h>
#include <limits.h>
#include <errno.h>
#include <fmc/core.h>


static const char git_version[] = "git version: " GIT_VERSION;
static char *name;

static void help(void)
{
	fprintf(stderr, "%s: Lists FMC carriers and Mezzanines\n"
		"\t-V  print version\n"
		"\t-h  print help\n"
		"\t-c  carrier number\n"
		"\t-s  slot number\n"
		"\t-t  EEPROM type to set\n"
		"\t-d  dump EEPROM content\n",
		name);
}

static void print_version(void)
{
	printf("%s version %s\nFMC library version: %s\n",
	       name, git_version, fmc_version_get());
}

static void print_dump(struct fmc_tkn *fmc, unsigned int slot_n,
		       const char *eeprom_type)
{
	char *buf;
	unsigned int len;
	int ret;

	ret = fmc_slot_eeprom_size(fmc, slot_n, &len);
	if (ret < 0)
		fputs("Failed to get EEPROM size\n", stderr);

	buf = malloc(len);
	if (!buf) {
		fputs("Failed to allocate buffer\n", stderr);
		return;
	}
	ret = fmc_slot_eeprom_read(fmc, slot_n, buf, len, 0);
	if (ret > 0)
		fwrite(buf, len, 1, stdout);
	else
		fputs("Failed to read EEPROM\n", stderr);
}

int main(int argc, char *argv[])
{
	struct fmc_tkn *fmc;
	unsigned int carr_n = FMC_ID_INVALID;
	unsigned int slot_n = FMC_ID_INVALID;
	char *eeprom_type = NULL;
	char eeprom_type_rb[16];
	int err = 0;
	char opt;

	name = strndup(basename(argv[0]), 64);
	if (!name) {
		err = -1;
		goto out_strdup;
	}
	while ((opt = getopt(argc, argv, "h?Vc:s:t:d")) != -1) {
		switch (opt) {
		case 'h':
		case '?':
			help();
			exit(EXIT_SUCCESS);
			break;
		case 'V':
			print_version();
			exit(EXIT_SUCCESS);
		case 'c':
			carr_n = strtoul(optarg, NULL, 10);
			if (errno == ERANGE || errno == EINVAL)
				goto out_opt;
			break;
		case 's':
			slot_n = strtoul(optarg, NULL, 10);
			if (errno == ERANGE || errno == EINVAL)
				goto out_opt;
			break;
		case 't':
			eeprom_type = optarg;
			break;
		case 'd':
			dump = 1;
			break;
		}
	}
	if (carr_n == FMC_ID_INVALID || slot_n == FMC_ID_INVALID) {
		fputs("Option '-c' and '-s' are mandatory\n", stderr);
		goto out_invalid;
	}

	fmc = fmc_carrier_open(carr_n);
	if (!fmc)
		goto out_open;
	if (eeprom_type) {
		err = fmc_slot_eeprom_type_set(fmc, slot_n,
					       eeprom_type,
					       sizeof(eeprom_type));
		if (err < 0)
			fputs("Can't set EEPROM\n", stderr);
	}
	fmc_slot_eeprom_type_get(fmc, slot_n,
				 eeprom_type_rb, sizeof(eeprom_type_rb));
	if (dump == 0)
		fprintf(stdout, "fmc-slot.%u.%u EEPROM type %s\n",
			carr_n, slot_n, eeprom_type_rb);
	else
		print_dump(fmc, slot_n, eeprom_type_rb);

	fmc_carrier_close(fmc);
out_open:
out_invalid:
out_opt:
	free(name);
out_strdup:
	exit(err ? EXIT_FAILURE : EXIT_SUCCESS);
}