firmware.c revision 5f59fa0900a5c127ce1a25d8ba3176f166662f96
220a21d38f675eb835f5758e3d23e896573aa5eaLennart Poettering * firmware - Load firmware device
b72ddf0f4f552dd53d6404b6ddbc9f17d02b8e12Kay Sievers * Copyright (C) 2009 Piter Punk <piterpunk@slackware.com>
b72ddf0f4f552dd53d6404b6ddbc9f17d02b8e12Kay Sievers * Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org>
b72ddf0f4f552dd53d6404b6ddbc9f17d02b8e12Kay Sievers * This program is free software; you can redistribute it and/or
b72ddf0f4f552dd53d6404b6ddbc9f17d02b8e12Kay Sievers * modify it under the terms of the GNU General Public License as
b72ddf0f4f552dd53d6404b6ddbc9f17d02b8e12Kay Sievers * published by the Free Software Foundation; either version 2 of the
3dff3e00e044e2d53c76fa842b9a4759d4a50e69Kay Sievers * License, or (at your option) any later version.
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering * This program is distributed in the hope that it will be useful, but
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering * WITHOUT ANY WARRANTY; without even the implied warranty of
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering * General Public License for more details:*
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poetteringstatic bool set_loading(struct udev *udev, char *loadpath, const char *state)
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering err(udev, "error: can not open '%s'\n", loadpath);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poetteringstatic bool copy_firmware(struct udev *udev, const char *source, const char *target, size_t size)
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering err(udev,"No memory available to load firmware file");
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering { "firmware", required_argument, NULL, 'f' },
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering { "devpath", required_argument, NULL, 'p' },
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering static const char *searchpath[] = { FIRMWARE_PATH };
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering unsigned int i;
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering option = getopt_long(argc, argv, "f:p:h", options, NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering printf("Usage: firmware --firmware=<fwfile> --devpath=<path> [--help]\n\n");
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering if (devpath == NULL || firmware == NULL) {
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering fprintf(stderr, "firmware or devpath parameter missing\n\n");
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering /* lookup firmware file */
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering for (i = 0; i < ARRAY_SIZE(searchpath); i++) {
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], kernel.release, "/", firmware, NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_strscpyl(fwpath, sizeof(fwpath), searchpath[i], firmware, NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_path_encode(firmware, fwencpath, sizeof(fwencpath));
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_strscpyl(misspath, sizeof(misspath), udev_get_dev_path(udev), "/.run/udev/firmware-missing/", fwencpath, NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_strscpyl(loadpath, sizeof(loadpath), udev_get_sys_path(udev), devpath, "/loading", NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering /* This link indicates the missing firmware file and the associated device */
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering info(udev, "did not find firmware file '%s'\n", firmware);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering udev_selinux_setfscreatecon(udev, misspath, S_IFLNK);
ce1dde29b92d1399ce502e0f7db790a99d14841fThomas Hindoe Paaboel Andersen err = symlink(devpath, misspath);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering if (stat(fwpath, &statbuf) < 0 || statbuf.st_size == 0) {
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
24a2bf4c9b0917231dd4f9b4289eabd46c382d3fLennart Poettering err(udev, "error sending firmware '%s' to device\n", firmware);