mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
add firmware_helper to load firmware
From: Bill Nottingham <notting@redhat.com> Changed reading of firmware blob to mmap and let firmware_helper follow the setting of the log level with UDEV_LOG.
This commit is contained in:
parent
1bcac4e483
commit
bebbc31b90
51
extras/firmware/Makefile
Normal file
51
extras/firmware/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
# Makefile for usb_id
|
||||
#
|
||||
# Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
|
||||
PROG = firmware_helper
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
prefix =
|
||||
exec_prefix = ${prefix}
|
||||
etcdir = ${prefix}/etc
|
||||
sbindir = ${exec_prefix}/sbin
|
||||
usrbindir = ${exec_prefix}/usr/bin
|
||||
usrsbindir = ${exec_prefix}/usr/sbin
|
||||
mandir = ${prefix}/usr/share/man
|
||||
devddir = ${etcdir}/dev.d/default
|
||||
configdir = ${etcdir}/udev/
|
||||
initdir = ${etcdir}/init.d/
|
||||
srcdir = .
|
||||
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_SCRIPT = ${INSTALL_PROGRAM}
|
||||
|
||||
OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a
|
||||
HEADERS =
|
||||
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
.c.o:
|
||||
$(QUIET) $(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(PROG): $(OBJS) $(HEADERS)
|
||||
$(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
spotless: clean
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
|
||||
|
||||
uninstall:
|
||||
- rm $(DESTDIR)$(sbindir)/$(PROG)
|
147
extras/firmware/firmware_helper.c
Normal file
147
extras/firmware/firmware_helper.c
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* A simple firmware helper program.
|
||||
*
|
||||
* Copyright 2005 Red Hat, Inc.
|
||||
*
|
||||
* This software may be freely redistributed under the terms of the GNU
|
||||
* public license.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../../udev_utils.h"
|
||||
#include "../../logging.h"
|
||||
|
||||
#define FIRMWARE_PATH "/lib/firmware"
|
||||
#define PATH_SIZE 256
|
||||
|
||||
#ifdef USE_LOG
|
||||
void log_message(int priority, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
static int udev_log = -1;
|
||||
|
||||
if (udev_log == -1) {
|
||||
const char *value;
|
||||
|
||||
value = getenv("UDEV_LOG");
|
||||
if (value)
|
||||
udev_log = log_priority(value);
|
||||
else
|
||||
udev_log = LOG_ERR;
|
||||
}
|
||||
|
||||
if (priority > udev_log)
|
||||
return;
|
||||
|
||||
va_start(args, format);
|
||||
vsyslog(priority, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the 'loading' attribute for a firmware device.
|
||||
* 1 == currently loading
|
||||
* 0 == done loading
|
||||
* -1 == error
|
||||
*/
|
||||
static int set_loading(const char *device, int value) {
|
||||
char loading_path[PATH_SIZE];
|
||||
int rc;
|
||||
FILE *f;
|
||||
|
||||
snprintf(loading_path, sizeof(loading_path), "/sys/%s/loading", device);
|
||||
loading_path[sizeof(loading_path)-1] = '\0';
|
||||
f = fopen(loading_path, "w");
|
||||
if (!f)
|
||||
return -1;
|
||||
rc = fprintf(f, "%d", value);
|
||||
fclose(f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *devpath, *firmware, *action, *driver;
|
||||
char fw_path[PATH_SIZE];
|
||||
char data_path[PATH_SIZE];
|
||||
int fw_fd;
|
||||
char *fw_buffer;
|
||||
size_t fw_buffer_size;
|
||||
size_t count;
|
||||
int rc = 0;
|
||||
|
||||
logging_init("firmware_helper");
|
||||
|
||||
driver = getenv("PHYSDEVDRIVER");
|
||||
if (!driver)
|
||||
driver = "(unknown)";
|
||||
devpath = getenv("DEVPATH");
|
||||
firmware = getenv("FIRMWARE");
|
||||
action = getenv("ACTION");
|
||||
if (!devpath || !firmware || !action || strcmp(action,"add") != 0) {
|
||||
err("missing devpath, action or firmware");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dbg("try to load firmware '%s' for '%s'", firmware, devpath);
|
||||
set_loading(devpath, 1);
|
||||
|
||||
snprintf(fw_path, sizeof(fw_path), "%s/%s", FIRMWARE_PATH, firmware);
|
||||
fw_path[sizeof(fw_path)-1] = '\0';
|
||||
if (file_map(fw_path, &fw_buffer, &fw_buffer_size) != 0 || fw_buffer_size == 0) {
|
||||
err("could not load firmware '%s' for '%s'", fw_path, devpath);
|
||||
fw_buffer = NULL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
snprintf(data_path, sizeof(data_path), "/sys/%s/data", devpath);
|
||||
fw_path[sizeof(data_path)-1] = '\0';
|
||||
fw_fd = open(data_path, O_RDWR);
|
||||
if (fw_fd < 0) {
|
||||
rc = errno;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (count < fw_buffer_size) {
|
||||
int c;
|
||||
|
||||
c = write(fw_fd, fw_buffer+count, fw_buffer_size);
|
||||
if (c <= 0) {
|
||||
rc = errno;
|
||||
close(fw_fd);
|
||||
goto out_err;
|
||||
}
|
||||
count += c;
|
||||
}
|
||||
|
||||
close(fw_fd);
|
||||
file_unmap(fw_buffer, fw_buffer_size);
|
||||
set_loading(devpath, 0);
|
||||
info("loaded '%s' for device '%s'", fw_path, devpath);
|
||||
logging_close();
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
if (fw_buffer)
|
||||
file_unmap(fw_buffer, fw_buffer_size);
|
||||
set_loading(devpath, -1);
|
||||
|
||||
err("error loading '%s' for device '%s' with driver '%s'", fw_path, devpath, driver);
|
||||
logging_close();
|
||||
return rc;
|
||||
}
|
@ -38,7 +38,7 @@
|
||||
#undef err
|
||||
#define err(format, arg...) \
|
||||
do { \
|
||||
log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \
|
||||
log_message(LOG_ERR ,"%s: " format ,__FILE__ ,## arg); \
|
||||
} while (0)
|
||||
|
||||
#undef info
|
||||
|
@ -8,7 +8,8 @@ EXTRAS="\
|
||||
extras/usb_id \
|
||||
extras/dasd_id \
|
||||
extras/floppy \
|
||||
extras/run_directory"
|
||||
extras/run_directory \
|
||||
extras/firmware"
|
||||
|
||||
[ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build
|
||||
echo KERNEL_DIR: "$KERNEL_DIR"
|
||||
|
Loading…
Reference in New Issue
Block a user