diff options
-rw-r--r-- | util-linux/mdev.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 84e72e2e6..79871d30e 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -756,37 +756,45 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | |||
756 | static void load_firmware(const char *firmware, const char *sysfs_path) | 756 | static void load_firmware(const char *firmware, const char *sysfs_path) |
757 | { | 757 | { |
758 | int cnt; | 758 | int cnt; |
759 | int firmware_fd, loading_fd, data_fd; | 759 | int firmware_fd, loading_fd; |
760 | 760 | ||
761 | /* check for /lib/firmware/$FIRMWARE */ | 761 | /* check for /lib/firmware/$FIRMWARE */ |
762 | xchdir("/lib/firmware"); | 762 | xchdir("/lib/firmware"); |
763 | firmware_fd = xopen(firmware, O_RDONLY); | 763 | firmware_fd = open(firmware, O_RDONLY); /* can fail */ |
764 | |||
765 | /* in case we goto out ... */ | ||
766 | data_fd = -1; | ||
767 | 764 | ||
768 | /* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */ | 765 | /* check for /sys/$DEVPATH/loading ... give 30 seconds to appear */ |
769 | xchdir(sysfs_path); | 766 | xchdir(sysfs_path); |
770 | for (cnt = 0; cnt < 30; ++cnt) { | 767 | for (cnt = 0; cnt < 30; ++cnt) { |
771 | loading_fd = open("loading", O_WRONLY); | 768 | loading_fd = open("loading", O_WRONLY); |
772 | if (loading_fd != -1) | 769 | if (loading_fd >= 0) |
773 | goto loading; | 770 | goto loading; |
774 | sleep(1); | 771 | sleep(1); |
775 | } | 772 | } |
776 | goto out; | 773 | goto out; |
777 | 774 | ||
778 | loading: | 775 | loading: |
779 | /* tell kernel we're loading by "echo 1 > /sys/$DEVPATH/loading" */ | 776 | cnt = 0; |
780 | if (full_write(loading_fd, "1", 1) != 1) | 777 | if (firmware_fd >= 0) { |
781 | goto out; | 778 | int data_fd; |
782 | 779 | ||
783 | /* load firmware into /sys/$DEVPATH/data */ | 780 | /* tell kernel we're loading by "echo 1 > /sys/$DEVPATH/loading" */ |
784 | data_fd = open("data", O_WRONLY); | 781 | if (full_write(loading_fd, "1", 1) != 1) |
785 | if (data_fd == -1) | 782 | goto out; |
786 | goto out; | 783 | |
787 | cnt = bb_copyfd_eof(firmware_fd, data_fd); | 784 | /* load firmware into /sys/$DEVPATH/data */ |
785 | data_fd = open("data", O_WRONLY); | ||
786 | if (data_fd < 0) | ||
787 | goto out; | ||
788 | cnt = bb_copyfd_eof(firmware_fd, data_fd); | ||
789 | if (ENABLE_FEATURE_CLEAN_UP) | ||
790 | close(data_fd); | ||
791 | } | ||
788 | 792 | ||
789 | /* tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading" */ | 793 | /* Tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading" |
794 | * Note: we emit -1 also if firmware file wasn't found. | ||
795 | * There are cases when otherwise kernel would wait for minutes | ||
796 | * before timing out. | ||
797 | */ | ||
790 | if (cnt > 0) | 798 | if (cnt > 0) |
791 | full_write(loading_fd, "0", 1); | 799 | full_write(loading_fd, "0", 1); |
792 | else | 800 | else |
@@ -796,7 +804,6 @@ static void load_firmware(const char *firmware, const char *sysfs_path) | |||
796 | if (ENABLE_FEATURE_CLEAN_UP) { | 804 | if (ENABLE_FEATURE_CLEAN_UP) { |
797 | close(firmware_fd); | 805 | close(firmware_fd); |
798 | close(loading_fd); | 806 | close(loading_fd); |
799 | close(data_fd); | ||
800 | } | 807 | } |
801 | } | 808 | } |
802 | 809 | ||