From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Anton Farygin Organization: ALT Linux Ltd. Date: Thu, 21 Jul 2005 09:55:15 +0400 User-Agent: Pan/0.14.2 (This is not a psychotic episode. It's a cleansing moment of clarity.) Message-Id: To: devel@altlinux.ru MIME-Version: 1.0 Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: 8bit Subject: [devel] [gmane.linux.hotplug.devel] [code] simple udev helper for firmware loading X-BeenThere: devel@altlinux.ru X-Mailman-Version: 2.1.5 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jul 2005 05:58:35 -0000 Archived-At: List-Archive: List-Post: А нам такое надо ? Мне проверят не на чем... кто-то у нас firmware использует ? Rgds, Rider On Wed, 20 Jul 2005 23:33:05 -0400, Bill Nottingham wrote: > As part of the move to newer udev releases, we've been getting rid of > various hotplug agents instead of udev rules. While some (pci, scsi, usb) > are simple transforms, firmware loading still needs a helper. > > Kay asked me to pass this along, so here it is. > > Compile is simply: > gcc -options_of_choice -o firmware_helper firmware_helper.c > > It's invoked via a udev rule as such: > > ACTION=="add", SUBSYSTEM=="firmware", FIRMWARE="*", \ > RUN+="/sbin/firmware_helper" > > Potential improvements: > - better logging of errors > - support for sysfs mounted somewhere other than /sys (port to libsysfs?) > > But it should work fine as-is. Well, barring the inevitable bugs. > > Bill/* > * 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 > #include > #include > #include > #include > #include > #include > > #include > > #define FIRMWARE_PATH "/lib/firmware" > > > void log_err(char *firmware, int err) { > char *driver; > > driver = getenv("PHYSDEVDRIVER"); > if (!driver) > driver = "(unknown)"; > openlog("firmware_helper",LOG_PID,LOG_USER); syslog(LOG_ERR,"Loading of > %s for %s driver failed: %s",firmware, driver, strerror(err)); > closelog(); > } > } > /* Set the 'loading' attribute for a firmware device. > * 1 == currently loading > * 0 == done loading > * -1 == error > */ > int set_loading(char *device, int value) { > char *path; > int rc; > FILE *f; > > path = alloca(strlen(device)+15); > sprintf(path,"/sys/%s/loading", device); f = fopen(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; > struct stat sbuf; > int fw_fd, count; > int rc; > char *fw_path, *data_path; > char *fw_buffer; > > devpath = getenv("DEVPATH"); > if (!devpath) return 0; > > firmware = getenv("FIRMWARE"); > if (!firmware) return 0; > > action = getenv("ACTION"); > if (strcmp(action,"add")) > return 0; > > set_loading(devpath, 1); > > fw_path = malloc(strlen(FIRMWARE_PATH) + strlen(firmware) + 2); if > (!fw_path) { > rc = errno; > goto out_err; > } > } > sprintf(fw_path,"%s/%s", FIRMWARE_PATH, firmware); fw_fd = open(fw_path, > O_RDONLY); > if (fw_fd == -1) { > rc = errno; > goto out_err; > } > } > fstat(fw_fd, &sbuf); > fw_buffer = malloc(sbuf.st_size); > if (!fw_buffer) { > rc = errno; > goto out_err; > } > if (read(fw_fd, fw_buffer, sbuf.st_size) != sbuf.st_size) { > rc = errno; > goto out_err; > } > close(fw_fd); > > data_path = malloc(strlen(devpath) + 12); if (!data_path) { > rc = errno; > goto out_err; > } > } > sprintf(data_path,"/sys/%s/data", devpath); > > fw_fd = open(data_path, O_RDWR); > if (fw_fd == -1) { > rc = errno; > goto out_err; > } > } > count = 0; > while (count < sbuf.st_size) { > int c; > > c = write(fw_fd,fw_buffer+count,sbuf.st_size-count); if (c <= 0) { > rc = errno; > goto out_err; > } > count += c; > } > close(fw_fd); > set_loading(devpath, 0); > return 0; > out_err: > close(fw_fd); > set_loading(devpath, -1); > log_err(fw_path, rc); > return rc; > }