From ed9b707f188af9e0db6b26c17a6bafa1c69a28d7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 9 Nov 2005 10:50:29 +0000 Subject: [PATCH] --- yaml --- r: 13623 b: refs/heads/master c: 2a98beb6390aef8fad85103ea25b3b1ace8015b5 h: refs/heads/master i: 13621: 6255c53496cadd3bbe0c826e43d6f9ca0486c4d6 13619: 355baa517ad33f8a9c6bfec2cba47979e55bd700 13615: 437318f72b3f9419cf3d3cff6e264a09e4a85307 v: v3 --- [refs] | 2 +- trunk/Documentation/connector/cn_test.c | 4 +- trunk/arch/arm/Kconfig | 2 +- trunk/arch/arm/boot/compressed/misc.c | 6 - trunk/arch/arm/common/scoop.c | 6 + trunk/arch/arm/kernel/armksyms.c | 4 - trunk/arch/arm/kernel/process.c | 2 +- trunk/arch/arm/mach-pxa/corgi.c | 48 +- trunk/arch/arm/mach-pxa/poodle.c | 32 +- trunk/arch/arm/mach-pxa/spitz.c | 95 +-- trunk/arch/arm/mach-pxa/time.c | 8 +- trunk/arch/arm/mach-pxa/tosa.c | 152 +--- trunk/arch/arm/mach-realview/Makefile | 1 + trunk/arch/arm/mach-realview/core.c | 2 +- trunk/arch/arm/mach-realview/localtimer.c | 130 ++++ trunk/arch/arm/mach-realview/platsmp.c | 5 + trunk/arch/arm/mach-s3c2410/Kconfig | 8 - trunk/arch/arm/mach-s3c2410/mach-anubis.c | 51 +- trunk/arch/arm/mach-s3c2410/mach-bast.c | 73 +- trunk/arch/arm/mach-s3c2410/mach-rx3715.c | 13 +- trunk/arch/arm/mach-s3c2410/mach-smdk2440.c | 23 +- trunk/arch/arm/mach-s3c2410/mach-vr1000.c | 56 +- trunk/arch/arm/mach-sa1100/time.c | 8 +- trunk/arch/s390/appldata/appldata_base.c | 7 +- trunk/arch/sparc64/mm/fault.c | 2 +- trunk/drivers/bluetooth/bpa10x.c | 4 +- trunk/drivers/bluetooth/hci_usb.c | 7 - trunk/drivers/net/Kconfig | 13 - trunk/drivers/net/Makefile | 1 - trunk/drivers/net/ioc3-eth.c | 42 +- trunk/drivers/net/irda/donauboe.c | 14 +- trunk/drivers/net/ppp_async.c | 17 +- trunk/drivers/net/ppp_generic.c | 88 +-- trunk/drivers/net/ppp_mppe.c | 724 ------------------ trunk/drivers/net/ppp_mppe.h | 86 --- trunk/drivers/pcmcia/pxa2xx_sharpsl.c | 140 ++-- trunk/drivers/sbus/char/openprom.c | 3 - trunk/fs/exec.c | 10 +- .../asm-arm/arch-realview/entry-macro.S | 11 + trunk/include/asm-arm/arch-realview/irqs.h | 3 + .../include/asm-arm/arch-realview/platform.h | 5 +- .../include/asm-arm/arch-s3c2410/uncompress.h | 22 +- trunk/include/asm-arm/hardware/scoop.h | 10 +- trunk/include/linux/if_ppp.h | 7 +- trunk/include/linux/ppp-comp.h | 9 - trunk/include/linux/proc_fs.h | 1 - trunk/include/linux/sysctl.h | 3 - trunk/include/net/bluetooth/bluetooth.h | 4 +- trunk/include/net/bluetooth/hci.h | 116 +-- trunk/include/net/bluetooth/hci_core.h | 9 +- trunk/include/net/bluetooth/rfcomm.h | 2 + trunk/include/net/ipv6.h | 67 +- trunk/include/net/sock.h | 20 +- trunk/kernel/sysctl.c | 136 +--- trunk/net/802/p8023.c | 3 +- trunk/net/ax25/af_ax25.c | 6 +- trunk/net/ax25/ax25_in.c | 6 +- trunk/net/ax25/ax25_route.c | 19 +- trunk/net/bluetooth/af_bluetooth.c | 12 +- trunk/net/bluetooth/hci_core.c | 2 +- trunk/net/bluetooth/hci_event.c | 6 +- trunk/net/bluetooth/hci_sock.c | 2 +- trunk/net/bluetooth/hci_sysfs.c | 4 +- trunk/net/bluetooth/hidp/core.c | 4 +- trunk/net/bluetooth/l2cap.c | 98 ++- trunk/net/bluetooth/rfcomm/core.c | 124 ++- trunk/net/bluetooth/rfcomm/sock.c | 90 ++- trunk/net/bluetooth/sco.c | 92 ++- trunk/net/core/dev_mcast.c | 3 +- trunk/net/core/sock.c | 3 +- trunk/net/dccp/ipv4.c | 6 +- trunk/net/dccp/proto.c | 3 +- trunk/net/decnet/dn_table.c | 14 +- trunk/net/ethernet/pe2.c | 3 +- trunk/net/ipv4/af_inet.c | 3 +- trunk/net/ipv4/fib_frontend.c | 3 +- trunk/net/ipv4/ip_options.c | 3 +- trunk/net/ipv4/ip_output.c | 15 +- trunk/net/ipv4/ip_sockglue.c | 12 +- trunk/net/ipv4/ipvs/ip_vs_app.c | 6 +- trunk/net/ipv4/ipvs/ip_vs_core.c | 7 +- trunk/net/ipv4/multipath_wrandom.c | 10 +- trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c | 3 +- trunk/net/ipv4/tcp_ipv4.c | 3 +- trunk/net/ipv6/addrconf.c | 433 ++++------- trunk/net/ipv6/ip6_fib.c | 54 +- trunk/net/ipv6/ip6_output.c | 15 +- trunk/net/ipv6/ip6_tunnel.c | 6 +- trunk/net/ipv6/ipcomp6.c | 3 +- trunk/net/ipv6/ipv6_sockglue.c | 3 +- trunk/net/ipv6/ipv6_syms.c | 2 +- trunk/net/irda/discovery.c | 3 +- trunk/net/irda/irias_object.c | 16 +- trunk/net/rose/rose_route.c | 6 +- trunk/net/sched/cls_fw.c | 3 +- trunk/net/sched/cls_route.c | 3 +- trunk/net/sched/cls_rsvp.h | 3 +- trunk/net/sched/cls_tcindex.c | 9 +- trunk/net/sched/cls_u32.c | 4 +- trunk/net/sched/em_meta.c | 3 +- trunk/net/sched/ematch.c | 5 - trunk/net/sctp/associola.c | 4 +- trunk/net/sctp/sm_make_chunk.c | 6 +- trunk/net/sunrpc/auth_gss/gss_krb5_seal.c | 2 +- trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c | 2 +- trunk/net/sunrpc/auth_gss/gss_mech_switch.c | 3 +- trunk/net/sunrpc/auth_gss/gss_spkm3_seal.c | 3 +- trunk/net/sunrpc/auth_gss/gss_spkm3_token.c | 3 +- trunk/net/sunrpc/auth_gss/gss_spkm3_unseal.c | 6 +- trunk/net/sunrpc/svc.c | 9 +- trunk/net/sunrpc/xdr.c | 3 +- trunk/net/wanrouter/af_wanpipe.c | 20 +- trunk/net/wanrouter/wanmain.c | 12 +- trunk/net/xfrm/xfrm_state.c | 12 +- 114 files changed, 1263 insertions(+), 2272 deletions(-) create mode 100644 trunk/arch/arm/mach-realview/localtimer.c delete mode 100644 trunk/drivers/net/ppp_mppe.c delete mode 100644 trunk/drivers/net/ppp_mppe.h diff --git a/[refs] b/[refs] index f3532492ade3..7cee5bbb86af 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c906107bb72b7bd5ecfc98cc807bdb8f34d17501 +refs/heads/master: 2a98beb6390aef8fad85103ea25b3b1ace8015b5 diff --git a/trunk/Documentation/connector/cn_test.c b/trunk/Documentation/connector/cn_test.c index 3e73231695b3..b7de82e9c0e0 100644 --- a/trunk/Documentation/connector/cn_test.c +++ b/trunk/Documentation/connector/cn_test.c @@ -25,7 +25,7 @@ #include #include -#include +#include "connector.h" static struct cb_id cn_test_id = { 0x123, 0x456 }; static char cn_test_name[] = "cn_test"; @@ -104,7 +104,7 @@ static int cn_test_want_notify(void) req->first = cn_test_id.val + 20; req->range = 10; - NETLINK_CB(skb).dst_group = ctl->group; + NETLINK_CB(skb).dst_groups = ctl->group; //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC); netlink_unicast(nls, skb, 0, 0); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 3bfef0934c9d..ec77721507cb 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -358,7 +358,7 @@ config HOTPLUG_CPU config LOCAL_TIMERS bool "Use local timer interrupts" - depends on SMP && n + depends on SMP && REALVIEW_MPCORE default y help Enable support for local timers on SMP platforms, rather then the diff --git a/trunk/arch/arm/boot/compressed/misc.c b/trunk/arch/arm/boot/compressed/misc.c index 5ab94584baee..50f13eec6cd7 100644 --- a/trunk/arch/arm/boot/compressed/misc.c +++ b/trunk/arch/arm/boot/compressed/misc.c @@ -283,14 +283,8 @@ void flush_window(void) putstr("."); } -#ifndef arch_error -#define arch_error(x) -#endif - static void error(char *x) { - arch_error(x); - putstr("\n\n"); putstr(x); putstr("\n\n -- System halted"); diff --git a/trunk/arch/arm/common/scoop.c b/trunk/arch/arm/common/scoop.c index c7fdf390cef9..bb4eff614413 100644 --- a/trunk/arch/arm/common/scoop.c +++ b/trunk/arch/arm/common/scoop.c @@ -19,6 +19,12 @@ #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) +/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c + There is no easy way to link multiple scoop devices into one + single entity for the pxa2xx_pcmcia device */ +int scoop_num; +struct scoop_pcmcia_dev *scoop_devs; + struct scoop_dev { void *base; spinlock_t scoop_lock; diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c index 7a3261f0bf79..7b17a87a3311 100644 --- a/trunk/arch/arm/kernel/armksyms.c +++ b/trunk/arch/arm/kernel/armksyms.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include @@ -127,9 +126,6 @@ EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); - /* crypto hash */ -EXPORT_SYMBOL(sha_transform); - /* gcc lib functions */ EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 07fb744f8a68..ba298277becd 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -355,7 +355,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = p->thread_info; struct pt_regs *childregs; - childregs = (void *)thread + THREAD_START_SP - sizeof(*regs); + childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; *childregs = *regs; childregs->ARM_r0 = 0; childregs->ARM_sp = stack_start; diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index 100fb31b5156..eb5f6d744a4a 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -62,37 +62,6 @@ static struct scoop_config corgi_scoop_setup = { .io_out = CORGI_SCOOP_IO_OUT, }; -struct platform_device corgiscoop_device = { - .name = "sharp-scoop", - .id = -1, - .dev = { - .platform_data = &corgi_scoop_setup, - }, - .num_resources = ARRAY_SIZE(corgi_scoop_resources), - .resource = corgi_scoop_resources, -}; - -static void corgi_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { { .dev = &corgiscoop_device.dev, @@ -102,14 +71,16 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { }, }; -static struct scoop_pcmcia_config corgi_pcmcia_config = { - .devs = &corgi_pcmcia_scoop[0], - .num_devs = 1, - .pcmcia_init = corgi_pcmcia_init, +struct platform_device corgiscoop_device = { + .name = "sharp-scoop", + .id = -1, + .dev = { + .platform_data = &corgi_scoop_setup, + }, + .num_resources = ARRAY_SIZE(corgi_scoop_resources), + .resource = corgi_scoop_resources, }; -EXPORT_SYMBOL(corgiscoop_device); - /* * Corgi SSP Device @@ -323,7 +294,8 @@ static void __init corgi_init(void) pxa_set_mci_info(&corgi_mci_platform_data); pxa_set_ficp_info(&corgi_ficp_platform_data); - platform_scoop_config = &corgi_pcmcia_config; + scoop_num = 1; + scoop_devs = &corgi_pcmcia_scoop[0]; platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/trunk/arch/arm/mach-pxa/poodle.c b/trunk/arch/arm/mach-pxa/poodle.c index eef3de26ad37..ad6a13f95a62 100644 --- a/trunk/arch/arm/mach-pxa/poodle.c +++ b/trunk/arch/arm/mach-pxa/poodle.c @@ -65,27 +65,6 @@ struct platform_device poodle_scoop_device = { .resource = poodle_scoop_resources, }; -static void poodle_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { { .dev = &poodle_scoop_device.dev, @@ -95,14 +74,6 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { }, }; -static struct scoop_pcmcia_config poodle_pcmcia_config = { - .devs = &poodle_pcmcia_scoop[0], - .num_devs = 1, - .pcmcia_init = poodle_pcmcia_init, -}; - -EXPORT_SYMBOL(poodle_scoop_device); - /* LoCoMo device */ static struct resource locomo_resources[] = { @@ -297,7 +268,8 @@ static void __init poodle_init(void) pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); - platform_scoop_config = &poodle_pcmcia_config; + scoop_num = 1; + scoop_devs = &poodle_pcmcia_scoop[0]; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index 4e9a699ee428..6c6878cd2207 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -104,66 +104,6 @@ struct platform_device spitzscoop2_device = { .resource = spitz_scoop2_resources, }; -#define SPITZ_PWR_SD 0x01 -#define SPITZ_PWR_CF 0x02 - -/* Power control is shared with between one of the CF slots and SD */ -static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) -{ - unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); - - if (new_cpr & 0x0007) { - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); - if (!(cpr & 0x0002) && !(cpr & 0x0004)) - mdelay(5); - if (device == SPITZ_PWR_CF) - cpr |= 0x0002; - if (device == SPITZ_PWR_SD) - cpr |= 0x0004; - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); - } else { - if (device == SPITZ_PWR_CF) - cpr &= ~0x0002; - if (device == SPITZ_PWR_SD) - cpr &= ~0x0004; - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); - if (!(cpr & 0x0002) && !(cpr & 0x0004)) { - mdelay(1); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); - } - } -} - -static void spitz_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2); - GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO85_nPCE_1_MD); - pxa_gpio_mode(GPIO54_nPCE_2_MD); - pxa_gpio_mode(GPIO104_pSKTSEL_MD); -} - -static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr) -{ - /* Only need to override behaviour for slot 0 */ - if (nr == 0) - spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr); - else - write_scoop_reg(scoop, SCOOP_CPR, cpr); -} - static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { { .dev = &spitzscoop_device.dev, @@ -177,16 +117,6 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { }, }; -static struct scoop_pcmcia_config spitz_pcmcia_config = { - .devs = &spitz_pcmcia_scoop[0], - .num_devs = 2, - .pcmcia_init = spitz_pcmcia_init, - .power_ctrl = spitz_pcmcia_pwr, -}; - -EXPORT_SYMBOL(spitzscoop_device); -EXPORT_SYMBOL(spitzscoop2_device); - /* * Spitz SSP Device @@ -305,14 +235,27 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in return 0; } +/* Power control is shared with one of the CF slots so we have a mess */ static void spitz_mci_setpower(struct device *dev, unsigned int vdd) { struct pxamci_platform_data* p_d = dev->platform_data; - if (( 1 << vdd) & p_d->ocr_mask) - spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004); - else - spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000); + unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); + + if (( 1 << vdd) & p_d->ocr_mask) { + /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ + set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); + mdelay(2); + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04); + } else { + /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */ + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04); + + if (!(cpr | 0x02)) { + mdelay(1); + reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); + } + } } static int spitz_mci_get_ro(struct device *dev) @@ -408,8 +351,8 @@ static void __init common_init(void) static void __init spitz_init(void) { - platform_scoop_config = &spitz_pcmcia_config; - + scoop_num = 2; + scoop_devs = &spitz_pcmcia_scoop[0]; spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; common_init(); diff --git a/trunk/arch/arm/mach-pxa/time.c b/trunk/arch/arm/mach-pxa/time.c index b9b2057349eb..7dad3f1465e0 100644 --- a/trunk/arch/arm/mach-pxa/time.c +++ b/trunk/arch/arm/mach-pxa/time.c @@ -132,13 +132,11 @@ static void __init pxa_timer_init(void) tv.tv_sec = pxa_get_rtc_time(); do_settimeofday(&tv); - OIER = 0; /* disable any timer interrupts */ - OSCR = LATCH*2; /* push OSCR out of the way */ - OSMR0 = LATCH; /* set initial match */ + OSMR0 = 0; /* set initial match at 0 */ OSSR = 0xf; /* clear status on all timers */ setup_irq(IRQ_OST0, &pxa_timer_irq); - OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer */ + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ } #ifdef CONFIG_NO_IDLE_HZ diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index c312054dfb88..400609f8b6a8 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -98,9 +98,6 @@ struct platform_device tosascoop_jc_device = { .resource = tosa_scoop_jc_resources, }; -/* - * PCMCIA - */ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { { .dev = &tosascoop_device.dev, @@ -114,155 +111,16 @@ static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { }, }; -static void tosa_pcmcia_init(void) -{ - /* Setup default state of GPIO outputs - before we enable them as outputs. */ - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | - GPIO_bit(GPIO53_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - pxa_gpio_mode(GPIO52_nPCE_1_MD); - pxa_gpio_mode(GPIO53_nPCE_2_MD); - pxa_gpio_mode(GPIO54_pSKTSEL_MD); -} - -static struct scoop_pcmcia_config tosa_pcmcia_config = { - .devs = &tosa_pcmcia_scoop[0], - .num_devs = 2, - .pcmcia_init = tosa_pcmcia_init, -}; - -/* - * USB Device Controller - */ -static void tosa_udc_command(int cmd) -{ - switch(cmd) { - case PXA2XX_UDC_CMD_CONNECT: - set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); - break; - case PXA2XX_UDC_CMD_DISCONNECT: - reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); - break; - } -} - -static int tosa_udc_is_connected(void) -{ - return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0); -} - - -static struct pxa2xx_udc_mach_info udc_info __initdata = { - .udc_command = tosa_udc_command, - .udc_is_connected = tosa_udc_is_connected, -}; - -/* - * MMC/SD Device - */ -static struct pxamci_platform_data tosa_mci_platform_data; - -static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data) -{ - int err; - - /* setup GPIO for PXA25x MMC controller */ - pxa_gpio_mode(GPIO6_MMCCLK_MD); - pxa_gpio_mode(GPIO8_MMCCS0_MD); - pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN); - - tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); - - err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT, - "MMC/SD card detect", data); - if (err) { - printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); - return -1; - } - - set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); - - return 0; -} - -static void tosa_mci_setpower(struct device *dev, unsigned int vdd) -{ - struct pxamci_platform_data* p_d = dev->platform_data; - - if (( 1 << vdd) & p_d->ocr_mask) { - set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); - } else { - reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); - } -} - -static int tosa_mci_get_ro(struct device *dev) -{ - return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP); -} - -static void tosa_mci_exit(struct device *dev, void *data) -{ - free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); -} - -static struct pxamci_platform_data tosa_mci_platform_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .init = tosa_mci_init, - .get_ro = tosa_mci_get_ro, - .setpower = tosa_mci_setpower, - .exit = tosa_mci_exit, -}; - -/* - * Irda - */ -static void tosa_irda_transceiver_mode(struct device *dev, int mode) -{ - if (mode & IR_OFF) { - reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); - pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW); - pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT); - } else { - pxa_gpio_mode(GPIO47_STTXD_MD); - set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); - } -} - -static struct pxaficp_platform_data tosa_ficp_platform_data = { - .transceiver_cap = IR_SIRMODE | IR_OFF, - .transceiver_mode = tosa_irda_transceiver_mode, -}; - -/* - * Tosa Keyboard - */ -static struct platform_device tosakbd_device = { - .name = "tosa-keyboard", - .id = -1, -}; static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, - &tosakbd_device, }; static void __init tosa_init(void) { pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); - pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); /* setup sleep mode values */ PWER = 0x00000002; @@ -273,15 +131,13 @@ static void __init tosa_init(void) PGSR2 = 0x00014000; PCFR |= PCFR_OPDE; - /* enable batt_fault */ + // enable batt_fault PMCR = 0x01; - pxa_set_mci_info(&tosa_mci_platform_data); - pxa_set_udc_info(&udc_info); - pxa_set_ficp_info(&tosa_ficp_platform_data); - platform_scoop_config = &tosa_pcmcia_config; - platform_add_devices(devices, ARRAY_SIZE(devices)); + + scoop_num = 2; + scoop_devs = &tosa_pcmcia_scoop[0]; } static void __init fixup_tosa(struct machine_desc *desc, diff --git a/trunk/arch/arm/mach-realview/Makefile b/trunk/arch/arm/mach-realview/Makefile index 011a85c10627..a6a40dac26a9 100644 --- a/trunk/arch/arm/mach-realview/Makefile +++ b/trunk/arch/arm/mach-realview/Makefile @@ -5,3 +5,4 @@ obj-y := core.o clock.o obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o diff --git a/trunk/arch/arm/mach-realview/core.c b/trunk/arch/arm/mach-realview/core.c index 4ea60d8b6e36..e2c6fa23d3cd 100644 --- a/trunk/arch/arm/mach-realview/core.c +++ b/trunk/arch/arm/mach-realview/core.c @@ -550,7 +550,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg timer_tick(regs); -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) smp_send_timer(); update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/arm/mach-realview/localtimer.c b/trunk/arch/arm/mach-realview/localtimer.c new file mode 100644 index 000000000000..5e917e37d095 --- /dev/null +++ b/trunk/arch/arm/mach-realview/localtimer.c @@ -0,0 +1,130 @@ +/* + * linux/arch/arm/mach-realview/localtimer.c + * + * Copyright (C) 2002 ARM Ltd. + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "core.h" + +#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ + ((cpu) * REALVIEW_TWD_SIZE)) + +static unsigned long mpcore_timer_rate; + +/* + * local_timer_ack: checks for a local timer interrupt. + * + * If a local timer interrupt has occured, acknowledge and return 1. + * Otherwise, return 0. + */ +int local_timer_ack(void) +{ + void __iomem *base = TWD_BASE(smp_processor_id()); + + if (__raw_readl(base + TWD_TIMER_INTSTAT)) { + __raw_writel(1, base + TWD_TIMER_INTSTAT); + return 1; + } + + return 0; +} + +void __cpuinit local_timer_setup(unsigned int cpu) +{ + void __iomem *base = TWD_BASE(cpu); + unsigned int load, offset; + u64 waitjiffies; + unsigned int count; + + /* + * If this is the first time round, we need to work out how fast + * the timer ticks + */ + if (mpcore_timer_rate == 0) { + printk("Calibrating local timer... "); + + /* Wait for a tick to start */ + waitjiffies = get_jiffies_64() + 1; + + while (get_jiffies_64() < waitjiffies) + udelay(10); + + /* OK, now the tick has started, let's get the timer going */ + waitjiffies += 5; + + /* enable, no interrupt or reload */ + __raw_writel(0x1, base + TWD_TIMER_CONTROL); + + /* maximum value */ + __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER); + + while (get_jiffies_64() < waitjiffies) + udelay(10); + + count = __raw_readl(base + TWD_TIMER_COUNTER); + + mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); + + printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000, + (mpcore_timer_rate / 100000) % 100); + } + + load = mpcore_timer_rate / HZ; + + __raw_writel(load, base + TWD_TIMER_LOAD); + __raw_writel(0x7, base + TWD_TIMER_CONTROL); + + /* + * Now maneuver our local tick into the right part of the jiffy. + * Start by working out where within the tick our local timer + * interrupt should go. + */ + offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1); + + /* + * gettimeoffset() will return a number of us since the last tick. + * Convert this number of us to a local timer tick count. + * Be careful of integer overflow whilst keeping maximum precision. + * + * with HZ=100 and 1MHz (fpga) ~ 1GHz processor: + * load = 1 ~ 10,000 + * mpcore_timer_rate/10000 = 100 ~ 100,000 + * + * so the multiply value will be less than 10^9 always. + */ + load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100; + + /* Add on our offset to get the load value */ + load = (load + offset) % (mpcore_timer_rate / HZ); + + __raw_writel(load, base + TWD_TIMER_COUNTER); + + /* Make sure our local interrupt controller has this enabled */ + __raw_writel(1 << IRQ_LOCALTIMER, + __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET); +} + +/* + * take a local timer down + */ +void __cpuexit local_timer_stop(unsigned int cpu) +{ + __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); +} diff --git a/trunk/arch/arm/mach-realview/platsmp.c b/trunk/arch/arm/mach-realview/platsmp.c index 09b35f62247a..0c7d4ac9a7b3 100644 --- a/trunk/arch/arm/mach-realview/platsmp.c +++ b/trunk/arch/arm/mach-realview/platsmp.c @@ -174,6 +174,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (max_cpus > ncores) max_cpus = ncores; + /* + * Enable the local timer for primary CPU + */ + local_timer_setup(cpu); + /* * Initialise the possible/present maps. * cpu_possible_map describes the set of CPUs which may be present diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig index 0b9d7ca49ec1..c796bcdd6158 100644 --- a/trunk/arch/arm/mach-s3c2410/Kconfig +++ b/trunk/arch/arm/mach-s3c2410/Kconfig @@ -121,14 +121,6 @@ config S3C2410_BOOT_WATCHDOG system resets depends on the value of PCLK. The timeout on an 200MHz s3c2410 should be about 30 seconds. -config S3C2410_BOOT_ERROR_RESET - bool "S3C2410 Reboot on decompression error" - depends on ARCH_S3C2410 - help - Say y here to use the watchdog to reset the system if the - kernel decompressor detects an error during decompression. - - comment "S3C2410 Setup" config S3C2410_DMA diff --git a/trunk/arch/arm/mach-s3c2410/mach-anubis.c b/trunk/arch/arm/mach-s3c2410/mach-anubis.c index 0f81fc0c2f7f..8390b685c2b6 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-anubis.c +++ b/trunk/arch/arm/mach-s3c2410/mach-anubis.c @@ -56,16 +56,8 @@ static struct map_desc anubis_iodesc[] __initdata = { /* ISA IO areas */ - { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = __phys_to_pfn(0x0), - .length = SZ_4M, - .type = MT_DEVICE - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = __phys_to_pfn(0x0), - .length = SZ_4M, MT_DEVICE - }, + { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, /* we could possibly compress the next set down into a set of smaller tables * pagetables, but that would mean using an L2 section, and it still means @@ -74,41 +66,16 @@ static struct map_desc anubis_iodesc[] __initdata = { /* CPLD control registers */ - { - .virtual = (u32)ANUBIS_VA_CTRL1, - .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), - .length = SZ_4K, - .type = MT_DEVICE - }, { - .virtual = (u32)ANUBIS_VA_CTRL2, - .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), - .length = SZ_4K, - .type =MT_DEVICE - }, + { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, + { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, /* IDE drives */ - { - .virtual = (u32)ANUBIS_IDEPRI, - .pfn = __phys_to_pfn(S3C2410_CS3), - .length = SZ_1M, - .type = MT_DEVICE - }, { - .virtual = (u32)ANUBIS_IDEPRIAUX, - .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)), - .length = SZ_1M, - .type = MT_DEVICE - }, { - .virtual = (u32)ANUBIS_IDESEC, - .pfn = __phys_to_pfn(S3C2410_CS4), - .length = SZ_1M, - .type = MT_DEVICE - }, { - .virtual = (u32)ANUBIS_IDESECAUX, - .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)), - .length = SZ_1M, - .type = MT_DEVICE - }, + { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, + { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, + + { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, + { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, }; #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c index 1be2567a7486..0b71c896bbd1 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-bast.c +++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c @@ -89,63 +89,32 @@ /* macros to modify the physical addresses for io space */ -#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) -#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) -#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) -#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) +#define PA_CS2(item) ((item) + S3C2410_CS2) +#define PA_CS3(item) ((item) + S3C2410_CS3) +#define PA_CS4(item) ((item) + S3C2410_CS4) +#define PA_CS5(item) ((item) + S3C2410_CS5) static struct map_desc bast_iodesc[] __initdata = { /* ISA IO areas */ - { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = PA_CS2(BAST_PA_ISAIO), - .length = SZ_16M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = PA_CS3(BAST_PA_ISAIO), - .length = SZ_16M, - .type = MT_DEVICE, - }, + + { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + /* bast CPLD control registers, and external interrupt controls */ - { - .virtual = (u32)BAST_VA_CTRL1, - .pfn = __phys_to_pfn(BAST_PA_CTRL1), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)BAST_VA_CTRL2, - .pfn = __phys_to_pfn(BAST_PA_CTRL2), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)BAST_VA_CTRL3, - .pfn = __phys_to_pfn(BAST_PA_CTRL3), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)BAST_VA_CTRL4, - .pfn = __phys_to_pfn(BAST_PA_CTRL4), - .length = SZ_1M, - .type = MT_DEVICE, - }, + { (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE }, + /* PC104 IRQ mux */ - { - .virtual = (u32)BAST_VA_PC104_IRQREQ, - .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)BAST_VA_PC104_IRQRAW, - .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)BAST_VA_PC104_IRQMASK, - .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK), - .length = SZ_1M, - .type = MT_DEVICE, - }, + { (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE }, + { (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE }, /* peripheral space... one for each of fast/slow/byte/16bit */ /* note, ide is only decoded in word space, even though some registers diff --git a/trunk/arch/arm/mach-s3c2410/mach-rx3715.c b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c index f8d86d1e16b6..24d69019a843 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/trunk/arch/arm/mach-s3c2410/mach-rx3715.c @@ -56,17 +56,8 @@ static struct map_desc rx3715_iodesc[] __initdata = { /* dump ISA space somewhere unused */ - { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = __phys_to_pfn(S3C2410_CS3), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = __phys_to_pfn(S3C2410_CS3), - .length = SZ_1M, - .type = MT_DEVICE, - }, + { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, }; diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c index 4e31118533e6..d666c621ad06 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -58,27 +58,8 @@ static struct map_desc smdk2440_iodesc[] __initdata = { /* ISA IO Space map (memory space selected by A24) */ - { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = __phys_to_pfn(S3C2410_CS2), - .length = 0x10000, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, - .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), - .length = SZ_4M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = __phys_to_pfn(S3C2410_CS2), - .length = 0x10000, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, - .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), - .length = SZ_4M, - .type = MT_DEVICE, - } + { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, }; #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c index ae7e099bf6c8..46b259673c18 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c @@ -74,47 +74,27 @@ /* macros to modify the physical addresses for io space */ -#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) -#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) -#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) -#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) +#define PA_CS2(item) ((item) + S3C2410_CS2) +#define PA_CS3(item) ((item) + S3C2410_CS3) +#define PA_CS4(item) ((item) + S3C2410_CS4) +#define PA_CS5(item) ((item) + S3C2410_CS5) static struct map_desc vr1000_iodesc[] __initdata = { /* ISA IO areas */ - { - .virtual = (u32)S3C24XX_VA_ISA_BYTE, - .pfn = PA_CS2(BAST_PA_ISAIO), - .length = SZ_16M, - .type = MT_DEVICE, - }, { - .virtual = (u32)S3C24XX_VA_ISA_WORD, - .pfn = PA_CS3(BAST_PA_ISAIO), - .length = SZ_16M, - .type = MT_DEVICE, - }, - - /* CPLD control registers, and external interrupt controls */ - { - .virtual = (u32)VR1000_VA_CTRL1, - .pfn = __phys_to_pfn(VR1000_PA_CTRL1), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)VR1000_VA_CTRL2, - .pfn = __phys_to_pfn(VR1000_PA_CTRL2), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)VR1000_VA_CTRL3, - .pfn = __phys_to_pfn(VR1000_PA_CTRL3), - .length = SZ_1M, - .type = MT_DEVICE, - }, { - .virtual = (u32)VR1000_VA_CTRL4, - .pfn = __phys_to_pfn(VR1000_PA_CTRL4), - .length = SZ_1M, - .type = MT_DEVICE, - }, + + { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* bast CPLD control registers, and external interrupt controls */ + { (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE }, + { (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE }, /* peripheral space... one for each of fast/slow/byte/16bit */ /* note, ide is only decoded in word space, even though some registers diff --git a/trunk/arch/arm/mach-sa1100/time.c b/trunk/arch/arm/mach-sa1100/time.c index e4b435e634e4..47e0420623fc 100644 --- a/trunk/arch/arm/mach-sa1100/time.c +++ b/trunk/arch/arm/mach-sa1100/time.c @@ -124,13 +124,11 @@ static void __init sa1100_timer_init(void) tv.tv_sec = sa1100_get_rtc_time(); do_settimeofday(&tv); - OIER = 0; /* disable any timer interrupts */ - OSCR = LATCH*2; /* push OSCR out of the way */ - OSMR0 = LATCH; /* set initial match */ + OSMR0 = 0; /* set initial match at 0 */ OSSR = 0xf; /* clear status on all timers */ setup_irq(IRQ_OST0, &sa1100_timer_irq); - OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer */ + OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ + OSCR = 0; /* initialize free-running timer, force first match */ } #ifdef CONFIG_NO_IDLE_HZ diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index dee6ab54984d..c9f2f60cfa58 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -592,15 +592,12 @@ int appldata_register_ops(struct appldata_ops *ops) */ void appldata_unregister_ops(struct appldata_ops *ops) { - void *table; spin_lock(&appldata_ops_lock); + unregister_sysctl_table(ops->sysctl_header); list_del(&ops->list); - /* at that point any incoming access will fail */ - table = ops->ctl_table; + kfree(ops->ctl_table); ops->ctl_table = NULL; spin_unlock(&appldata_ops_lock); - unregister_sysctl_table(ops->sysctl_header); - kfree(table); P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management **************************/ diff --git a/trunk/arch/sparc64/mm/fault.c b/trunk/arch/sparc64/mm/fault.c index 3be278d916db..31fbc67719a1 100644 --- a/trunk/arch/sparc64/mm/fault.c +++ b/trunk/arch/sparc64/mm/fault.c @@ -109,7 +109,7 @@ static void bad_kernel_pc(struct pt_regs *regs) * this. Additionally, to prevent kswapd from ripping ptes from * under us, raise interrupts around the time that we look at the * pte, kswapd will have to wait to get his smp ipi response from - * us. vmtruncate likewise. This saves us having to get pte lock. + * us. This saves us having to get page_table_lock. */ static unsigned int get_user_insn(unsigned long tpc) { diff --git a/trunk/drivers/bluetooth/bpa10x.c b/trunk/drivers/bluetooth/bpa10x.c index 394796315adc..ecbeb7eaba8e 100644 --- a/trunk/drivers/bluetooth/bpa10x.c +++ b/trunk/drivers/bluetooth/bpa10x.c @@ -84,8 +84,8 @@ struct bpa10x_data { struct hci_vendor_hdr { __u8 type; - __le16 snum; - __le16 dlen; + __u16 snum; + __u16 dlen; } __attribute__ ((packed)); static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count) diff --git a/trunk/drivers/bluetooth/hci_usb.c b/trunk/drivers/bluetooth/hci_usb.c index 057cb2b6e6d1..f510b25b2c59 100644 --- a/trunk/drivers/bluetooth/hci_usb.c +++ b/trunk/drivers/bluetooth/hci_usb.c @@ -65,7 +65,6 @@ #endif static int ignore = 0; -static int ignore_dga = 0; static int ignore_csr = 0; static int ignore_sniffer = 0; static int reset = 0; @@ -842,9 +841,6 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id if (ignore || id->driver_info & HCI_IGNORE) return -ENODEV; - if (ignore_dga && id->driver_info & HCI_DIGIANSWER) - return -ENODEV; - if (ignore_csr && id->driver_info & HCI_CSR) return -ENODEV; @@ -1074,9 +1070,6 @@ module_exit(hci_usb_exit); module_param(ignore, bool, 0644); MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); -module_param(ignore_dga, bool, 0644); -MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001"); - module_param(ignore_csr, bool, 0644); MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 24f1691b84f9..1958d9e16a3a 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2523,19 +2523,6 @@ config PPP_BSDCOMP module; it is called bsd_comp and will show up in the directory modules once you have said "make modules". If unsure, say N. -config PPP_MPPE - tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" - depends on PPP && EXPERIMENTAL - select CRYPTO - select CRYPTO_SHA1 - select CRYPTO_ARC4 - ---help--- - Support for the MPPE Encryption protocol, as employed by the - Microsoft Point-to-Point Tunneling Protocol. - - See http://pptpclient.sourceforge.net/ for information on - configuring PPTP clients and servers to utilize this method. - config PPPOE tristate "PPP over Ethernet (EXPERIMENTAL)" depends on EXPERIMENTAL && PPP diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 4cffd34442aa..7c313cb341b8 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -112,7 +112,6 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o -obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_SLIP) += slip.o diff --git a/trunk/drivers/net/ioc3-eth.c b/trunk/drivers/net/ioc3-eth.c index 6a3129bc15a6..49e5467bdd73 100644 --- a/trunk/drivers/net/ioc3-eth.c +++ b/trunk/drivers/net/ioc3-eth.c @@ -46,8 +46,10 @@ #include #ifdef CONFIG_SERIAL_8250 -#include -#include +#include +#include +#define IOC3_BAUD (22000000 / (3*16)) +#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) #endif #include @@ -1144,11 +1146,12 @@ static inline int ioc3_is_menet(struct pci_dev *pdev) * around ioc3 oddities in this respect. * * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. + * (IOC3_BAUD = (22000000 / (3*16))) */ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) { - struct uart_port port; + struct serial_struct req; /* * We need to recognice and treat the fourth MENET serial as it @@ -1162,25 +1165,20 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3) return; - /* - * Register to interrupt zero because we share the interrupt with - * the serial driver which we don't properly support yet. - * - * Can't use UPF_IOREMAP as the whole of IOC3 resources have already - * been registered. - */ - memset(&port, 0, sizeof(port)); - port.irq = 0; - port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; - port.iotype = UPIO_MEM; - port.regshift = 0; - port.uartclk = 22000000 / 3; - - port.membase = (unsigned char *) &ioc3->sregs.uarta; - serial8250_register_port(&port); - - port.membase = (unsigned char *) &ioc3->sregs.uartb; - serial8250_register_port(&port); + /* Register to interrupt zero because we share the interrupt with + the serial driver which we don't properly support yet. */ + memset(&req, 0, sizeof(req)); + req.irq = 0; + req.flags = IOC3_COM_FLAGS; + req.io_type = SERIAL_IO_MEM; + req.iomem_reg_shift = 0; + req.baud_base = IOC3_BAUD; + + req.iomem_base = (unsigned char *) &ioc3->sregs.uarta; + register_serial(&req); + + req.iomem_base = (unsigned char *) &ioc3->sregs.uartb; + register_serial(&req); } #endif diff --git a/trunk/drivers/net/irda/donauboe.c b/trunk/drivers/net/irda/donauboe.c index 3137592d60c0..0282771b1cbb 100644 --- a/trunk/drivers/net/irda/donauboe.c +++ b/trunk/drivers/net/irda/donauboe.c @@ -1459,10 +1459,8 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) */ IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); - if (!in_interrupt () && !capable (CAP_NET_ADMIN)) { - ret = -EPERM; - goto out; - } + if (!in_interrupt () && !capable (CAP_NET_ADMIN)) + return -EPERM; /* self->speed=irq->ifr_baudrate; */ /* toshoboe_setbaud(self); */ @@ -1472,10 +1470,8 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) case SIOCSMEDIABUSY: /* Set media busy */ IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); - if (!capable (CAP_NET_ADMIN)) { - ret = -EPERM; - goto out; - } + if (!capable (CAP_NET_ADMIN)) + return -EPERM; irda_device_set_media_busy (self->netdev, TRUE); break; case SIOCGRECEIVING: /* Check if we are receiving right now */ @@ -1487,7 +1483,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); ret = -EOPNOTSUPP; } -out: + spin_unlock_irqrestore(&self->spinlock, flags); return ret; diff --git a/trunk/drivers/net/ppp_async.c b/trunk/drivers/net/ppp_async.c index 400f652282d7..59e8183c639e 100644 --- a/trunk/drivers/net/ppp_async.c +++ b/trunk/drivers/net/ppp_async.c @@ -31,7 +31,6 @@ #include #include #include -#include #define PPP_VERSION "2.4.2" @@ -836,11 +835,8 @@ process_input_packet(struct asyncppp *ap) err: /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */ ap->state = SC_PREV_ERROR; - if (skb) { - /* make skb appear as freshly allocated */ + if (skb) skb_trim(skb, 0); - skb_reserve(skb, - skb_headroom(skb)); - } } /* Called when the tty driver has data for us. Runs parallel with the @@ -893,17 +889,10 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf, skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); if (skb == 0) goto nomem; - ap->rpkt = skb; - } - if (skb->len == 0) { - /* Try to get the payload 4-byte aligned. - * This should match the - * PPP_ALLSTATIONS/PPP_UI/compressed tests in - * process_input_packet, but we do not have - * enough chars here to test buf[1] and buf[2]. - */ + /* Try to get the payload 4-byte aligned */ if (buf[0] != PPP_ALLSTATIONS) skb_reserve(skb, 2 + (buf[0] & 1)); + ap->rpkt = skb; } if (n > skb_tailroom(skb)) { /* packet overflowed MRU */ diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 50430f79f8cf..d3c9958b00d0 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -137,14 +137,13 @@ struct ppp { /* * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC, - * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP, - * SC_MUST_COMP + * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP. * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR. * Bits in xstate: SC_COMP_RUN */ #define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \ |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \ - |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP) + |SC_COMP_TCP|SC_REJ_COMP_TCP) /* * Private data structure for each channel. @@ -1028,56 +1027,6 @@ ppp_xmit_process(struct ppp *ppp) ppp_xmit_unlock(ppp); } -static inline struct sk_buff * -pad_compress_skb(struct ppp *ppp, struct sk_buff *skb) -{ - struct sk_buff *new_skb; - int len; - int new_skb_size = ppp->dev->mtu + - ppp->xcomp->comp_extra + ppp->dev->hard_header_len; - int compressor_skb_size = ppp->dev->mtu + - ppp->xcomp->comp_extra + PPP_HDRLEN; - new_skb = alloc_skb(new_skb_size, GFP_ATOMIC); - if (!new_skb) { - if (net_ratelimit()) - printk(KERN_ERR "PPP: no memory (comp pkt)\n"); - return NULL; - } - if (ppp->dev->hard_header_len > PPP_HDRLEN) - skb_reserve(new_skb, - ppp->dev->hard_header_len - PPP_HDRLEN); - - /* compressor still expects A/C bytes in hdr */ - len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2, - new_skb->data, skb->len + 2, - compressor_skb_size); - if (len > 0 && (ppp->flags & SC_CCP_UP)) { - kfree_skb(skb); - skb = new_skb; - skb_put(skb, len); - skb_pull(skb, 2); /* pull off A/C bytes */ - } else if (len == 0) { - /* didn't compress, or CCP not up yet */ - kfree_skb(new_skb); - new_skb = skb; - } else { - /* - * (len < 0) - * MPPE requires that we do not send unencrypted - * frames. The compressor will return -1 if we - * should drop the frame. We cannot simply test - * the compress_proto because MPPE and MPPC share - * the same number. - */ - if (net_ratelimit()) - printk(KERN_ERR "ppp: compressor dropped pkt\n"); - kfree_skb(skb); - kfree_skb(new_skb); - new_skb = NULL; - } - return new_skb; -} - /* * Compress and send a frame. * The caller should have locked the xmit path, @@ -1164,14 +1113,29 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) /* try to do packet compression */ if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 && proto != PPP_LCP && proto != PPP_CCP) { - if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) { - if (net_ratelimit()) - printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n"); + new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, + GFP_ATOMIC); + if (new_skb == 0) { + printk(KERN_ERR "PPP: no memory (comp pkt)\n"); goto drop; } - skb = pad_compress_skb(ppp, skb); - if (!skb) - goto drop; + if (ppp->dev->hard_header_len > PPP_HDRLEN) + skb_reserve(new_skb, + ppp->dev->hard_header_len - PPP_HDRLEN); + + /* compressor still expects A/C bytes in hdr */ + len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2, + new_skb->data, skb->len + 2, + ppp->dev->mtu + PPP_HDRLEN); + if (len > 0 && (ppp->flags & SC_CCP_UP)) { + kfree_skb(skb); + skb = new_skb; + skb_put(skb, len); + skb_pull(skb, 2); /* pull off A/C bytes */ + } else { + /* didn't compress, or CCP not up yet */ + kfree_skb(new_skb); + } } /* @@ -1191,8 +1155,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) return; drop: - if (skb) - kfree_skb(skb); + kfree_skb(skb); ++ppp->stats.tx_errors; } @@ -1589,9 +1552,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) skb = ppp_decompress_frame(ppp, skb); - if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR) - goto err; - proto = PPP_PROTO(skb); switch (proto) { case PPP_VJC_COMP: diff --git a/trunk/drivers/net/ppp_mppe.c b/trunk/drivers/net/ppp_mppe.c deleted file mode 100644 index 1985d1b57c45..000000000000 --- a/trunk/drivers/net/ppp_mppe.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * ppp_mppe.c - interface MPPE to the PPP code. - * This version is for use with Linux kernel 2.6.14+ - * - * By Frank Cusack . - * Copyright (c) 2002,2003,2004 Google, Inc. - * All rights reserved. - * - * License: - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. - * - * ALTERNATIVELY, provided that this notice is retained in full, this product - * may be distributed under the terms of the GNU General Public License (GPL), - * in which case the provisions of the GPL apply INSTEAD OF those given above. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * Changelog: - * 08/12/05 - Matt Domsch - * Only need extra skb padding on transmit, not receive. - * 06/18/04 - Matt Domsch , Oleg Makarenko - * Use Linux kernel 2.6 arc4 and sha1 routines rather than - * providing our own. - * 2/15/04 - TS: added #include and testing for Kernel - * version before using - * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are - * deprecated in 2.6 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ppp_mppe.h" - -MODULE_AUTHOR("Frank Cusack "); -MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE)); -MODULE_VERSION("1.0.2"); - -static void -setup_sg(struct scatterlist *sg, const void *address, unsigned int length) -{ - sg[0].page = virt_to_page(address); - sg[0].offset = offset_in_page(address); - sg[0].length = length; -} - -#define SHA1_PAD_SIZE 40 - -/* - * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module - * static data area. That means sha_pad needs to be kmalloc'd. - */ - -struct sha_pad { - unsigned char sha_pad1[SHA1_PAD_SIZE]; - unsigned char sha_pad2[SHA1_PAD_SIZE]; -}; -static struct sha_pad *sha_pad; - -static inline void sha_pad_init(struct sha_pad *shapad) -{ - memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1)); - memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2)); -} - -/* - * State for an MPPE (de)compressor. - */ -struct ppp_mppe_state { - struct crypto_tfm *arc4; - struct crypto_tfm *sha1; - unsigned char *sha1_digest; - unsigned char master_key[MPPE_MAX_KEY_LEN]; - unsigned char session_key[MPPE_MAX_KEY_LEN]; - unsigned keylen; /* key length in bytes */ - /* NB: 128-bit == 16, 40-bit == 8! */ - /* If we want to support 56-bit, */ - /* the unit has to change to bits */ - unsigned char bits; /* MPPE control bits */ - unsigned ccount; /* 12-bit coherency count (seqno) */ - unsigned stateful; /* stateful mode flag */ - int discard; /* stateful mode packet loss flag */ - int sanity_errors; /* take down LCP if too many */ - int unit; - int debug; - struct compstat stats; -}; - -/* struct ppp_mppe_state.bits definitions */ -#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */ -#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */ -#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */ -#define MPPE_BIT_D 0x10 /* This is an encrypted frame */ - -#define MPPE_BIT_FLUSHED MPPE_BIT_A -#define MPPE_BIT_ENCRYPTED MPPE_BIT_D - -#define MPPE_BITS(p) ((p)[4] & 0xf0) -#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5]) -#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */ - -#define MPPE_OVHD 2 /* MPPE overhead/packet */ -#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */ - -/* - * Key Derivation, from RFC 3078, RFC 3079. - * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. - */ -static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey) -{ - struct scatterlist sg[4]; - - setup_sg(&sg[0], state->master_key, state->keylen); - setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1)); - setup_sg(&sg[2], state->session_key, state->keylen); - setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2)); - - crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest); - - memcpy(InterimKey, state->sha1_digest, state->keylen); -} - -/* - * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3. - * Well, not what's written there, but rather what they meant. - */ -static void mppe_rekey(struct ppp_mppe_state * state, int initial_key) -{ - unsigned char InterimKey[MPPE_MAX_KEY_LEN]; - struct scatterlist sg_in[1], sg_out[1]; - - get_new_key_from_sha(state, InterimKey); - if (!initial_key) { - crypto_cipher_setkey(state->arc4, InterimKey, state->keylen); - setup_sg(sg_in, InterimKey, state->keylen); - setup_sg(sg_out, state->session_key, state->keylen); - if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, - state->keylen) != 0) { - printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n"); - } - } else { - memcpy(state->session_key, InterimKey, state->keylen); - } - if (state->keylen == 8) { - /* See RFC 3078 */ - state->session_key[0] = 0xd1; - state->session_key[1] = 0x26; - state->session_key[2] = 0x9e; - } - crypto_cipher_setkey(state->arc4, state->session_key, state->keylen); -} - -/* - * Allocate space for a (de)compressor. - */ -static void *mppe_alloc(unsigned char *options, int optlen) -{ - struct ppp_mppe_state *state; - unsigned int digestsize; - - if (optlen != CILEN_MPPE + sizeof(state->master_key) - || options[0] != CI_MPPE || options[1] != CILEN_MPPE) - goto out; - - state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL); - if (state == NULL) - goto out; - - memset(state, 0, sizeof(*state)); - - state->arc4 = crypto_alloc_tfm("arc4", 0); - if (!state->arc4) - goto out_free; - - state->sha1 = crypto_alloc_tfm("sha1", 0); - if (!state->sha1) - goto out_free; - - digestsize = crypto_tfm_alg_digestsize(state->sha1); - if (digestsize < MPPE_MAX_KEY_LEN) - goto out_free; - - state->sha1_digest = kmalloc(digestsize, GFP_KERNEL); - if (!state->sha1_digest) - goto out_free; - - /* Save keys. */ - memcpy(state->master_key, &options[CILEN_MPPE], - sizeof(state->master_key)); - memcpy(state->session_key, state->master_key, - sizeof(state->master_key)); - - /* - * We defer initial key generation until mppe_init(), as mppe_alloc() - * is called frequently during negotiation. - */ - - return (void *)state; - - out_free: - if (state->sha1_digest) - kfree(state->sha1_digest); - if (state->sha1) - crypto_free_tfm(state->sha1); - if (state->arc4) - crypto_free_tfm(state->arc4); - kfree(state); - out: - return NULL; -} - -/* - * Deallocate space for a (de)compressor. - */ -static void mppe_free(void *arg) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - if (state) { - if (state->sha1_digest) - kfree(state->sha1_digest); - if (state->sha1) - crypto_free_tfm(state->sha1); - if (state->arc4) - crypto_free_tfm(state->arc4); - kfree(state); - } -} - -/* - * Initialize (de)compressor state. - */ -static int -mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug, - const char *debugstr) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - unsigned char mppe_opts; - - if (optlen != CILEN_MPPE - || options[0] != CI_MPPE || options[1] != CILEN_MPPE) - return 0; - - MPPE_CI_TO_OPTS(&options[2], mppe_opts); - if (mppe_opts & MPPE_OPT_128) - state->keylen = 16; - else if (mppe_opts & MPPE_OPT_40) - state->keylen = 8; - else { - printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, - unit); - return 0; - } - if (mppe_opts & MPPE_OPT_STATEFUL) - state->stateful = 1; - - /* Generate the initial session key. */ - mppe_rekey(state, 1); - - if (debug) { - int i; - char mkey[sizeof(state->master_key) * 2 + 1]; - char skey[sizeof(state->session_key) * 2 + 1]; - - printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", - debugstr, unit, (state->keylen == 16) ? 128 : 40, - (state->stateful) ? "stateful" : "stateless"); - - for (i = 0; i < sizeof(state->master_key); i++) - sprintf(mkey + i * 2, "%02x", state->master_key[i]); - for (i = 0; i < sizeof(state->session_key); i++) - sprintf(skey + i * 2, "%02x", state->session_key[i]); - printk(KERN_DEBUG - "%s[%d]: keys: master: %s initial session: %s\n", - debugstr, unit, mkey, skey); - } - - /* - * Initialize the coherency count. The initial value is not specified - * in RFC 3078, but we can make a reasonable assumption that it will - * start at 0. Setting it to the max here makes the comp/decomp code - * do the right thing (determined through experiment). - */ - state->ccount = MPPE_CCOUNT_SPACE - 1; - - /* - * Note that even though we have initialized the key table, we don't - * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1. - */ - state->bits = MPPE_BIT_ENCRYPTED; - - state->unit = unit; - state->debug = debug; - - return 1; -} - -static int -mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit, - int hdrlen, int debug) -{ - /* ARGSUSED */ - return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init"); -} - -/* - * We received a CCP Reset-Request (actually, we are sending a Reset-Ack), - * tell the compressor to rekey. Note that we MUST NOT rekey for - * every CCP Reset-Request; we only rekey on the next xmit packet. - * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost. - * So, rekeying for every CCP Reset-Request is broken as the peer will not - * know how many times we've rekeyed. (If we rekey and THEN get another - * CCP Reset-Request, we must rekey again.) - */ -static void mppe_comp_reset(void *arg) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - - state->bits |= MPPE_BIT_FLUSHED; -} - -/* - * Compress (encrypt) a packet. - * It's strange to call this a compressor, since the output is always - * MPPE_OVHD + 2 bytes larger than the input. - */ -static int -mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf, - int isize, int osize) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - int proto; - struct scatterlist sg_in[1], sg_out[1]; - - /* - * Check that the protocol is in the range we handle. - */ - proto = PPP_PROTOCOL(ibuf); - if (proto < 0x0021 || proto > 0x00fa) - return 0; - - /* Make sure we have enough room to generate an encrypted packet. */ - if (osize < isize + MPPE_OVHD + 2) { - /* Drop the packet if we should encrypt it, but can't. */ - printk(KERN_DEBUG "mppe_compress[%d]: osize too small! " - "(have: %d need: %d)\n", state->unit, - osize, osize + MPPE_OVHD + 2); - return -1; - } - - osize = isize + MPPE_OVHD + 2; - - /* - * Copy over the PPP header and set control bits. - */ - obuf[0] = PPP_ADDRESS(ibuf); - obuf[1] = PPP_CONTROL(ibuf); - obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */ - obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */ - obuf += PPP_HDRLEN; - - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - if (state->debug >= 7) - printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit, - state->ccount); - obuf[0] = state->ccount >> 8; - obuf[1] = state->ccount & 0xff; - - if (!state->stateful || /* stateless mode */ - ((state->ccount & 0xff) == 0xff) || /* "flag" packet */ - (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */ - /* We must rekey */ - if (state->debug && state->stateful) - printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", - state->unit); - mppe_rekey(state, 0); - state->bits |= MPPE_BIT_FLUSHED; - } - obuf[0] |= state->bits; - state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */ - - obuf += MPPE_OVHD; - ibuf += 2; /* skip to proto field */ - isize -= 2; - - /* Encrypt packet */ - setup_sg(sg_in, ibuf, isize); - setup_sg(sg_out, obuf, osize); - if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) { - printk(KERN_DEBUG "crypto_cypher_encrypt failed\n"); - return -1; - } - - state->stats.unc_bytes += isize; - state->stats.unc_packets++; - state->stats.comp_bytes += osize; - state->stats.comp_packets++; - - return osize; -} - -/* - * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going - * to look bad ... and the longer the link is up the worse it will get. - */ -static void mppe_comp_stats(void *arg, struct compstat *stats) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - - *stats = state->stats; -} - -static int -mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit, - int hdrlen, int mru, int debug) -{ - /* ARGSUSED */ - return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init"); -} - -/* - * We received a CCP Reset-Ack. Just ignore it. - */ -static void mppe_decomp_reset(void *arg) -{ - /* ARGSUSED */ - return; -} - -/* - * Decompress (decrypt) an MPPE packet. - */ -static int -mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf, - int osize) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - unsigned ccount; - int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED; - int sanity = 0; - struct scatterlist sg_in[1], sg_out[1]; - - if (isize <= PPP_HDRLEN + MPPE_OVHD) { - if (state->debug) - printk(KERN_DEBUG - "mppe_decompress[%d]: short pkt (%d)\n", - state->unit, isize); - return DECOMP_ERROR; - } - - /* - * Make sure we have enough room to decrypt the packet. - * Note that for our test we only subtract 1 byte whereas in - * mppe_compress() we added 2 bytes (+MPPE_OVHD); - * this is to account for possible PFC. - */ - if (osize < isize - MPPE_OVHD - 1) { - printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! " - "(have: %d need: %d)\n", state->unit, - osize, isize - MPPE_OVHD - 1); - return DECOMP_ERROR; - } - osize = isize - MPPE_OVHD - 2; /* assume no PFC */ - - ccount = MPPE_CCOUNT(ibuf); - if (state->debug >= 7) - printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", - state->unit, ccount); - - /* sanity checks -- terminate with extreme prejudice */ - if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) { - printk(KERN_DEBUG - "mppe_decompress[%d]: ENCRYPTED bit not set!\n", - state->unit); - state->sanity_errors += 100; - sanity = 1; - } - if (!state->stateful && !flushed) { - printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in " - "stateless mode!\n", state->unit); - state->sanity_errors += 100; - sanity = 1; - } - if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) { - printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on " - "flag packet!\n", state->unit); - state->sanity_errors += 100; - sanity = 1; - } - - if (sanity) { - if (state->sanity_errors < SANITY_MAX) - return DECOMP_ERROR; - else - /* - * Take LCP down if the peer is sending too many bogons. - * We don't want to do this for a single or just a few - * instances since it could just be due to packet corruption. - */ - return DECOMP_FATALERROR; - } - - /* - * Check the coherency count. - */ - - if (!state->stateful) { - /* RFC 3078, sec 8.1. Rekey for every packet. */ - while (state->ccount != ccount) { - mppe_rekey(state, 0); - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - } - } else { - /* RFC 3078, sec 8.2. */ - if (!state->discard) { - /* normal state */ - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - if (ccount != state->ccount) { - /* - * (ccount > state->ccount) - * Packet loss detected, enter the discard state. - * Signal the peer to rekey (by sending a CCP Reset-Request). - */ - state->discard = 1; - return DECOMP_ERROR; - } - } else { - /* discard state */ - if (!flushed) { - /* ccp.c will be silent (no additional CCP Reset-Requests). */ - return DECOMP_ERROR; - } else { - /* Rekey for every missed "flag" packet. */ - while ((ccount & ~0xff) != - (state->ccount & ~0xff)) { - mppe_rekey(state, 0); - state->ccount = - (state->ccount + - 256) % MPPE_CCOUNT_SPACE; - } - - /* reset */ - state->discard = 0; - state->ccount = ccount; - /* - * Another problem with RFC 3078 here. It implies that the - * peer need not send a Reset-Ack packet. But RFC 1962 - * requires it. Hopefully, M$ does send a Reset-Ack; even - * though it isn't required for MPPE synchronization, it is - * required to reset CCP state. - */ - } - } - if (flushed) - mppe_rekey(state, 0); - } - - /* - * Fill in the first part of the PPP header. The protocol field - * comes from the decrypted data. - */ - obuf[0] = PPP_ADDRESS(ibuf); /* +1 */ - obuf[1] = PPP_CONTROL(ibuf); /* +1 */ - obuf += 2; - ibuf += PPP_HDRLEN + MPPE_OVHD; - isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */ - /* net osize: isize-4 */ - - /* - * Decrypt the first byte in order to check if it is - * a compressed or uncompressed protocol field. - */ - setup_sg(sg_in, ibuf, 1); - setup_sg(sg_out, obuf, 1); - if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) { - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); - return DECOMP_ERROR; - } - - /* - * Do PFC decompression. - * This would be nicer if we were given the actual sk_buff - * instead of a char *. - */ - if ((obuf[0] & 0x01) != 0) { - obuf[1] = obuf[0]; - obuf[0] = 0; - obuf++; - osize++; - } - - /* And finally, decrypt the rest of the packet. */ - setup_sg(sg_in, ibuf + 1, isize - 1); - setup_sg(sg_out, obuf + 1, osize - 1); - if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) { - printk(KERN_DEBUG "crypto_cypher_decrypt failed\n"); - return DECOMP_ERROR; - } - - state->stats.unc_bytes += osize; - state->stats.unc_packets++; - state->stats.comp_bytes += isize; - state->stats.comp_packets++; - - /* good packet credit */ - state->sanity_errors >>= 1; - - return osize; -} - -/* - * Incompressible data has arrived (this should never happen!). - * We should probably drop the link if the protocol is in the range - * of what should be encrypted. At the least, we should drop this - * packet. (How to do this?) - */ -static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt) -{ - struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg; - - if (state->debug && - (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa)) - printk(KERN_DEBUG - "mppe_incomp[%d]: incompressible (unencrypted) data! " - "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf)); - - state->stats.inc_bytes += icnt; - state->stats.inc_packets++; - state->stats.unc_bytes += icnt; - state->stats.unc_packets++; -} - -/************************************************************* - * Module interface table - *************************************************************/ - -/* - * Procedures exported to if_ppp.c. - */ -static struct compressor ppp_mppe = { - .compress_proto = CI_MPPE, - .comp_alloc = mppe_alloc, - .comp_free = mppe_free, - .comp_init = mppe_comp_init, - .comp_reset = mppe_comp_reset, - .compress = mppe_compress, - .comp_stat = mppe_comp_stats, - .decomp_alloc = mppe_alloc, - .decomp_free = mppe_free, - .decomp_init = mppe_decomp_init, - .decomp_reset = mppe_decomp_reset, - .decompress = mppe_decompress, - .incomp = mppe_incomp, - .decomp_stat = mppe_comp_stats, - .owner = THIS_MODULE, - .comp_extra = MPPE_PAD, -}; - -/* - * ppp_mppe_init() - * - * Prior to allowing load, try to load the arc4 and sha1 crypto - * libraries. The actual use will be allocated later, but - * this way the module will fail to insmod if they aren't available. - */ - -static int __init ppp_mppe_init(void) -{ - int answer; - if (!(crypto_alg_available("arc4", 0) && - crypto_alg_available("sha1", 0))) - return -ENODEV; - - sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL); - if (!sha_pad) - return -ENOMEM; - sha_pad_init(sha_pad); - - answer = ppp_register_compressor(&ppp_mppe); - - if (answer == 0) - printk(KERN_INFO "PPP MPPE Compression module registered\n"); - else - kfree(sha_pad); - - return answer; -} - -static void __exit ppp_mppe_cleanup(void) -{ - ppp_unregister_compressor(&ppp_mppe); - kfree(sha_pad); -} - -module_init(ppp_mppe_init); -module_exit(ppp_mppe_cleanup); diff --git a/trunk/drivers/net/ppp_mppe.h b/trunk/drivers/net/ppp_mppe.h deleted file mode 100644 index 7a14e058c668..000000000000 --- a/trunk/drivers/net/ppp_mppe.h +++ /dev/null @@ -1,86 +0,0 @@ -#define MPPE_PAD 4 /* MPPE growth per frame */ -#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ - -/* option bits for ccp_options.mppe */ -#define MPPE_OPT_40 0x01 /* 40 bit */ -#define MPPE_OPT_128 0x02 /* 128 bit */ -#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ -/* unsupported opts */ -#define MPPE_OPT_56 0x08 /* 56 bit */ -#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ -#define MPPE_OPT_D 0x20 /* Unknown */ -#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) -#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ - -/* - * This is not nice ... the alternative is a bitfield struct though. - * And unfortunately, we cannot share the same bits for the option - * names above since C and H are the same bit. We could do a u_int32 - * but then we have to do a htonl() all the time and/or we still need - * to know which octet is which. - */ -#define MPPE_C_BIT 0x01 /* MPPC */ -#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ -#define MPPE_L_BIT 0x20 /* 40-bit */ -#define MPPE_S_BIT 0x40 /* 128-bit */ -#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ -#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ - -/* Does not include H bit; used for least significant octet only. */ -#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) - -/* Build a CI from mppe opts (see RFC 3078) */ -#define MPPE_OPTS_TO_CI(opts, ci) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - /* H bit */ \ - if (opts & MPPE_OPT_STATEFUL) \ - *ptr++ = 0x0; \ - else \ - *ptr++ = MPPE_H_BIT; \ - *ptr++ = 0; \ - *ptr++ = 0; \ - \ - /* S,L bits */ \ - *ptr = 0; \ - if (opts & MPPE_OPT_128) \ - *ptr |= MPPE_S_BIT; \ - if (opts & MPPE_OPT_40) \ - *ptr |= MPPE_L_BIT; \ - /* M,D,C bits not supported */ \ - } while (/* CONSTCOND */ 0) - -/* The reverse of the above */ -#define MPPE_CI_TO_OPTS(ci, opts) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - opts = 0; \ - \ - /* H bit */ \ - if (!(ptr[0] & MPPE_H_BIT)) \ - opts |= MPPE_OPT_STATEFUL; \ - \ - /* S,L bits */ \ - if (ptr[3] & MPPE_S_BIT) \ - opts |= MPPE_OPT_128; \ - if (ptr[3] & MPPE_L_BIT) \ - opts |= MPPE_OPT_40; \ - \ - /* M,D,C bits */ \ - if (ptr[3] & MPPE_M_BIT) \ - opts |= MPPE_OPT_56; \ - if (ptr[3] & MPPE_D_BIT) \ - opts |= MPPE_OPT_D; \ - if (ptr[3] & MPPE_C_BIT) \ - opts |= MPPE_OPT_MPPC; \ - \ - /* Other bits */ \ - if (ptr[0] & ~MPPE_H_BIT) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[1] || ptr[2]) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[3] & ~MPPE_ALL_BITS) \ - opts |= MPPE_OPT_UNKNOWN; \ - } while (/* CONSTCOND */ 0) diff --git a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c index 56c58831e80e..fe5ea36e7de3 100644 --- a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c @@ -22,20 +22,16 @@ #include #include #include +#ifdef CONFIG_SA1100_COLLIE +#include +#else +#include +#endif #include "soc_common.h" #define NO_KEEP_VS 0x0001 -/* PCMCIA to Scoop linkage - - There is no easy way to link multiple scoop devices into one - single entity for the pxa2xx_pcmcia device so this structure - is used which is setup by the platform code -*/ -struct scoop_pcmcia_config *platform_scoop_config; -#define SCOOP_DEV platform_scoop_config->devs - static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) { reset_scoop(scoopdev->dev); @@ -47,16 +43,38 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - if (platform_scoop_config->pcmcia_init) - platform_scoop_config->pcmcia_init(); +#ifndef CONFIG_SA1100_COLLIE + /* + * Setup default state of GPIO outputs + * before we enable them as outputs. + */ + GPSR(GPIO48_nPOE) = + GPIO_bit(GPIO48_nPOE) | + GPIO_bit(GPIO49_nPWE) | + GPIO_bit(GPIO50_nPIOR) | + GPIO_bit(GPIO51_nPIOW) | + GPIO_bit(GPIO52_nPCE_1) | + GPIO_bit(GPIO53_nPCE_2); + + pxa_gpio_mode(GPIO48_nPOE_MD); + pxa_gpio_mode(GPIO49_nPWE_MD); + pxa_gpio_mode(GPIO50_nPIOR_MD); + pxa_gpio_mode(GPIO51_nPIOW_MD); + pxa_gpio_mode(GPIO52_nPCE_1_MD); + pxa_gpio_mode(GPIO53_nPCE_2_MD); + pxa_gpio_mode(GPIO54_pSKTSEL_MD); + pxa_gpio_mode(GPIO55_nPREG_MD); + pxa_gpio_mode(GPIO56_nPWAIT_MD); + pxa_gpio_mode(GPIO57_nIOIS16_MD); +#endif /* Register interrupts */ - if (SCOOP_DEV[skt->nr].cd_irq >= 0) { + if (scoop_devs[skt->nr].cd_irq >= 0) { struct pcmcia_irqs cd_irq; cd_irq.sock = skt->nr; - cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; - cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; + cd_irq.irq = scoop_devs[skt->nr].cd_irq; + cd_irq.str = scoop_devs[skt->nr].cd_irq_str; ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); if (ret) { @@ -65,19 +83,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) } } - skt->irq = SCOOP_DEV[skt->nr].irq; + skt->irq = scoop_devs[skt->nr].irq; return 0; } static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - if (SCOOP_DEV[skt->nr].cd_irq >= 0) { + if (scoop_devs[skt->nr].cd_irq >= 0) { struct pcmcia_irqs cd_irq; cd_irq.sock = skt->nr; - cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq; - cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str; + cd_irq.irq = scoop_devs[skt->nr].cd_irq; + cd_irq.str = scoop_devs[skt->nr].cd_irq_str; soc_pcmcia_free_irqs(skt, &cd_irq, 1); } } @@ -87,9 +105,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { unsigned short cpr, csr; - struct device *scoop = SCOOP_DEV[skt->nr].dev; + struct device *scoop = scoop_devs[skt->nr].dev; - cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR); + cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); write_scoop_reg(scoop, SCOOP_ISR, 0x0000); @@ -98,25 +116,21 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, if (csr & 0x0004) { /* card eject */ write_scoop_reg(scoop, SCOOP_CDR, 0x0000); - SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; + scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; } - else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) { + else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { /* keep vs1,vs2 */ write_scoop_reg(scoop, SCOOP_CDR, 0x0000); - csr |= SCOOP_DEV[skt->nr].keep_vs; + csr |= scoop_devs[skt->nr].keep_vs; } else if (cpr & 0x0003) { /* power on */ write_scoop_reg(scoop, SCOOP_CDR, 0x0000); - SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0); + scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); } else { /* card detect */ - if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) { - write_scoop_reg(scoop, SCOOP_CDR, 0x0000); - } else { - write_scoop_reg(scoop, SCOOP_CDR, 0x0002); - } + write_scoop_reg(scoop, SCOOP_CDR, 0x0002); } state->detect = (csr & 0x0004) ? 0 : 1; @@ -130,6 +144,7 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); } + } @@ -137,7 +152,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { unsigned long flags; - struct device *scoop = SCOOP_DEV[skt->nr].dev; + struct device *scoop = scoop_devs[skt->nr].dev; unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; @@ -162,13 +177,8 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; - if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) { - ncpr |= (state->Vcc == 33) ? 0x0002 : - (state->Vcc == 50) ? 0x0002 : 0; - } else { - ncpr |= (state->Vcc == 33) ? 0x0001 : - (state->Vcc == 50) ? 0x0002 : 0; - } + ncpr |= (state->Vcc == 33) ? 0x0001 : + (state->Vcc == 50) ? 0x0002 : 0; nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; nccr |= (state->flags&SS_RESET)? 0x0080: 0; @@ -180,22 +190,18 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ((skt->status&SS_WRPROT) ? 0x0008 : 0); if (!(ncpr & 0x0003)) { - SCOOP_DEV[skt->nr].keep_rd = 0; - } else if (!SCOOP_DEV[skt->nr].keep_rd) { + scoop_devs[skt->nr].keep_rd = 0; + } else if (!scoop_devs[skt->nr].keep_rd) { if (nccr & 0x0080) - SCOOP_DEV[skt->nr].keep_rd = 1; + scoop_devs[skt->nr].keep_rd = 1; else nccr |= 0x0080; } if (mcr != nmcr) write_scoop_reg(scoop, SCOOP_MCR, nmcr); - if (cpr != ncpr) { - if (platform_scoop_config->power_ctrl) - platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr); - else - write_scoop_reg(scoop, SCOOP_CPR, ncpr); - } + if (cpr != ncpr) + write_scoop_reg(scoop, SCOOP_CPR, ncpr); if (ccr != nccr) write_scoop_reg(scoop, SCOOP_CCR, nccr); if (imr != nimr) @@ -208,43 +214,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) { - sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]); + sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); /* Enable interrupt */ - write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0); - write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101); - SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS; + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); + scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; if (machine_is_collie()) /* We need to disable SS_OUTPUT_ENA here. */ - write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080); + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); } static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { /* CF_BUS_OFF */ - sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]); + sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); if (machine_is_collie()) /* We need to disable SS_OUTPUT_ENA here. */ - write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080); + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); } static struct pcmcia_low_level sharpsl_pcmcia_ops = { - .owner = THIS_MODULE, - .hw_init = sharpsl_pcmcia_hw_init, - .hw_shutdown = sharpsl_pcmcia_hw_shutdown, - .socket_state = sharpsl_pcmcia_socket_state, - .configure_socket = sharpsl_pcmcia_configure_socket, - .socket_init = sharpsl_pcmcia_socket_init, - .socket_suspend = sharpsl_pcmcia_socket_suspend, - .first = 0, - .nr = 0, + .owner = THIS_MODULE, + .hw_init = sharpsl_pcmcia_hw_init, + .hw_shutdown = sharpsl_pcmcia_hw_shutdown, + .socket_state = sharpsl_pcmcia_socket_state, + .configure_socket = sharpsl_pcmcia_configure_socket, + .socket_init = sharpsl_pcmcia_socket_init, + .socket_suspend = sharpsl_pcmcia_socket_suspend, + .first = 0, + .nr = 0, }; -#ifdef CONFIG_SA1100_COLLIE -#include "sa11xx_base.h" +static struct platform_device *sharpsl_pcmcia_device; +#ifdef CONFIG_SA1100_COLLIE int __init pcmcia_collie_init(struct device *dev) { int ret = -ENODEV; @@ -257,13 +263,11 @@ int __init pcmcia_collie_init(struct device *dev) #else -static struct platform_device *sharpsl_pcmcia_device; - static int __init sharpsl_pcmcia_init(void) { int ret; - sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; + sharpsl_pcmcia_ops.nr=scoop_num; sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); if (!sharpsl_pcmcia_device) return -ENOMEM; @@ -271,7 +275,7 @@ static int __init sharpsl_pcmcia_init(void) memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; - sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; + sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; ret = platform_device_register(sharpsl_pcmcia_device); if (ret) diff --git a/trunk/drivers/sbus/char/openprom.c b/trunk/drivers/sbus/char/openprom.c index 383a95f34a0d..5028ac214326 100644 --- a/trunk/drivers/sbus/char/openprom.c +++ b/trunk/drivers/sbus/char/openprom.c @@ -596,8 +596,6 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd, lock_kernel(); break; } - - return rval; } static int openprom_open(struct inode * inode, struct file * file) @@ -625,7 +623,6 @@ static struct file_operations openprom_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = openprom_ioctl, - .compat_ioctl = openprom_compat_ioctl, .open = openprom_open, .release = openprom_release, }; diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 5a4e3acc2e9f..cd6c574557dc 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -590,7 +590,6 @@ static inline int de_thread(struct task_struct *tsk) struct signal_struct *sig = tsk->signal; struct sighand_struct *newsighand, *oldsighand = tsk->sighand; spinlock_t *lock = &oldsighand->siglock; - struct task_struct *leader = NULL; int count; /* @@ -666,7 +665,7 @@ static inline int de_thread(struct task_struct *tsk) * and to assume its PID: */ if (!thread_group_leader(current)) { - struct task_struct *parent; + struct task_struct *leader = current->group_leader, *parent; struct dentry *proc_dentry1, *proc_dentry2; unsigned long exit_state, ptrace; @@ -675,7 +674,6 @@ static inline int de_thread(struct task_struct *tsk) * It should already be zombie at this point, most * of the time. */ - leader = current->group_leader; while (leader->exit_state != EXIT_ZOMBIE) yield(); @@ -735,6 +733,7 @@ static inline int de_thread(struct task_struct *tsk) proc_pid_flush(proc_dentry2); BUG_ON(exit_state != EXIT_ZOMBIE); + release_task(leader); } /* @@ -744,11 +743,8 @@ static inline int de_thread(struct task_struct *tsk) sig->flags = 0; no_thread_group: - exit_itimers(sig); - if (leader) - release_task(leader); - BUG_ON(atomic_read(&sig->count) != 1); + exit_itimers(sig); if (atomic_read(&oldsighand->count) == 1) { /* diff --git a/trunk/include/asm-arm/arch-realview/entry-macro.S b/trunk/include/asm-arm/arch-realview/entry-macro.S index 4df469bf42e2..6288fad0dc41 100644 --- a/trunk/include/asm-arm/arch-realview/entry-macro.S +++ b/trunk/include/asm-arm/arch-realview/entry-macro.S @@ -61,3 +61,14 @@ strcc \irqstat, [\base, #GIC_CPU_EOI] cmpcs \irqnr, \irqnr .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm diff --git a/trunk/include/asm-arm/arch-realview/irqs.h b/trunk/include/asm-arm/arch-realview/irqs.h index ff376494e5b1..c16223c9588d 100644 --- a/trunk/include/asm-arm/arch-realview/irqs.h +++ b/trunk/include/asm-arm/arch-realview/irqs.h @@ -21,6 +21,9 @@ #include +#define IRQ_LOCALTIMER 29 +#define IRQ_LOCALWDOG 30 + /* * IRQ interrupts definitions are the same the INT definitions * held within platform.h diff --git a/trunk/include/asm-arm/arch-realview/platform.h b/trunk/include/asm-arm/arch-realview/platform.h index aef9b36b3c37..18d7c18b738c 100644 --- a/trunk/include/asm-arm/arch-realview/platform.h +++ b/trunk/include/asm-arm/arch-realview/platform.h @@ -209,6 +209,8 @@ #else #define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */ #define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_TWD_BASE 0x10100700 +#define REALVIEW_TWD_SIZE 0x00000100 #define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ #endif #define REALVIEW_SMC_BASE 0x10080000 /* SMC */ @@ -305,9 +307,6 @@ #define INT_TSPENINT 30 /* Touchscreen pen */ #define INT_TSKPADINT 31 /* Touchscreen keypad */ #else -#define INT_LOCALTIMER 29 -#define INT_LOCALWDOG 30 - #define INT_AACI 0 #define INT_TIMERINT0_1 1 #define INT_TIMERINT2_3 2 diff --git a/trunk/include/asm-arm/arch-s3c2410/uncompress.h b/trunk/include/asm-arm/arch-s3c2410/uncompress.h index ddd1578a7ee0..d7a4a8354fa9 100644 --- a/trunk/include/asm-arm/arch-s3c2410/uncompress.h +++ b/trunk/include/asm-arm/arch-s3c2410/uncompress.h @@ -116,8 +116,6 @@ putstr(const char *ptr) } } -#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0) - /* CONFIG_S3C2410_BOOT_WATCHDOG * * Simple boot-time watchdog setup, to reboot the system if there is @@ -128,6 +126,8 @@ putstr(const char *ptr) #define WDOG_COUNT (0xff00) +#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0) + static inline void arch_decomp_wdog(void) { __raw_writel(WDOG_COUNT, S3C2410_WTCNT); @@ -145,24 +145,6 @@ static void arch_decomp_wdog_start(void) #define arch_decomp_wdog() #endif -#ifdef CONFIG_S3C2410_BOOT_ERROR_RESET - -static void arch_decomp_error(const char *x) -{ - putstr("\n\n"); - putstr(x); - putstr("\n\n -- System resetting\n"); - - __raw_writel(0x4000, S3C2410_WTDAT); - __raw_writel(0x4000, S3C2410_WTCNT); - __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); - - while(1); -} - -#define arch_error arch_decomp_error -#endif - static void error(char *err); static void diff --git a/trunk/include/asm-arm/hardware/scoop.h b/trunk/include/asm-arm/hardware/scoop.h index d37bf7443264..a8f1013930e3 100644 --- a/trunk/include/asm-arm/hardware/scoop.h +++ b/trunk/include/asm-arm/hardware/scoop.h @@ -52,14 +52,8 @@ struct scoop_pcmcia_dev { unsigned char keep_rd; }; -struct scoop_pcmcia_config { - struct scoop_pcmcia_dev *devs; - int num_devs; - void (*pcmcia_init)(void); - void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr); -}; - -extern struct scoop_pcmcia_config *platform_scoop_config; +extern int scoop_num; +extern struct scoop_pcmcia_dev *scoop_devs; void reset_scoop(struct device *dev); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); diff --git a/trunk/include/linux/if_ppp.h b/trunk/include/linux/if_ppp.h index 768372f07caa..572aff7daa21 100644 --- a/trunk/include/linux/if_ppp.h +++ b/trunk/include/linux/if_ppp.h @@ -21,7 +21,7 @@ */ /* - * ==FILEVERSION 20050812== + * ==FILEVERSION 20000724== * * NOTE TO MAINTAINERS: * If you modify this file at all, please set the above date. @@ -35,8 +35,6 @@ #ifndef _IF_PPP_H_ #define _IF_PPP_H_ -#include - /* * Packet sizes */ @@ -72,8 +70,7 @@ #define SC_LOG_RAWIN 0x00080000 /* log all chars received */ #define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ #define SC_SYNC 0x00200000 /* synchronous serial mode */ -#define SC_MUST_COMP 0x00400000 /* no uncompressed packets may be sent or received */ -#define SC_MASK 0x0f600fff /* bits that user can change */ +#define SC_MASK 0x0f200fff /* bits that user can change */ /* state bits */ #define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ diff --git a/trunk/include/linux/ppp-comp.h b/trunk/include/linux/ppp-comp.h index e86a7a5cf355..7227e653b3be 100644 --- a/trunk/include/linux/ppp-comp.h +++ b/trunk/include/linux/ppp-comp.h @@ -111,8 +111,6 @@ struct compressor { /* Used in locking compressor modules */ struct module *owner; - /* Extra skb space needed by the compressor algorithm */ - unsigned int comp_extra; }; /* @@ -192,13 +190,6 @@ struct compressor { #define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL) #define DEFLATE_CHK_SEQUENCE 0 -/* - * Definitions for MPPE. - */ - -#define CI_MPPE 18 /* config option for MPPE */ -#define CILEN_MPPE 6 /* length of config option */ - /* * Definitions for other, as yet unsupported, compression methods. */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index 74488e49166d..65ceeaa30652 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -66,7 +66,6 @@ struct proc_dir_entry { write_proc_t *write_proc; atomic_t count; /* use count */ int deleted; /* delete flag */ - void *set; }; struct kcore_list { diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index fc131d6602b9..fc8e367f671e 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -24,7 +24,6 @@ #include struct file; -struct completion; #define CTL_MAXNAME 10 /* how many path components do we allow in a call to sysctl? In other words, what is @@ -926,8 +925,6 @@ struct ctl_table_header { ctl_table *ctl_table; struct list_head ctl_entry; - int used; - struct completion *unregistering; }; struct ctl_table_header * register_sysctl_table(ctl_table * table, diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 911ceb5cd263..e42d728b1620 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -57,6 +57,8 @@ #define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg) +extern struct proc_dir_entry *proc_bt; + /* Connection and socket states */ enum { BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ @@ -175,6 +177,4 @@ extern int hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); -extern struct class bt_class; - #endif /* __BLUETOOTH_H */ diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index b06a2d2f63d2..fa2d12b0579b 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -184,10 +184,10 @@ enum { struct hci_rp_read_loc_version { __u8 status; __u8 hci_ver; - __le16 hci_rev; + __u16 hci_rev; __u8 lmp_ver; - __le16 manufacturer; - __le16 lmp_subver; + __u16 manufacturer; + __u16 lmp_subver; } __attribute__ ((packed)); #define OCF_READ_LOCAL_FEATURES 0x0003 @@ -199,10 +199,10 @@ struct hci_rp_read_loc_features { #define OCF_READ_BUFFER_SIZE 0x0005 struct hci_rp_read_buffer_size { __u8 status; - __le16 acl_mtu; + __u16 acl_mtu; __u8 sco_mtu; - __le16 acl_max_pkt; - __le16 sco_max_pkt; + __u16 acl_max_pkt; + __u16 sco_max_pkt; } __attribute__ ((packed)); #define OCF_READ_BD_ADDR 0x0009 @@ -267,21 +267,21 @@ struct hci_cp_write_dev_class { #define OCF_READ_VOICE_SETTING 0x0025 struct hci_rp_read_voice_setting { - __u8 status; - __le16 voice_setting; + __u8 status; + __u16 voice_setting; } __attribute__ ((packed)); #define OCF_WRITE_VOICE_SETTING 0x0026 struct hci_cp_write_voice_setting { - __le16 voice_setting; + __u16 voice_setting; } __attribute__ ((packed)); #define OCF_HOST_BUFFER_SIZE 0x0033 struct hci_cp_host_buffer_size { - __le16 acl_mtu; + __u16 acl_mtu; __u8 sco_mtu; - __le16 acl_max_pkt; - __le16 sco_max_pkt; + __u16 acl_max_pkt; + __u16 sco_max_pkt; } __attribute__ ((packed)); /* Link Control */ @@ -289,10 +289,10 @@ struct hci_cp_host_buffer_size { #define OCF_CREATE_CONN 0x0005 struct hci_cp_create_conn { bdaddr_t bdaddr; - __le16 pkt_type; + __u16 pkt_type; __u8 pscan_rep_mode; __u8 pscan_mode; - __le16 clock_offset; + __u16 clock_offset; __u8 role_switch; } __attribute__ ((packed)); @@ -310,14 +310,14 @@ struct hci_cp_reject_conn_req { #define OCF_DISCONNECT 0x0006 struct hci_cp_disconnect { - __le16 handle; + __u16 handle; __u8 reason; } __attribute__ ((packed)); #define OCF_ADD_SCO 0x0007 struct hci_cp_add_sco { - __le16 handle; - __le16 pkt_type; + __u16 handle; + __u16 pkt_type; } __attribute__ ((packed)); #define OCF_INQUIRY 0x0001 @@ -354,56 +354,56 @@ struct hci_cp_pin_code_neg_reply { #define OCF_CHANGE_CONN_PTYPE 0x000F struct hci_cp_change_conn_ptype { - __le16 handle; - __le16 pkt_type; + __u16 handle; + __u16 pkt_type; } __attribute__ ((packed)); #define OCF_AUTH_REQUESTED 0x0011 struct hci_cp_auth_requested { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); #define OCF_SET_CONN_ENCRYPT 0x0013 struct hci_cp_set_conn_encrypt { - __le16 handle; + __u16 handle; __u8 encrypt; } __attribute__ ((packed)); #define OCF_CHANGE_CONN_LINK_KEY 0x0015 struct hci_cp_change_conn_link_key { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); #define OCF_READ_REMOTE_FEATURES 0x001B struct hci_cp_read_rmt_features { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); #define OCF_READ_REMOTE_VERSION 0x001D struct hci_cp_read_rmt_version { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); /* Link Policy */ #define OGF_LINK_POLICY 0x02 #define OCF_ROLE_DISCOVERY 0x0009 struct hci_cp_role_discovery { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); struct hci_rp_role_discovery { __u8 status; - __le16 handle; + __u16 handle; __u8 role; } __attribute__ ((packed)); #define OCF_READ_LINK_POLICY 0x000C struct hci_cp_read_link_policy { - __le16 handle; + __u16 handle; } __attribute__ ((packed)); struct hci_rp_read_link_policy { __u8 status; - __le16 handle; - __le16 policy; + __u16 handle; + __u16 policy; } __attribute__ ((packed)); #define OCF_SWITCH_ROLE 0x000B @@ -414,12 +414,12 @@ struct hci_cp_switch_role { #define OCF_WRITE_LINK_POLICY 0x000D struct hci_cp_write_link_policy { - __le16 handle; - __le16 policy; + __u16 handle; + __u16 policy; } __attribute__ ((packed)); struct hci_rp_write_link_policy { __u8 status; - __le16 handle; + __u16 handle; } __attribute__ ((packed)); /* Status params */ @@ -441,7 +441,7 @@ struct inquiry_info { __u8 pscan_period_mode; __u8 pscan_mode; __u8 dev_class[3]; - __le16 clock_offset; + __u16 clock_offset; } __attribute__ ((packed)); #define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 @@ -450,7 +450,7 @@ struct inquiry_info_with_rssi { __u8 pscan_rep_mode; __u8 pscan_period_mode; __u8 dev_class[3]; - __le16 clock_offset; + __u16 clock_offset; __s8 rssi; } __attribute__ ((packed)); struct inquiry_info_with_rssi_and_pscan_mode { @@ -459,7 +459,7 @@ struct inquiry_info_with_rssi_and_pscan_mode { __u8 pscan_period_mode; __u8 pscan_mode; __u8 dev_class[3]; - __le16 clock_offset; + __u16 clock_offset; __s8 rssi; } __attribute__ ((packed)); @@ -469,7 +469,7 @@ struct extended_inquiry_info { __u8 pscan_rep_mode; __u8 pscan_period_mode; __u8 dev_class[3]; - __le16 clock_offset; + __u16 clock_offset; __s8 rssi; __u8 data[240]; } __attribute__ ((packed)); @@ -477,7 +477,7 @@ struct extended_inquiry_info { #define HCI_EV_CONN_COMPLETE 0x03 struct hci_ev_conn_complete { __u8 status; - __le16 handle; + __u16 handle; bdaddr_t bdaddr; __u8 link_type; __u8 encr_mode; @@ -493,27 +493,27 @@ struct hci_ev_conn_request { #define HCI_EV_DISCONN_COMPLETE 0x05 struct hci_ev_disconn_complete { __u8 status; - __le16 handle; + __u16 handle; __u8 reason; } __attribute__ ((packed)); #define HCI_EV_AUTH_COMPLETE 0x06 struct hci_ev_auth_complete { __u8 status; - __le16 handle; + __u16 handle; } __attribute__ ((packed)); #define HCI_EV_ENCRYPT_CHANGE 0x08 struct hci_ev_encrypt_change { __u8 status; - __le16 handle; + __u16 handle; __u8 encrypt; } __attribute__ ((packed)); #define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09 struct hci_ev_change_conn_link_key_complete { __u8 status; - __le16 handle; + __u16 handle; } __attribute__ ((packed)); #define HCI_EV_QOS_SETUP_COMPLETE 0x0D @@ -526,21 +526,21 @@ struct hci_qos { } __attribute__ ((packed)); struct hci_ev_qos_setup_complete { __u8 status; - __le16 handle; + __u16 handle; struct hci_qos qos; } __attribute__ ((packed)); #define HCI_EV_CMD_COMPLETE 0x0E struct hci_ev_cmd_complete { __u8 ncmd; - __le16 opcode; + __u16 opcode; } __attribute__ ((packed)); #define HCI_EV_CMD_STATUS 0x0F struct hci_ev_cmd_status { __u8 status; __u8 ncmd; - __le16 opcode; + __u16 opcode; } __attribute__ ((packed)); #define HCI_EV_NUM_COMP_PKTS 0x13 @@ -559,9 +559,9 @@ struct hci_ev_role_change { #define HCI_EV_MODE_CHANGE 0x14 struct hci_ev_mode_change { __u8 status; - __le16 handle; + __u16 handle; __u8 mode; - __le16 interval; + __u16 interval; } __attribute__ ((packed)); #define HCI_EV_PIN_CODE_REQ 0x16 @@ -584,24 +584,24 @@ struct hci_ev_link_key_notify { #define HCI_EV_RMT_FEATURES 0x0B struct hci_ev_rmt_features { __u8 status; - __le16 handle; + __u16 handle; __u8 features[8]; } __attribute__ ((packed)); #define HCI_EV_RMT_VERSION 0x0C struct hci_ev_rmt_version { __u8 status; - __le16 handle; + __u16 handle; __u8 lmp_ver; - __le16 manufacturer; - __le16 lmp_subver; + __u16 manufacturer; + __u16 lmp_subver; } __attribute__ ((packed)); #define HCI_EV_CLOCK_OFFSET 0x01C struct hci_ev_clock_offset { __u8 status; - __le16 handle; - __le16 clock_offset; + __u16 handle; + __u16 clock_offset; } __attribute__ ((packed)); #define HCI_EV_PSCAN_REP_MODE 0x20 @@ -638,7 +638,7 @@ struct hci_ev_si_security { #define HCI_SCO_HDR_SIZE 3 struct hci_command_hdr { - __le16 opcode; /* OCF & OGF */ + __u16 opcode; /* OCF & OGF */ __u8 plen; } __attribute__ ((packed)); @@ -648,22 +648,22 @@ struct hci_event_hdr { } __attribute__ ((packed)); struct hci_acl_hdr { - __le16 handle; /* Handle & Flags(PB, BC) */ - __le16 dlen; + __u16 handle; /* Handle & Flags(PB, BC) */ + __u16 dlen; } __attribute__ ((packed)); struct hci_sco_hdr { - __le16 handle; + __u16 handle; __u8 dlen; } __attribute__ ((packed)); /* Command opcode pack/unpack */ -#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10)) +#define hci_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10)) #define hci_opcode_ogf(op) (op >> 10) #define hci_opcode_ocf(op) (op & 0x03ff) /* ACL handle and flags pack/unpack */ -#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12)) +#define hci_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12)) #define hci_handle(h) (h & 0x0fff) #define hci_flags(h) (h >> 12) diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index bb9f81dc8723..7f933f302078 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -25,6 +25,7 @@ #ifndef __HCI_CORE_H #define __HCI_CORE_H +#include #include /* HCI upper protocols */ @@ -33,6 +34,8 @@ #define HCI_INIT_TIMEOUT (HZ * 10) +extern struct proc_dir_entry *proc_bt_hci; + /* HCI Core structures */ struct inquiry_data { @@ -41,7 +44,7 @@ struct inquiry_data { __u8 pscan_period_mode; __u8 pscan_mode; __u8 dev_class[3]; - __le16 clock_offset; + __u16 clock_offset; __s8 rssi; }; @@ -123,6 +126,10 @@ struct hci_dev { atomic_t promisc; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc; +#endif + struct class_device class_dev; struct module *owner; diff --git a/trunk/include/net/bluetooth/rfcomm.h b/trunk/include/net/bluetooth/rfcomm.h index bbfac86734ec..e656be7c001a 100644 --- a/trunk/include/net/bluetooth/rfcomm.h +++ b/trunk/include/net/bluetooth/rfcomm.h @@ -351,4 +351,6 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); int rfcomm_init_ttys(void); void rfcomm_cleanup_ttys(void); +extern struct proc_dir_entry *proc_bt_rfcomm; + #endif /* __RFCOMM_H */ diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index 6addb4d464d6..65ec86678a08 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -252,25 +252,12 @@ typedef int (*inet_getfrag_t) (const void *data, char *, unsigned int, unsigned int); -extern int __ipv6_addr_type(const struct in6_addr *addr); -static inline int ipv6_addr_type(const struct in6_addr *addr) -{ - return __ipv6_addr_type(addr) & 0xffff; -} - -static inline int ipv6_addr_scope(const struct in6_addr *addr) -{ - return __ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; -} -static inline int __ipv6_addr_src_scope(int type) -{ - return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16)); -} +extern int ipv6_addr_type(const struct in6_addr *addr); -static inline int ipv6_addr_src_scope(const struct in6_addr *addr) +static inline int ipv6_addr_scope(const struct in6_addr *addr) { - return __ipv6_addr_src_scope(__ipv6_addr_type(addr)); + return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK; } static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2) @@ -353,54 +340,6 @@ static inline int ipv6_addr_any(const struct in6_addr *a) a->s6_addr32[2] | a->s6_addr32[3] ) == 0); } -/* - * find the first different bit between two addresses - * length of address must be a multiple of 32bits - */ -static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen) -{ - const __u32 *a1 = token1, *a2 = token2; - int i; - - addrlen >>= 2; - - for (i = 0; i < addrlen; i++) { - __u32 xb = a1[i] ^ a2[i]; - if (xb) { - int j = 31; - - xb = ntohl(xb); - while ((xb & (1 << j)) == 0) - j--; - - return (i * 32 + 31 - j); - } - } - - /* - * we should *never* get to this point since that - * would mean the addrs are equal - * - * However, we do get to it 8) And exacly, when - * addresses are equal 8) - * - * ip route add 1111::/128 via ... - * ip route add 1111::/64 via ... - * and we are here. - * - * Ideally, this function should stop comparison - * at prefix length. It does not, but it is still OK, - * if returned value is greater than prefix length. - * --ANK (980803) - */ - return (addrlen << 5); -} - -static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2) -{ - return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); -} - /* * Prototypes exported by ipv6 */ diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index ff13c4cc287a..e0498bd36004 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -461,16 +461,16 @@ static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) } /* The per-socket spinlock must be held here. */ -static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) -{ - if (!sk->sk_backlog.tail) { - sk->sk_backlog.head = sk->sk_backlog.tail = skb; - } else { - sk->sk_backlog.tail->next = skb; - sk->sk_backlog.tail = skb; - } - skb->next = NULL; -} +#define sk_add_backlog(__sk, __skb) \ +do { if (!(__sk)->sk_backlog.tail) { \ + (__sk)->sk_backlog.head = \ + (__sk)->sk_backlog.tail = (__skb); \ + } else { \ + ((__sk)->sk_backlog.tail)->next = (__skb); \ + (__sk)->sk_backlog.tail = (__skb); \ + } \ + (__skb)->next = NULL; \ +} while(0) #define sk_wait_event(__sk, __timeo, __condition) \ ({ int rc; \ diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 9990e10192e8..c4f35f96884d 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -169,7 +169,7 @@ struct file_operations proc_sys_file_operations = { extern struct proc_dir_entry *proc_sys_root; -static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *); +static void register_proc_table(ctl_table *, struct proc_dir_entry *); static void unregister_proc_table(ctl_table *, struct proc_dir_entry *); #endif @@ -992,51 +992,10 @@ static ctl_table dev_table[] = { extern void init_irq_proc (void); -static DEFINE_SPINLOCK(sysctl_lock); - -/* called under sysctl_lock */ -static int use_table(struct ctl_table_header *p) -{ - if (unlikely(p->unregistering)) - return 0; - p->used++; - return 1; -} - -/* called under sysctl_lock */ -static void unuse_table(struct ctl_table_header *p) -{ - if (!--p->used) - if (unlikely(p->unregistering)) - complete(p->unregistering); -} - -/* called under sysctl_lock, will reacquire if has to wait */ -static void start_unregistering(struct ctl_table_header *p) -{ - /* - * if p->used is 0, nobody will ever touch that entry again; - * we'll eliminate all paths to it before dropping sysctl_lock - */ - if (unlikely(p->used)) { - struct completion wait; - init_completion(&wait); - p->unregistering = &wait; - spin_unlock(&sysctl_lock); - wait_for_completion(&wait); - spin_lock(&sysctl_lock); - } - /* - * do not remove from the list until nobody holds it; walking the - * list in do_sysctl() relies on that. - */ - list_del_init(&p->ctl_entry); -} - void __init sysctl_init(void) { #ifdef CONFIG_PROC_FS - register_proc_table(root_table, proc_sys_root, &root_table_header); + register_proc_table(root_table, proc_sys_root); init_irq_proc(); #endif } @@ -1045,7 +1004,6 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol void __user *newval, size_t newlen) { struct list_head *tmp; - int error = -ENOTDIR; if (nlen <= 0 || nlen >= CTL_MAXNAME) return -ENOTDIR; @@ -1054,30 +1012,20 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol if (!oldlenp || get_user(old_len, oldlenp)) return -EFAULT; } - spin_lock(&sysctl_lock); tmp = &root_table_header.ctl_entry; do { struct ctl_table_header *head = list_entry(tmp, struct ctl_table_header, ctl_entry); void *context = NULL; - - if (!use_table(head)) - continue; - - spin_unlock(&sysctl_lock); - - error = parse_table(name, nlen, oldval, oldlenp, + int error = parse_table(name, nlen, oldval, oldlenp, newval, newlen, head->ctl_table, &context); kfree(context); - - spin_lock(&sysctl_lock); - unuse_table(head); if (error != -ENOTDIR) - break; - } while ((tmp = tmp->next) != &root_table_header.ctl_entry); - spin_unlock(&sysctl_lock); - return error; + return error; + tmp = tmp->next; + } while (tmp != &root_table_header.ctl_entry); + return -ENOTDIR; } asmlinkage long sys_sysctl(struct __sysctl_args __user *args) @@ -1288,16 +1236,12 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table, return NULL; tmp->ctl_table = table; INIT_LIST_HEAD(&tmp->ctl_entry); - tmp->used = 0; - tmp->unregistering = NULL; - spin_lock(&sysctl_lock); if (insert_at_head) list_add(&tmp->ctl_entry, &root_table_header.ctl_entry); else list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); - spin_unlock(&sysctl_lock); #ifdef CONFIG_PROC_FS - register_proc_table(table, proc_sys_root, tmp); + register_proc_table(table, proc_sys_root); #endif return tmp; } @@ -1311,13 +1255,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table, */ void unregister_sysctl_table(struct ctl_table_header * header) { - might_sleep(); - spin_lock(&sysctl_lock); - start_unregistering(header); + list_del(&header->ctl_entry); #ifdef CONFIG_PROC_FS unregister_proc_table(header->ctl_table, proc_sys_root); #endif - spin_unlock(&sysctl_lock); kfree(header); } @@ -1328,7 +1269,7 @@ void unregister_sysctl_table(struct ctl_table_header * header) #ifdef CONFIG_PROC_FS /* Scan the sysctl entries in table and add them all into /proc */ -static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set) +static void register_proc_table(ctl_table * table, struct proc_dir_entry *root) { struct proc_dir_entry *de; int len; @@ -1364,14 +1305,13 @@ static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, de = create_proc_entry(table->procname, mode, root); if (!de) continue; - de->set = set; de->data = (void *) table; if (table->proc_handler) de->proc_fops = &proc_sys_file_operations; } table->de = de; if (de->mode & S_IFDIR) - register_proc_table(table->child, de, set); + register_proc_table(table->child, de); } } @@ -1396,13 +1336,6 @@ static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root continue; } - /* - * In any case, mark the entry as goner; we'll keep it - * around if it's busy, but we'll know to do nothing with - * its fields. We are under sysctl_lock here. - */ - de->data = NULL; - /* Don't unregister proc entries that are still being used.. */ if (atomic_read(&de->count)) continue; @@ -1416,38 +1349,27 @@ static ssize_t do_rw_proc(int write, struct file * file, char __user * buf, size_t count, loff_t *ppos) { int op; - struct proc_dir_entry *de = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *de; struct ctl_table *table; size_t res; - ssize_t error = -ENOTDIR; + ssize_t error; - spin_lock(&sysctl_lock); - if (de && de->data && use_table(de->set)) { - /* - * at that point we know that sysctl was not unregistered - * and won't be until we finish - */ - spin_unlock(&sysctl_lock); - table = (struct ctl_table *) de->data; - if (!table || !table->proc_handler) - goto out; - error = -EPERM; - op = (write ? 002 : 004); - if (ctl_perm(table, op)) - goto out; - - /* careful: calling conventions are nasty here */ - res = count; - error = (*table->proc_handler)(table, write, file, - buf, &res, ppos); - if (!error) - error = res; - out: - spin_lock(&sysctl_lock); - unuse_table(de->set); - } - spin_unlock(&sysctl_lock); - return error; + de = PDE(file->f_dentry->d_inode); + if (!de || !de->data) + return -ENOTDIR; + table = (struct ctl_table *) de->data; + if (!table || !table->proc_handler) + return -ENOTDIR; + op = (write ? 002 : 004); + if (ctl_perm(table, op)) + return -EPERM; + + res = count; + + error = (*table->proc_handler) (table, write, file, buf, &res, ppos); + if (error) + return error; + return res; } static int proc_opensys(struct inode *inode, struct file *file) diff --git a/trunk/net/802/p8023.c b/trunk/net/802/p8023.c index d23e906456eb..6368d3dce444 100644 --- a/trunk/net/802/p8023.c +++ b/trunk/net/802/p8023.c @@ -54,7 +54,8 @@ struct datalink_proto *make_8023_client(void) */ void destroy_8023_client(struct datalink_proto *dl) { - kfree(dl); + if (dl) + kfree(dl); } EXPORT_SYMBOL(destroy_8023_client); diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index 1b683f302657..8e37e71e34ff 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -1138,8 +1138,10 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - kfree(ax25->digipeat); - ax25->digipeat = NULL; + if (ax25->digipeat != NULL) { + kfree(ax25->digipeat); + ax25->digipeat = NULL; + } /* * Handle digi-peaters to be used. diff --git a/trunk/net/ax25/ax25_in.c b/trunk/net/ax25/ax25_in.c index 4cf87540fb3a..73cfc3411c46 100644 --- a/trunk/net/ax25/ax25_in.c +++ b/trunk/net/ax25/ax25_in.c @@ -401,8 +401,10 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, } if (dp.ndigi == 0) { - kfree(ax25->digipeat); - ax25->digipeat = NULL; + if (ax25->digipeat != NULL) { + kfree(ax25->digipeat); + ax25->digipeat = NULL; + } } else { /* Reverse the source SABM's path */ memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi)); diff --git a/trunk/net/ax25/ax25_route.c b/trunk/net/ax25/ax25_route.c index b1e945bd6ed3..26b77d972220 100644 --- a/trunk/net/ax25/ax25_route.c +++ b/trunk/net/ax25/ax25_route.c @@ -54,13 +54,15 @@ void ax25_rt_device_down(struct net_device *dev) if (s->dev == dev) { if (ax25_route_list == s) { ax25_route_list = s->next; - kfree(s->digipeat); + if (s->digipeat != NULL) + kfree(s->digipeat); kfree(s); } else { for (t = ax25_route_list; t != NULL; t = t->next) { if (t->next == s) { t->next = s->next; - kfree(s->digipeat); + if (s->digipeat != NULL) + kfree(s->digipeat); kfree(s); break; } @@ -88,8 +90,10 @@ static int ax25_rt_add(struct ax25_routes_struct *route) while (ax25_rt != NULL) { if (ax25cmp(&ax25_rt->callsign, &route->dest_addr) == 0 && ax25_rt->dev == ax25_dev->dev) { - kfree(ax25_rt->digipeat); - ax25_rt->digipeat = NULL; + if (ax25_rt->digipeat != NULL) { + kfree(ax25_rt->digipeat); + ax25_rt->digipeat = NULL; + } if (route->digi_count != 0) { if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { write_unlock(&ax25_route_lock); @@ -141,7 +145,8 @@ static int ax25_rt_add(struct ax25_routes_struct *route) static void ax25_rt_destroy(ax25_route *ax25_rt) { if (atomic_read(&ax25_rt->ref) == 0) { - kfree(ax25_rt->digipeat); + if (ax25_rt->digipeat != NULL) + kfree(ax25_rt->digipeat); kfree(ax25_rt); return; } @@ -525,7 +530,9 @@ void __exit ax25_rt_free(void) s = ax25_rt; ax25_rt = ax25_rt->next; - kfree(s->digipeat); + if (s->digipeat != NULL) + kfree(s->digipeat); + kfree(s); } write_unlock(&ax25_route_lock); diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index ea616e3fc98e..03532062a46a 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #if defined(CONFIG_KMOD) @@ -49,7 +50,10 @@ #define BT_DBG(D...) #endif -#define VERSION "2.8" +#define VERSION "2.7" + +struct proc_dir_entry *proc_bt; +EXPORT_SYMBOL(proc_bt); /* Bluetooth sockets */ #define BT_MAX_PROTO 8 @@ -308,6 +312,10 @@ static int __init bt_init(void) { BT_INFO("Core ver %s", VERSION); + proc_bt = proc_mkdir("bluetooth", NULL); + if (proc_bt) + proc_bt->owner = THIS_MODULE; + sock_register(&bt_sock_family_ops); BT_INFO("HCI device and connection manager initialized"); @@ -326,6 +334,8 @@ static void __exit bt_exit(void) bt_sysfs_cleanup(); sock_unregister(PF_BLUETOOTH); + + remove_proc_entry("bluetooth", NULL); } subsys_initcall(bt_init); diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 9106354c781e..cf0df1c8c933 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -183,7 +183,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) static void hci_init_req(struct hci_dev *hdev, unsigned long opt) { struct sk_buff *skb; - __le16 param; + __u16 param; BT_DBG("%s %ld", hdev->name, opt); diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index eb64555d1fb3..b61b4e8e36fd 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -242,7 +242,7 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb break; status = *((__u8 *) skb->data); - setting = __le16_to_cpu(get_unaligned((__le16 *) sent)); + setting = __le16_to_cpu(get_unaligned((__u16 *) sent)); if (!status && hdev->voice_setting != setting) { hdev->voice_setting = setting; @@ -728,7 +728,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data; - __le16 *ptr; + __u16 *ptr; int i; skb_pull(skb, sizeof(*ev)); @@ -742,7 +742,7 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s tasklet_disable(&hdev->tx_task); - for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) { + for (i = 0, ptr = (__u16 *) skb->data; i < ev->num_hndl; i++) { struct hci_conn *conn; __u16 handle, count; diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index 1d6d0a15c099..799e448750ad 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -416,7 +416,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, skb->dev = (void *) hdev; if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { - u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data)); + u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data)); u16 ogf = hci_opcode_ogf(opcode); u16 ocf = hci_opcode_ocf(opcode); diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index bd7568ac87fc..7856bc26accb 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev) kfree(hdev); } -struct class bt_class = { +static struct class bt_class = { .name = "bluetooth", .release = bt_release, #ifdef CONFIG_HOTPLUG @@ -111,8 +111,6 @@ struct class bt_class = { #endif }; -EXPORT_SYMBOL_GPL(bt_class); - int hci_register_sysfs(struct hci_dev *hdev) { struct class_device *cdev = &hdev->class_dev; diff --git a/trunk/net/bluetooth/hidp/core.c b/trunk/net/bluetooth/hidp/core.c index cdb9cfafd960..860444a7fc0f 100644 --- a/trunk/net/bluetooth/hidp/core.c +++ b/trunk/net/bluetooth/hidp/core.c @@ -660,7 +660,9 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, failed: up_write(&hidp_session_sem); - kfree(session->input); + if (session->input) + kfree(session->input); + kfree(session); return err; } diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index e3bb11ca4235..59b2dd36baa7 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -38,8 +38,9 @@ #include #include #include +#include +#include #include -#include #include #include @@ -55,7 +56,7 @@ #define BT_DBG(D...) #endif -#define VERSION "2.8" +#define VERSION "2.7" static struct proto_ops l2cap_sock_ops; @@ -2136,29 +2137,94 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl return 0; } -static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) +/* ---- Proc fs support ---- */ +#ifdef CONFIG_PROC_FS +static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos) { struct sock *sk; struct hlist_node *node; - char *str = buf; + loff_t l = *pos; read_lock_bh(&l2cap_sk_list.lock); - sk_for_each(sk, node, &l2cap_sk_list.head) { - struct l2cap_pinfo *pi = l2cap_pi(sk); + sk_for_each(sk, node, &l2cap_sk_list.head) + if (!l--) + goto found; + sk = NULL; +found: + return sk; +} - str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, - pi->omtu, pi->link_mode); - } +static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos) +{ + (*pos)++; + return sk_next(e); +} +static void l2cap_seq_stop(struct seq_file *seq, void *e) +{ read_unlock_bh(&l2cap_sk_list.lock); +} - return (str - buf); +static int l2cap_seq_show(struct seq_file *seq, void *e) +{ + struct sock *sk = e; + struct l2cap_pinfo *pi = l2cap_pi(sk); + + seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, + pi->omtu, pi->link_mode); + return 0; } -static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); +static struct seq_operations l2cap_seq_ops = { + .start = l2cap_seq_start, + .next = l2cap_seq_next, + .stop = l2cap_seq_stop, + .show = l2cap_seq_show +}; + +static int l2cap_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &l2cap_seq_ops); +} + +static struct file_operations l2cap_seq_fops = { + .owner = THIS_MODULE, + .open = l2cap_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init l2cap_proc_init(void) +{ + struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt); + if (!p) + return -ENOMEM; + p->owner = THIS_MODULE; + p->proc_fops = &l2cap_seq_fops; + return 0; +} + +static void __exit l2cap_proc_cleanup(void) +{ + remove_proc_entry("l2cap", proc_bt); +} + +#else /* CONFIG_PROC_FS */ + +static int __init l2cap_proc_init(void) +{ + return 0; +} + +static void __exit l2cap_proc_cleanup(void) +{ + return; +} +#endif /* CONFIG_PROC_FS */ static struct proto_ops l2cap_sock_ops = { .family = PF_BLUETOOTH, @@ -2200,7 +2266,7 @@ static struct hci_proto l2cap_hci_proto = { static int __init l2cap_init(void) { int err; - + err = proto_register(&l2cap_proto, 0); if (err < 0) return err; @@ -2218,7 +2284,7 @@ static int __init l2cap_init(void) goto error; } - class_create_file(&bt_class, &class_attr_l2cap); + l2cap_proc_init(); BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP socket layer initialized"); @@ -2232,7 +2298,7 @@ static int __init l2cap_init(void) static void __exit l2cap_exit(void) { - class_remove_file(&bt_class, &class_attr_l2cap); + l2cap_proc_cleanup(); if (bt_sock_unregister(BTPROTO_L2CAP) < 0) BT_ERR("L2CAP socket unregistration failed"); diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index 0d89d6434136..c3d56ead840c 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -35,8 +35,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -46,13 +47,17 @@ #include #include -#define VERSION "1.6" +#define VERSION "1.5" #ifndef CONFIG_BT_RFCOMM_DEBUG #undef BT_DBG #define BT_DBG(D...) #endif +#ifdef CONFIG_PROC_FS +struct proc_dir_entry *proc_bt_rfcomm; +#endif + static struct task_struct *rfcomm_thread; static DECLARE_MUTEX(rfcomm_sem); @@ -1996,32 +2001,117 @@ static struct hci_cb rfcomm_cb = { .encrypt_cfm = rfcomm_encrypt_cfm }; -static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) +/* ---- Proc fs support ---- */ +#ifdef CONFIG_PROC_FS +static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos) { struct rfcomm_session *s; struct list_head *pp, *p; - char *str = buf; + loff_t l = *pos; rfcomm_lock(); list_for_each(p, &session_list) { s = list_entry(p, struct rfcomm_session, list); - list_for_each(pp, &s->dlcs) { - struct sock *sk = s->sock->sk; - struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); + list_for_each(pp, &s->dlcs) + if (!l--) { + seq->private = s; + return pp; + } + } + return NULL; +} - str += sprintf(str, "%s %s %ld %d %d %d %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); +static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos) +{ + struct rfcomm_session *s = seq->private; + struct list_head *pp, *p = e; + (*pos)++; + + if (p->next != &s->dlcs) + return p->next; + + list_for_each(p, &session_list) { + s = list_entry(p, struct rfcomm_session, list); + __list_for_each(pp, &s->dlcs) { + seq->private = s; + return pp; } } + return NULL; +} +static void rfcomm_seq_stop(struct seq_file *seq, void *e) +{ rfcomm_unlock(); +} + +static int rfcomm_seq_show(struct seq_file *seq, void *e) +{ + struct rfcomm_session *s = seq->private; + struct sock *sk = s->sock->sk; + struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list); + + seq_printf(seq, "%s %s %ld %d %d %d %d\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); + return 0; +} + +static struct seq_operations rfcomm_seq_ops = { + .start = rfcomm_seq_start, + .next = rfcomm_seq_next, + .stop = rfcomm_seq_stop, + .show = rfcomm_seq_show +}; + +static int rfcomm_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &rfcomm_seq_ops); +} + +static struct file_operations rfcomm_seq_fops = { + .owner = THIS_MODULE, + .open = rfcomm_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init rfcomm_proc_init(void) +{ + struct proc_dir_entry *p; + + proc_bt_rfcomm = proc_mkdir("rfcomm", proc_bt); + if (proc_bt_rfcomm) { + proc_bt_rfcomm->owner = THIS_MODULE; + + p = create_proc_entry("dlc", S_IRUGO, proc_bt_rfcomm); + if (p) + p->proc_fops = &rfcomm_seq_fops; + } + return 0; +} + +static void __exit rfcomm_proc_cleanup(void) +{ + remove_proc_entry("dlc", proc_bt_rfcomm); - return (str - buf); + remove_proc_entry("rfcomm", proc_bt); } -static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL); +#else /* CONFIG_PROC_FS */ + +static int __init rfcomm_proc_init(void) +{ + return 0; +} + +static void __exit rfcomm_proc_cleanup(void) +{ + return; +} +#endif /* CONFIG_PROC_FS */ /* ---- Initialization ---- */ static int __init rfcomm_init(void) @@ -2032,7 +2122,9 @@ static int __init rfcomm_init(void) kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); - class_create_file(&bt_class, &class_attr_rfcomm_dlc); + BT_INFO("RFCOMM ver %s", VERSION); + + rfcomm_proc_init(); rfcomm_init_sockets(); @@ -2040,15 +2132,11 @@ static int __init rfcomm_init(void) rfcomm_init_ttys(); #endif - BT_INFO("RFCOMM ver %s", VERSION); - return 0; } static void __exit rfcomm_exit(void) { - class_remove_file(&bt_class, &class_attr_rfcomm_dlc); - hci_unregister_cb(&rfcomm_cb); /* Terminate working thread. @@ -2065,6 +2153,8 @@ static void __exit rfcomm_exit(void) #endif rfcomm_cleanup_sockets(); + + rfcomm_proc_cleanup(); } module_init(rfcomm_init); diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 6c34261b232e..a2b30f0aedb7 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -42,7 +42,8 @@ #include #include #include -#include +#include +#include #include #include @@ -886,26 +887,89 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * return result; } -static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf) +/* ---- Proc fs support ---- */ +#ifdef CONFIG_PROC_FS +static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos) { struct sock *sk; struct hlist_node *node; - char *str = buf; + loff_t l = *pos; read_lock_bh(&rfcomm_sk_list.lock); - sk_for_each(sk, node, &rfcomm_sk_list.head) { - str += sprintf(str, "%s %s %d %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, rfcomm_pi(sk)->channel); - } + sk_for_each(sk, node, &rfcomm_sk_list.head) + if (!l--) + return sk; + return NULL; +} + +static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos) +{ + struct sock *sk = e; + (*pos)++; + return sk_next(sk); +} +static void rfcomm_seq_stop(struct seq_file *seq, void *e) +{ read_unlock_bh(&rfcomm_sk_list.lock); +} - return (str - buf); +static int rfcomm_seq_show(struct seq_file *seq, void *e) +{ + struct sock *sk = e; + seq_printf(seq, "%s %s %d %d\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + sk->sk_state, rfcomm_pi(sk)->channel); + return 0; +} + +static struct seq_operations rfcomm_seq_ops = { + .start = rfcomm_seq_start, + .next = rfcomm_seq_next, + .stop = rfcomm_seq_stop, + .show = rfcomm_seq_show +}; + +static int rfcomm_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &rfcomm_seq_ops); } -static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); +static struct file_operations rfcomm_seq_fops = { + .owner = THIS_MODULE, + .open = rfcomm_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init rfcomm_sock_proc_init(void) +{ + struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm); + if (!p) + return -ENOMEM; + p->proc_fops = &rfcomm_seq_fops; + return 0; +} + +static void __exit rfcomm_sock_proc_cleanup(void) +{ + remove_proc_entry("sock", proc_bt_rfcomm); +} + +#else /* CONFIG_PROC_FS */ + +static int __init rfcomm_sock_proc_init(void) +{ + return 0; +} + +static void __exit rfcomm_sock_proc_cleanup(void) +{ + return; +} +#endif /* CONFIG_PROC_FS */ static struct proto_ops rfcomm_sock_ops = { .family = PF_BLUETOOTH, @@ -933,7 +997,7 @@ static struct net_proto_family rfcomm_sock_family_ops = { .create = rfcomm_sock_create }; -int __init rfcomm_init_sockets(void) +int __init rfcomm_init_sockets(void) { int err; @@ -945,7 +1009,7 @@ int __init rfcomm_init_sockets(void) if (err < 0) goto error; - class_create_file(&bt_class, &class_attr_rfcomm); + rfcomm_sock_proc_init(); BT_INFO("RFCOMM socket layer initialized"); @@ -959,7 +1023,7 @@ int __init rfcomm_init_sockets(void) void __exit rfcomm_cleanup_sockets(void) { - class_remove_file(&bt_class, &class_attr_rfcomm); + rfcomm_sock_proc_cleanup(); if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) BT_ERR("RFCOMM socket layer unregistration failed"); diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 9cb00dc6c08c..997e42df115c 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -38,7 +38,8 @@ #include #include #include -#include +#include +#include #include #include @@ -54,7 +55,7 @@ #define BT_DBG(D...) #endif -#define VERSION "0.5" +#define VERSION "0.4" static struct proto_ops sco_sock_ops; @@ -892,26 +893,91 @@ static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb) return 0; } -static ssize_t sco_sysfs_show(struct class *dev, char *buf) +/* ---- Proc fs support ---- */ +#ifdef CONFIG_PROC_FS +static void *sco_seq_start(struct seq_file *seq, loff_t *pos) { struct sock *sk; struct hlist_node *node; - char *str = buf; + loff_t l = *pos; read_lock_bh(&sco_sk_list.lock); - sk_for_each(sk, node, &sco_sk_list.head) { - str += sprintf(str, "%s %s %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state); - } + sk_for_each(sk, node, &sco_sk_list.head) + if (!l--) + goto found; + sk = NULL; +found: + return sk; +} + +static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos) +{ + struct sock *sk = e; + (*pos)++; + return sk_next(sk); +} +static void sco_seq_stop(struct seq_file *seq, void *e) +{ read_unlock_bh(&sco_sk_list.lock); +} + +static int sco_seq_show(struct seq_file *seq, void *e) +{ + struct sock *sk = e; + seq_printf(seq, "%s %s %d\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state); + return 0; +} - return (str - buf); +static struct seq_operations sco_seq_ops = { + .start = sco_seq_start, + .next = sco_seq_next, + .stop = sco_seq_stop, + .show = sco_seq_show +}; + +static int sco_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &sco_seq_ops); } -static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); +static struct file_operations sco_seq_fops = { + .owner = THIS_MODULE, + .open = sco_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int __init sco_proc_init(void) +{ + struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt); + if (!p) + return -ENOMEM; + p->owner = THIS_MODULE; + p->proc_fops = &sco_seq_fops; + return 0; +} + +static void __exit sco_proc_cleanup(void) +{ + remove_proc_entry("sco", proc_bt); +} + +#else /* CONFIG_PROC_FS */ + +static int __init sco_proc_init(void) +{ + return 0; +} + +static void __exit sco_proc_cleanup(void) +{ + return; +} +#endif /* CONFIG_PROC_FS */ static struct proto_ops sco_sock_ops = { .family = PF_BLUETOOTH, @@ -969,7 +1035,7 @@ static int __init sco_init(void) goto error; } - class_create_file(&bt_class, &class_attr_sco); + sco_proc_init(); BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO socket layer initialized"); @@ -983,7 +1049,7 @@ static int __init sco_init(void) static void __exit sco_exit(void) { - class_remove_file(&bt_class, &class_attr_sco); + sco_proc_cleanup(); if (bt_sock_unregister(BTPROTO_SCO) < 0) BT_ERR("SCO socket unregistration failed"); diff --git a/trunk/net/core/dev_mcast.c b/trunk/net/core/dev_mcast.c index cb530eef0e39..db098ff3cd6a 100644 --- a/trunk/net/core/dev_mcast.c +++ b/trunk/net/core/dev_mcast.c @@ -194,7 +194,8 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) done: spin_unlock_bh(&dev->xmit_lock); - kfree(dmi1); + if (dmi1) + kfree(dmi1); return err; } diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 13cc3be4f056..9602ceb3bac9 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -1242,7 +1242,8 @@ static void sock_def_write_space(struct sock *sk) static void sock_def_destruct(struct sock *sk) { - kfree(sk->sk_protinfo); + if (sk->sk_protinfo) + kfree(sk->sk_protinfo); } void sk_send_sigurg(struct sock *sk) diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index ca03521112c5..4b9bc81ae1a3 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -1263,8 +1263,10 @@ static int dccp_v4_destroy_sock(struct sock *sk) if (inet_csk(sk)->icsk_bind_hash != NULL) inet_put_port(&dccp_hashinfo, sk); - kfree(dp->dccps_service_list); - dp->dccps_service_list = NULL; + if (dp->dccps_service_list != NULL) { + kfree(dp->dccps_service_list); + dp->dccps_service_list = NULL; + } ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk); ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk); diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index e0ace7cbb996..a021c3422f67 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -238,7 +238,8 @@ static int dccp_setsockopt_service(struct sock *sk, const u32 service, lock_sock(sk); dp->dccps_service = service; - kfree(dp->dccps_service_list); + if (dp->dccps_service_list != NULL) + kfree(dp->dccps_service_list); dp->dccps_service_list = sl; release_sock(sk); diff --git a/trunk/net/decnet/dn_table.c b/trunk/net/decnet/dn_table.c index 6f8b5658cb4e..eeba56f99323 100644 --- a/trunk/net/decnet/dn_table.c +++ b/trunk/net/decnet/dn_table.c @@ -784,14 +784,16 @@ struct dn_fib_table *dn_fib_get_table(int n, int create) static void dn_fib_del_tree(int n) { - struct dn_fib_table *t; + struct dn_fib_table *t; - write_lock(&dn_fib_tables_lock); - t = dn_fib_tables[n]; - dn_fib_tables[n] = NULL; - write_unlock(&dn_fib_tables_lock); + write_lock(&dn_fib_tables_lock); + t = dn_fib_tables[n]; + dn_fib_tables[n] = NULL; + write_unlock(&dn_fib_tables_lock); - kfree(t); + if (t) { + kfree(t); + } } struct dn_fib_table *dn_fib_empty_table(void) diff --git a/trunk/net/ethernet/pe2.c b/trunk/net/ethernet/pe2.c index 9d57b4fb6440..98a494be6039 100644 --- a/trunk/net/ethernet/pe2.c +++ b/trunk/net/ethernet/pe2.c @@ -32,7 +32,8 @@ struct datalink_proto *make_EII_client(void) void destroy_EII_client(struct datalink_proto *dl) { - kfree(dl); + if (dl) + kfree(dl); } EXPORT_SYMBOL(destroy_EII_client); diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index eaa150c33b04..a9d84f93442c 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -147,7 +147,8 @@ void inet_sock_destruct(struct sock *sk) BUG_TRAP(!sk->sk_wmem_queued); BUG_TRAP(!sk->sk_forward_alloc); - kfree(inet->opt); + if (inet->opt) + kfree(inet->opt); dst_release(sk->sk_dst_cache); sk_refcnt_debug_dec(sk); } diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index 2267c1fad879..990633c09dfe 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -266,7 +266,8 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg) if (tb) err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL); } - kfree(rta.rta_mx); + if (rta.rta_mx) + kfree(rta.rta_mx); } rtnl_unlock(); return err; diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index dbe12da8d8b3..bce4e875193b 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -510,7 +510,8 @@ static int ip_options_get_finish(struct ip_options **optp, kfree(opt); return -EINVAL; } - kfree(*optp); + if (*optp) + kfree(*optp); *optp = opt; return 0; } diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 11c2f68254f0..17758234a3e3 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -353,8 +353,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) ip_options_build(skb, opt, inet->daddr, rt, 0); } - ip_select_ident_more(iph, &rt->u.dst, sk, - (skb_shinfo(skb)->tso_segs ?: 1) - 1); + ip_select_ident_more(iph, &rt->u.dst, sk, skb_shinfo(skb)->tso_segs); /* Add an IP checksum. */ ip_send_check(iph); @@ -1263,8 +1262,10 @@ int ip_push_pending_frames(struct sock *sk) out: inet->cork.flags &= ~IPCORK_OPT; - kfree(inet->cork.opt); - inet->cork.opt = NULL; + if (inet->cork.opt) { + kfree(inet->cork.opt); + inet->cork.opt = NULL; + } if (inet->cork.rt) { ip_rt_put(inet->cork.rt); inet->cork.rt = NULL; @@ -1288,8 +1289,10 @@ void ip_flush_pending_frames(struct sock *sk) kfree_skb(skb); inet->cork.flags &= ~IPCORK_OPT; - kfree(inet->cork.opt); - inet->cork.opt = NULL; + if (inet->cork.opt) { + kfree(inet->cork.opt); + inet->cork.opt = NULL; + } if (inet->cork.rt) { ip_rt_put(inet->cork.rt); inet->cork.rt = NULL; diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index 4f2d87257309..2f0b47da5b37 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -202,7 +202,8 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s if (ra->sk == sk) { if (on) { write_unlock_bh(&ip_ra_lock); - kfree(new_ra); + if (new_ra) + kfree(new_ra); return -EADDRINUSE; } *rap = ra->next; @@ -445,7 +446,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, #endif } opt = xchg(&inet->opt, opt); - kfree(opt); + if (opt) + kfree(opt); break; } case IP_PKTINFO: @@ -826,8 +828,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, err = ip_mc_msfilter(sk, msf, ifindex); mc_msf_out: - kfree(msf); - kfree(gsf); + if (msf) + kfree(msf); + if (gsf) + kfree(gsf); break; } case IP_ROUTER_ALERT: diff --git a/trunk/net/ipv4/ipvs/ip_vs_app.c b/trunk/net/ipv4/ipvs/ip_vs_app.c index d7eb680101c2..fc6f95aaa969 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_app.c +++ b/trunk/net/ipv4/ipvs/ip_vs_app.c @@ -110,7 +110,8 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) return 0; out: - kfree(inc->timeout_table); + if (inc->timeout_table) + kfree(inc->timeout_table); kfree(inc); return ret; } @@ -135,7 +136,8 @@ ip_vs_app_inc_release(struct ip_vs_app *inc) list_del(&inc->a_list); - kfree(inc->timeout_table); + if (inc->timeout_table != NULL) + kfree(inc->timeout_table); kfree(inc); } diff --git a/trunk/net/ipv4/ipvs/ip_vs_core.c b/trunk/net/ipv4/ipvs/ip_vs_core.c index 1a0843cd58a9..981cc3244ef2 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_core.c +++ b/trunk/net/ipv4/ipvs/ip_vs_core.c @@ -1009,10 +1009,11 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb, if (sysctl_ip_vs_expire_nodest_conn) { /* try to expire the connection immediately */ ip_vs_conn_expire_now(cp); + } else { + /* don't restart its timer, and silently + drop the packet. */ + __ip_vs_conn_put(cp); } - /* don't restart its timer, and silently - drop the packet. */ - __ip_vs_conn_put(cp); return NF_DROP; } diff --git a/trunk/net/ipv4/multipath_wrandom.c b/trunk/net/ipv4/multipath_wrandom.c index d34a9fa608e0..bd7d75b6abe0 100644 --- a/trunk/net/ipv4/multipath_wrandom.c +++ b/trunk/net/ipv4/multipath_wrandom.c @@ -207,12 +207,16 @@ static void wrandom_select_route(const struct flowi *flp, decision = mpc->rt; last_power = mpc->power; - kfree(last_mpc); + if (last_mpc) + kfree(last_mpc); + last_mpc = mpc; } - /* concurrent __multipath_flush may lead to !last_mpc */ - kfree(last_mpc); + if (last_mpc) { + /* concurrent __multipath_flush may lead to !last_mpc */ + kfree(last_mpc); + } decision->u.dst.__use++; *rp = decision; diff --git a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c index 8acb7ed40b47..93b2c5111bb2 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1161,7 +1161,8 @@ static int snmp_parse_mangle(unsigned char *msg, if (!snmp_object_decode(&ctx, obj)) { if (*obj) { - kfree((*obj)->id); + if ((*obj)->id) + kfree((*obj)->id); kfree(*obj); } kfree(obj); diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 634dabb558fd..49d67cd75edd 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -823,7 +823,8 @@ static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req, */ static void tcp_v4_reqsk_destructor(struct request_sock *req) { - kfree(inet_rsk(req)->opt); + if (inet_rsk(req)->opt) + kfree(inet_rsk(req)->opt); } static inline void syn_flood_warning(struct sk_buff *skb) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index b7a5f51238b3..2c5f57299d63 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -35,9 +35,6 @@ * YOSHIFUJI Hideaki @USAGI : ARCnet support * YOSHIFUJI Hideaki @USAGI : convert /proc/net/if_inet6 to * seq_file. - * YOSHIFUJI Hideaki @USAGI : improved source address - * selection; consider scope, - * status etc. */ #include @@ -196,51 +193,46 @@ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; #endif const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; -#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16) - -static inline unsigned ipv6_addr_scope2type(unsigned scope) -{ - switch(scope) { - case IPV6_ADDR_SCOPE_NODELOCAL: - return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) | - IPV6_ADDR_LOOPBACK); - case IPV6_ADDR_SCOPE_LINKLOCAL: - return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL) | - IPV6_ADDR_LINKLOCAL); - case IPV6_ADDR_SCOPE_SITELOCAL: - return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL) | - IPV6_ADDR_SITELOCAL); - } - return IPV6_ADDR_SCOPE_TYPE(scope); -} - -int __ipv6_addr_type(const struct in6_addr *addr) +int ipv6_addr_type(const struct in6_addr *addr) { + int type; u32 st; st = addr->s6_addr32[0]; + if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) { + type = IPV6_ADDR_MULTICAST; + + switch((st & htonl(0x00FF0000))) { + case __constant_htonl(0x00010000): + type |= IPV6_ADDR_LOOPBACK; + break; + + case __constant_htonl(0x00020000): + type |= IPV6_ADDR_LINKLOCAL; + break; + + case __constant_htonl(0x00050000): + type |= IPV6_ADDR_SITELOCAL; + break; + }; + return type; + } + + type = IPV6_ADDR_UNICAST; + /* Consider all addresses with the first three bits different of - 000 and 111 as unicasts. + 000 and 111 as finished. */ if ((st & htonl(0xE0000000)) != htonl(0x00000000) && (st & htonl(0xE0000000)) != htonl(0xE0000000)) - return (IPV6_ADDR_UNICAST | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); - - if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) { - /* multicast */ - /* addr-select 3.1 */ - return (IPV6_ADDR_MULTICAST | - ipv6_addr_scope2type(IPV6_ADDR_MC_SCOPE(addr))); - } - + return type; + if ((st & htonl(0xFFC00000)) == htonl(0xFE800000)) - return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.1 */ + return (IPV6_ADDR_LINKLOCAL | type); + if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000)) - return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL)); /* addr-select 3.1 */ + return (IPV6_ADDR_SITELOCAL | type); if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) { if (addr->s6_addr32[2] == 0) { @@ -248,20 +240,24 @@ int __ipv6_addr_type(const struct in6_addr *addr) return IPV6_ADDR_ANY; if (addr->s6_addr32[3] == htonl(0x00000001)) - return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL)); /* addr-select 3.4 */ + return (IPV6_ADDR_LOOPBACK | type); - return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */ + return (IPV6_ADDR_COMPATv4 | type); } if (addr->s6_addr32[2] == htonl(0x0000ffff)) - return (IPV6_ADDR_MAPPED | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.3 */ + return IPV6_ADDR_MAPPED; } - return (IPV6_ADDR_RESERVED | - IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL)); /* addr-select 3.4 */ + st &= htonl(0xFF000000); + if (st == 0) + return IPV6_ADDR_RESERVED; + st &= htonl(0xFE000000); + if (st == htonl(0x02000000)) + return IPV6_ADDR_RESERVED; /* for NSAP */ + if (st == htonl(0x04000000)) + return IPV6_ADDR_RESERVED; /* for IPX */ + return type; } static void addrconf_del_timer(struct inet6_ifaddr *ifp) @@ -809,274 +805,138 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i #endif /* - * Choose an appropriate source address (RFC3484) + * Choose an appropriate source address + * should do: + * i) get an address with an appropriate scope + * ii) see if there is a specific route for the destination and use + * an address of the attached interface + * iii) don't use deprecated addresses */ -struct ipv6_saddr_score { - int addr_type; - unsigned int attrs; - int matchlen; - unsigned int scope; - unsigned int rule; -}; - -#define IPV6_SADDR_SCORE_LOCAL 0x0001 -#define IPV6_SADDR_SCORE_PREFERRED 0x0004 -#define IPV6_SADDR_SCORE_HOA 0x0008 -#define IPV6_SADDR_SCORE_OIF 0x0010 -#define IPV6_SADDR_SCORE_LABEL 0x0020 -#define IPV6_SADDR_SCORE_PRIVACY 0x0040 - -static int inline ipv6_saddr_preferred(int type) +static int inline ipv6_saddr_pref(const struct inet6_ifaddr *ifp, u8 invpref) { - if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4| - IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED)) - return 1; - return 0; + int pref; + pref = ifp->flags&IFA_F_DEPRECATED ? 0 : 2; +#ifdef CONFIG_IPV6_PRIVACY + pref |= (ifp->flags^invpref)&IFA_F_TEMPORARY ? 0 : 1; +#endif + return pref; } -/* static matching label */ -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type) -{ - /* - * prefix (longest match) label - * ----------------------------- - * ::1/128 0 - * ::/0 1 - * 2002::/16 2 - * ::/96 3 - * ::ffff:0:0/96 4 - */ - if (type & IPV6_ADDR_LOOPBACK) - return 0; - else if (type & IPV6_ADDR_COMPATv4) - return 3; - else if (type & IPV6_ADDR_MAPPED) - return 4; - else if (addr->s6_addr16[0] == htons(0x2002)) - return 2; - return 1; -} +#ifdef CONFIG_IPV6_PRIVACY +#define IPV6_GET_SADDR_MAXSCORE(score) ((score) == 3) +#else +#define IPV6_GET_SADDR_MAXSCORE(score) (score) +#endif -int ipv6_dev_get_saddr(struct net_device *daddr_dev, +int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr) { - struct ipv6_saddr_score hiscore; - struct inet6_ifaddr *ifa_result = NULL; - int daddr_type = __ipv6_addr_type(daddr); - int daddr_scope = __ipv6_addr_src_scope(daddr_type); - u32 daddr_label = ipv6_saddr_label(daddr, daddr_type); - struct net_device *dev; + struct inet6_ifaddr *ifp = NULL; + struct inet6_ifaddr *match = NULL; + struct inet6_dev *idev; + int scope; + int err; + int hiscore = -1, score; - memset(&hiscore, 0, sizeof(hiscore)); + scope = ipv6_addr_scope(daddr); - read_lock(&dev_base_lock); - read_lock(&addrconf_lock); + /* + * known dev + * search dev and walk through dev addresses + */ - for (dev = dev_base; dev; dev=dev->next) { - struct inet6_dev *idev; - struct inet6_ifaddr *ifa; - - /* Rule 0: Candidate Source Address (section 4) - * - multicast and link-local destination address, - * the set of candidate source address MUST only - * include addresses assigned to interfaces - * belonging to the same link as the outgoing - * interface. - * (- For site-local destination addresses, the - * set of candidate source addresses MUST only - * include addresses assigned to interfaces - * belonging to the same site as the outgoing - * interface.) - */ - if ((daddr_type & IPV6_ADDR_MULTICAST || - daddr_scope <= IPV6_ADDR_SCOPE_LINKLOCAL) && - daddr_dev && dev != daddr_dev) - continue; + if (dev) { + if (dev->flags & IFF_LOOPBACK) + scope = IFA_HOST; + read_lock(&addrconf_lock); idev = __in6_dev_get(dev); - if (!idev) - continue; - - read_lock_bh(&idev->lock); - for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { - struct ipv6_saddr_score score; - - score.addr_type = __ipv6_addr_type(&ifa->addr); - - /* Rule 0: Candidate Source Address (section 4) - * - In any case, anycast addresses, multicast - * addresses, and the unspecified address MUST - * NOT be included in a candidate set. - */ - if (unlikely(score.addr_type == IPV6_ADDR_ANY || - score.addr_type & IPV6_ADDR_MULTICAST)) { - LIMIT_NETDEBUG(KERN_DEBUG - "ADDRCONF: unspecified / multicast address" - "assigned as unicast address on %s", - dev->name); - continue; - } - - score.attrs = 0; - score.matchlen = 0; - score.scope = 0; - score.rule = 0; - - if (ifa_result == NULL) { - /* record it if the first available entry */ - goto record_it; - } + if (idev) { + read_lock_bh(&idev->lock); + for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { + if (ifp->scope == scope) { + if (ifp->flags&IFA_F_TENTATIVE) + continue; +#ifdef CONFIG_IPV6_PRIVACY + score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0); +#else + score = ipv6_saddr_pref(ifp, 0); +#endif + if (score <= hiscore) + continue; - /* Rule 1: Prefer same address */ - if (hiscore.rule < 1) { - if (ipv6_addr_equal(&ifa_result->addr, daddr)) - hiscore.attrs |= IPV6_SADDR_SCORE_LOCAL; - hiscore.rule++; - } - if (ipv6_addr_equal(&ifa->addr, daddr)) { - score.attrs |= IPV6_SADDR_SCORE_LOCAL; - if (!(hiscore.attrs & IPV6_SADDR_SCORE_LOCAL)) { - score.rule = 1; - goto record_it; - } - } else { - if (hiscore.attrs & IPV6_SADDR_SCORE_LOCAL) - continue; - } + if (match) + in6_ifa_put(match); + match = ifp; + hiscore = score; + in6_ifa_hold(ifp); - /* Rule 2: Prefer appropriate scope */ - if (hiscore.rule < 2) { - hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type); - hiscore.rule++; - } - score.scope = __ipv6_addr_src_scope(score.addr_type); - if (hiscore.scope < score.scope) { - if (hiscore.scope < daddr_scope) { - score.rule = 2; - goto record_it; - } else - continue; - } else if (score.scope < hiscore.scope) { - if (score.scope < daddr_scope) - continue; - else { - score.rule = 2; - goto record_it; + if (IPV6_GET_SADDR_MAXSCORE(score)) { + read_unlock_bh(&idev->lock); + read_unlock(&addrconf_lock); + goto out; + } } } + read_unlock_bh(&idev->lock); + } + read_unlock(&addrconf_lock); + } - /* Rule 3: Avoid deprecated address */ - if (hiscore.rule < 3) { - if (ipv6_saddr_preferred(hiscore.addr_type) || - !(ifa_result->flags & IFA_F_DEPRECATED)) - hiscore.attrs |= IPV6_SADDR_SCORE_PREFERRED; - hiscore.rule++; - } - if (ipv6_saddr_preferred(score.addr_type) || - !(ifa->flags & IFA_F_DEPRECATED)) { - score.attrs |= IPV6_SADDR_SCORE_PREFERRED; - if (!(hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED)) { - score.rule = 3; - goto record_it; - } - } else { - if (hiscore.attrs & IPV6_SADDR_SCORE_PREFERRED) - continue; - } + if (scope == IFA_LINK) + goto out; - /* Rule 4: Prefer home address -- not implemented yet */ + /* + * dev == NULL or search failed for specified dev + */ - /* Rule 5: Prefer outgoing interface */ - if (hiscore.rule < 5) { - if (daddr_dev == NULL || - daddr_dev == ifa_result->idev->dev) - hiscore.attrs |= IPV6_SADDR_SCORE_OIF; - hiscore.rule++; - } - if (daddr_dev == NULL || - daddr_dev == ifa->idev->dev) { - score.attrs |= IPV6_SADDR_SCORE_OIF; - if (!(hiscore.attrs & IPV6_SADDR_SCORE_OIF)) { - score.rule = 5; - goto record_it; - } - } else { - if (hiscore.attrs & IPV6_SADDR_SCORE_OIF) - continue; - } + read_lock(&dev_base_lock); + read_lock(&addrconf_lock); + for (dev = dev_base; dev; dev=dev->next) { + idev = __in6_dev_get(dev); + if (idev) { + read_lock_bh(&idev->lock); + for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { + if (ifp->scope == scope) { + if (ifp->flags&IFA_F_TENTATIVE) + continue; +#ifdef CONFIG_IPV6_PRIVACY + score = ipv6_saddr_pref(ifp, idev->cnf.use_tempaddr > 1 ? IFA_F_TEMPORARY : 0); +#else + score = ipv6_saddr_pref(ifp, 0); +#endif + if (score <= hiscore) + continue; - /* Rule 6: Prefer matching label */ - if (hiscore.rule < 6) { - if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label) - hiscore.attrs |= IPV6_SADDR_SCORE_LABEL; - hiscore.rule++; - } - if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) { - score.attrs |= IPV6_SADDR_SCORE_LABEL; - if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) { - score.rule = 6; - goto record_it; - } - } else { - if (hiscore.attrs & IPV6_SADDR_SCORE_LABEL) - continue; - } + if (match) + in6_ifa_put(match); + match = ifp; + hiscore = score; + in6_ifa_hold(ifp); - /* Rule 7: Prefer public address - * Note: prefer temprary address if use_tempaddr >= 2 - */ - if (hiscore.rule < 7) { - if ((!(ifa_result->flags & IFA_F_TEMPORARY)) ^ - (ifa_result->idev->cnf.use_tempaddr >= 2)) - hiscore.attrs |= IPV6_SADDR_SCORE_PRIVACY; - hiscore.rule++; - } - if ((!(ifa->flags & IFA_F_TEMPORARY)) ^ - (ifa->idev->cnf.use_tempaddr >= 2)) { - score.attrs |= IPV6_SADDR_SCORE_PRIVACY; - if (!(hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)) { - score.rule = 7; - goto record_it; + if (IPV6_GET_SADDR_MAXSCORE(score)) { + read_unlock_bh(&idev->lock); + goto out_unlock_base; + } } - } else { - if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY) - continue; - } - - /* Rule 8: Use longest matching prefix */ - if (hiscore.rule < 8) - hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr); - score.rule++; - score.matchlen = ipv6_addr_diff(&ifa->addr, daddr); - if (score.matchlen > hiscore.matchlen) { - score.rule = 8; - goto record_it; } -#if 0 - else if (score.matchlen < hiscore.matchlen) - continue; -#endif - - /* Final Rule: choose first available one */ - continue; -record_it: - if (ifa_result) - in6_ifa_put(ifa_result); - in6_ifa_hold(ifa); - ifa_result = ifa; - hiscore = score; + read_unlock_bh(&idev->lock); } - read_unlock_bh(&idev->lock); } + +out_unlock_base: read_unlock(&addrconf_lock); read_unlock(&dev_base_lock); - if (!ifa_result) - return -EADDRNOTAVAIL; - - ipv6_addr_copy(saddr, &ifa_result->addr); - in6_ifa_put(ifa_result); - return 0; +out: + err = -EADDRNOTAVAIL; + if (match) { + ipv6_addr_copy(saddr, &match->addr); + err = 0; + in6_ifa_put(match); + } + + return err; } @@ -3090,7 +2950,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, nlmsg_failure: rtattr_failure: - kfree(array); + if (array) + kfree(array); skb_trim(skb, b - skb->data); return -1; } diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 1bf6d9a769e6..4fcc5a7acf6e 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -127,6 +127,56 @@ static __inline__ int addr_bit_set(void *token, int fn_bit) return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5]; } +/* + * find the first different bit between two addresses + * length of address must be a multiple of 32bits + */ + +static __inline__ int addr_diff(void *token1, void *token2, int addrlen) +{ + __u32 *a1 = token1; + __u32 *a2 = token2; + int i; + + addrlen >>= 2; + + for (i = 0; i < addrlen; i++) { + __u32 xb; + + xb = a1[i] ^ a2[i]; + + if (xb) { + int j = 31; + + xb = ntohl(xb); + + while ((xb & (1 << j)) == 0) + j--; + + return (i * 32 + 31 - j); + } + } + + /* + * we should *never* get to this point since that + * would mean the addrs are equal + * + * However, we do get to it 8) And exacly, when + * addresses are equal 8) + * + * ip route add 1111::/128 via ... + * ip route add 1111::/64 via ... + * and we are here. + * + * Ideally, this function should stop comparison + * at prefix length. It does not, but it is still OK, + * if returned value is greater than prefix length. + * --ANK (980803) + */ + + return addrlen<<5; +} + static __inline__ struct fib6_node * node_alloc(void) { struct fib6_node *fn; @@ -246,11 +296,11 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr, /* find 1st bit in difference between the 2 addrs. - See comment in __ipv6_addr_diff: bit may be an invalid value, + See comment in addr_diff: bit may be an invalid value, but if it is >= plen, the value is ignored in any case. */ - bit = __ipv6_addr_diff(addr, &key->addr, addrlen); + bit = addr_diff(addr, &key->addr, addrlen); /* * (intermediate)[in] diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index dbd9767b32e4..614296a920c6 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -587,7 +587,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb->next = NULL; } - kfree(tmp_hdr); + if (tmp_hdr) + kfree(tmp_hdr); if (err == 0) { IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); @@ -1185,8 +1186,10 @@ int ip6_push_pending_frames(struct sock *sk) out: inet->cork.flags &= ~IPCORK_OPT; - kfree(np->cork.opt); - np->cork.opt = NULL; + if (np->cork.opt) { + kfree(np->cork.opt); + np->cork.opt = NULL; + } if (np->cork.rt) { dst_release(&np->cork.rt->u.dst); np->cork.rt = NULL; @@ -1211,8 +1214,10 @@ void ip6_flush_pending_frames(struct sock *sk) inet->cork.flags &= ~IPCORK_OPT; - kfree(np->cork.opt); - np->cork.opt = NULL; + if (np->cork.opt) { + kfree(np->cork.opt); + np->cork.opt = NULL; + } if (np->cork.rt) { dst_release(&np->cork.rt->u.dst); np->cork.rt = NULL; diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index e6b0e3954c02..cf94372d1af3 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -756,7 +756,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) } ip6_tnl_dst_store(t, dst); - kfree(opt); + if (opt) + kfree(opt); t->recursion--; return 0; @@ -765,7 +766,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) dst_link_failure(skb); tx_err_dst_release: dst_release(dst); - kfree(opt); + if (opt) + kfree(opt); tx_err: stats->tx_errors++; stats->tx_dropped++; diff --git a/trunk/net/ipv6/ipcomp6.c b/trunk/net/ipv6/ipcomp6.c index 55917fb17094..85bfbc69b2c3 100644 --- a/trunk/net/ipv6/ipcomp6.c +++ b/trunk/net/ipv6/ipcomp6.c @@ -130,7 +130,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s out_put_cpu: put_cpu(); out: - kfree(tmp_hdr); + if (tmp_hdr) + kfree(tmp_hdr); if (err) goto error_out; return nexthdr; diff --git a/trunk/net/ipv6/ipv6_sockglue.c b/trunk/net/ipv6/ipv6_sockglue.c index 003fd99ff597..8567873d0dd8 100644 --- a/trunk/net/ipv6/ipv6_sockglue.c +++ b/trunk/net/ipv6/ipv6_sockglue.c @@ -80,7 +80,8 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) if (ra->sk == sk) { if (sel>=0) { write_unlock_bh(&ip6_ra_lock); - kfree(new_ra); + if (new_ra) + kfree(new_ra); return -EADDRINUSE; } diff --git a/trunk/net/ipv6/ipv6_syms.c b/trunk/net/ipv6/ipv6_syms.c index 16482785bdfd..37a4a99c9fe9 100644 --- a/trunk/net/ipv6/ipv6_syms.c +++ b/trunk/net/ipv6/ipv6_syms.c @@ -7,7 +7,7 @@ #include #include -EXPORT_SYMBOL(__ipv6_addr_type); +EXPORT_SYMBOL(ipv6_addr_type); EXPORT_SYMBOL(icmpv6_send); EXPORT_SYMBOL(icmpv6_statistics); EXPORT_SYMBOL(icmpv6_err_convert); diff --git a/trunk/net/irda/discovery.c b/trunk/net/irda/discovery.c index 3fefc822c1c0..c4ba5fa1446a 100644 --- a/trunk/net/irda/discovery.c +++ b/trunk/net/irda/discovery.c @@ -194,7 +194,8 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force) /* Remove it from the log */ curr = hashbin_remove_this(log, (irda_queue_t *) curr); - kfree(curr); + if (curr) + kfree(curr); } } diff --git a/trunk/net/irda/irias_object.c b/trunk/net/irda/irias_object.c index 75f2666e8630..6fec428b4512 100644 --- a/trunk/net/irda/irias_object.c +++ b/trunk/net/irda/irias_object.c @@ -122,7 +122,8 @@ static void __irias_delete_attrib(struct ias_attrib *attrib) IRDA_ASSERT(attrib != NULL, return;); IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;); - kfree(attrib->name); + if (attrib->name) + kfree(attrib->name); irias_delete_value(attrib->value); attrib->magic = ~IAS_ATTRIB_MAGIC; @@ -135,7 +136,8 @@ void __irias_delete_object(struct ias_object *obj) IRDA_ASSERT(obj != NULL, return;); IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - kfree(obj->name); + if (obj->name) + kfree(obj->name); hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib); @@ -560,12 +562,14 @@ void irias_delete_value(struct ias_value *value) /* No need to deallocate */ break; case IAS_STRING: - /* Deallocate string */ - kfree(value->t.string); + /* If string, deallocate string */ + if (value->t.string != NULL) + kfree(value->t.string); break; case IAS_OCT_SEQ: - /* Deallocate byte stream */ - kfree(value->t.oct_seq); + /* If byte stream, deallocate byte stream */ + if (value->t.oct_seq != NULL) + kfree(value->t.oct_seq); break; default: IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__); diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index 8631b65a7312..b18fe5043019 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -240,7 +240,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) if ((s = rose_neigh_list) == rose_neigh) { rose_neigh_list = rose_neigh->next; spin_unlock_bh(&rose_neigh_list_lock); - kfree(rose_neigh->digipeat); + if (rose_neigh->digipeat != NULL) + kfree(rose_neigh->digipeat); kfree(rose_neigh); return; } @@ -249,7 +250,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) if (s->next == rose_neigh) { s->next = rose_neigh->next; spin_unlock_bh(&rose_neigh_list_lock); - kfree(rose_neigh->digipeat); + if (rose_neigh->digipeat != NULL) + kfree(rose_neigh->digipeat); kfree(rose_neigh); return; } diff --git a/trunk/net/sched/cls_fw.c b/trunk/net/sched/cls_fw.c index 75470486e405..29d8b9a4d162 100644 --- a/trunk/net/sched/cls_fw.c +++ b/trunk/net/sched/cls_fw.c @@ -298,7 +298,8 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, return 0; errout: - kfree(f); + if (f) + kfree(f); return err; } diff --git a/trunk/net/sched/cls_route.c b/trunk/net/sched/cls_route.c index 520ff716dab2..02996ac05c75 100644 --- a/trunk/net/sched/cls_route.c +++ b/trunk/net/sched/cls_route.c @@ -525,7 +525,8 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, return 0; errout: - kfree(f); + if (f) + kfree(f); return err; } diff --git a/trunk/net/sched/cls_rsvp.h b/trunk/net/sched/cls_rsvp.h index 572f06be3b02..006168d69376 100644 --- a/trunk/net/sched/cls_rsvp.h +++ b/trunk/net/sched/cls_rsvp.h @@ -555,7 +555,8 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, goto insert; errout: - kfree(f); + if (f) + kfree(f); errout2: tcf_exts_destroy(tp, &e); return err; diff --git a/trunk/net/sched/cls_tcindex.c b/trunk/net/sched/cls_tcindex.c index 9f921174c8ab..404d9d83a7fa 100644 --- a/trunk/net/sched/cls_tcindex.c +++ b/trunk/net/sched/cls_tcindex.c @@ -194,7 +194,8 @@ __tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock) } tcf_unbind_filter(tp, &r->res); tcf_exts_destroy(tp, &r->exts); - kfree(f); + if (f) + kfree(f); return 0; } @@ -441,8 +442,10 @@ static void tcindex_destroy(struct tcf_proto *tp) walker.skip = 0; walker.fn = &tcindex_destroy_element; tcindex_walk(tp,&walker); - kfree(p->perfect); - kfree(p->h); + if (p->perfect) + kfree(p->perfect); + if (p->h) + kfree(p->h); kfree(p); tp->root = NULL; } diff --git a/trunk/net/sched/cls_u32.c b/trunk/net/sched/cls_u32.c index 2b670479dde1..364b87d86455 100644 --- a/trunk/net/sched/cls_u32.c +++ b/trunk/net/sched/cls_u32.c @@ -347,7 +347,7 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n) if (n->ht_down) n->ht_down->refcnt--; #ifdef CONFIG_CLS_U32_PERF - if (n) + if (n && (NULL != n->pf)) kfree(n->pf); #endif kfree(n); @@ -680,7 +680,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, return 0; } #ifdef CONFIG_CLS_U32_PERF - if (n) + if (n && (NULL != n->pf)) kfree(n->pf); #endif kfree(n); diff --git a/trunk/net/sched/em_meta.c b/trunk/net/sched/em_meta.c index 700844d49d79..cf68a59fdc5a 100644 --- a/trunk/net/sched/em_meta.c +++ b/trunk/net/sched/em_meta.c @@ -561,7 +561,8 @@ static int meta_var_change(struct meta_value *dst, struct rtattr *rta) static void meta_var_destroy(struct meta_value *v) { - kfree((void *) v->val); + if (v->val) + kfree((void *) v->val); } static void meta_var_apply_extras(struct meta_value *v, diff --git a/trunk/net/sched/ematch.c b/trunk/net/sched/ematch.c index 64b047c65568..ebfe2e7d21bd 100644 --- a/trunk/net/sched/ematch.c +++ b/trunk/net/sched/ematch.c @@ -298,11 +298,6 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, struct tcf_ematch_tree_hdr *tree_hdr; struct tcf_ematch *em; - if (!rta) { - memset(tree, 0, sizeof(*tree)); - return 0; - } - if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0) goto errout; diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 8c8ddf7f9b61..12b0f582a66b 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -344,7 +344,9 @@ void sctp_association_free(struct sctp_association *asoc) } /* Free peer's cached cookie. */ - kfree(asoc->peer.cookie); + if (asoc->peer.cookie) { + kfree(asoc->peer.cookie); + } /* Release the transport structures. */ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index f9573eba5c7a..660c61bdf164 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -254,7 +254,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, aiparam.adaption_ind = htonl(sp->adaption_ind); sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); nodata: - kfree(addrs.v); + if (addrs.v) + kfree(addrs.v); return retval; } @@ -346,7 +347,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, nomem_chunk: kfree(cookie); nomem_cookie: - kfree(addrs.v); + if (addrs.v) + kfree(addrs.v); return retval; } diff --git a/trunk/net/sunrpc/auth_gss/gss_krb5_seal.c b/trunk/net/sunrpc/auth_gss/gss_krb5_seal.c index d0dfdfd5e79e..13f8ae979454 100644 --- a/trunk/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/trunk/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -143,6 +143,6 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); out_err: - kfree(md5cksum.data); + if (md5cksum.data) kfree(md5cksum.data); return GSS_S_FAILURE; } diff --git a/trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c b/trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c index db055fd7d778..2030475d98ed 100644 --- a/trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/trunk/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -176,6 +176,6 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx, ret = GSS_S_COMPLETE; out: - kfree(md5cksum.data); + if (md5cksum.data) kfree(md5cksum.data); return ret; } diff --git a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c index f8bac6ccd524..b048bf672da2 100644 --- a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c @@ -60,7 +60,8 @@ gss_mech_free(struct gss_api_mech *gm) for (i = 0; i < gm->gm_pf_num; i++) { pf = &gm->gm_pfs[i]; - kfree(pf->auth_domain_name); + if (pf->auth_domain_name) + kfree(pf->auth_domain_name); pf->auth_domain_name = NULL; } } diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_seal.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_seal.c index d1e12b25d6e2..148201e929d0 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_seal.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_seal.c @@ -122,7 +122,8 @@ spkm3_make_token(struct spkm3_ctx *ctx, return GSS_S_COMPLETE; out_err: - kfree(md5cksum.data); + if (md5cksum.data) + kfree(md5cksum.data); token->data = NULL; token->len = 0; return GSS_S_FAILURE; diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c index 1f824578d773..46c08a0710f6 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c @@ -259,7 +259,8 @@ spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **ck ret = GSS_S_COMPLETE; out: - kfree(spkm3_ctx_id.data); + if (spkm3_ctx_id.data) + kfree(spkm3_ctx_id.data); return ret; } diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_unseal.c index 241d5b30dfcb..c3c0d9586103 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_unseal.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_unseal.c @@ -120,7 +120,9 @@ spkm3_read_token(struct spkm3_ctx *ctx, /* XXX: need to add expiration and sequencing */ ret = GSS_S_COMPLETE; out: - kfree(md5cksum.data); - kfree(wire_cksum.data); + if (md5cksum.data) + kfree(md5cksum.data); + if (wire_cksum.data) + kfree(wire_cksum.data); return ret; } diff --git a/trunk/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index e4296c8b861e..5a220b2bb376 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -196,9 +196,12 @@ svc_exit_thread(struct svc_rqst *rqstp) struct svc_serv *serv = rqstp->rq_server; svc_release_buffer(rqstp); - kfree(rqstp->rq_resp); - kfree(rqstp->rq_argp); - kfree(rqstp->rq_auth_data); + if (rqstp->rq_resp) + kfree(rqstp->rq_resp); + if (rqstp->rq_argp) + kfree(rqstp->rq_argp); + if (rqstp->rq_auth_data) + kfree(rqstp->rq_auth_data); kfree(rqstp); /* Release the server */ diff --git a/trunk/net/sunrpc/xdr.c b/trunk/net/sunrpc/xdr.c index aaf08cdd19f0..32df43372ee9 100644 --- a/trunk/net/sunrpc/xdr.c +++ b/trunk/net/sunrpc/xdr.c @@ -992,7 +992,8 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, err = 0; out: - kfree(elem); + if (elem) + kfree(elem); if (ppages) kunmap(*ppages); return err; diff --git a/trunk/net/wanrouter/af_wanpipe.c b/trunk/net/wanrouter/af_wanpipe.c index 59fec59b2132..596cb96e5f47 100644 --- a/trunk/net/wanrouter/af_wanpipe.c +++ b/trunk/net/wanrouter/af_wanpipe.c @@ -1099,7 +1099,7 @@ static void release_driver(struct sock *sk) sock_reset_flag(sk, SOCK_ZAPPED); wp = wp_sk(sk); - if (wp) { + if (wp && wp->mbox) { kfree(wp->mbox); wp->mbox = NULL; } @@ -1186,8 +1186,10 @@ static void wanpipe_kill_sock_timer (unsigned long data) return; } - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; + if (wp_sk(sk)) { + kfree(wp_sk(sk)); + wp_sk(sk) = NULL; + } if (atomic_read(&sk->sk_refcnt) != 1) { atomic_set(&sk->sk_refcnt, 1); @@ -1217,8 +1219,10 @@ static void wanpipe_kill_sock_accept (struct sock *sk) sk->sk_socket = NULL; - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; + if (wp_sk(sk)) { + kfree(wp_sk(sk)); + wp_sk(sk) = NULL; + } if (atomic_read(&sk->sk_refcnt) != 1) { atomic_set(&sk->sk_refcnt, 1); @@ -1239,8 +1243,10 @@ static void wanpipe_kill_sock_irq (struct sock *sk) sk->sk_socket = NULL; - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; + if (wp_sk(sk)) { + kfree(wp_sk(sk)); + wp_sk(sk) = NULL; + } if (atomic_read(&sk->sk_refcnt) != 1) { atomic_set(&sk->sk_refcnt, 1); diff --git a/trunk/net/wanrouter/wanmain.c b/trunk/net/wanrouter/wanmain.c index bcf7b3faa76a..13b650ad22e2 100644 --- a/trunk/net/wanrouter/wanmain.c +++ b/trunk/net/wanrouter/wanmain.c @@ -714,8 +714,10 @@ static int wanrouter_device_new_if(struct wan_device *wandev, } /* This code has moved from del_if() function */ - kfree(dev->priv); - dev->priv = NULL; + if (dev->priv) { + kfree(dev->priv); + dev->priv = NULL; + } #ifdef CONFIG_WANPIPE_MULTPPP if (cnf->config_id == WANCONFIG_MPPP) @@ -849,8 +851,10 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name) /* Due to new interface linking method using dev->priv, * this code has moved from del_if() function.*/ - kfree(dev->priv); - dev->priv=NULL; + if (dev->priv){ + kfree(dev->priv); + dev->priv=NULL; + } unregister_netdev(dev); diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 7cf48aa6c95b..8b9a4747417d 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -62,10 +62,14 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) { if (del_timer(&x->timer)) BUG(); - kfree(x->aalg); - kfree(x->ealg); - kfree(x->calg); - kfree(x->encap); + if (x->aalg) + kfree(x->aalg); + if (x->ealg) + kfree(x->ealg); + if (x->calg) + kfree(x->calg); + if (x->encap) + kfree(x->encap); if (x->type) { x->type->destructor(x); xfrm_put_type(x->type);