diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-06-25 08:32:25 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-06-25 08:32:25 +0000 | 
| commit | 1d5d64e647517cdd5bc8d0bb8c408babfec51d79 (patch) | |
| tree | 1db4163deba31f36d771177dfcfabb21cd93f2ac | |
| parent | 52242b5f8e3dc36c54338c921d43e468e3cce71d (diff) | |
fix failsafe on broadcom, send netlink events in diag when running linux 2.6
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7722 3c298f89-4303-0410-b956-a3cf2f4a3e73
| -rw-r--r-- | package/base-files/files/etc/hotplug2-init.rules (renamed from package/hotplug2/files/hotplug2-init.rules) | 0 | ||||
| -rwxr-xr-x | package/base-files/files/etc/init.d/boot | 2 | ||||
| -rwxr-xr-x | package/base-files/files/etc/preinit | 26 | ||||
| -rw-r--r-- | package/broadcom-diag/Makefile | 2 | ||||
| -rw-r--r-- | package/broadcom-diag/src/diag.c | 132 | ||||
| -rw-r--r-- | package/broadcom-diag/src/diag.h | 18 | ||||
| -rw-r--r-- | package/broadcom-diag/src/gpio.h | 10 | ||||
| -rw-r--r-- | package/hotplug2/Makefile | 1 | ||||
| -rw-r--r-- | target/linux/brcm-2.4/base-files/default/etc/hotplug2-init.rules | 12 | ||||
| -rw-r--r-- | target/linux/brcm47xx-2.6/patches-2.6.22/140-export_uevent_handler.patch | 12 | ||||
| -rw-r--r-- | target/linux/brcm47xx-2.6/patches/140-export_uevent_handler.patch | 11 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches-2.6.22/213-kobject_uevent.patch | 37 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/213-kobject_uevent.patch | 37 | 
13 files changed, 219 insertions, 81 deletions
| diff --git a/package/hotplug2/files/hotplug2-init.rules b/package/base-files/files/etc/hotplug2-init.rules index 6efd54668..6efd54668 100644 --- a/package/hotplug2/files/hotplug2-init.rules +++ b/package/base-files/files/etc/hotplug2-init.rules diff --git a/package/base-files/files/etc/init.d/boot b/package/base-files/files/etc/init.d/boot index 02519fbbc..9990dc782 100755 --- a/package/base-files/files/etc/init.d/boot +++ b/package/base-files/files/etc/init.d/boot @@ -40,7 +40,7 @@ start() {  	touch /var/log/lastlog  	ln -s /tmp/resolv.conf.auto /tmp/resolv.conf  	[ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe -	 +  	/sbin/hotplug2 --persistent --max-children 1 &  	# the coldplugging of network interfaces needs to happen later, so we do it manually here diff --git a/package/base-files/files/etc/preinit b/package/base-files/files/etc/preinit index 85dbf314d..e5fdd43ae 100755 --- a/package/base-files/files/etc/preinit +++ b/package/base-files/files/etc/preinit @@ -23,7 +23,8 @@ else  	mount -t tmpfs tmpfs /dev -o size=512K  	mknod /dev/console c 5 1  	mkdir /dev/shm -	/sbin/hotplug2 --no-persistent --coldplug --set-rules-file /etc/hotplug2-init.rules +	/sbin/hotplug2 --coldplug --set-rules-file /etc/hotplug2-init.rules +	/sbin/hotplug2 --no-coldplug --persistent --set-rules-file /etc/hotplug2-init.rules &  	M0=/dev/ptmx  	M1=/dev/ptmx  	HOTPLUG= @@ -42,19 +43,16 @@ dd if=/dev/console of=/dev/null bs=1 count=0 >/dev/null 2>/dev/null && {  exec <$M0 >$M1 2>&0 -{ -	echo "- preinit -" -	[ -e /etc/preinit.arch ] && . /etc/preinit.arch -	set_state preinit +echo "- preinit -" -	echo "$HOTPLUG" > /proc/sys/kernel/hotplug - -	eval ${FAILSAFE:+failsafe} -	lock -w /tmp/.failsafe - -	mount_root - -	echo "- init -" -} | tee /tmp/preinit.log +[ -e /etc/preinit.arch ] && . /etc/preinit.arch +set_state preinit +echo "$HOTPLUG" > /proc/sys/kernel/hotplug +eval ${FAILSAFE:+failsafe} +lock -w /tmp/.failsafe +mount_root +echo "- init -" +	 +killall hotplug2  exec /sbin/init diff --git a/package/broadcom-diag/Makefile b/package/broadcom-diag/Makefile index c414c3d1c..b21f33a63 100644 --- a/package/broadcom-diag/Makefile +++ b/package/broadcom-diag/Makefile @@ -30,7 +30,7 @@ define Build/Prepare  endef  ifeq ($(BOARD),brcm) -	BUILDFLAGS=-DBCMDRIVER -I$(LINUX_DIR)/arch/mips/bcm947xx/include +	BUILDFLAGS=-DBCMDRIVER -I$(LINUX_DIR)/arch/mips/bcm947xx/include $(if $(CONFIG_LINUX_2_4),-DLINUX_2_4)  endif  define Build/Compile diff --git a/package/broadcom-diag/src/diag.c b/package/broadcom-diag/src/diag.c index af1907992..c53ff2f97 100644 --- a/package/broadcom-diag/src/diag.c +++ b/package/broadcom-diag/src/diag.c @@ -2,7 +2,7 @@   * diag.c - GPIO interface driver for Broadcom boards   *   * Copyright (C) 2006 Mike Baker <mbm@openwrt.org>, - *                    Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org>   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License @@ -28,10 +28,13 @@  #include <linux/version.h>  #include <asm/uaccess.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#include <linux/kobject.h> +#ifndef LINUX_2_4  #include <linux/workqueue.h> -#define hotplug_path uevent_helper +#include <linux/skbuff.h> +#include <linux/netlink.h> +#include <net/sock.h> +extern struct sock *uevent_sock; +extern u64 uevent_next_seqnum(void);  #else  #include <linux/tqueue.h>  #define INIT_WORK INIT_TQUEUE @@ -43,6 +46,7 @@  #include "diag.h"  #define getvar(str) (nvram_get(str)?:"") +static int fill_event(struct event_t *);  static unsigned int gpiomask = 0;  module_param(gpiomask, int, 0644); @@ -713,23 +717,104 @@ static void unregister_buttons(struct button_t *b)  	gpio_set_irqenable(0, button_handler);  } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) + +#ifndef LINUX_2_4 +static void add_msg(struct event_t *event, char *msg, int argv) +{ +	char *s; + +	if (argv) +		return; + +	s = skb_put(event->skb, strlen(msg) + 1); +	strcpy(s, msg); +} +  static void hotplug_button(struct work_struct *work)  {  	struct event_t *event = container_of(work, struct event_t, wq); -#else +	char *s; + +	if (!uevent_sock) +		return; + +	event->skb = alloc_skb(2048, GFP_KERNEL); + +	s = skb_put(event->skb, strlen(event->action) + 2); +	sprintf(s, "%s@", event->action); +	fill_event(event); + +	NETLINK_CB(event->skb).dst_group = 1; +	netlink_broadcast(uevent_sock, event->skb, 0, 1, GFP_KERNEL); + +	kfree(event); +} + +#else /* !LINUX_2_4 */ +static inline char *kzalloc(unsigned int size, unsigned int gfp) +{ +	char *p; + +	p = kmalloc(size, gfp); +	if (p == NULL) +		return NULL; + +	memset(p, 0, size); + +	return p; +} + +static void add_msg(struct event_t *event, char *msg, int argv) +{ +	if (argv) +		event->argv[event->anr++] = event->scratch; +	else +		event->envp[event->enr++] = event->scratch; + +	event->scratch += sprintf(event->scratch, "%s", msg) + 1; +} +  static void hotplug_button(struct event_t *event)  { -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -	call_usermodehelper (event->argv[0], event->argv, event->envp, 1); -#else +	char *scratch = kzalloc(256, GFP_KERNEL); +	event->scratch = scratch; + +	add_msg(event, hotplug_path, 1); +	add_msg(event, "button", 1); +	fill_event(event);  	call_usermodehelper (event->argv[0], event->argv, event->envp); -#endif +	kfree(scratch);  	kfree(event);  } +#endif /* !LINUX_2_4 */ +static int fill_event (struct event_t *event) +{ +	static char buf[128]; + +	add_msg(event, "HOME=/", 0); +	add_msg(event, "PATH=/sbin:/bin:/usr/sbin:/usr/bin", 0); +	add_msg(event, "SUBSYSTEM=button", 0); +	snprintf(buf, 128, "ACTION=%s", event->action); +	add_msg(event, buf, 0); +	snprintf(buf, 128, "BUTTON=%s", event->name); +	add_msg(event, buf, 0); +	snprintf(buf, 128, "SEEN=%ld", event->seen); +	add_msg(event, buf, 0); +#ifndef LINUX_2_4 +	snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum()); +	add_msg(event, buf, 0); +#endif + +	return 0; +} + + +#ifndef LINUX_2_4 +static irqreturn_t button_handler(int irq, void *dev_id) +#else  static irqreturn_t button_handler(int irq, void *dev_id, struct pt_regs *regs) +#endif  {  	struct button_t *b;  	u32 in, changed; @@ -748,26 +833,10 @@ static irqreturn_t button_handler(int irq, void *dev_id, struct pt_regs *regs)  		b->pressed ^= 1; -		if ((event = (struct event_t *)kmalloc (sizeof(struct event_t), GFP_ATOMIC))) { -			int i; -			char *scratch = event->buf; - -			i = 0; -			event->argv[i++] = hotplug_path; -			event->argv[i++] = "button"; -			event->argv[i] = 0; - -			i = 0; -			event->envp[i++] = "HOME=/"; -			event->envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; -			event->envp[i++] = scratch; -			scratch += sprintf (scratch, "ACTION=%s", b->pressed?"pressed":"released") + 1; -			event->envp[i++] = scratch; -			scratch += sprintf (scratch, "BUTTON=%s", b->name) + 1; -			event->envp[i++] = scratch; -			scratch += sprintf (scratch, "SEEN=%ld", (jiffies - b->seen)/HZ) + 1; -			event->envp[i] = 0; - +		if ((event = (struct event_t *)kzalloc (sizeof(struct event_t), GFP_ATOMIC))) { +			event->seen = (jiffies - b->seen)/HZ; +			event->name = b->name; +			event->action = b->pressed ? "pressed" : "released";  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)  			INIT_WORK(&event->wq, (void *)(void *)hotplug_button);  #else @@ -1024,7 +1093,6 @@ static int __init diag_init(void)  static void __exit diag_exit(void)  { -  	del_timer(&led_timer);  	if (platform.buttons) diff --git a/package/broadcom-diag/src/diag.h b/package/broadcom-diag/src/diag.h index 9b6dc3633..93fdedb85 100644 --- a/package/broadcom-diag/src/diag.h +++ b/package/broadcom-diag/src/diag.h @@ -74,9 +74,16 @@ struct platform_t {  struct event_t {  	struct work_struct wq; -	char buf[256]; -	char *argv[3]; -	char *envp[6]; +	unsigned long seen; +	char *name, *action; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +	struct sk_buff *skb; +#else +	char *scratch; +	char *argv[4]; +	char *envp[7]; +	u8 enr, anr; +#endif  };  extern char *nvram_get(char *str); @@ -88,12 +95,13 @@ static struct platform_t platform;  static void register_buttons(struct button_t *b);  static void unregister_buttons(struct button_t *b); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +#ifndef LINUX_2_4  static void hotplug_button(struct work_struct *work); +static irqreturn_t button_handler(int irq, void *dev_id);  #else  static void hotplug_button(struct event_t *event); -#endif  static irqreturn_t button_handler(int irq, void *dev_id, struct pt_regs *regs); +#endif  /* leds */ diff --git a/package/broadcom-diag/src/gpio.h b/package/broadcom-diag/src/gpio.h index 16f6ca41c..6d83039ee 100644 --- a/package/broadcom-diag/src/gpio.h +++ b/package/broadcom-diag/src/gpio.h @@ -53,7 +53,7 @@ static inline u32 gpio_intpolarity(u32 mask, u32 value)  	gpio_op(polarity, mask, value);  } -static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *, struct pt_regs *)) +static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))  {  	int irq; @@ -63,10 +63,12 @@ static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *,  		irq = ssb_mips_irq(ssb.extif.dev) + 2;  	else return; -	if (enabled) -		request_irq(irq, handler, SA_SHIRQ | SA_SAMPLE_RANDOM, "gpio", handler); -	else +	if (enabled) { +		if (request_irq(irq, handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, "gpio", handler)) +			return; +	} else {  		free_irq(irq, handler); +	}  	if (ssb.chipco.dev)  		ssb_write32_masked(ssb.chipco.dev, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0)); diff --git a/package/hotplug2/Makefile b/package/hotplug2/Makefile index c696f09f5..94aadc085 100644 --- a/package/hotplug2/Makefile +++ b/package/hotplug2/Makefile @@ -34,7 +34,6 @@ MAKE_FLAGS += CFLAGS="$(TARGET_CFLAGS) -DHAVE_RULES"  define Package/hotplug2/install  	$(INSTALL_DIR) $(1)/etc  	$(INSTALL_DATA) ./files/hotplug2.rules $(1)/etc/ -	$(INSTALL_DATA) ./files/hotplug2-init.rules $(1)/etc/  	$(INSTALL_DIR) $(1)/sbin  	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hotplug2 $(1)/sbin/  endef diff --git a/target/linux/brcm-2.4/base-files/default/etc/hotplug2-init.rules b/target/linux/brcm-2.4/base-files/default/etc/hotplug2-init.rules new file mode 100644 index 000000000..098ad047a --- /dev/null +++ b/target/linux/brcm-2.4/base-files/default/etc/hotplug2-init.rules @@ -0,0 +1,12 @@ +DEVICENAME ~~ (tun|tap[0-9]) { +	makedev /dev/net/%DEVICENAME% 0644 +	next +} + +DEVPATH is set { +	makedev /dev/%DEVICENAME% 0644 +} + +SUBSYSTEM ~~ button { +	exec kill -USR1 1 ; +} diff --git a/target/linux/brcm47xx-2.6/patches-2.6.22/140-export_uevent_handler.patch b/target/linux/brcm47xx-2.6/patches-2.6.22/140-export_uevent_handler.patch deleted file mode 100644 index f6a41f32a..000000000 --- a/target/linux/brcm47xx-2.6/patches-2.6.22/140-export_uevent_handler.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.6.22-rc4/lib/kobject_uevent.c -=================================================================== ---- linux-2.6.22-rc4.orig/lib/kobject_uevent.c	2007-06-10 21:32:13.000000000 +0100 -+++ linux-2.6.22-rc4/lib/kobject_uevent.c	2007-06-10 21:33:18.000000000 +0100 -@@ -29,6 +29,7 @@ - u64 uevent_seqnum; - char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; - static DEFINE_SPINLOCK(sequence_lock); -+EXPORT_SYMBOL(uevent_helper); - #if defined(CONFIG_NET) - static struct sock *uevent_sock; - #endif diff --git a/target/linux/brcm47xx-2.6/patches/140-export_uevent_handler.patch b/target/linux/brcm47xx-2.6/patches/140-export_uevent_handler.patch deleted file mode 100644 index 6a6f51aa7..000000000 --- a/target/linux/brcm47xx-2.6/patches/140-export_uevent_handler.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -urN linux-2.6.19.ref/lib/kobject_uevent.c linux-2.6.19/lib/kobject_uevent.c ---- linux-2.6.19.ref/lib/kobject_uevent.c	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19/lib/kobject_uevent.c	2006-12-04 21:33:48.000000000 +0100 -@@ -29,6 +29,7 @@ - u64 uevent_seqnum; - char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; - static DEFINE_SPINLOCK(sequence_lock); -+EXPORT_SYMBOL(uevent_helper); - #if defined(CONFIG_NET) - static struct sock *uevent_sock; - #endif diff --git a/target/linux/generic-2.6/patches-2.6.22/213-kobject_uevent.patch b/target/linux/generic-2.6/patches-2.6.22/213-kobject_uevent.patch new file mode 100644 index 000000000..62af2a182 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.22/213-kobject_uevent.patch @@ -0,0 +1,37 @@ +--- linux-2.6.22-rc5/lib/kobject_uevent.c.old	2007-06-25 07:34:27.002266528 +0200 ++++ linux-2.6.22-rc5/lib/kobject_uevent.c	2007-06-25 08:39:53.762308264 +0200 +@@ -30,9 +30,22 @@ + char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; + static DEFINE_SPINLOCK(sequence_lock); + #if defined(CONFIG_NET) +-static struct sock *uevent_sock; ++struct sock *uevent_sock = NULL; ++EXPORT_SYMBOL_GPL(uevent_sock); + #endif +  ++u64 uevent_next_seqnum(void) ++{ ++	u64 seq; ++ ++	spin_lock(&sequence_lock); ++	seq = ++uevent_seqnum; ++	spin_unlock(&sequence_lock); ++	 ++	return seq; ++} ++EXPORT_SYMBOL_GPL(uevent_next_seqnum); ++ + static char *action_to_string(enum kobject_action action) + { + 	switch (action) { +@@ -169,9 +182,7 @@ + 	} +  + 	/* we will send an event, request a new sequence number */ +-	spin_lock(&sequence_lock); +-	seq = ++uevent_seqnum; +-	spin_unlock(&sequence_lock); ++	seq = uevent_next_seqnum(); + 	sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq); +  + #if defined(CONFIG_NET) diff --git a/target/linux/generic-2.6/patches/213-kobject_uevent.patch b/target/linux/generic-2.6/patches/213-kobject_uevent.patch new file mode 100644 index 000000000..62af2a182 --- /dev/null +++ b/target/linux/generic-2.6/patches/213-kobject_uevent.patch @@ -0,0 +1,37 @@ +--- linux-2.6.22-rc5/lib/kobject_uevent.c.old	2007-06-25 07:34:27.002266528 +0200 ++++ linux-2.6.22-rc5/lib/kobject_uevent.c	2007-06-25 08:39:53.762308264 +0200 +@@ -30,9 +30,22 @@ + char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; + static DEFINE_SPINLOCK(sequence_lock); + #if defined(CONFIG_NET) +-static struct sock *uevent_sock; ++struct sock *uevent_sock = NULL; ++EXPORT_SYMBOL_GPL(uevent_sock); + #endif +  ++u64 uevent_next_seqnum(void) ++{ ++	u64 seq; ++ ++	spin_lock(&sequence_lock); ++	seq = ++uevent_seqnum; ++	spin_unlock(&sequence_lock); ++	 ++	return seq; ++} ++EXPORT_SYMBOL_GPL(uevent_next_seqnum); ++ + static char *action_to_string(enum kobject_action action) + { + 	switch (action) { +@@ -169,9 +182,7 @@ + 	} +  + 	/* we will send an event, request a new sequence number */ +-	spin_lock(&sequence_lock); +-	seq = ++uevent_seqnum; +-	spin_unlock(&sequence_lock); ++	seq = uevent_next_seqnum(); + 	sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq); +  + #if defined(CONFIG_NET) | 
