diff -Nur modutils-2.3.18/ChangeLog modutils-2.3.19/ChangeLog --- modutils-2.3.18/ChangeLog Wed Oct 11 09:41:10 2000 +++ modutils-2.3.19/ChangeLog Sun Oct 22 15:54:01 2000 @@ -1,3 +1,14 @@ +2000-10-22 Keith Owens + + modutils 2.3.19 + + * Add insmod -O. + * Generate usbmap from MODULE_DEVICE_TABLE(usb). + * Move print map before sys_init_module to assist debugging. + * Ignore ALLOC attribute for .modinfo. + * Correct R_MIPS_26 relocations by Maciej W. Rozycki. + * Switch back to .gz to suit kernel.org. + 2000-10-11 Keith Owens modutils 2.3.18 diff -Nur modutils-2.3.18/depmod/depmod.c modutils-2.3.19/depmod/depmod.c --- modutils-2.3.18/depmod/depmod.c Tue Oct 10 12:16:02 2000 +++ modutils-2.3.19/depmod/depmod.c Sat Oct 21 15:17:56 2000 @@ -37,7 +37,7 @@ Keith Owens April 2000. */ -#ident "$Id: depmod.c 1.25 Tue, 10 Oct 2000 12:16:02 +1100 kaos $" +#ident "$Id: depmod.c 1.26 Sat, 21 Oct 2000 15:17:56 +1100 kaos $" #include #include @@ -101,6 +101,57 @@ } devs[ISAPNP_CARD_DEVS]; /* logical devices */ }; +/* Extracted from 2.4.0-test10-pre3 + David Brownell usb-device_id patch 2 */ +#ifndef __u16 +#define __u16 u_int16_t +#endif +#ifndef __u8 +#define __u8 u_int8_t +#endif +/* + * Device table entry for "new style" table-driven USB drivers. + * User mode code can read these tables to choose which modules to load. + * Declare the table as __devinitdata, and as a MODULE_DEVICE_TABLE. + * + * With a device table provide bind() instead of probe(). Then the + * third bind() parameter will point to a matching entry from this + * table. (Null value reserved.) + * + * Terminate the driver's table with an all-zeroes entry. + * Init the fields you care about; zeroes are not used in comparisons. + */ +struct usb_device_id { + /* + * vendor/product codes are checked, if vendor is nonzero + * Range is for device revision (bcdDevice), inclusive; + * zero values here mean range isn't considered + */ + __u16 idVendor; + __u16 idProduct; + __u16 bcdDevice_lo, bcdDevice_hi; + + /* + * if device class != 0, these can be match criteria; + * but only if this bDeviceClass value is nonzero + */ + __u8 bDeviceClass; + __u8 bDeviceSubClass; + __u8 bDeviceProtocol; + + /* + * if interface class != 0, these can be match criteria; + * but only if this bInterfaceClass value is nonzero + */ + __u8 bInterfaceClass; + __u8 bInterfaceSubClass; + __u8 bInterfaceProtocol; + + /* + * for driver's use; not involved in driver matching. + */ + unsigned long driver_info; +}; + typedef struct MODULE { char *name; int resolved; @@ -114,6 +165,8 @@ int n_isapnp_device; struct isapnp_card_id *isapnp_card; int n_isapnp_card; + struct usb_device_id *usb_device; + int n_usb_device; } MODULE; typedef enum SYM_STATUS { @@ -401,6 +454,37 @@ } /* + * Extract any usb_device_table from the module. + * Note: assumes same machine and arch for depmod and module. + */ +static void extract_usb_device_id(struct obj_file *f, void *image, unsigned long m_size, MODULE *mod) +{ + struct usb_device_id usb_device; + ElfW(Addr) ref_usb, ref_ref_usb; + unsigned long usb_device_size; + ref_usb = obj_symbol_final_value(f, obj_find_symbol(f, "__module_usb_device_size")); + if (!in_range(f, m_size, ref_usb, sizeof(usb_device_size))) + return; + memcpy(&usb_device_size, (char *)image + ref_usb - f->baseaddr, sizeof(usb_device_size)); + if (usb_device_size != sizeof(usb_device)) { + error("Unexpected value (%ld) for usb_device_size%s", usb_device_size, has_kernel_changed); + exit(-1); + } + ref_ref_usb = obj_symbol_final_value(f, obj_find_symbol(f, "__module_usb_device_table")); + if (!in_range(f, m_size, ref_ref_usb, sizeof(ref_usb))) + return; + memcpy(&ref_usb, (char *)image + ref_ref_usb - f->baseaddr, sizeof(ref_usb)); + while (in_range(f, m_size, ref_usb, sizeof(usb_device))) { + memcpy(&usb_device, (char *)image + ref_usb - f->baseaddr, sizeof(usb_device)); + ref_usb += sizeof(usb_device); + if (!usb_device.idVendor) + break; + mod->usb_device = xrealloc(mod->usb_device, ++(mod->n_usb_device)*sizeof(*(mod->usb_device))); + mod->usb_device[mod->n_usb_device-1] = usb_device; + } +} + +/* * Read the symbols in an object and register them in the symbol table. * Return -1 if there is an error. */ @@ -575,6 +659,7 @@ extract_pci_device_id(f, image, m_size, mod); extract_isapnp_device_id(f, image, m_size, mod); extract_isapnp_card_id(f, image, m_size, mod); + extract_usb_device_id(f, image, m_size, mod); free(image); obj_free(f); @@ -705,15 +790,18 @@ * Print the dependancies in the depfile (or stdout if depfile is NULL). * Print the pcimap in the pcimapfile (or stdout if pcimapfile is NULL). * Print the isapnpmap in the isapnpmapfile (or stdout if isapnpmapfile is NULL). + * Print the usbmap in the usbmapfile (or stdout if usbmapfile is NULL). */ static void prtdepend(char *base_dir, const char *pdepfile, const char *ppcimapfile, - const char *pisapnpmapfile) + const char *pisapnpmapfile, + const char *pusbmapfile) { FILE *dep = stdout; FILE *pcimap = stdout; FILE *isapnpmap = stdout; + FILE *usbmap = stdout; MODULE **tbdep; MODULE *ptmod; int i; @@ -740,6 +828,13 @@ } } + if (pusbmapfile != NULL) { + if ((usbmap = fopen(pusbmapfile, "w")) == NULL) { + error("Can't open %s for writing", pusbmapfile); + exit(-1); + } + } + skipchars = strlen(base_dir); tbdep = (MODULE **)alloca(sizeof(MODULE) * n_modules); @@ -889,11 +984,62 @@ free(name); } + ptmod = modules; + fprintf(usbmap, "# module idVendor idProduct bcdDevice_lo bcdDevice_hi" + " bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass" + " bInterfaceProtocol driver_info\n"); + for (i = 0; i < n_modules; i++, ptmod++) { + int j, l; + struct usb_device_id *usb_device = ptmod->usb_device; + char *name, *shortname; + if (!ptmod->n_usb_device) + continue; + name = xstrdup(ptmod->name); + shortname = strrchr(name, '/'); + if (!shortname) + shortname = name; /* should never happen */ + else { + ++shortname; + l = strlen(shortname); + if (l > 3 && strcmp(shortname+l-3, ".gz") == 0) { + *(shortname+l-3) = '\0'; + l -= 3; + } + if (l > 2 && strcmp(shortname+l-2, ".o") == 0) { + *(shortname+l-2) = '\0'; + l -= 2; + } else if (l > 4 && strcmp(shortname+l-4, ".mod") == 0) { + *(shortname+l-4) = '\0'; + l -= 4; + } + } + for (j = 0; j < ptmod->n_usb_device; j++, usb_device++) { + fprintf(usbmap, "%-20s 0x%0*x 0x%0*x 0x%0*x 0x%0*x " + "0x%0*x 0x%0*x 0x%0*x 0x%0*x 0x%0*x " + "0x%0*x 0x%0*lx\n", + shortname, + 2*sizeof(usb_device->idVendor), usb_device->idVendor, + 2*sizeof(usb_device->idProduct), usb_device->idProduct, + 2*sizeof(usb_device->bcdDevice_lo), usb_device->bcdDevice_lo, + 2*sizeof(usb_device->bcdDevice_hi), usb_device->bcdDevice_hi, + 2*sizeof(usb_device->bDeviceClass), usb_device->bDeviceClass, + 2*sizeof(usb_device->bDeviceSubClass), usb_device->bDeviceSubClass, + 2*sizeof(usb_device->bDeviceProtocol), usb_device->bDeviceProtocol, + 2*sizeof(usb_device->bInterfaceClass), usb_device->bInterfaceClass, + 2*sizeof(usb_device->bInterfaceSubClass), usb_device->bInterfaceSubClass, + 2*sizeof(usb_device->bInterfaceProtocol), usb_device->bInterfaceProtocol, + 2*sizeof(usb_device->driver_info), usb_device->driver_info); + } + free(name); + } + /* Close depfile last, critical timestamp */ if (ppcimapfile != NULL) fclose(pcimap); if (pisapnpmapfile != NULL) fclose(isapnpmap); + if (pusbmapfile != NULL) + fclose(usbmap); if (pdepfile != NULL) fclose(dep); } @@ -1087,7 +1233,8 @@ prtdepend(base_dir, nflag ? NULL : depfile, nflag ? NULL : pcimapfile, - nflag ? NULL : isapnpmapfile); + nflag ? NULL : isapnpmapfile, + nflag ? NULL : usbmapfile); } } else { /* not stdmode */ @@ -1095,7 +1242,7 @@ for (; argc > 0 && ret != -1; ++argv, --argc) loadobj(*argv, ignore_suffix); resolve(); - prtdepend(base_dir, NULL, NULL, NULL); + prtdepend(base_dir, NULL, NULL, NULL, NULL); } } diff -Nur modutils-2.3.18/include/config.h modutils-2.3.19/include/config.h --- modutils-2.3.18/include/config.h Tue Oct 10 12:16:02 2000 +++ modutils-2.3.19/include/config.h Sat Oct 21 15:17:56 2000 @@ -66,6 +66,7 @@ extern char *depfile; extern char *pcimapfile; extern char *isapnpmapfile; +extern char *usbmapfile; extern char *config_file; extern char *optlist[]; extern char *prune[]; diff -Nur modutils-2.3.18/include/version.h modutils-2.3.19/include/version.h --- modutils-2.3.18/include/version.h Mon Sep 25 15:05:37 2000 +++ modutils-2.3.19/include/version.h Fri Oct 13 12:25:49 2000 @@ -1 +1 @@ -#define MODUTILS_VERSION "2.3.18" +#define MODUTILS_VERSION "2.3.19" diff -Nur modutils-2.3.18/insmod/insmod.c modutils-2.3.19/insmod/insmod.c --- modutils-2.3.18/insmod/insmod.c Sun Sep 10 11:25:29 2000 +++ modutils-2.3.19/insmod/insmod.c Sat Oct 21 15:31:41 2000 @@ -48,9 +48,11 @@ Keith Owens April 2000. archdata support Keith Owens August 2000. + Add insmod -O, move print map before sys_init_module. + Keith Owens October 2000. */ -#ident "$Id: insmod.c 1.27 Sun, 10 Sep 2000 11:25:29 +1100 kaos $" +#ident "$Id: insmod.c 1.29 Sat, 21 Oct 2000 15:31:41 +1100 kaos $" #include #include @@ -1021,12 +1023,13 @@ static int init_module(const char *m_name, struct obj_file *f, - unsigned long m_size) + unsigned long m_size, const char *blob_name, + unsigned int noload, unsigned int flag_load_map) { struct module *module; struct obj_section *sec; void *image; - int ret; + int ret = 0; tgt_long m_addr; sec = obj_find_section(f, ".this"); @@ -1086,11 +1089,33 @@ image = xmalloc(m_size); obj_create_image(f, image); - ret = sys_init_module(m_name, (struct module *) image); - if (ret) { - error("init_module: %m"); - lprintf("Hint: insmod errors can be caused by incorrect module parameters, " - "including invalid IO or IRQ parameters"); + if (flag_load_map) + print_load_map(f); + + if (blob_name) { + int fd, l; + fd = open(blob_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (fd < 0) { + error("open %s failed %m", blob_name); + ret = -1; + } + else { + if ((l = write(fd, image, m_size)) != m_size) { + error("write %s failed %m", blob_name); + ret = -1; + } + close(fd); + } + } + + if (ret == 0 && !noload) { + fflush(stdout); /* Flush any debugging output */ + ret = sys_init_module(m_name, (struct module *) image); + if (ret) { + error("init_module: %m"); + lprintf("Hint: insmod errors can be caused by incorrect module parameters, " + "including invalid IO or IRQ parameters"); + } } free(image); @@ -1223,6 +1248,7 @@ " -m, --map Generate load map (so crashes can be traced)\n" " -n, --noload Don't load, just show\n" " -o NAME, --name=NAME Set internal module name to NAME\n" + " -O NAME, --blob=NAME Save the object as a binary blob in NAME\n" " -p, --poll Poll mode; check if the module matches the kernel\n" " -q, --quiet Don't print unresolved symbols\n" " -s, --syslog Report errors via syslog\n" @@ -1260,6 +1286,7 @@ {"map", 0, 0, 'm'}, {"noload", 0, 0, 'n'}, {"name", 1, 0, 'o'}, + {"blob", 1, 0, 'O'}, {"poll", 0, 0, 'p'}, {"syslog", 0, 0, 's'}, {"verbose", 0, 0, 'v'}, @@ -1276,6 +1303,7 @@ {0, 0, 0, 0} }; char *m_name = NULL; + char *blob_name = NULL; /* Save object as binary blob */ int m_version; ElfW(Addr) m_addr; unsigned long m_size; @@ -1298,7 +1326,7 @@ errors = optind = 0; /* Process the command line. */ - while ((o = getopt_long(argc, argv, "fhkmno:pqsvVxXLP:yYr", + while ((o = getopt_long(argc, argv, "fhkmno:O:pqsvVxXLP:yYr", &long_opts[0], NULL)) != EOF) switch (o) { case 'f': /* force loading */ @@ -1319,6 +1347,9 @@ case 'o': /* name the output module */ m_name = optarg; break; + case 'O': /* save the output module object */ + blob_name = optarg; + break; case 'p': /* silent poll mode */ flag_silent_poll = 1; break; @@ -1563,23 +1594,19 @@ if (add_kallsyms(f, &kallsyms)) goto out; - if (!noload) { #ifdef COMPAT_2_0 - if (k_new_syscalls) - init_module(m_name, f, m_size); - else - old_init_module(m_name, f, m_size); + if (k_new_syscalls) + init_module(m_name, f, m_size, blob_name, noload, flag_load_map); + else if (!noload) + old_init_module(m_name, f, m_size); #else - init_module(m_name, f, m_size); + init_module(m_name, f, m_size, blob_name, noload, flag_load_map); #endif - } if (errors) { if (!noload) delete_module(m_name); goto out; } - if (flag_load_map) - print_load_map(f); exit_status = 0; out: diff -Nur modutils-2.3.18/man/insmod.8 modutils-2.3.19/man/insmod.8 --- modutils-2.3.18/man/insmod.8 Sun Aug 13 23:45:56 2000 +++ modutils-2.3.19/man/insmod.8 Sun Oct 15 11:31:12 2000 @@ -1,9 +1,9 @@ .\" Copyright (c) 1996 Free Software Foundation, Inc. .\" This program is distributed according to the Gnu General Public License. .\" See the file COPYING in the kernel source directory. -.\" $Id: insmod.8 1.9 Sun, 13 Aug 2000 23:45:56 +1000 kaos $ +.\" $Id: insmod.8 1.10 Sun, 15 Oct 2000 11:31:12 +1100 kaos $ .\" -.TH INSMOD 8 "October 12 1999" Linux "Linux Module Support" +.TH INSMOD 8 "October 15 2000" Linux "Linux Module Support" .SH NAME insmod \- install loadable kernel module .SH SYNOPSIS @@ -47,6 +47,15 @@ .I "\-o \fRmodule_name" Explicitly name the module, rather than deriving the name from the base name of the source object file. +.TP +.I "\-O \fRfilename" +Save the binary object in +.IR filename . +The result is a binary blob (no ELF headers) showing exactly what is +loaded into the kernel, after section manipulation and relocation. +Option +.I -m +is recommended to get a map of the object. .TP .I \-p Probe the module to see if it could be successfully loaded. This diff -Nur modutils-2.3.18/man/modules.conf.5 modutils-2.3.19/man/modules.conf.5 --- modutils-2.3.18/man/modules.conf.5 Tue Oct 10 12:16:02 2000 +++ modutils-2.3.19/man/modules.conf.5 Sat Oct 21 15:17:56 2000 @@ -42,6 +42,7 @@ path[TAG]=A_PATH pcimapfile=A_PATH isapnpmapfile=A_PATH + usbmapfile=A_PATH [add] probe name module_list [add] probeall name module_list prune filename @@ -270,6 +271,12 @@ and used by install scripts to find the module that supports an ISA PNP device. Normally the default value should be used, see below. .TP +.I "usbmapfile=A_PATH" +This is the path to the usbmap file that will be created by +.B depmod +and used by install scripts to find the module that supports an ISA PNP device. +Normally the default value should be used, see below. +.TP .I "alias alias_name result" The "alias" directive can be used to give alias names to modules. A line in /etc/modules.conf that looks like this: @@ -371,8 +378,9 @@ .I "prune filename" The top level module directory for a kernel install contains files which are not modules. These include modules.dep, modules.pcimap, -modules.isapnpmap, the build symlink to the kernel source tree and any -other files that the install process wants to save from a kernel build. +modules.isapnpmap, modules.usbmap, the build symlink to the kernel +source tree and any other files that the install process wants to save +from a kernel build. To prevent .B depmod issuing warnings about "not an ELF file", these non-module files should @@ -543,6 +551,7 @@ depfile=/lib/modules/`uname \-r`/modules.dep pcimapfile=/lib/modules/`uname \-r`/modules.pcimap isapnpmapfile=/lib/modules/`uname \-r`/modules.isapnpmap + usbmapfile=/lib/modules/`uname \-r`/modules.usbmap path[boot]=/lib/modules/boot path[toplevel]=/lib/modules/`uname \-r` diff -Nur modutils-2.3.18/modutils.spec modutils-2.3.19/modutils.spec --- modutils-2.3.18/modutils.spec Wed Oct 11 09:41:10 2000 +++ modutils-2.3.19/modutils.spec Sun Oct 22 15:54:01 2000 @@ -1,10 +1,10 @@ Summary: Module utilities Name: modutils -Version: 2.3.18 -Release: 1 +Version: 2.3.19 +Release: 2 Copyright: GPL Group: Utilities/System -Source: modutils-%{version}.tar.bz2 +Source: modutils-%{version}.tar.gz ExclusiveOS: Linux BuildRoot: /var/tmp/modutils-root diff -Nur modutils-2.3.18/obj/obj_load.c modutils-2.3.19/obj/obj_load.c --- modutils-2.3.18/obj/obj_load.c Tue Oct 10 22:05:46 2000 +++ modutils-2.3.19/obj/obj_load.c Sat Oct 21 16:41:21 2000 @@ -21,7 +21,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id: obj_load.c 1.9 Tue, 10 Oct 2000 22:05:46 +1100 kaos $" +#ident "$Id: obj_load.c 1.10 Sat, 21 Oct 2000 16:41:21 +1100 kaos $" #include #include @@ -188,6 +188,12 @@ for (i = 0; i < shnum; ++i) { struct obj_section *sec = f->sections[i]; + + /* .modinfo should be contents only but gcc has no attribute for that. + * The kernel may have marked .modinfo as ALLOC, ignore this bit. + */ + if (strcmp(sec->name, ".modinfo") == 0) + sec->header.sh_flags &= ~SHF_ALLOC; if (sec->header.sh_flags & SHF_ALLOC) obj_insert_section_load_order(f, sec); diff -Nur modutils-2.3.18/obj/obj_mips.c modutils-2.3.19/obj/obj_mips.c --- modutils-2.3.18/obj/obj_mips.c Wed Aug 23 10:23:26 2000 +++ modutils-2.3.19/obj/obj_mips.c Sun Oct 22 12:37:33 2000 @@ -18,7 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ident "$Id: obj_mips.c 1.5 Wed, 23 Aug 2000 10:23:26 +1000 kaos $" +#ident "$Id: obj_mips.c 1.6 Sun, 22 Oct 2000 12:37:33 +1100 kaos $" #include #include @@ -130,7 +130,7 @@ case R_MIPS_26: if (v % 4) ret = obj_reloc_dangerous; - if ((v & 0xf0000000) != (dot & 0xf0000000)) + if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000)) ret = obj_reloc_overflow; *loc = (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & 0x03ffffff); break; diff -Nur modutils-2.3.18/util/alias.h modutils-2.3.19/util/alias.h --- modutils-2.3.18/util/alias.h Tue Oct 10 22:05:46 2000 +++ modutils-2.3.19/util/alias.h Sat Oct 21 15:17:56 2000 @@ -212,6 +212,7 @@ "modules.dep", "modules.pcimap", "modules.isapnpmap", + "modules.usbmap", "System.map", ".config", "build", /* symlink to source tree */ diff -Nur modutils-2.3.18/util/config.c modutils-2.3.19/util/config.c --- modutils-2.3.18/util/config.c Tue Oct 10 12:16:02 2000 +++ modutils-2.3.19/util/config.c Sat Oct 21 15:17:56 2000 @@ -102,6 +102,7 @@ char *depfile = NULL; char *pcimapfile = NULL; char *isapnpmapfile = NULL; +char *usbmapfile = NULL; char *config_file = NULL; /* Which file was actually used */ time_t config_mtime; int root_check_off = CONFIG_ROOT_CHECK_OFF; /* Default is modules must be owned by root */ @@ -129,6 +130,7 @@ static time_t dep_mtime; static time_t pcimap_mtime; static time_t isapnpmap_mtime; +static time_t usbmap_mtime; static int check_update (const char *file, const struct stat *sb) { int len = strlen(file); @@ -137,7 +139,8 @@ return 0; if (sb->st_mtime <= dep_mtime && sb->st_mtime <= pcimap_mtime && - sb->st_mtime <= isapnpmap_mtime) + sb->st_mtime <= isapnpmap_mtime && + sb->st_mtime <= usbmap_mtime) return 0; if (len > 2 && !strcmp(file + len - 2, ".o")) @@ -153,7 +156,7 @@ static int need_update (const char *force_ver, const char *base_dir) { - struct stat statdep, statpcimap, statisapnpmap, tmp; + struct stat statdep, statpcimap, statisapnpmap, statusbmap, tmp; char dep[PATH_MAX]; uname (&uts_info); if (!force_ver) @@ -165,7 +168,8 @@ if (stat (depfile, &statdep) || stat (pcimapfile, &statpcimap) || - stat (isapnpmapfile, &statisapnpmap)) + stat (isapnpmapfile, &statisapnpmap) || + stat (usbmapfile, &statusbmap)) /* No dependency file yet, so we need to build it. */ return 1; @@ -175,13 +179,15 @@ if (tmp.st_mtime > statdep.st_mtime || tmp.st_mtime > statpcimap.st_mtime || - tmp.st_mtime > statisapnpmap.st_mtime) + tmp.st_mtime > statisapnpmap.st_mtime || + tmp.st_mtime > statusbmap.st_mtime) /* Config file is newer. */ return 1; dep_mtime = statdep.st_mtime; pcimap_mtime = statpcimap.st_mtime; isapnpmap_mtime = statisapnpmap.st_mtime; + usbmap_mtime = statusbmap.st_mtime; sprintf (dep, "%s/lib/modules/%s", base_dir, force_ver); return xftw (dep, check_update); } @@ -419,6 +425,7 @@ char depfile_tmp[PATH_MAX]; char pcimapfile_tmp[PATH_MAX]; char isapnpmapfile_tmp[PATH_MAX]; + char usbmapfile_tmp[PATH_MAX]; char **glb; char old_name[] = "/etc/conf.modules"; int conf_file_specified = 0; @@ -575,6 +582,7 @@ depfile_tmp[0] = '\0'; pcimapfile_tmp[0] = '\0'; isapnpmapfile_tmp[0] = '\0'; + usbmapfile_tmp[0] = '\0'; /* Only read the default entries on the first file */ if (depth == 0) { @@ -712,6 +720,11 @@ strncpy(isapnpmapfile_tmp, envpath, sizeof(isapnpmapfile_tmp)); } + /* USBMAPPATH is intended for testing only */ + if ((envpath = getenv("USBMAPPATH")) != NULL) { + strncpy(usbmapfile_tmp, envpath, sizeof(usbmapfile_tmp)); + } + } /* End of depth == 0 */ if (conf_file || @@ -1208,6 +1221,24 @@ } /* + * usbmapfile= + */ + else if (assgn && (strcmp(parm, "usbmapfile") == 0) && + (usbmapfile_tmp[0] == '\0')) { + /* + * The default value for the usbmapfile parameter is: + * + * usbmapfile=/lib/modules/`uname -r`/modules.usbmap + * + * If the config file exist but doesn't have a usbmapfile + * specification, the default is used since modprobe + * can't work without one. + */ + strcpy(usbmapfile_tmp, arg); + one_err = 0; + } + + /* * keep */ else if (!assgn && (strcmp(parm, "keep") == 0)) { @@ -1413,6 +1444,36 @@ ret = -1; else isapnpmapfile = g.pathv[0]; + } + + /* + * Make sure we have a definition of "usbmapfile" + */ + if (usbmapfile_tmp[0] == '\0') { + /* + * Specification: config file / no usbmapfile parameter + * The default value for the usbmapfile parameter is: + * + * usbmapfile=/lib/modules/`uname -r`/modules.usbmap + * + * If the config file exists but lack a usbmapfile + * specification, the default value is used since + * the system can't work without one. + */ + sprintf(usbmapfile_tmp, "%s/lib/modules/%s/modules.usbmap", + base_dir, version); + usbmapfile = xstrdup(usbmapfile_tmp); + } else { /* usbmapfile defined in modules.conf */ + /* + * If we have a usbmapfile definition in the configuration file + * we must resolve any shell meta-chars in its value. + */ + if (meta_expand(usbmapfile_tmp, &g, base_dir, version)) + ret = -1; + else if (!g.pathv || g.pathv[0] == NULL) + ret = -1; + else + usbmapfile = g.pathv[0]; } return ret;