aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:15:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 20:15:44 -0400
commita8251096b427283c47e7d8f9568be6b388dd68ec (patch)
treeedc9747e30b4b4413aa99acfbd3104d81b1c303b
parent27a3353a4525afe984f3b793681869d636136b69 (diff)
parent480b02df3aa9f07d1c7df0cd8be7a5ca73893455 (diff)
Merge branch 'modules' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* 'modules' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: module: drop the lock while waiting for module to complete initialization. MODULE_DEVICE_TABLE(isapnp, ...) does nothing hisax_fcpcipnp: fix broken isapnp device table. isapnp: move definitions to mod_devicetable.h so file2alias can reach them.
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c3
-rw-r--r--include/linux/isapnp.h8
-rw-r--r--include/linux/mod_devicetable.h7
-rw-r--r--kernel/module.c59
-rw-r--r--scripts/mod/file2alias.c17
5 files changed, 64 insertions, 30 deletions
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 1925118122f8..8b0a7d86b30f 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -74,9 +74,10 @@ static struct pnp_device_id fcpnp_ids[] __devinitdata = {
74 .id = "AVM0900", 74 .id = "AVM0900",
75 .driver_data = (unsigned long) "Fritz!Card PnP", 75 .driver_data = (unsigned long) "Fritz!Card PnP",
76 }, 76 },
77 { .id = "" }
77}; 78};
78 79
79MODULE_DEVICE_TABLE(isapnp, fcpnp_ids); 80MODULE_DEVICE_TABLE(pnp, fcpnp_ids);
80#endif 81#endif
81 82
82static int protocol = 2; /* EURO-ISDN Default */ 83static int protocol = 2; /* EURO-ISDN Default */
diff --git a/include/linux/isapnp.h b/include/linux/isapnp.h
index cd5a269fdb5e..e2d28b026a8c 100644
--- a/include/linux/isapnp.h
+++ b/include/linux/isapnp.h
@@ -43,10 +43,10 @@
43 */ 43 */
44 44
45#ifdef __KERNEL__ 45#ifdef __KERNEL__
46#include <linux/mod_devicetable.h>
46 47
47#define DEVICE_COUNT_COMPATIBLE 4 48#define DEVICE_COUNT_COMPATIBLE 4
48 49
49#define ISAPNP_ANY_ID 0xffff
50#define ISAPNP_CARD_DEVS 8 50#define ISAPNP_CARD_DEVS 8
51 51
52#define ISAPNP_CARD_ID(_va, _vb, _vc, _device) \ 52#define ISAPNP_CARD_ID(_va, _vb, _vc, _device) \
@@ -74,12 +74,6 @@ struct isapnp_card_id {
74#define ISAPNP_DEVICE_SINGLE_END \ 74#define ISAPNP_DEVICE_SINGLE_END \
75 .card_vendor = 0, .card_device = 0 75 .card_vendor = 0, .card_device = 0
76 76
77struct isapnp_device_id {
78 unsigned short card_vendor, card_device;
79 unsigned short vendor, function;
80 unsigned long driver_data; /* data private to the driver */
81};
82
83#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE)) 77#if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
84 78
85#define __ISAPNP__ 79#define __ISAPNP__
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 007fbaafead0..48c007dae476 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -509,4 +509,11 @@ struct zorro_device_id {
509 509
510#define ZORRO_DEVICE_MODALIAS_FMT "zorro:i%08X" 510#define ZORRO_DEVICE_MODALIAS_FMT "zorro:i%08X"
511 511
512#define ISAPNP_ANY_ID 0xffff
513struct isapnp_device_id {
514 unsigned short card_vendor, card_device;
515 unsigned short vendor, function;
516 kernel_ulong_t driver_data; /* data private to the driver */
517};
518
512#endif /* LINUX_MOD_DEVICETABLE_H */ 519#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/kernel/module.c b/kernel/module.c
index 3c4fc4bb4b82..a8014bfb5a4e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -565,33 +565,26 @@ int use_module(struct module *a, struct module *b)
565 struct module_use *use; 565 struct module_use *use;
566 int no_warn, err; 566 int no_warn, err;
567 567
568 if (b == NULL || already_uses(a, b)) return 1; 568 if (b == NULL || already_uses(a, b))
569
570 /* If we're interrupted or time out, we fail. */
571 if (wait_event_interruptible_timeout(
572 module_wq, (err = strong_try_module_get(b)) != -EBUSY,
573 30 * HZ) <= 0) {
574 printk("%s: gave up waiting for init of module %s.\n",
575 a->name, b->name);
576 return 0; 569 return 0;
577 }
578 570
579 /* If strong_try_module_get() returned a different error, we fail. */ 571 /* If we're interrupted or time out, we fail. */
572 err = strong_try_module_get(b);
580 if (err) 573 if (err)
581 return 0; 574 return err;
582 575
583 DEBUGP("Allocating new usage for %s.\n", a->name); 576 DEBUGP("Allocating new usage for %s.\n", a->name);
584 use = kmalloc(sizeof(*use), GFP_ATOMIC); 577 use = kmalloc(sizeof(*use), GFP_ATOMIC);
585 if (!use) { 578 if (!use) {
586 printk("%s: out of memory loading\n", a->name); 579 printk("%s: out of memory loading\n", a->name);
587 module_put(b); 580 module_put(b);
588 return 0; 581 return -ENOMEM;
589 } 582 }
590 583
591 use->module_which_uses = a; 584 use->module_which_uses = a;
592 list_add(&use->list, &b->modules_which_use_me); 585 list_add(&use->list, &b->modules_which_use_me);
593 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); 586 no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
594 return 1; 587 return 0;
595} 588}
596EXPORT_SYMBOL_GPL(use_module); 589EXPORT_SYMBOL_GPL(use_module);
597 590
@@ -884,7 +877,7 @@ static inline void module_unload_free(struct module *mod)
884 877
885int use_module(struct module *a, struct module *b) 878int use_module(struct module *a, struct module *b)
886{ 879{
887 return strong_try_module_get(b) == 0; 880 return strong_try_module_get(b);
888} 881}
889EXPORT_SYMBOL_GPL(use_module); 882EXPORT_SYMBOL_GPL(use_module);
890 883
@@ -1055,17 +1048,39 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
1055 struct module *owner; 1048 struct module *owner;
1056 const struct kernel_symbol *sym; 1049 const struct kernel_symbol *sym;
1057 const unsigned long *crc; 1050 const unsigned long *crc;
1051 DEFINE_WAIT(wait);
1052 int err;
1053 long timeleft = 30 * HZ;
1058 1054
1055again:
1059 sym = find_symbol(name, &owner, &crc, 1056 sym = find_symbol(name, &owner, &crc,
1060 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true); 1057 !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
1061 /* use_module can fail due to OOM, 1058 if (!sym)
1062 or module initialization or unloading */ 1059 return NULL;
1063 if (sym) { 1060
1064 if (!check_version(sechdrs, versindex, name, mod, crc, owner) 1061 if (!check_version(sechdrs, versindex, name, mod, crc, owner))
1065 || !use_module(mod, owner)) 1062 return NULL;
1066 sym = NULL; 1063
1067 } 1064 prepare_to_wait(&module_wq, &wait, TASK_INTERRUPTIBLE);
1068 return sym; 1065 err = use_module(mod, owner);
1066 if (likely(!err) || err != -EBUSY || signal_pending(current)) {
1067 finish_wait(&module_wq, &wait);
1068 return err ? NULL : sym;
1069 }
1070
1071 /* Module is still loading. Drop lock and wait. */
1072 mutex_unlock(&module_mutex);
1073 timeleft = schedule_timeout(timeleft);
1074 mutex_lock(&module_mutex);
1075 finish_wait(&module_wq, &wait);
1076
1077 /* Module might be gone entirely, or replaced. Re-lookup. */
1078 if (timeleft)
1079 goto again;
1080
1081 printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
1082 mod->name, owner->name);
1083 return NULL;
1069} 1084}
1070 1085
1071/* 1086/*
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 9cf2400580a7..5758aab0d8bb 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -828,6 +828,19 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
828 return 1; 828 return 1;
829} 829}
830 830
831/* looks like: "pnp:dD" */
832static int do_isapnp_entry(const char *filename,
833 struct isapnp_device_id *id, char *alias)
834{
835 sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
836 'A' + ((id->vendor >> 2) & 0x3f) - 1,
837 'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1,
838 'A' + ((id->vendor >> 8) & 0x1f) - 1,
839 (id->function >> 4) & 0x0f, id->function & 0x0f,
840 (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
841 return 1;
842}
843
831/* Ignore any prefix, eg. some architectures prepend _ */ 844/* Ignore any prefix, eg. some architectures prepend _ */
832static inline int sym_is(const char *symbol, const char *name) 845static inline int sym_is(const char *symbol, const char *name)
833{ 846{
@@ -983,6 +996,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
983 do_table(symval, sym->st_size, 996 do_table(symval, sym->st_size,
984 sizeof(struct zorro_device_id), "zorro", 997 sizeof(struct zorro_device_id), "zorro",
985 do_zorro_entry, mod); 998 do_zorro_entry, mod);
999 else if (sym_is(symname, "__mod_isapnp_device_table"))
1000 do_table(symval, sym->st_size,
1001 sizeof(struct isapnp_device_id), "isa",
1002 do_isapnp_entry, mod);
986 free(zeros); 1003 free(zeros);
987} 1004}
988 1005