11.1Sjmcneill/* $NetBSD: firmload.c,v 1.1 2017/08/10 20:43:12 jmcneill Exp $ */
21.1Sjmcneill
31.1Sjmcneill/*-
41.1Sjmcneill * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
51.1Sjmcneill * All rights reserved.
61.1Sjmcneill *
71.1Sjmcneill * Redistribution and use in source and binary forms, with or without
81.1Sjmcneill * modification, are permitted provided that the following conditions
91.1Sjmcneill * are met:
101.1Sjmcneill * 1. Redistributions of source code must retain the above copyright
111.1Sjmcneill *    notice, this list of conditions and the following disclaimer.
121.1Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright
131.1Sjmcneill *    notice, this list of conditions and the following disclaimer in the
141.1Sjmcneill *    documentation and/or other materials provided with the distribution.
151.1Sjmcneill *
161.1Sjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
171.1Sjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
181.1Sjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191.1Sjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
201.1Sjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
211.1Sjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
221.1Sjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
231.1Sjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241.1Sjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
251.1Sjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261.1Sjmcneill * SUCH DAMAGE.
271.1Sjmcneill */
281.1Sjmcneill
291.1Sjmcneill#include <sys/param.h>
301.1Sjmcneill#include <sys/sysctl.h>
311.1Sjmcneill#include <fcntl.h>
321.1Sjmcneill#include <stdio.h>
331.1Sjmcneill#include <stdlib.h>
341.1Sjmcneill#include <string.h>
351.1Sjmcneill
361.1Sjmcneill#include "firmload.h"
371.1Sjmcneill
381.1Sjmcneill#define HW_FIRMWARE_PATH	"hw.firmware.path"
391.1Sjmcneill#define	HW_FIRMWARE_PATH_DELIM	":"
401.1Sjmcneill
411.1Sjmcneillstatic int
421.1Sjmcneillfirmware_search(char *paths, const char *drvname, const char *imgname)
431.1Sjmcneill{
441.1Sjmcneill	char *p, *f;
451.1Sjmcneill	const int debug = getenv("FIRMWARE_DEBUG") != NULL;
461.1Sjmcneill	int fd;
471.1Sjmcneill
481.1Sjmcneill	p = strtok(paths, HW_FIRMWARE_PATH_DELIM);
491.1Sjmcneill	while (p) {
501.1Sjmcneill		if (asprintf(&f, "%s/%s/%s", p, drvname, imgname) == -1)
511.1Sjmcneill			return -1;
521.1Sjmcneill		if (debug)
531.1Sjmcneill			printf("%s: trying %s...\n", __func__, f);
541.1Sjmcneill		fd = open(f, O_RDONLY);
551.1Sjmcneill		free(f);
561.1Sjmcneill		if (fd != -1) {
571.1Sjmcneill			if (debug)
581.1Sjmcneill				printf("%s: using image at %s\n", __func__, f);
591.1Sjmcneill			return fd;
601.1Sjmcneill		}
611.1Sjmcneill		p = strtok(NULL, HW_FIRMWARE_PATH_DELIM);
621.1Sjmcneill	}
631.1Sjmcneill
641.1Sjmcneill	/* Not found */
651.1Sjmcneill	return -1;
661.1Sjmcneill}
671.1Sjmcneill
681.1Sjmcneillint
691.1Sjmcneillfirmware_open(const char *drvname, const char *imgname)
701.1Sjmcneill{
711.1Sjmcneill	size_t len;
721.1Sjmcneill	char *paths;
731.1Sjmcneill	int fd;
741.1Sjmcneill
751.1Sjmcneill	paths = asysctlbyname(HW_FIRMWARE_PATH, &len);
761.1Sjmcneill	if (paths == NULL)
771.1Sjmcneill		return -1;
781.1Sjmcneill
791.1Sjmcneill	fd = firmware_search(paths, drvname, imgname);
801.1Sjmcneill
811.1Sjmcneill	free(paths);
821.1Sjmcneill
831.1Sjmcneill	return fd;
841.1Sjmcneill}
85