udev-builtin-firmware.c revision 85eaf38c3b2fd70a8b01b72bbdb936c0a5944b3c
b341a780162d809b187a8f35a10bba7642b69798vboxsync * firmware - Kernel firmware loader
b341a780162d809b187a8f35a10bba7642b69798vboxsync * Copyright (C) 2009 Piter Punk <piterpunk@slackware.com>
b341a780162d809b187a8f35a10bba7642b69798vboxsync * Copyright (C) 2009-2011 Kay Sievers <kay.sievers@vrfy.org>
b341a780162d809b187a8f35a10bba7642b69798vboxsync * This program is free software; you can redistribute it and/or
b341a780162d809b187a8f35a10bba7642b69798vboxsync * modify it under the terms of the GNU General Public License as
b341a780162d809b187a8f35a10bba7642b69798vboxsync * published by the Free Software Foundation; either version 2 of the
b341a780162d809b187a8f35a10bba7642b69798vboxsync * License, or (at your option) any later version.
b341a780162d809b187a8f35a10bba7642b69798vboxsync * This program is distributed in the hope that it will be useful, but
b341a780162d809b187a8f35a10bba7642b69798vboxsync * WITHOUT ANY WARRANTY; without even the implied warranty of
b341a780162d809b187a8f35a10bba7642b69798vboxsync * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b341a780162d809b187a8f35a10bba7642b69798vboxsync * General Public License for more details:*
b341a780162d809b187a8f35a10bba7642b69798vboxsyncstatic bool set_loading(struct udev *udev, char *loadpath, const char *state)
99ea85d57b86febcbb71ed923c8e628ef9406105vboxsync return false;
b341a780162d809b187a8f35a10bba7642b69798vboxsync return true;
b341a780162d809b187a8f35a10bba7642b69798vboxsyncstatic bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size)
b341a780162d809b187a8f35a10bba7642b69798vboxsync bool ret = false;
b341a780162d809b187a8f35a10bba7642b69798vboxsync err(udev,"No memory available to load firmware file");
b341a780162d809b187a8f35a10bba7642b69798vboxsync return false;
b341a780162d809b187a8f35a10bba7642b69798vboxsync info(udev, "writing '%s' (%zi) to '%s'\n", source, size, target);
b341a780162d809b187a8f35a10bba7642b69798vboxsyncstatic int builtin_firmware(struct udev_device *dev, int argc, char *argv[], bool test)
b341a780162d809b187a8f35a10bba7642b69798vboxsync static const char *searchpath[] = { FIRMWARE_PATH };
f7422473f089cb7f3b8be1c3fc223c441627d15cvboxsync const char *firmware;
b341a780162d809b187a8f35a10bba7642b69798vboxsync unsigned int i;
b341a780162d809b187a8f35a10bba7642b69798vboxsync firmware = udev_device_get_property_value(dev, "FIRMWARE");
b341a780162d809b187a8f35a10bba7642b69798vboxsync /* lookup firmware file */
b341a780162d809b187a8f35a10bba7642b69798vboxsync util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
374979da4e9440f386798bce28aa9165f3fb5e3avboxsync util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
cae5cca5168e18e168df5541b11f462b60062a7avboxsync util_path_encode(firmware, fwencpath, sizeof(fwencpath));
b341a780162d809b187a8f35a10bba7642b69798vboxsync util_strscpyl(misspath, sizeof(misspath), udev_get_run_path(udev), "/firmware-missing/", fwencpath, NULL);
b341a780162d809b187a8f35a10bba7642b69798vboxsync util_strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL);
b341a780162d809b187a8f35a10bba7642b69798vboxsync /* This link indicates the missing firmware file and the associated device */
b341a780162d809b187a8f35a10bba7642b69798vboxsync info(udev, "did not find firmware file '%s'\n", firmware);
b341a780162d809b187a8f35a10bba7642b69798vboxsync err = symlink(udev_device_get_devpath(dev), misspath);
a4b605335b7e6a6ba6d5a301bc96de0e89e4b663vboxsync if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
b341a780162d809b187a8f35a10bba7642b69798vboxsync util_strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL);
b341a780162d809b187a8f35a10bba7642b69798vboxsync if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
b341a780162d809b187a8f35a10bba7642b69798vboxsync err(udev, "error sending firmware '%s' to device\n", firmware);