Author: cem
Date: Wed Nov 14 00:21:49 2018
New Revision: 340421
URL: https://svnweb.freebsd.org/changeset/base/340421

Log:
  cpucontrol(8): De-duplicate common update logic
  
  Every µcode-updater must open the cpucontrol devfs node RDWR, open a
  firmware file, validate the FW file has a positive length, mmap it, etc.
  De-duplicate that identical logic between every individual platform.
  
  Also, constify references to the readonly-mapped firmware files while here.
  
  Sponsored by: Dell EMC Isilon

Modified:
  head/usr.sbin/cpucontrol/amd.c
  head/usr.sbin/cpucontrol/amd10h.c
  head/usr.sbin/cpucontrol/cpucontrol.c
  head/usr.sbin/cpucontrol/cpucontrol.h
  head/usr.sbin/cpucontrol/intel.c
  head/usr.sbin/cpucontrol/via.c

Modified: head/usr.sbin/cpucontrol/amd.c
==============================================================================
--- head/usr.sbin/cpucontrol/amd.c      Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/amd.c      Wed Nov 14 00:21:49 2018        
(r340421)
@@ -73,16 +73,16 @@ amd_probe(int fd)
 }
 
 void
-amd_update(const char *dev, const char *path)
+amd_update(const struct ucode_update_params *params)
 {
-       int fd, devfd;
+       int devfd;
        unsigned int i;
-       struct stat st;
-       uint32_t *fw_image;
-       amd_fw_header_t *fw_header;
+       const char *dev, *path;
+       const uint32_t *fw_image;
+       const amd_fw_header_t *fw_header;
        uint32_t sum;
        uint32_t signature;
-       uint32_t *fw_data;
+       const uint32_t *fw_data;
        size_t fw_size;
        cpuctl_cpuid_args_t idargs = {
                .level  = 1,    /* Request signature. */
@@ -90,16 +90,14 @@ amd_update(const char *dev, const char *path)
        cpuctl_update_args_t args;
        int error;
 
+       dev = params->dev_path;
+       path = params->fw_path;
+       devfd = params->devfd;
+       fw_image = params->fwimage;
+
        assert(path);
        assert(dev);
 
-       fd  = -1;
-       fw_image = MAP_FAILED;
-       devfd = open(dev, O_RDWR);
-       if (devfd < 0) {
-               WARN(0, "could not open %s for writing", dev);
-               return;
-       }
        error = ioctl(devfd, CPUCTL_CPUID, &idargs);
        if (error < 0) {
                WARN(0, "ioctl()");
@@ -115,37 +113,18 @@ amd_update(const char *dev, const char *path)
        /*
         * Open the firmware file.
         */
-       fd = open(path, O_RDONLY, 0);
-       if (fd < 0) {
-               WARN(0, "open(%s)", path);
-               goto fail;
-       }
-       error = fstat(fd, &st);
-       if (error != 0) {
-               WARN(0, "fstat(%s)", path);
-               goto fail;
-       }
-       if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+       if (params->fwsize < sizeof(*fw_header)) {
                WARNX(2, "file too short: %s", path);
                goto fail;
        }
-       /*
-        * mmap the whole image.
-        */
-       fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-           MAP_PRIVATE, fd, 0);
-       if  (fw_image == MAP_FAILED) {
-               WARN(0, "mmap(%s)", path);
-               goto fail;
-       }
-       fw_header = (amd_fw_header_t *)fw_image;
+       fw_header = (const amd_fw_header_t *)fw_image;
        if ((fw_header->magic >> 8) != AMD_MAGIC) {
                WARNX(2, "%s is not a valid amd firmware: version mismatch",
                    path);
                goto fail;
        }
-       fw_data = (uint32_t *)(fw_header + 1);
-       fw_size = (st.st_size - sizeof(*fw_header)) / sizeof(uint32_t);
+       fw_data = (const uint32_t *)(fw_header + 1);
+       fw_size = (params->fwsize - sizeof(*fw_header)) / sizeof(uint32_t);
 
        /*
         * Check the primary checksum.
@@ -160,8 +139,8 @@ amd_update(const char *dev, const char *path)
        if (signature == fw_header->signature) {
                fprintf(stderr, "%s: updating cpu %s... ", path, dev);
 
-               args.data = fw_image;
-               args.size = st.st_size;
+               args.data = __DECONST(void *, fw_image);
+               args.size = params->fwsize;
                error = ioctl(devfd, CPUCTL_UPDATE, &args);
                if (error < 0) {
                        fprintf(stderr, "failed.\n");
@@ -172,12 +151,5 @@ amd_update(const char *dev, const char *path)
        }
 
 fail:
-       if (fd >= 0)
-               close(fd);
-       if (devfd >= 0)
-               close(devfd);
-       if (fw_image != MAP_FAILED)
-               if(munmap(fw_image, st.st_size) != 0)
-                       warn("munmap(%s)", path);
        return;
 }

Modified: head/usr.sbin/cpucontrol/amd10h.c
==============================================================================
--- head/usr.sbin/cpucontrol/amd10h.c   Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/amd10h.c   Wed Nov 14 00:21:49 2018        
(r340421)
@@ -88,9 +88,8 @@ amd10h_probe(int fd)
  * source code.
  */
 void
-amd10h_update(const char *dev, const char *path)
+amd10h_update(const struct ucode_update_params *params)
 {
-       struct stat st;
        cpuctl_cpuid_args_t idargs;
        cpuctl_msr_args_t msrargs;
        cpuctl_update_args_t args;
@@ -100,27 +99,27 @@ amd10h_update(const char *dev, const char *path)
        const section_header_t *section_header;
        const container_header_t *container_header;
        const uint8_t *fw_data;
-       uint8_t *fw_image;
+       const uint8_t *fw_image;
+       const char *dev, *path;
        size_t fw_size;
        size_t selected_size;
        uint32_t revision;
        uint32_t new_rev;
        uint32_t signature;
        uint16_t equiv_id;
-       int fd, devfd;
+       int devfd;
        unsigned int i;
        int error;
 
+       dev = params->dev_path;
+       path = params->fw_path;
+       devfd = params->devfd;
+       fw_image = params->fwimage;
+       fw_size = params->fwsize;
+
        assert(path);
        assert(dev);
 
-       fd = -1;
-       fw_image = MAP_FAILED;
-       devfd = open(dev, O_RDWR);
-       if (devfd < 0) {
-               WARN(0, "could not open %s for writing", dev);
-               return;
-       }
        idargs.level = 1;
        error = ioctl(devfd, CPUCTL_CPUID, &idargs);
        if (error < 0) {
@@ -149,33 +148,15 @@ amd10h_update(const char *dev, const char *path)
         * Open the firmware file.
         */
        WARNX(1, "checking %s for update.", path);
-       fd = open(path, O_RDONLY, 0);
-       if (fd < 0) {
-               WARN(0, "open(%s)", path);
-               goto done;
-       }
-       error = fstat(fd, &st);
-       if (error != 0) {
-               WARN(0, "fstat(%s)", path);
-               goto done;
-       }
-       if (st.st_size < 0 || (size_t)st.st_size <
+       if (fw_size <
            (sizeof(*container_header) + sizeof(*section_header))) {
                WARNX(2, "file too short: %s", path);
                goto done;
        }
-       fw_size = st.st_size;
 
        /*
         * mmap the whole image.
         */
-       fw_image = (uint8_t *)mmap(NULL, st.st_size, PROT_READ,
-           MAP_PRIVATE, fd, 0);
-       if (fw_image == MAP_FAILED) {
-               WARN(0, "mmap(%s)", path);
-               goto done;
-       }
-
        fw_data = fw_image;
        container_header = (const container_header_t *)fw_data;
        if (container_header->magic != AMD_10H_MAGIC) {
@@ -306,12 +287,5 @@ amd10h_update(const char *dev, const char *path)
                WARNX(0, "revision after update %#x", new_rev);
 
 done:
-       if (fd >= 0)
-               close(fd);
-       if (devfd >= 0)
-               close(devfd);
-       if (fw_image != MAP_FAILED)
-               if (munmap(fw_image, st.st_size) != 0)
-                       warn("munmap(%s)", path);
        return;
 }

Modified: head/usr.sbin/cpucontrol/cpucontrol.c
==============================================================================
--- head/usr.sbin/cpucontrol/cpucontrol.c       Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/cpucontrol.c       Wed Nov 14 00:21:49 2018        
(r340421)
@@ -34,18 +34,20 @@
 __FBSDID("$FreeBSD$");
 
 #include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <fcntl.h>
-#include <err.h>
 #include <sysexits.h>
-#include <dirent.h>
 
 #include <sys/queue.h>
 #include <sys/param.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/cpuctl.h>
@@ -74,16 +76,6 @@ int  verbosity_level = 0;
 #define        HIGH(val)       (uint32_t)(((val) >> 32) & 0xffffffff)
 #define        LOW(val)        (uint32_t)((val) & 0xffffffff)
 
-/*
- * Macros for freeing SLISTs, probably must be in /sys/queue.h
- */
-#define        SLIST_FREE(head, field, freef) do {                             
\
-               typeof(SLIST_FIRST(head)) __elm0;                       \
-               typeof(SLIST_FIRST(head)) __elm;                        \
-               SLIST_FOREACH_SAFE(__elm, (head), field, __elm0)        \
-                       (void)(freef)(__elm);                           \
-} while(0);
-
 struct datadir {
        const char              *path;
        SLIST_ENTRY(datadir)    next;
@@ -102,7 +94,6 @@ static struct ucode_handler {
 #define NHANDLERS (sizeof(handlers) / sizeof(*handlers))
 
 static void    usage(void);
-static int     isdir(const char *path);
 static int     do_cpuid(const char *cmdarg, const char *dev);
 static int     do_cpuid_count(const char *cmdarg, const char *dev);
 static int     do_msr(const char *cmdarg, const char *dev);
@@ -123,20 +114,6 @@ usage(void)
 }
 
 static int
-isdir(const char *path)
-{
-       int error;
-       struct stat st;
-
-       error = stat(path, &st);
-       if (error < 0) {
-               WARN(0, "stat(%s)", path);
-               return (error);
-       }
-       return (st.st_mode & S_IFDIR);
-}
-
-static int
 do_cpuid(const char *cmdarg, const char *dev)
 {
        unsigned int level;
@@ -361,16 +338,77 @@ do_eval_cpu_features(const char *dev)
 }
 
 static int
+try_a_fw_image(const char *dev_path, int devfd, int fwdfd, const char *dpath,
+    const char *fname, struct ucode_handler *handler)
+{
+       struct ucode_update_params parm;
+       struct stat st;
+       char *fw_path;
+       void *fw_map;
+       int fwfd, rc;
+
+       rc = 0;
+       fw_path = NULL;
+       fw_map = MAP_FAILED;
+       fwfd = openat(fwdfd, fname, O_RDONLY);
+       if (fwfd < 0) {
+               WARN(0, "openat(%s, %s)", dpath, fname);
+               goto out;
+       }
+
+       rc = asprintf(&fw_path, "%s/%s", dpath, fname);
+       if (rc == -1) {
+               WARNX(0, "out of memory");
+               rc = ENOMEM;
+               goto out;
+       }
+
+       rc = fstat(fwfd, &st);
+       if (rc != 0) {
+               WARN(0, "fstat(%s)", fw_path);
+               rc = 0;
+               goto out;
+       }
+       if (st.st_size <= 0) {
+               WARN(0, "%s: empty", fw_path);
+               goto out;
+       }
+
+       fw_map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fwfd, 0);
+       if (fw_map == MAP_FAILED) {
+               WARN(0, "mmap(%s)", fw_path);
+               goto out;
+       }
+
+
+       memset(&parm, 0, sizeof(parm));
+       parm.devfd = devfd;
+       parm.fwimage = fw_map;
+       parm.fwsize = st.st_size;
+       parm.dev_path = dev_path;
+       parm.fw_path = fw_path;
+
+       handler->update(&parm);
+
+out:
+       if (fw_map != MAP_FAILED)
+               munmap(fw_map, st.st_size);
+       free(fw_path);
+       if (fwfd >= 0)
+               close(fwfd);
+       return (rc);
+}
+
+static int
 do_update(const char *dev)
 {
-       int fd;
+       int fd, fwdfd;
        unsigned int i;
        int error;
        struct ucode_handler *handler;
        struct datadir *dir;
        DIR *dirp;
        struct dirent *direntry;
-       char buf[MAXPATHLEN];
 
        fd = open(dev, O_RDONLY);
        if (fd < 0) {
@@ -379,7 +417,7 @@ do_update(const char *dev)
        }
 
        /*
-        * Find the appropriate handler for device.
+        * Find the appropriate handler for CPU.
         */
        for (i = 0; i < NHANDLERS; i++)
                if (handlers[i].probe(fd) == 0)
@@ -387,39 +425,54 @@ do_update(const char *dev)
        if (i < NHANDLERS)
                handler = &handlers[i];
        else {
-               WARNX(0, "cannot find the appropriate handler for device");
+               WARNX(0, "cannot find the appropriate handler for %s", dev);
                close(fd);
                return (1);
        }
        close(fd);
 
+       fd = open(dev, O_RDWR);
+       if (fd < 0) {
+               WARN(0, "error opening %s for writing", dev);
+               return (1);
+       }
+
        /*
         * Process every image in specified data directories.
         */
        SLIST_FOREACH(dir, &datadirs, next) {
-               dirp = opendir(dir->path);
-               if (dirp == NULL) {
-                       WARNX(1, "skipping directory %s: not accessible", 
dir->path);
+               fwdfd = open(dir->path, O_RDONLY);
+               if (fwdfd < 0) {
+                       WARN(1, "skipping directory %s: not accessible", 
dir->path);
                        continue;
                }
+               dirp = fdopendir(fwdfd);
+               if (dirp == NULL) {
+                       WARNX(0, "out of memory");
+                       close(fwdfd);
+                       close(fd);
+                       return (1);
+               }
+
                while ((direntry = readdir(dirp)) != NULL) {
                        if (direntry->d_namlen == 0)
                                continue;
-                       error = snprintf(buf, sizeof(buf), "%s/%s", dir->path,
-                           direntry->d_name);
-                       if ((unsigned)error >= sizeof(buf))
-                               WARNX(0, "skipping %s, buffer too short",
-                                   direntry->d_name);
-                       if (isdir(buf) != 0) {
-                               WARNX(2, "skipping %s: is a directory", buf);
+                       if (direntry->d_type == DT_DIR)
                                continue;
+
+                       error = try_a_fw_image(dev, fd, fwdfd, dir->path,
+                           direntry->d_name, handler);
+                       if (error != 0) {
+                               closedir(dirp);
+                               close(fd);
+                               return (1);
                        }
-                       handler->update(dev, buf);
                }
                error = closedir(dirp);
                if (error != 0)
                        WARN(0, "closedir(%s)", dir->path);
        }
+       close(fd);
        return (0);
 }
 
@@ -441,6 +494,7 @@ datadir_add(const char *path)
 int
 main(int argc, char *argv[])
 {
+       struct datadir *elm;
        int c, flags;
        const char *cmdarg;
        const char *dev;
@@ -511,6 +565,9 @@ main(int argc, char *argv[])
        default:
                usage();        /* Only one command can be selected. */
        }
-       SLIST_FREE(&datadirs, next, free);
+       while ((elm = SLIST_FIRST(&datadirs)) != NULL) {
+               SLIST_REMOVE_HEAD(&datadirs, next);
+               free(elm);
+       }
        return (error == 0 ? 0 : 1);
 }

Modified: head/usr.sbin/cpucontrol/cpucontrol.h
==============================================================================
--- head/usr.sbin/cpucontrol/cpucontrol.h       Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/cpucontrol.h       Wed Nov 14 00:21:49 2018        
(r340421)
@@ -30,8 +30,17 @@
 #ifndef CPUCONTROL_H
 #define        CPUCONTROL_H
 
+#include <stddef.h>
+
 typedef int ucode_probe_t(int fd);
-typedef void ucode_update_t(const char *dev, const char *image);
+struct ucode_update_params {
+       int devfd;              /* RDWR handle to cpucontrol device */
+       const void *fwimage;    /* READ mapping of firmware image */
+       size_t fwsize;          /* Non-zero size of firmware image */
+       const char *dev_path;   /* cpucontrol device path, for logging */
+       const char *fw_path;    /* firmware image path, for logging */
+};
+typedef void ucode_update_t(const struct ucode_update_params *params);
 
 extern int verbosity_level;
 

Modified: head/usr.sbin/cpucontrol/intel.c
==============================================================================
--- head/usr.sbin/cpucontrol/intel.c    Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/intel.c    Wed Nov 14 00:21:49 2018        
(r340421)
@@ -76,23 +76,23 @@ intel_probe(int fd)
 }
 
 void
-intel_update(const char *dev, const char *path)
+intel_update(const struct ucode_update_params *params)
 {
-       int fd, devfd;
-       struct stat st;
-       uint32_t *fw_image;
+       int devfd;
+       const char *dev, *path;
+       const uint32_t *fw_image;
        int have_ext_table;
        uint32_t sum;
        unsigned int i;
        size_t payload_size;
-       intel_fw_header_t *fw_header;
-       intel_cpu_signature_t *ext_table;
-       intel_ext_header_t *ext_header;
+       const intel_fw_header_t *fw_header;
+       const intel_cpu_signature_t *ext_table;
+       const intel_ext_header_t *ext_header;
        uint32_t sig, signature, flags;
        int32_t revision;
        ssize_t ext_size;
        size_t ext_table_size;
-       void *fw_data;
+       const void *fw_data;
        size_t data_size, total_size;
        cpuctl_msr_args_t msrargs = {
                .msr = MSR_BIOS_SIGN,
@@ -104,18 +104,17 @@ intel_update(const char *dev, const char *path)
        cpuctl_update_args_t args;
        int error;
 
+       dev = params->dev_path;
+       path = params->fw_path;
+       devfd = params->devfd;
+       fw_image = params->fwimage;
+
        assert(path);
        assert(dev);
 
-       fd = -1;
-       fw_image = MAP_FAILED;
        ext_table = NULL;
        ext_header = NULL;
-       devfd = open(dev, O_RDWR);
-       if (devfd < 0) {
-               WARN(0, "could not open %s for writing", dev);
-               return;
-       }
+
        error = ioctl(devfd, CPUCTL_WRMSR, &msrargs);
        if (error < 0) {
                WARN(0, "ioctl(%s)", dev);
@@ -151,31 +150,12 @@ intel_update(const char *dev, const char *path)
        /*
         * Open firmware image.
         */
-       fd = open(path, O_RDONLY, 0);
-       if (fd < 0) {
-               WARN(0, "open(%s)", path);
-               goto fail;
-       }
-       error = fstat(fd, &st);
-       if (error != 0) {
-               WARN(0, "fstat(%s)", path);
-               goto fail;
-       }
-       if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+       if (params->fwsize < sizeof(*fw_header)) {
                WARNX(2, "file too short: %s", path);
                goto fail;
        }
 
-       /*
-        * mmap the whole image.
-        */
-       fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-           MAP_PRIVATE, fd, 0);
-       if  (fw_image == MAP_FAILED) {
-               WARN(0, "mmap(%s)", path);
-               goto fail;
-       }
-       fw_header = (intel_fw_header_t *)fw_image;
+       fw_header = (const intel_fw_header_t *)fw_image;
        if (fw_header->header_version != INTEL_HEADER_VERSION ||
            fw_header->loader_revision != INTEL_LOADER_REVISION) {
                WARNX(2, "%s is not a valid intel firmware: version mismatch",
@@ -193,7 +173,7 @@ intel_update(const char *dev, const char *path)
                total_size = data_size + sizeof(*fw_header);
        else
                total_size = fw_header->total_size;
-       if (total_size > (unsigned)st.st_size || st.st_size < 0) {
+       if (total_size > params->fwsize) {
                WARNX(2, "file too short: %s", path);
                goto fail;
        }
@@ -204,7 +184,7 @@ intel_update(const char *dev, const char *path)
         */
        sum = 0;
        for (i = 0; i < (payload_size / sizeof(uint32_t)); i++)
-               sum += *((uint32_t *)fw_image + i);
+               sum += *((const uint32_t *)fw_image + i);
        if (sum != 0) {
                WARNX(2, "%s: update data checksum invalid", path);
                goto fail;
@@ -217,9 +197,9 @@ intel_update(const char *dev, const char *path)
        have_ext_table = 0;
 
        if (ext_size > (signed)sizeof(*ext_header)) {
-               ext_header =
-                   (intel_ext_header_t *)((char *)fw_image + payload_size);
-               ext_table = (intel_cpu_signature_t *)(ext_header + 1);
+               ext_header = (const intel_ext_header_t *)
+                   ((const char *)fw_image + payload_size);
+               ext_table = (const intel_cpu_signature_t *)(ext_header + 1);
 
                /*
                 * Check the extended table size.
@@ -236,7 +216,7 @@ intel_update(const char *dev, const char *path)
                 */
                sum = 0;
                for (i = 0; i < (ext_table_size / sizeof(uint32_t)); i++)
-                       sum += *((uint32_t *)ext_header + i);
+                       sum += *((const uint32_t *)ext_header + i);
                if (sum != 0) {
                        WARNX(2,
                            "%s: extended signature table checksum invalid",
@@ -273,7 +253,7 @@ matched:
        }
        fprintf(stderr, "%s: updating cpu %s from rev %#x to rev %#x... ",
            path, dev, revision, fw_header->revision);
-       args.data = fw_data;
+       args.data = __DECONST(void *, fw_data);
        args.size = data_size;
        error = ioctl(devfd, CPUCTL_UPDATE, &args);
        if (error < 0) {
@@ -286,11 +266,5 @@ matched:
        fprintf(stderr, "done.\n");
 
 fail:
-       if (fw_image != MAP_FAILED)
-               if (munmap(fw_image, st.st_size) != 0)
-                       warn("munmap(%s)", path);
-       if (devfd >= 0)
-               close(devfd);
-       if (fd >= 0)
-               close(fd);
+       return;
 }

Modified: head/usr.sbin/cpucontrol/via.c
==============================================================================
--- head/usr.sbin/cpucontrol/via.c      Wed Nov 14 00:12:04 2018        
(r340420)
+++ head/usr.sbin/cpucontrol/via.c      Wed Nov 14 00:21:49 2018        
(r340421)
@@ -76,18 +76,18 @@ via_probe(int fd)
 }
 
 void
-via_update(const char *dev, const char *path)
+via_update(const struct ucode_update_params *params)
 {
-       int fd, devfd;
-       struct stat st;
-       uint32_t *fw_image;
+       int devfd;
+       const char *dev, *path;
+       const uint32_t *fw_image;
        uint32_t sum;
        unsigned int i;
        size_t payload_size;
-       via_fw_header_t *fw_header;
+       const via_fw_header_t *fw_header;
        uint32_t signature;
        int32_t revision;
-       void *fw_data;
+       const void *fw_data;
        size_t data_size, total_size;
        cpuctl_msr_args_t msrargs = {
                .msr = MSR_IA32_PLATFORM_ID,
@@ -98,17 +98,14 @@ via_update(const char *dev, const char *path)
        cpuctl_update_args_t args;
        int error;
 
+       dev = params->dev_path;
+       path = params->fw_path;
+       devfd = params->devfd;
+       fw_image = params->fwimage;
+
        assert(path);
        assert(dev);
 
-       fd = -1;
-       devfd = -1;
-       fw_image = MAP_FAILED;
-       devfd = open(dev, O_RDWR);
-       if (devfd < 0) {
-               WARN(0, "could not open %s for writing", dev);
-               return;
-       }
        error = ioctl(devfd, CPUCTL_CPUID, &idargs);
        if (error < 0) {
                WARN(0, "ioctl(%s)", dev);
@@ -134,34 +131,13 @@ via_update(const char *dev, const char *path)
        WARNX(2, "found cpu type %#x family %#x model %#x stepping %#x.",
            (signature >> 12) & 0x03, (signature >> 8) & 0x0f,
            (signature >> 4) & 0x0f, (signature >> 0) & 0x0f);
-       /*
-        * Open firmware image.
-        */
-       fd = open(path, O_RDONLY, 0);
-       if (fd < 0) {
-               WARN(0, "open(%s)", path);
-               goto fail;
-       }
-       error = fstat(fd, &st);
-       if (error != 0) {
-               WARN(0, "fstat(%s)", path);
-               goto fail;
-       }
-       if (st.st_size < 0 || (unsigned)st.st_size < sizeof(*fw_header)) {
+
+       if (params->fwsize < sizeof(*fw_header)) {
                WARNX(2, "file too short: %s", path);
                goto fail;
        }
 
-       /*
-        * mmap the whole image.
-        */
-       fw_image = (uint32_t *)mmap(NULL, st.st_size, PROT_READ,
-           MAP_PRIVATE, fd, 0);
-       if  (fw_image == MAP_FAILED) {
-               WARN(0, "mmap(%s)", path);
-               goto fail;
-       }
-       fw_header = (via_fw_header_t *)fw_image;
+       fw_header = (const via_fw_header_t *)fw_image;
        if (fw_header->signature != VIA_HEADER_SIGNATURE ||
            fw_header->loader_revision != VIA_LOADER_REVISION) {
                WARNX(2, "%s is not a valid via firmware: version mismatch",
@@ -170,7 +146,7 @@ via_update(const char *dev, const char *path)
        }
        data_size = fw_header->data_size;
        total_size = fw_header->total_size;
-       if (total_size > (unsigned)st.st_size || st.st_size < 0) {
+       if (total_size > params->fwsize) {
                WARNX(2, "file too short: %s", path);
                goto fail;
        }
@@ -181,7 +157,7 @@ via_update(const char *dev, const char *path)
         */
        sum = 0;
        for (i = 0; i < (payload_size / sizeof(uint32_t)); i++)
-               sum += *((uint32_t *)fw_image + i);
+               sum += *((const uint32_t *)fw_image + i);
        if (sum != 0) {
                WARNX(2, "%s: update data checksum invalid", path);
                goto fail;
@@ -202,25 +178,18 @@ via_update(const char *dev, const char *path)
        }
        fprintf(stderr, "%s: updating cpu %s from rev %#x to rev %#x... ",
                        path, dev, revision, fw_header->revision);
-       args.data = fw_data;
+       args.data = __DECONST(void *, fw_data);
        args.size = data_size;
        error = ioctl(devfd, CPUCTL_UPDATE, &args);
        if (error < 0) {
                error = errno;
-               fprintf(stderr, "failed.\n");
+              fprintf(stderr, "failed.\n");
                errno = error;
-               WARN(0, "ioctl()");
-               goto fail;
+              WARN(0, "ioctl()");
+              goto fail;
        }
        fprintf(stderr, "done.\n");
 
 fail:
-       if (fw_image != MAP_FAILED)
-               if (munmap(fw_image, st.st_size) != 0)
-                       warn("munmap(%s)", path);
-       if (devfd >= 0)
-               close(devfd);
-       if (fd >= 0)
-               close(fd);
        return;
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to