Merge master.kernel.org:/home/rmk/linux-2.6-serial
authorLinus Torvalds <torvalds@g5.osdl.org>
Wed, 9 Nov 2005 00:04:39 +0000 (16:04 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 9 Nov 2005 00:04:39 +0000 (16:04 -0800)
105 files changed:
Documentation/connector/cn_test.c
arch/arm/Kconfig
arch/arm/boot/compressed/misc.c
arch/arm/common/scoop.c
arch/arm/kernel/armksyms.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/irq.c
arch/arm/kernel/smp.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-realview/core.c
arch/arm/mach-realview/platsmp.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-sa1100/time.c
arch/sparc64/mm/fault.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/hci_usb.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/irda/donauboe.c
drivers/net/ppp_async.c
drivers/net/ppp_generic.c
drivers/net/ppp_mppe.c [new file with mode: 0644]
drivers/net/ppp_mppe.h [new file with mode: 0644]
drivers/pcmcia/pxa2xx_sharpsl.c
drivers/sbus/char/openprom.c
drivers/video/amba-clcd.c
fs/exec.c
include/asm-arm/arch-s3c2410/uncompress.h
include/asm-arm/hardirq.h
include/asm-arm/hardware/scoop.h
include/asm-arm/smp.h
include/linux/if_ppp.h
include/linux/ppp-comp.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/rfcomm.h
include/net/ipv6.h
include/net/sock.h
net/802/p8023.c
net/ax25/af_ax25.c
net/ax25/ax25_in.c
net/ax25/ax25_route.c
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/core/dev_mcast.c
net/core/sock.c
net/dccp/ipv4.c
net/dccp/proto.c
net/decnet/dn_table.c
net/ethernet/pe2.c
net/ipv4/af_inet.c
net/ipv4/fib_frontend.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipvs/ip_vs_app.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/multipath_wrandom.c
net/ipv4/netfilter/ip_nat_snmp_basic.c
net/ipv4/tcp_ipv4.c
net/ipv6/addrconf.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ipv6_syms.c
net/irda/discovery.c
net/irda/irias_object.c
net/rose/rose_route.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/em_meta.c
net/sched/ematch.c
net/sctp/associola.c
net/sctp/sm_make_chunk.c
net/sunrpc/auth_gss/gss_krb5_seal.c
net/sunrpc/auth_gss/gss_krb5_unseal.c
net/sunrpc/auth_gss/gss_mech_switch.c
net/sunrpc/auth_gss/gss_spkm3_seal.c
net/sunrpc/auth_gss/gss_spkm3_token.c
net/sunrpc/auth_gss/gss_spkm3_unseal.c
net/sunrpc/svc.c
net/sunrpc/xdr.c
net/wanrouter/af_wanpipe.c
net/wanrouter/wanmain.c
net/xfrm/xfrm_state.c

index b7de82e9c0e014aeff8fecfb3e7b271821b4598c..3e73231695b3107eb743452836e8d0b24d17af85 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/skbuff.h>
 #include <linux/timer.h>
 
-#include "connector.h"
+#include <linux/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_groups = ctl->group;
+       NETLINK_CB(skb).dst_group = ctl->group;
        //netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
        netlink_unicast(nls, skb, 0, 0);
 
index 91d5ef3397be3d56f643dc5fb21eaa4315303499..3bfef0934c9d39162e346e73764f379aad8946f4 100644 (file)
@@ -356,6 +356,16 @@ config HOTPLUG_CPU
          Say Y here to experiment with turning CPUs off and on.  CPUs
          can be controlled through /sys/devices/system/cpu.
 
+config LOCAL_TIMERS
+       bool "Use local timer interrupts"
+       depends on SMP && n
+       default y
+       help
+         Enable support for local timers on SMP platforms, rather then the
+         legacy IPI broadcast method.  Local timers allows the system
+         accounting to be spread across the timer interval, preventing a
+         "thundering herd" at every timer tick.
+
 config PREEMPT
        bool "Preemptible Kernel (EXPERIMENTAL)"
        depends on EXPERIMENTAL
index 50f13eec6cd70cd4c2e0a93233af141027211529..5ab94584baee6a46839e58819a9b443422c2a923 100644 (file)
@@ -283,8 +283,14 @@ 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");
index bb4eff61441307458f92a104b0fa655542e118b7..c7fdf390cef9cbf20325431ea092d07c658f7f18 100644 (file)
 
 #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;
index 7b17a87a3311af3ece561f3cbc19debf459e4a8c..7a3261f0bf79012e158e81eab69e7f633d56b4c6 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/cryptohash.h>
 #include <linux/delay.h>
 #include <linux/in6.h>
 #include <linux/syscalls.h>
@@ -126,6 +127,9 @@ 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);
index a511ec5b11a33344c945b66811b889c0a91bf084..d9fb819bf7cc3960aedb4b9836451371458a4893 100644 (file)
        movne   r0, sp
        adrne   lr, 1b
        bne     do_IPI
+
+#ifdef CONFIG_LOCAL_TIMERS
+       test_for_ltirq r0, r6, r5, lr
+       movne   r0, sp
+       adrne   lr, 1b
+       bne     do_local_timer
+#endif
 #endif
 
        .endm
index 9def4404e1f27607e46931d4e093725d705d843a..d7099dbbb879ab8cd9ed6c417bdcc87d461dd747 100644 (file)
@@ -264,6 +264,7 @@ unlock:
 #endif
 #ifdef CONFIG_SMP
                show_ipi_list(p);
+               show_local_irqs(p);
 #endif
                seq_printf(p, "Err: %10lu\n", irq_err_count);
        }
@@ -995,7 +996,7 @@ void __init init_irq_proc(void)
        struct proc_dir_entry *dir;
        int irq;
 
-       dir = proc_mkdir("irq", 0);
+       dir = proc_mkdir("irq", NULL);
        if (!dir)
                return;
 
index edb5a406922f3953b02f3f5ba148d3b438585588..77e2e9ca89fab8477cdb13567d1c992c2e1c7d8b 100644 (file)
@@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
                        ret = -EIO;
        }
 
-       secondary_data.stack = 0;
+       secondary_data.stack = NULL;
        secondary_data.pgdir = 0;
 
        *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
@@ -184,6 +184,11 @@ int __cpuexit __cpu_disable(void)
         */
        migrate_irqs();
 
+       /*
+        * Stop the local timer for this CPU.
+        */
+       local_timer_stop(cpu);
+
        /*
         * Flush user cache and TLB mappings, and then remove this CPU
         * from the vm mask set of all processes.
@@ -289,6 +294,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
         */
        cpu_set(cpu, cpu_online_map);
 
+       /*
+        * Setup local timer for this CPU.
+        */
+       local_timer_setup(cpu);
+
        /*
         * OK, it's off to the idle thread for us
         */
@@ -359,8 +369,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
  * You must not call this function with disabled interrupts, from a
  * hardware interrupt handler, nor from a bottom half handler.
  */
-int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry,
-                             int wait, cpumask_t callmap)
+static int smp_call_function_on_cpu(void (*func)(void *info), void *info,
+                                   int retry, int wait, cpumask_t callmap)
 {
        struct smp_call_struct data;
        unsigned long timeout;
@@ -454,6 +464,18 @@ void show_ipi_list(struct seq_file *p)
        seq_putc(p, '\n');
 }
 
+void show_local_irqs(struct seq_file *p)
+{
+       unsigned int cpu;
+
+       seq_printf(p, "LOC: ");
+
+       for_each_present_cpu(cpu)
+               seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
+
+       seq_putc(p, '\n');
+}
+
 static void ipi_timer(struct pt_regs *regs)
 {
        int user = user_mode(regs);
@@ -464,6 +486,18 @@ static void ipi_timer(struct pt_regs *regs)
        irq_exit();
 }
 
+#ifdef CONFIG_LOCAL_TIMERS
+asmlinkage void do_local_timer(struct pt_regs *regs)
+{
+       int cpu = smp_processor_id();
+
+       if (local_timer_ack()) {
+               irq_stat[cpu].local_timer_irqs++;
+               ipi_timer(regs);
+       }
+}
+#endif
+
 /*
  * ipi_call_function - handle IPI from smp_call_function()
  *
@@ -515,7 +549,7 @@ static void ipi_cpu_stop(unsigned int cpu)
  *
  *  Bit 0 - Inter-processor function call
  */
-void do_IPI(struct pt_regs *regs)
+asmlinkage void do_IPI(struct pt_regs *regs)
 {
        unsigned int cpu = smp_processor_id();
        struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
index eb5f6d744a4a77778d290ba063b18cccd01973d5..100fb31b5156df4a9cb3e6b0372ef2736d23d7e0 100644 (file)
@@ -62,6 +62,37 @@ 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,
@@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
 },
 };
 
-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 struct scoop_pcmcia_config corgi_pcmcia_config = {
+       .devs         = &corgi_pcmcia_scoop[0],
+       .num_devs     = 1,
+       .pcmcia_init  = corgi_pcmcia_init,
 };
 
+EXPORT_SYMBOL(corgiscoop_device);
+
 
 /*
  * Corgi SSP Device
@@ -294,8 +323,7 @@ static void __init corgi_init(void)
        pxa_set_mci_info(&corgi_mci_platform_data);
        pxa_set_ficp_info(&corgi_ficp_platform_data);
 
-       scoop_num = 1;
-       scoop_devs = &corgi_pcmcia_scoop[0];
+       platform_scoop_config = &corgi_pcmcia_config;
 
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
index ad6a13f95a62cfcae51bc94ffc2fd1f243f17be7..eef3de26ad3704dba4604255abcf13bb3942b16a 100644 (file)
@@ -65,6 +65,27 @@ 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,
@@ -74,6 +95,14 @@ 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[] = {
@@ -268,8 +297,7 @@ static void __init poodle_init(void)
        pxa_set_mci_info(&poodle_mci_platform_data);
        pxa_set_ficp_info(&poodle_ficp_platform_data);
 
-       scoop_num = 1;
-       scoop_devs = &poodle_pcmcia_scoop[0];
+       platform_scoop_config = &poodle_pcmcia_config;
 
        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        if (ret) {
index 6c6878cd2207db94f3b70343beef634fbb6491f2..4e9a699ee4280e61560a5672e9bd6c276c36a284 100644 (file)
@@ -104,6 +104,66 @@ 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,
@@ -117,6 +177,16 @@ 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
@@ -235,27 +305,14 @@ 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;
 
-       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);
-               }
-       }
+       if (( 1 << vdd) & p_d->ocr_mask)
+               spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004);
+       else
+               spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
 }
 
 static int spitz_mci_get_ro(struct device *dev)
@@ -351,8 +408,8 @@ static void __init common_init(void)
 
 static void __init spitz_init(void)
 {
-       scoop_num = 2;
-       scoop_devs = &spitz_pcmcia_scoop[0];
+       platform_scoop_config = &spitz_pcmcia_config;
+
        spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
 
        common_init();
index 7dad3f1465e076028954b1f18169ed8b82b2502e..b9b2057349ebe9a1738fd327ab668bd11decb4e7 100644 (file)
@@ -132,11 +132,13 @@ static void __init pxa_timer_init(void)
        tv.tv_sec = pxa_get_rtc_time();
        do_settimeofday(&tv);
 
-       OSMR0 = 0;              /* set initial match at 0 */
+       OIER = 0;               /* disable any timer interrupts */
+       OSCR = LATCH*2;         /* push OSCR out of the way */
+       OSMR0 = LATCH;          /* set initial match */
        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, force first match */
+       OIER = OIER_E0;         /* enable match on timer 0 to cause interrupts */
+       OSCR = 0;               /* initialize free-running timer */
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
index 400609f8b6a85e3703e5b64933bbfd0373d47a00..c312054dfb8872b3e2af9a1065fdd227488af969 100644 (file)
@@ -98,6 +98,9 @@ struct platform_device tosascoop_jc_device = {
        .resource       = tosa_scoop_jc_resources,
 };
 
+/*
+ * PCMCIA
+ */
 static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
 {
        .dev        = &tosascoop_device.dev,
@@ -111,16 +114,155 @@ 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;
@@ -131,13 +273,15 @@ static void __init tosa_init(void)
        PGSR2 = 0x00014000;
        PCFR |= PCFR_OPDE;
 
-       // enable batt_fault
+       /* enable batt_fault */
        PMCR = 0x01;
 
-       platform_add_devices(devices, ARRAY_SIZE(devices));
+       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;
 
-       scoop_num = 2;
-       scoop_devs = &tosa_pcmcia_scoop[0];
+       platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 static void __init fixup_tosa(struct machine_desc *desc,
index 482eb512ebe8a79d0b38d1989b39e68d77ac4add..4ea60d8b6e36838bdd5deb72955732297edf6cf9 100644 (file)
@@ -550,6 +550,11 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
 
        timer_tick(regs);
 
+#ifdef CONFIG_SMP
+       smp_send_timer();
+       update_process_times(user_mode(regs));
+#endif
+
        write_sequnlock(&xtime_lock);
 
        return IRQ_HANDLED;
index 9844644d0fb5c69400c76588ca4d24ed19d550f8..09b35f62247a8863c268ec0ae4c1b3d3259c1d1d 100644 (file)
@@ -32,7 +32,7 @@ static unsigned int __init get_core_count(void)
 {
        unsigned int ncores;
 
-       ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
+       ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
 
        return (ncores & 0x03) + 1;
 }
@@ -133,12 +133,12 @@ static void __init poke_milo(void)
 #if 1
 #define REALVIEW_SYS_FLAGSS_OFFSET 0x30
        __raw_writel(virt_to_phys(realview_secondary_startup),
-                    (IO_ADDRESS(REALVIEW_SYS_BASE) +
-                     REALVIEW_SYS_FLAGSS_OFFSET));
+                    __io_address(REALVIEW_SYS_BASE) +
+                    REALVIEW_SYS_FLAGSS_OFFSET);
 #define REALVIEW_SYS_FLAGSC_OFFSET 0x34
        __raw_writel(3,
-                    (IO_ADDRESS(REALVIEW_SYS_BASE) +
-                     REALVIEW_SYS_FLAGSC_OFFSET));
+                    __io_address(REALVIEW_SYS_BASE) +
+                    REALVIEW_SYS_FLAGSC_OFFSET);
 #endif
 
        mb();
index c796bcdd6158208c77cc1f97b7bfbb8a12ca6573..0b9d7ca49ec1ff9f9520cc02c845c0c8990c30b1 100644 (file)
@@ -121,6 +121,14 @@ 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
index 0b71c896bbd1ac5fe5ebb9ae55487cf01992e9d4..1be2567a7486606039f1f36902d97fad891b0aaf 100644 (file)
 
 /* macros to modify the physical addresses for io space */
 
-#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)
+#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))
 
 static struct map_desc bast_iodesc[] __initdata = {
   /* ISA IO areas */
-
-  { (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
-   */
-
+  {
+         .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,
+  },
   /* bast CPLD control registers, and external interrupt controls */
-  { (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 },
-
+  {
+         .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,
+  },
   /* PC104 IRQ mux */
-  { (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 },
+  {
+         .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,
+  },
 
   /* peripheral space... one for each of fast/slow/byte/16bit */
   /* note, ide is only decoded in word space, even though some registers
index 46b259673c18156606f6ffb190ce69790d4b5274..ae7e099bf6c80521eaf32cd9279881642dbea94d 100644 (file)
 
 /* macros to modify the physical addresses for io space */
 
-#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)
+#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))
 
 static struct map_desc vr1000_iodesc[] __initdata = {
   /* ISA IO areas */
-
-  { (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 },
+  {
+         .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,
+  },
 
   /* peripheral space... one for each of fast/slow/byte/16bit */
   /* note, ide is only decoded in word space, even though some registers
index 47e0420623fc25083a486f74887bff522260108b..e4b435e634e41a657321360a5c6d22173ad98fc6 100644 (file)
@@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void)
        tv.tv_sec = sa1100_get_rtc_time();
        do_settimeofday(&tv);
 
-       OSMR0 = 0;              /* set initial match at 0 */
+       OIER = 0;               /* disable any timer interrupts */
+       OSCR = LATCH*2;         /* push OSCR out of the way */
+       OSMR0 = LATCH;          /* set initial match */
        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, force first match */
+       OIER = OIER_E0;         /* enable match on timer 0 to cause interrupts */
+       OSCR = 0;               /* initialize free-running timer */
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
index 31fbc67719a1f653f643c346615a261173541a98..3be278d916dbcaeb679fafdefc3f03cb01a78c16 100644 (file)
@@ -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. This saves us having to get page_table_lock.
+ * us. vmtruncate likewise. This saves us having to get pte lock.
  */
 static unsigned int get_user_insn(unsigned long tpc)
 {
index ecbeb7eaba8e25c3c45ee0a8de1cd8163a8446b8..394796315adcb18decd1ca61d13b62e1aae4ffe6 100644 (file)
@@ -84,8 +84,8 @@ struct bpa10x_data {
 
 struct hci_vendor_hdr {
        __u8    type;
-       __u16   snum;
-       __u16   dlen;
+       __le16  snum;
+       __le16  dlen;
 } __attribute__ ((packed));
 
 static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
index f510b25b2c59010c0967e4488eebccbeaee994cc..057cb2b6e6d1f537723051c122eca2d59fec0c82 100644 (file)
@@ -65,6 +65,7 @@
 #endif
 
 static int ignore = 0;
+static int ignore_dga = 0;
 static int ignore_csr = 0;
 static int ignore_sniffer = 0;
 static int reset = 0;
@@ -841,6 +842,9 @@ 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;
 
@@ -1070,6 +1074,9 @@ 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");
 
index 1958d9e16a3aaaa606541ee56173b5811a286c5c..24f1691b84f90d37b684acb665efc66a12f40d8f 100644 (file)
@@ -2523,6 +2523,19 @@ 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
index 7c313cb341b8874866b9f279141f70d6ed8d8d6a..4cffd34442aafaddc00865df86c26f410ccd61a2 100644 (file)
@@ -112,6 +112,7 @@ 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
index 0282771b1cbb3ca27d625c0b8b60dc8810672fcb..3137592d60c01816f3bb03bb0d4bd05227432f99 100644 (file)
@@ -1459,8 +1459,10 @@ 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))
-        return -EPERM;
+      if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
+       ret = -EPERM;
+       goto out;
+      }
 
       /* self->speed=irq->ifr_baudrate; */
       /* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ 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))
-        return -EPERM;
+      if (!capable (CAP_NET_ADMIN)) {
+       ret = -EPERM;
+       goto out;
+      }
       irda_device_set_media_busy (self->netdev, TRUE);
       break;
     case SIOCGRECEIVING:       /* Check if we are receiving right now */
@@ -1483,7 +1487,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;
 
index 59e8183c639e0be7e9a07dc9c8295d5bd78281e6..400f652282d76f4fe7c0d003ca0ec1f22d3da27f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
+#include <asm/string.h>
 
 #define PPP_VERSION    "2.4.2"
 
@@ -835,8 +836,11 @@ 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)
+       if (skb) {
+               /* make skb appear as freshly allocated */
                skb_trim(skb, 0);
+               skb_reserve(skb, - skb_headroom(skb));
+       }
 }
 
 /* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
                                skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
                                if (skb == 0)
                                        goto nomem;
-                               /* Try to get the payload 4-byte aligned */
+                               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].
+                                */
                                if (buf[0] != PPP_ALLSTATIONS)
                                        skb_reserve(skb, 2 + (buf[0] & 1));
-                               ap->rpkt = skb;
                        }
                        if (n > skb_tailroom(skb)) {
                                /* packet overflowed MRU */
index d3c9958b00d06db4895a7d6e2b54a58726c2e088..50430f79f8cf8190541e47495d625cae0cd7a765 100644 (file)
@@ -137,13 +137,14 @@ 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_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
+ * SC_MUST_COMP
  * 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_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
 
 /*
  * Private data structure for each channel.
@@ -1027,6 +1028,56 @@ 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,
@@ -1113,29 +1164,14 @@ 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) {
-               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");
+               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");
                        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);
-               }
+               skb = pad_compress_skb(ppp, skb);
+               if (!skb)
+                       goto drop;
        }
 
        /*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
        return;
 
  drop:
-       kfree_skb(skb);
+       if (skb)
+               kfree_skb(skb);
        ++ppp->stats.tx_errors;
 }
 
@@ -1552,6 +1589,9 @@ 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/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
new file mode 100644 (file)
index 0000000..1985d1b
--- /dev/null
@@ -0,0 +1,724 @@
+/*
+ * ppp_mppe.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.6.14+
+ *
+ * By Frank Cusack <fcusack@fcusack.com>.
+ * 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 <Matt_Domsch@dell.com>
+ *                 Only need extra skb padding on transmit, not receive.
+ *      06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
+ *                 Use Linux kernel 2.6 arc4 and sha1 routines rather than
+ *                 providing our own.
+ *      2/15/04 - TS: added #include <version.h> and testing for Kernel
+ *                    version before using
+ *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
+ *                    deprecated in 2.6
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include <asm/scatterlist.h>
+
+#include "ppp_mppe.h"
+
+MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
+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/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
new file mode 100644 (file)
index 0000000..7a14e05
--- /dev/null
@@ -0,0 +1,86 @@
+#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)
index fe5ea36e7de3878e63b7819cab7872c89d8acd49..56c58831e80e593eae62c2e33744fcd508ad7cd2 100644 (file)
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/hardware/scoop.h>
-#ifdef CONFIG_SA1100_COLLIE
-#include <asm/arch-sa1100/collie.h>
-#else
-#include <asm/arch-pxa/pxa-regs.h>
-#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);
@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
 
-#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
+       if (platform_scoop_config->pcmcia_init)
+               platform_scoop_config->pcmcia_init();
 
        /* Register interrupts */
-       if (scoop_devs[skt->nr].cd_irq >= 0) {
+       if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
                struct pcmcia_irqs cd_irq;
 
                cd_irq.sock = skt->nr;
-               cd_irq.irq  = scoop_devs[skt->nr].cd_irq;
-               cd_irq.str  = scoop_devs[skt->nr].cd_irq_str;
+               cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
+               cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
                ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
 
                if (ret) {
@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                }
        }
 
-       skt->irq = scoop_devs[skt->nr].irq;
+       skt->irq = SCOOP_DEV[skt->nr].irq;
 
        return 0;
 }
 
 static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       if (scoop_devs[skt->nr].cd_irq >= 0) {
+       if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
                struct pcmcia_irqs cd_irq;
 
                cd_irq.sock = skt->nr;
-               cd_irq.irq  = scoop_devs[skt->nr].cd_irq;
-               cd_irq.str  = scoop_devs[skt->nr].cd_irq_str;
+               cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
+               cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
                soc_pcmcia_free_irqs(skt, &cd_irq, 1);
        }
 }
@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                    struct pcmcia_state *state)
 {
        unsigned short cpr, csr;
-       struct device *scoop = scoop_devs[skt->nr].dev;
+       struct device *scoop = SCOOP_DEV[skt->nr].dev;
 
-       cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR);
+       cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
 
        write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
        write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
        if (csr & 0x0004) {
                /* card eject */
                write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
-               scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
+               SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
        }
-       else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) {
+       else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
                /* keep vs1,vs2 */
                write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
-               csr |= scoop_devs[skt->nr].keep_vs;
+               csr |= SCOOP_DEV[skt->nr].keep_vs;
        }
        else if (cpr & 0x0003) {
                /* power on */
                write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
-               scoop_devs[skt->nr].keep_vs = (csr & 0x00C0);
+               SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
        }
        else {
                /* card detect */
-               write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
+               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);
+               }
        }
 
        state->detect = (csr & 0x0004) ? 0 : 1;
@@ -144,7 +130,6 @@ 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);
        }
-
 }
 
 
@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                       const socket_state_t *state)
 {
        unsigned long flags;
-       struct device *scoop = scoop_devs[skt->nr].dev;
+       struct device *scoop = SCOOP_DEV[skt->nr].dev;
 
        unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
 
@@ -177,8 +162,13 @@ 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;
 
-       ncpr |= (state->Vcc == 33) ? 0x0001 :
-                               (state->Vcc == 50) ? 0x0002 : 0;
+       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;
+       }
        nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
        ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
        nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                        ((skt->status&SS_WRPROT) ? 0x0008 : 0);
 
        if (!(ncpr & 0x0003)) {
-               scoop_devs[skt->nr].keep_rd = 0;
-       } else if (!scoop_devs[skt->nr].keep_rd) {
+               SCOOP_DEV[skt->nr].keep_rd = 0;
+       } else if (!SCOOP_DEV[skt->nr].keep_rd) {
                if (nccr & 0x0080)
-                       scoop_devs[skt->nr].keep_rd = 1;
+                       SCOOP_DEV[skt->nr].keep_rd = 1;
                else
                        nccr |= 0x0080;
        }
 
        if (mcr != nmcr)
                write_scoop_reg(scoop, SCOOP_MCR, nmcr);
-       if (cpr != ncpr)
-               write_scoop_reg(scoop, SCOOP_CPR, ncpr);
+       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 (ccr != nccr)
                write_scoop_reg(scoop, SCOOP_CCR, nccr);
        if (imr != nimr)
@@ -214,43 +208,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_devs[skt->nr]);
+       sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
 
        /* Enable interrupt */
-       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;
+       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;
 
        if (machine_is_collie())
                /* We need to disable SS_OUTPUT_ENA here. */
-               write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+               write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[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_devs[skt->nr]);
+       sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
 
        if (machine_is_collie())
                /* We need to disable SS_OUTPUT_ENA here. */
-               write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+               write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[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,
 };
 
-static struct platform_device *sharpsl_pcmcia_device;
-
 #ifdef CONFIG_SA1100_COLLIE
+#include "sa11xx_base.h"
+
 int __init pcmcia_collie_init(struct device *dev)
 {
        int ret = -ENODEV;
@@ -263,11 +257,13 @@ 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=scoop_num;
+       sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
        sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
        if (!sharpsl_pcmcia_device)
                return -ENOMEM;
@@ -275,7 +271,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=scoop_devs[0].dev;
+       sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
 
        ret = platform_device_register(sharpsl_pcmcia_device);
        if (ret)
index 5028ac2143262d44418d758682c31c766f6bd21f..383a95f34a0da4e8adec682df992786d572efe27 100644 (file)
@@ -596,6 +596,8 @@ 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)
@@ -623,6 +625,7 @@ 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,
 };
index 467a1d7ebbdecdf14f129a34c172e8e0ae5ae5d9..a3c2c45e29e03e7d9e42a64036501904305ee4df 100644 (file)
@@ -518,7 +518,7 @@ static struct amba_driver clcd_driver = {
        .id_table       = clcdfb_id_table,
 };
 
-int __init amba_clcdfb_init(void)
+static int __init amba_clcdfb_init(void)
 {
        if (fb_get_options("ambafb", NULL))
                return -ENODEV;
index cd6c574557dc19a0b405d7fac06bc166db72a830..5a4e3acc2e9fcfc549cf2d0330cb80c919e37c6a 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -590,6 +590,7 @@ 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;
 
        /*
@@ -665,7 +666,7 @@ static inline int de_thread(struct task_struct *tsk)
         * and to assume its PID:
         */
        if (!thread_group_leader(current)) {
-               struct task_struct *leader = current->group_leader, *parent;
+               struct task_struct *parent;
                struct dentry *proc_dentry1, *proc_dentry2;
                unsigned long exit_state, ptrace;
 
@@ -674,6 +675,7 @@ 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();
 
@@ -733,7 +735,6 @@ static inline int de_thread(struct task_struct *tsk)
                proc_pid_flush(proc_dentry2);
 
                BUG_ON(exit_state != EXIT_ZOMBIE);
-               release_task(leader);
         }
 
        /*
@@ -743,8 +744,11 @@ static inline int de_thread(struct task_struct *tsk)
        sig->flags = 0;
 
 no_thread_group:
-       BUG_ON(atomic_read(&sig->count) != 1);
        exit_itimers(sig);
+       if (leader)
+               release_task(leader);
+
+       BUG_ON(atomic_read(&sig->count) != 1);
 
        if (atomic_read(&oldsighand->count) == 1) {
                /*
index d7a4a8354fa9854be8a2bc23203a0336b57b93fa..ddd1578a7ee0a40d2877434176f7718797c9b1a4 100644 (file)
@@ -116,6 +116,8 @@ 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
@@ -126,8 +128,6 @@ 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,6 +145,24 @@ 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
index e5ccb6b8ff83c60700f57db2279de77fac382454..1cbb173bf5b108b2d136a78961ed7ffc873dc276 100644 (file)
@@ -8,6 +8,7 @@
 
 typedef struct {
        unsigned int __softirq_pending;
+       unsigned int local_timer_irqs;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
index a8f1013930e363140381c9f9385b63885b0dd774..d37bf7443264c347141ae9550dfbda9d59dedd85 100644 (file)
@@ -52,8 +52,14 @@ struct scoop_pcmcia_dev {
        unsigned char keep_rd;
 };
 
-extern int scoop_num;
-extern struct scoop_pcmcia_dev *scoop_devs;
+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;
 
 void reset_scoop(struct device *dev);
 unsigned short set_scoop_gpio(struct device *dev, unsigned short bit);
index 551cd3c3093cd8bde19f3a435e46ca4a86d446a4..5a72e50ca9fc0ab5f1640d5ba975ee155851e14e 100644 (file)
@@ -36,6 +36,11 @@ struct seq_file;
  */
 extern void show_ipi_list(struct seq_file *p);
 
+/*
+ * Called from assembly code, this handles an IPI.
+ */
+asmlinkage void do_IPI(struct pt_regs *regs);
+
 /*
  * Move global data into per-processor storage.
  */
@@ -46,12 +51,23 @@ extern void smp_store_cpu_info(unsigned int cpuid);
  */
 extern void smp_cross_call(cpumask_t callmap);
 
+/*
+ * Broadcast a timer interrupt to the other CPUs.
+ */
+extern void smp_send_timer(void);
+
 /*
  * Boot a secondary CPU, and assign it the specified idle task.
  * This also gives us the initial stack to use for this CPU.
  */
 extern int boot_secondary(unsigned int cpu, struct task_struct *);
 
+/*
+ * Called from platform specific assembly code, this is the
+ * secondary CPU entry point.
+ */
+asmlinkage void secondary_start_kernel(void);
+
 /*
  * Perform platform specific initialisation of the specified CPU.
  */
@@ -76,4 +92,42 @@ extern void platform_cpu_die(unsigned int cpu);
 extern int platform_cpu_kill(unsigned int cpu);
 extern void platform_cpu_enable(unsigned int cpu);
 
+#ifdef CONFIG_LOCAL_TIMERS
+/*
+ * Setup a local timer interrupt for a CPU.
+ */
+extern void local_timer_setup(unsigned int cpu);
+
+/*
+ * Stop a local timer interrupt.
+ */
+extern void local_timer_stop(unsigned int cpu);
+
+/*
+ * Platform provides this to acknowledge a local timer IRQ
+ */
+extern int local_timer_ack(void);
+
+#else
+
+static inline void local_timer_setup(unsigned int cpu)
+{
+}
+
+static inline void local_timer_stop(unsigned int cpu)
+{
+}
+
+#endif
+
+/*
+ * show local interrupt info
+ */
+extern void show_local_irqs(struct seq_file *);
+
+/*
+ * Called from assembly, this is the local timer IRQ handler
+ */
+asmlinkage void do_local_timer(struct pt_regs *);
+
 #endif /* ifndef __ASM_ARM_SMP_H */
index 572aff7daa216fd9956407f6bae82bad480ca5da..768372f07caab7928a284acf592174608eb87213 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /*
- *  ==FILEVERSION 20000724==
+ *  ==FILEVERSION 20050812==
  *
  *  NOTE TO MAINTAINERS:
  *     If you modify this file at all, please set the above date.
@@ -35,6 +35,8 @@
 #ifndef _IF_PPP_H_
 #define _IF_PPP_H_
 
+#include <linux/compiler.h>
+
 /*
  * Packet sizes
  */
@@ -70,7 +72,8 @@
 #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_MASK         0x0f200fff      /* bits that user can change */
+#define        SC_MUST_COMP    0x00400000      /* no uncompressed packets may be sent or received */
+#define        SC_MASK         0x0f600fff      /* bits that user can change */
 
 /* state bits */
 #define SC_XMIT_BUSY   0x10000000      /* (used by isdn_ppp?) */
index 7227e653b3beacdb7e496196e86b08f821671772..e86a7a5cf355ce3135e3351f9bec314fbbb24b24 100644 (file)
@@ -111,6 +111,8 @@ struct compressor {
 
        /* Used in locking compressor modules */
        struct module *owner;
+       /* Extra skb space needed by the compressor algorithm */
+       unsigned int comp_extra;
 };
 
 /*
@@ -190,6 +192,13 @@ 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.
  */
index e42d728b16208d70d1398ec5f1bada1cca4401ea..911ceb5cd263b51c90eee3e5803cee3206a88bd8 100644 (file)
@@ -57,8 +57,6 @@
 #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 */
@@ -177,4 +175,6 @@ 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 */
index fa2d12b0579b49fc9c5e480c65a931ad36c784a5..b06a2d2f63d2dd3d8aaef4b7f7ad22431609a64d 100644 (file)
@@ -184,10 +184,10 @@ enum {
 struct hci_rp_read_loc_version {
        __u8     status;
        __u8     hci_ver;
-       __u16    hci_rev;
+       __le16   hci_rev;
        __u8     lmp_ver;
-       __u16    manufacturer;
-       __u16    lmp_subver;
+       __le16   manufacturer;
+       __le16   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;
-       __u16    acl_mtu;
+       __le16   acl_mtu;
        __u8     sco_mtu;
-       __u16    acl_max_pkt;
-       __u16    sco_max_pkt;
+       __le16   acl_max_pkt;
+       __le16   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;
-       __u16   voice_setting;
+       __u8     status;
+       __le16   voice_setting;
 } __attribute__ ((packed));
 
 #define OCF_WRITE_VOICE_SETTING        0x0026
 struct hci_cp_write_voice_setting {
-       __u16   voice_setting;
+       __le16   voice_setting;
 } __attribute__ ((packed));
 
 #define OCF_HOST_BUFFER_SIZE   0x0033
 struct hci_cp_host_buffer_size {
-       __u16    acl_mtu;
+       __le16   acl_mtu;
        __u8     sco_mtu;
-       __u16    acl_max_pkt;
-       __u16    sco_max_pkt;
+       __le16   acl_max_pkt;
+       __le16   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;
-       __u16    pkt_type;
+       __le16   pkt_type;
        __u8     pscan_rep_mode;
        __u8     pscan_mode;
-       __u16    clock_offset;
+       __le16   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 {
-       __u16    handle;
+       __le16   handle;
        __u8     reason;
 } __attribute__ ((packed));
 
 #define OCF_ADD_SCO    0x0007
 struct hci_cp_add_sco {
-       __u16    handle;
-       __u16    pkt_type;
+       __le16   handle;
+       __le16   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 {
-       __u16    handle;
-       __u16    pkt_type;
+       __le16   handle;
+       __le16   pkt_type;
 } __attribute__ ((packed));
 
 #define OCF_AUTH_REQUESTED     0x0011
 struct hci_cp_auth_requested {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 #define OCF_SET_CONN_ENCRYPT   0x0013
 struct hci_cp_set_conn_encrypt {
-       __u16    handle;
+       __le16   handle;
        __u8     encrypt;
 } __attribute__ ((packed));
 
 #define OCF_CHANGE_CONN_LINK_KEY 0x0015
 struct hci_cp_change_conn_link_key {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 #define OCF_READ_REMOTE_FEATURES 0x001B
 struct hci_cp_read_rmt_features {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 #define OCF_READ_REMOTE_VERSION 0x001D
 struct hci_cp_read_rmt_version {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 /* Link Policy */
 #define OGF_LINK_POLICY         0x02   
 #define OCF_ROLE_DISCOVERY     0x0009
 struct hci_cp_role_discovery {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 struct hci_rp_role_discovery {
        __u8     status;
-       __u16    handle;
+       __le16   handle;
        __u8     role;
 } __attribute__ ((packed));
 
 #define OCF_READ_LINK_POLICY   0x000C
 struct hci_cp_read_link_policy {
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 struct hci_rp_read_link_policy {
        __u8     status;
-       __u16    handle;
-       __u16    policy;
+       __le16   handle;
+       __le16   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 {
-       __u16    handle;
-       __u16    policy;
+       __le16   handle;
+       __le16   policy;
 } __attribute__ ((packed));
 struct hci_rp_write_link_policy {
        __u8     status;
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 /* Status params */
@@ -441,7 +441,7 @@ struct inquiry_info {
        __u8     pscan_period_mode;
        __u8     pscan_mode;
        __u8     dev_class[3];
-       __u16    clock_offset;
+       __le16   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];
-       __u16    clock_offset;
+       __le16   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];
-       __u16    clock_offset;
+       __le16   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];
-       __u16    clock_offset;
+       __le16   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;
-       __u16    handle;
+       __le16   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;
-       __u16    handle;
+       __le16   handle;
        __u8     reason;
 } __attribute__ ((packed));
 
 #define HCI_EV_AUTH_COMPLETE   0x06
 struct hci_ev_auth_complete {
        __u8     status;
-       __u16    handle;
+       __le16   handle;
 } __attribute__ ((packed));
 
 #define HCI_EV_ENCRYPT_CHANGE  0x08
 struct hci_ev_encrypt_change {
        __u8     status;
-       __u16    handle;
+       __le16   handle;
        __u8     encrypt;
 } __attribute__ ((packed));
 
 #define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE   0x09
 struct hci_ev_change_conn_link_key_complete {
        __u8     status;
-       __u16    handle;
+       __le16   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;
-       __u16    handle;
+       __le16   handle;
        struct   hci_qos qos;
 } __attribute__ ((packed));
 
 #define HCI_EV_CMD_COMPLETE    0x0E
 struct hci_ev_cmd_complete {
        __u8     ncmd;
-       __u16    opcode;
+       __le16   opcode;
 } __attribute__ ((packed));
 
 #define HCI_EV_CMD_STATUS      0x0F
 struct hci_ev_cmd_status {
        __u8     status;
        __u8     ncmd;
-       __u16    opcode;
+       __le16   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;
-       __u16    handle;
+       __le16   handle;
        __u8     mode;
-       __u16    interval;
+       __le16   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;
-       __u16    handle;
+       __le16   handle;
        __u8     features[8];
 } __attribute__ ((packed));
 
 #define HCI_EV_RMT_VERSION     0x0C
 struct hci_ev_rmt_version {
        __u8     status;
-       __u16    handle;
+       __le16   handle;
        __u8     lmp_ver;
-       __u16    manufacturer;
-       __u16    lmp_subver;
+       __le16   manufacturer;
+       __le16   lmp_subver;
 } __attribute__ ((packed));
 
 #define HCI_EV_CLOCK_OFFSET    0x01C
 struct hci_ev_clock_offset {
        __u8     status;
-       __u16    handle;
-       __u16    clock_offset;
+       __le16   handle;
+       __le16   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 {
-       __u16   opcode;         /* OCF & OGF */
+       __le16  opcode;         /* OCF & OGF */
        __u8    plen;
 } __attribute__ ((packed));
 
@@ -648,22 +648,22 @@ struct hci_event_hdr {
 } __attribute__ ((packed));
 
 struct hci_acl_hdr {
-       __u16   handle;         /* Handle & Flags(PB, BC) */
-       __u16   dlen;
+       __le16  handle;         /* Handle & Flags(PB, BC) */
+       __le16  dlen;
 } __attribute__ ((packed));
 
 struct hci_sco_hdr {
-       __u16   handle;
+       __le16  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)
 
index 7f933f30207830333996a9d872acbbef536e636d..bb9f81dc8723c5522daffd6d6184f3df675d0321 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
-#include <linux/proc_fs.h>
 #include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
@@ -34,8 +33,6 @@
 
 #define HCI_INIT_TIMEOUT (HZ * 10)
 
-extern struct proc_dir_entry *proc_bt_hci;
-
 /* HCI Core structures */
 
 struct inquiry_data {
@@ -44,7 +41,7 @@ struct inquiry_data {
        __u8            pscan_period_mode;
        __u8            pscan_mode;
        __u8            dev_class[3];
-       __u16           clock_offset;
+       __le16          clock_offset;
        __s8            rssi;
 };
 
@@ -126,10 +123,6 @@ struct hci_dev {
 
        atomic_t                promisc;
 
-#ifdef CONFIG_PROC_FS
-       struct proc_dir_entry   *proc;
-#endif
-
        struct class_device     class_dev;
 
        struct module           *owner;
index e656be7c001a342935119c44a8ffd741a5aa0a13..bbfac86734ec44f50b34efaf5067498c8080a3dc 100644 (file)
@@ -351,6 +351,4 @@ 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 */
index 65ec86678a08e34280fdd23e7e10f2c2cbb1494f..6addb4d464d6c87b0b7d9ae2884c46e57c2e8737 100644 (file)
@@ -252,12 +252,25 @@ typedef int               (*inet_getfrag_t) (const void *data,
                                           char *,
                                           unsigned int, unsigned int);
 
-
-extern int             ipv6_addr_type(const struct in6_addr *addr);
+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;
+       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));
+}
+
+static inline int ipv6_addr_src_scope(const struct in6_addr *addr)
+{
+       return __ipv6_addr_src_scope(__ipv6_addr_type(addr));
 }
 
 static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr *a2)
@@ -340,6 +353,54 @@ 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
  */
index e0498bd360042121d99fa0aea7ec77b8ebb2a03b..ff13c4cc287add76e658418aaae91970c1c87f66 100644 (file)
@@ -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. */
-#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)
+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_wait_event(__sk, __timeo, __condition)              \
 ({     int rc;                                                 \
index 6368d3dce444489ea41e654067aa92c012c0b924..d23e906456eb373ccbbd5ead89270ff198ceaf2e 100644 (file)
@@ -54,8 +54,7 @@ struct datalink_proto *make_8023_client(void)
  */
 void destroy_8023_client(struct datalink_proto *dl)
 {
-       if (dl)
-               kfree(dl);
+       kfree(dl);
 }
 
 EXPORT_SYMBOL(destroy_8023_client);
index 8e37e71e34ff1929aef5a8b8efb2ef362dec6b54..1b683f302657d376f438b8f9ea68805bdd14118c 100644 (file)
@@ -1138,10 +1138,8 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr,
        sk->sk_state   = TCP_CLOSE;
        sock->state = SS_UNCONNECTED;
 
-       if (ax25->digipeat != NULL) {
-               kfree(ax25->digipeat);
-               ax25->digipeat = NULL;
-       }
+       kfree(ax25->digipeat);
+       ax25->digipeat = NULL;
 
        /*
         *      Handle digi-peaters to be used.
index 73cfc3411c461d50d7dbb7d718dd3e2315d26428..4cf87540fb3abd79df222319a9c79e3dc09f2e3d 100644 (file)
@@ -401,10 +401,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
        }
 
        if (dp.ndigi == 0) {
-               if (ax25->digipeat != NULL) {
-                       kfree(ax25->digipeat);
-                       ax25->digipeat = NULL;
-               }
+               kfree(ax25->digipeat);
+               ax25->digipeat = NULL;
        } else {
                /* Reverse the source SABM's path */
                memcpy(ax25->digipeat, &reverse_dp, sizeof(ax25_digi));
index 26b77d9722201232d7adfcb2bb27dcc3fb90e246..b1e945bd6ed3d0f22e1a306303ad32ca4a471cc6 100644 (file)
@@ -54,15 +54,13 @@ void ax25_rt_device_down(struct net_device *dev)
                if (s->dev == dev) {
                        if (ax25_route_list == s) {
                                ax25_route_list = s->next;
-                               if (s->digipeat != NULL)
-                                       kfree(s->digipeat);
+                               kfree(s->digipeat);
                                kfree(s);
                        } else {
                                for (t = ax25_route_list; t != NULL; t = t->next) {
                                        if (t->next == s) {
                                                t->next = s->next;
-                                               if (s->digipeat != NULL)
-                                                       kfree(s->digipeat);
+                                               kfree(s->digipeat);
                                                kfree(s);
                                                break;
                                        }
@@ -90,10 +88,8 @@ 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) {
-                       if (ax25_rt->digipeat != NULL) {
-                               kfree(ax25_rt->digipeat);
-                               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);
@@ -145,8 +141,7 @@ 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) {
-               if (ax25_rt->digipeat != NULL)
-                       kfree(ax25_rt->digipeat);
+               kfree(ax25_rt->digipeat);
                kfree(ax25_rt);
                return;
        }
@@ -530,9 +525,7 @@ void __exit ax25_rt_free(void)
                s       = ax25_rt;
                ax25_rt = ax25_rt->next;
 
-               if (s->digipeat != NULL)
-                       kfree(s->digipeat);
-
+               kfree(s->digipeat);
                kfree(s);
        }
        write_unlock(&ax25_route_lock);
index 03532062a46a9168b662abad180a2e2347017e9d..ea616e3fc98e73f3806a5dc04e9770b6fba38425 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/proc_fs.h>
 #include <net/sock.h>
 
 #if defined(CONFIG_KMOD)
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.7"
-
-struct proc_dir_entry *proc_bt;
-EXPORT_SYMBOL(proc_bt);
+#define VERSION "2.8"
 
 /* Bluetooth sockets */
 #define BT_MAX_PROTO   8
@@ -312,10 +308,6 @@ 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");
@@ -334,8 +326,6 @@ static void __exit bt_exit(void)
        bt_sysfs_cleanup();
 
        sock_unregister(PF_BLUETOOTH);
-
-       remove_proc_entry("bluetooth", NULL);
 }
 
 subsys_initcall(bt_init);
index cf0df1c8c933c0f346b50f77578ba92f636d99a4..9106354c781e68c868d1830bec83c4312d1ccd04 100644 (file)
@@ -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;
-       __u16 param;
+       __le16 param;
 
        BT_DBG("%s %ld", hdev->name, opt);
 
index b61b4e8e36fdab2bd7c555acdfb7a93f23de5e14..eb64555d1fb346d90ff34dad9ed16ef4700d0fdc 100644 (file)
@@ -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((__u16 *) sent));
+               setting = __le16_to_cpu(get_unaligned((__le16 *) 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;
-       __u16 *ptr;
+       __le16 *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 = (__u16 *) skb->data; i < ev->num_hndl; i++) {
+       for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
                struct hci_conn *conn;
                __u16  handle, count;
 
index 799e448750ad906114c85c3a908e10ab44ec7cb4..1d6d0a15c099a8c4e8f38a63ed78925c0c6f827e 100644 (file)
@@ -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((u16 *)skb->data));
+               u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
                u16 ogf = hci_opcode_ogf(opcode);
                u16 ocf = hci_opcode_ocf(opcode);
 
index 7856bc26accb2acf6bdc28f9aaa91b6acee89667..bd7568ac87fc5ad7883e19cdd63b2dfb98193760 100644 (file)
@@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev)
        kfree(hdev);
 }
 
-static struct class bt_class = {
+struct class bt_class = {
        .name           = "bluetooth",
        .release        = bt_release,
 #ifdef CONFIG_HOTPLUG
@@ -111,6 +111,8 @@ static 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;
index 860444a7fc0f8e1e014f063721ecdc221a365304..cdb9cfafd960b5c45730b933f0515e1b79f1bfd4 100644 (file)
@@ -660,9 +660,7 @@ unlink:
 failed:
        up_write(&hidp_session_sem);
 
-       if (session->input)
-               kfree(session->input);
-
+       kfree(session->input);
        kfree(session);
        return err;
 }
index 59b2dd36baa77e1414177e1363cb697f2feebbc6..e3bb11ca4235562af24b7748873ef8de5ba1d362 100644 (file)
@@ -38,9 +38,8 @@
 #include <linux/interrupt.h>
 #include <linux/socket.h>
 #include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <linux/list.h>
+#include <linux/device.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -56,7 +55,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.7"
+#define VERSION "2.8"
 
 static struct proto_ops l2cap_sock_ops;
 
@@ -2137,94 +2136,29 @@ drop:
        return 0;
 }
 
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
 {
        struct sock *sk;
        struct hlist_node *node;
-       loff_t l = *pos;
+       char *str = buf;
 
        read_lock_bh(&l2cap_sk_list.lock);
 
-       sk_for_each(sk, node, &l2cap_sk_list.head)
-               if (!l--)
-                       goto found;
-       sk = NULL;
-found:
-       return sk;
-}
+       sk_for_each(sk, node, &l2cap_sk_list.head) {
+               struct l2cap_pinfo *pi = l2cap_pi(sk);
 
-static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos)
-{
-       (*pos)++;
-       return sk_next(e);
-}
+               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_stop(struct seq_file *seq, void *e)
-{
        read_unlock_bh(&l2cap_sk_list.lock);
-}
 
-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;
+       return (str - buf);
 }
 
-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 CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
 
 static struct proto_ops l2cap_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -2266,7 +2200,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;
@@ -2284,7 +2218,7 @@ static int __init l2cap_init(void)
                goto error;
        }
 
-       l2cap_proc_init();
+       class_create_file(&bt_class, &class_attr_l2cap);
 
        BT_INFO("L2CAP ver %s", VERSION);
        BT_INFO("L2CAP socket layer initialized");
@@ -2298,7 +2232,7 @@ error:
 
 static void __exit l2cap_exit(void)
 {
-       l2cap_proc_cleanup();
+       class_remove_file(&bt_class, &class_attr_l2cap);
 
        if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
                BT_ERR("L2CAP socket unregistration failed");
index c3d56ead840cbb42cbfc6814e32fed1ff83de066..0d89d64341364fcf9e6eb4214568c24795ea6a51 100644 (file)
@@ -35,9 +35,8 @@
 #include <linux/signal.h>
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/device.h>
 #include <linux/net.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
-#define VERSION "1.5"
+#define VERSION "1.6"
 
 #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);
@@ -2001,117 +1996,32 @@ static struct hci_cb rfcomm_cb = {
        .encrypt_cfm    = rfcomm_encrypt_cfm
 };
 
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
 {
        struct rfcomm_session *s;
        struct list_head *pp, *p;
-       loff_t l = *pos;
+       char *str = buf;
 
        rfcomm_lock();
 
        list_for_each(p, &session_list) {
                s = list_entry(p, struct rfcomm_session, list);
-               list_for_each(pp, &s->dlcs)
-                       if (!l--) {
-                               seq->private = s;
-                               return pp;
-                       }
-       }
-       return NULL;
-}
+               list_for_each(pp, &s->dlcs) {
+                       struct sock *sk = s->sock->sk;
+                       struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
 
-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;
+                       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);
                }
        }
-       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);
 
-       remove_proc_entry("rfcomm", proc_bt);
+       return (str - buf);
 }
 
-#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 */
+static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
 
 /* ---- Initialization ---- */
 static int __init rfcomm_init(void)
@@ -2122,9 +2032,7 @@ static int __init rfcomm_init(void)
 
        kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
 
-       BT_INFO("RFCOMM ver %s", VERSION);
-
-       rfcomm_proc_init();
+       class_create_file(&bt_class, &class_attr_rfcomm_dlc);
 
        rfcomm_init_sockets();
 
@@ -2132,11 +2040,15 @@ 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.
@@ -2153,8 +2065,6 @@ static void __exit rfcomm_exit(void)
 #endif
 
        rfcomm_cleanup_sockets();
-
-       rfcomm_proc_cleanup();
 }
 
 module_init(rfcomm_init);
index a2b30f0aedb7b4bc586cdabc141c392fc6eca775..6c34261b232e4cd2d9d0b254e7ae8701a3dfd021 100644 (file)
@@ -42,8 +42,7 @@
 #include <linux/socket.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/device.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -887,89 +886,26 @@ done:
        return result;
 }
 
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
 {
        struct sock *sk;
        struct hlist_node *node;
-       loff_t l = *pos;
+       char *str = buf;
 
        read_lock_bh(&rfcomm_sk_list.lock);
 
-       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);
-}
+       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);
+       }
 
-static void rfcomm_seq_stop(struct seq_file *seq, void *e)
-{
        read_unlock_bh(&rfcomm_sk_list.lock);
-}
 
-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);
+       return (str - buf);
 }
 
-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 CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
 
 static struct proto_ops rfcomm_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -997,7 +933,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;
 
@@ -1009,7 +945,7 @@ int  __init rfcomm_init_sockets(void)
        if (err < 0)
                goto error;
 
-       rfcomm_sock_proc_init();
+       class_create_file(&bt_class, &class_attr_rfcomm);
 
        BT_INFO("RFCOMM socket layer initialized");
 
@@ -1023,7 +959,7 @@ error:
 
 void __exit rfcomm_cleanup_sockets(void)
 {
-       rfcomm_sock_proc_cleanup();
+       class_remove_file(&bt_class, &class_attr_rfcomm);
 
        if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
                BT_ERR("RFCOMM socket layer unregistration failed");
index 997e42df115c5f6eba7be27fa4ec02883eb42a56..9cb00dc6c08c6d18b4cf1031a4405e144d1f69c0 100644 (file)
@@ -38,8 +38,7 @@
 #include <linux/interrupt.h>
 #include <linux/socket.h>
 #include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#include <linux/device.h>
 #include <linux/list.h>
 #include <net/sock.h>
 
@@ -55,7 +54,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.4"
+#define VERSION "0.5"
 
 static struct proto_ops sco_sock_ops;
 
@@ -893,91 +892,26 @@ drop:
        return 0;
 }
 
-/* ---- Proc fs support ---- */
-#ifdef CONFIG_PROC_FS
-static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
+static ssize_t sco_sysfs_show(struct class *dev, char *buf)
 {
        struct sock *sk;
        struct hlist_node *node;
-       loff_t l = *pos;
+       char *str = buf;
 
        read_lock_bh(&sco_sk_list.lock);
 
-       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);
-}
+       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);
+       }
 
-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;
-}
 
-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);
+       return (str - buf);
 }
 
-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 CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
 
 static struct proto_ops sco_sock_ops = {
        .family         = PF_BLUETOOTH,
@@ -1035,7 +969,7 @@ static int __init sco_init(void)
                goto error;
        }
 
-       sco_proc_init();
+       class_create_file(&bt_class, &class_attr_sco);
 
        BT_INFO("SCO (Voice Link) ver %s", VERSION);
        BT_INFO("SCO socket layer initialized");
@@ -1049,7 +983,7 @@ error:
 
 static void __exit sco_exit(void)
 {
-       sco_proc_cleanup();
+       class_remove_file(&bt_class, &class_attr_sco);
 
        if (bt_sock_unregister(BTPROTO_SCO) < 0)
                BT_ERR("SCO socket unregistration failed");
index db098ff3cd6a7509b58cec0b45da50e6cf76673e..cb530eef0e3990f2f3fce1076b2660b5109555b7 100644 (file)
@@ -194,8 +194,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
 
 done:
        spin_unlock_bh(&dev->xmit_lock);
-       if (dmi1)
-               kfree(dmi1);
+       kfree(dmi1);
        return err;
 }
 
index 9602ceb3bac9a2d33eec5ce1bc0cb8a55340203b..13cc3be4f056fb92f86cd660b6dcd29ba88ed30d 100644 (file)
@@ -1242,8 +1242,7 @@ static void sock_def_write_space(struct sock *sk)
 
 static void sock_def_destruct(struct sock *sk)
 {
-       if (sk->sk_protinfo)
-               kfree(sk->sk_protinfo);
+       kfree(sk->sk_protinfo);
 }
 
 void sk_send_sigurg(struct sock *sk)
index 4b9bc81ae1a3a35c6fe91a1c4cea05678c2e0781..ca03521112c52bfa4e279b351aee54c980105e71 100644 (file)
@@ -1263,10 +1263,8 @@ static int dccp_v4_destroy_sock(struct sock *sk)
        if (inet_csk(sk)->icsk_bind_hash != NULL)
                inet_put_port(&dccp_hashinfo, sk);
 
-       if (dp->dccps_service_list != NULL) {
-               kfree(dp->dccps_service_list);
-               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);
index a021c3422f6773d3d5643e9b7e9ccdc475511951..e0ace7cbb9960cc5d145304b7ce8bf8a8a5de2a2 100644 (file)
@@ -238,8 +238,7 @@ static int dccp_setsockopt_service(struct sock *sk, const u32 service,
        lock_sock(sk);
        dp->dccps_service = service;
 
-       if (dp->dccps_service_list != NULL)
-               kfree(dp->dccps_service_list);
+       kfree(dp->dccps_service_list);
 
        dp->dccps_service_list = sl;
        release_sock(sk);
index eeba56f99323b0cf82131b0fa3f6c9614dc2927e..6f8b5658cb4e9caf0c9d84438f02dcdd37348b66 100644 (file)
@@ -784,16 +784,14 @@ 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);
 
-        if (t) {
-                kfree(t);
-        }
+       kfree(t);
 }
 
 struct dn_fib_table *dn_fib_empty_table(void)
index 98a494be6039452700e39a227fcf7a23d69ab3f6..9d57b4fb6440c74532856b9fc4160821aa19d2b8 100644 (file)
@@ -32,8 +32,7 @@ struct datalink_proto *make_EII_client(void)
 
 void destroy_EII_client(struct datalink_proto *dl)
 {
-       if (dl)
-               kfree(dl);
+       kfree(dl);
 }
 
 EXPORT_SYMBOL(destroy_EII_client);
index a9d84f93442c9560a8e7050a60292876b09bd508..eaa150c33b0403204fa22224d6434e5c45f7695c 100644 (file)
@@ -147,8 +147,7 @@ void inet_sock_destruct(struct sock *sk)
        BUG_TRAP(!sk->sk_wmem_queued);
        BUG_TRAP(!sk->sk_forward_alloc);
 
-       if (inet->opt)
-               kfree(inet->opt);
+       kfree(inet->opt);
        dst_release(sk->sk_dst_cache);
        sk_refcnt_debug_dec(sk);
 }
index 990633c09dfe4ccdf345d06281880117b57c7906..2267c1fad879f6d047d86a52d572b270d3af5af0 100644 (file)
@@ -266,8 +266,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
                                if (tb)
                                        err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL);
                        }
-                       if (rta.rta_mx)
-                               kfree(rta.rta_mx);
+                       kfree(rta.rta_mx);
                }
                rtnl_unlock();
                return err;
index bce4e875193be1d596c4c607ab42e9e1f966513f..dbe12da8d8b3960fe7dc796de97eae2546e1528d 100644 (file)
@@ -510,8 +510,7 @@ static int ip_options_get_finish(struct ip_options **optp,
                kfree(opt);
                return -EINVAL;
        }
-       if (*optp)
-               kfree(*optp);
+       kfree(*optp);
        *optp = opt;
        return 0;
 }
index 17758234a3e351e4787824bf1e1cda3dc72dfded..11c2f68254f0a8a04602222216a03578c0327d20 100644 (file)
@@ -353,7 +353,8 @@ packet_routed:
                ip_options_build(skb, opt, inet->daddr, rt, 0);
        }
 
-       ip_select_ident_more(iph, &rt->u.dst, sk, skb_shinfo(skb)->tso_segs);
+       ip_select_ident_more(iph, &rt->u.dst, sk,
+                            (skb_shinfo(skb)->tso_segs ?: 1) - 1);
 
        /* Add an IP checksum. */
        ip_send_check(iph);
@@ -1262,10 +1263,8 @@ int ip_push_pending_frames(struct sock *sk)
 
 out:
        inet->cork.flags &= ~IPCORK_OPT;
-       if (inet->cork.opt) {
-               kfree(inet->cork.opt);
-               inet->cork.opt = NULL;
-       }
+       kfree(inet->cork.opt);
+       inet->cork.opt = NULL;
        if (inet->cork.rt) {
                ip_rt_put(inet->cork.rt);
                inet->cork.rt = NULL;
@@ -1289,10 +1288,8 @@ void ip_flush_pending_frames(struct sock *sk)
                kfree_skb(skb);
 
        inet->cork.flags &= ~IPCORK_OPT;
-       if (inet->cork.opt) {
-               kfree(inet->cork.opt);
-               inet->cork.opt = NULL;
-       }
+       kfree(inet->cork.opt);
+       inet->cork.opt = NULL;
        if (inet->cork.rt) {
                ip_rt_put(inet->cork.rt);
                inet->cork.rt = NULL;
index 2f0b47da5b37e3b3c0c44235355e704958cba8a3..4f2d8725730958f498b3d319c9e3dca68cd50722 100644 (file)
@@ -202,8 +202,7 @@ 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);
-                               if (new_ra)
-                                       kfree(new_ra);
+                               kfree(new_ra);
                                return -EADDRINUSE;
                        }
                        *rap = ra->next;
@@ -446,8 +445,7 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
 #endif
                        }
                        opt = xchg(&inet->opt, opt);
-                       if (opt)
-                               kfree(opt);
+                       kfree(opt);
                        break;
                }
                case IP_PKTINFO:
@@ -828,10 +826,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
 
                        err = ip_mc_msfilter(sk, msf, ifindex);
 mc_msf_out:
-                       if (msf)
-                               kfree(msf);
-                       if (gsf)
-                               kfree(gsf);
+                       kfree(msf);
+                       kfree(gsf);
                        break;
                }
                case IP_ROUTER_ALERT:   
index fc6f95aaa96976e27c14d733e09f03888ea31592..d7eb680101c25311233b9195faedca1aa17d812b 100644 (file)
@@ -110,8 +110,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
        return 0;
 
   out:
-       if (inc->timeout_table)
-               kfree(inc->timeout_table);
+       kfree(inc->timeout_table);
        kfree(inc);
        return ret;
 }
@@ -136,8 +135,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc)
 
        list_del(&inc->a_list);
 
-       if (inc->timeout_table != NULL)
-               kfree(inc->timeout_table);
+       kfree(inc->timeout_table);
        kfree(inc);
 }
 
index 981cc3244ef2724827e9c303a27d2a79a511cb4c..1a0843cd58a9e40d84e03b003ed0984e16763edf 100644 (file)
@@ -1009,11 +1009,10 @@ 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;
        }
 
index bd7d75b6abe0a6a7e1ed63d78b5d18becf3eb961..d34a9fa608e0b88dec20adaa567100a5b63c4ee0 100644 (file)
@@ -207,16 +207,12 @@ static void wrandom_select_route(const struct flowi *flp,
                        decision = mpc->rt;
 
                last_power = mpc->power;
-               if (last_mpc)
-                       kfree(last_mpc);
-
+               kfree(last_mpc);
                last_mpc = mpc;
        }
 
-       if (last_mpc) {
-               /* concurrent __multipath_flush may lead to !last_mpc */
-               kfree(last_mpc);
-       }
+       /* concurrent __multipath_flush may lead to !last_mpc */
+       kfree(last_mpc);
 
        decision->u.dst.__use++;
        *rp = decision;
index 93b2c5111bb2338b15f765ed604866d4a860310b..8acb7ed40b47f7c5e25adae81f774601ffaa15ba 100644 (file)
@@ -1161,8 +1161,7 @@ static int snmp_parse_mangle(unsigned char *msg,
                
                if (!snmp_object_decode(&ctx, obj)) {
                        if (*obj) {
-                               if ((*obj)->id)
-                                       kfree((*obj)->id);
+                               kfree((*obj)->id);
                                kfree(*obj);
                        }       
                        kfree(obj);
index 49d67cd75eddcf07a79946c8204fa1265cbca498..634dabb558fd6f5942e709c99846f83985db8b41 100644 (file)
@@ -823,8 +823,7 @@ out:
  */
 static void tcp_v4_reqsk_destructor(struct request_sock *req)
 {
-       if (inet_rsk(req)->opt)
-               kfree(inet_rsk(req)->opt);
+       kfree(inet_rsk(req)->opt);
 }
 
 static inline void syn_flood_warning(struct sk_buff *skb)
index 2c5f57299d63b1f2badbd056286513f7ef51e646..b7a5f51238b3958f88bc18adfac17704d3aa0bf7 100644 (file)
@@ -35,6 +35,9 @@
  *     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 <linux/config.h>
@@ -193,46 +196,51 @@ const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 #endif
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 
-int ipv6_addr_type(const struct in6_addr *addr)
+#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 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 finished.
+          000 and 111 as unicasts.
         */
        if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
            (st & htonl(0xE0000000)) != htonl(0xE0000000))
-               return type;
-       
-       if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
-               return (IPV6_ADDR_LINKLOCAL | type);
+               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)));
+       }
 
+       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 */
        if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
-               return (IPV6_ADDR_SITELOCAL | type);
+               return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST |
+                       IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_SITELOCAL));               /* addr-select 3.1 */
 
        if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
                if (addr->s6_addr32[2] == 0) {
@@ -240,24 +248,20 @@ int ipv6_addr_type(const struct in6_addr *addr)
                                return IPV6_ADDR_ANY;
 
                        if (addr->s6_addr32[3] == htonl(0x00000001))
-                               return (IPV6_ADDR_LOOPBACK | type);
+                               return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST |
+                                       IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_LINKLOCAL));       /* addr-select 3.4 */
 
-                       return (IPV6_ADDR_COMPATv4 | type);
+                       return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST |
+                               IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
                }
 
                if (addr->s6_addr32[2] == htonl(0x0000ffff))
-                       return IPV6_ADDR_MAPPED;
+                       return (IPV6_ADDR_MAPPED | 
+                               IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.3 */
        }
 
-       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;
+       return (IPV6_ADDR_RESERVED | 
+               IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_GLOBAL));  /* addr-select 3.4 */
 }
 
 static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -805,138 +809,274 @@ out:
 #endif
 
 /*
- *     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
+ *     Choose an appropriate source address (RFC3484)
  */
-static int inline ipv6_saddr_pref(const struct inet6_ifaddr *ifp, u8 invpref)
+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)
 {
-       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;
+       if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
+                   IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
+               return 1;
+       return 0;
 }
 
-#ifdef CONFIG_IPV6_PRIVACY
-#define IPV6_GET_SADDR_MAXSCORE(score) ((score) == 3)
-#else
-#define IPV6_GET_SADDR_MAXSCORE(score) (score)
-#endif
+/* 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;
+}
 
-int ipv6_dev_get_saddr(struct net_device *dev,
+int ipv6_dev_get_saddr(struct net_device *daddr_dev,
                       struct in6_addr *daddr, struct in6_addr *saddr)
 {
-       struct inet6_ifaddr *ifp = NULL;
-       struct inet6_ifaddr *match = NULL;
-       struct inet6_dev *idev;
-       int scope;
-       int err;
-       int hiscore = -1, score;
+       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;
 
-       scope = ipv6_addr_scope(daddr);
+       memset(&hiscore, 0, sizeof(hiscore));
 
-       /*
-        *      known dev
-        *      search dev and walk through dev addresses
-        */
+       read_lock(&dev_base_lock);
+       read_lock(&addrconf_lock);
 
-       if (dev) {
-               if (dev->flags & IFF_LOOPBACK)
-                       scope = IFA_HOST;
+       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;
 
-               read_lock(&addrconf_lock);
                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;
+               if (!idev)
+                       continue;
 
-                                       if (match)
-                                               in6_ifa_put(match);
-                                       match = ifp;
-                                       hiscore = score;
-                                       in6_ifa_hold(ifp);
+               read_lock_bh(&idev->lock);
+               for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
+                       struct ipv6_saddr_score score;
 
-                                       if (IPV6_GET_SADDR_MAXSCORE(score)) {
-                                               read_unlock_bh(&idev->lock);
-                                               read_unlock(&addrconf_lock);
-                                               goto out;
-                                       }
+                       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;
+                       }
+
+                       /* 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;
                        }
-                       read_unlock_bh(&idev->lock);
-               }
-               read_unlock(&addrconf_lock);
-       }
 
-       if (scope == IFA_LINK)
-               goto out;
+                       /* 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;
+                               }
+                       }
 
-       /*
-        *      dev == NULL or search failed for specified dev
-        */
+                       /* 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;
+                       }
 
-       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 4: Prefer home address -- not implemented yet */
 
-                                       if (match)
-                                               in6_ifa_put(match);
-                                       match = ifp;
-                                       hiscore = score;
-                                       in6_ifa_hold(ifp);
+                       /* 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;
+                       }
 
-                                       if (IPV6_GET_SADDR_MAXSCORE(score)) {
-                                               read_unlock_bh(&idev->lock);
-                                               goto out_unlock_base;
-                                       }
+                       /* 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;
+                       }
+
+                       /* 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;
                                }
+                       } else {
+                               if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
+                                       continue;
                        }
-                       read_unlock_bh(&idev->lock);
+
+                       /* 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);
        }
-
-out_unlock_base:
        read_unlock(&addrconf_lock);
        read_unlock(&dev_base_lock);
 
-out:
-       err = -EADDRNOTAVAIL;
-       if (match) {
-               ipv6_addr_copy(saddr, &match->addr);
-               err = 0;
-               in6_ifa_put(match);
-       }
-
-       return err;
+       if (!ifa_result)
+               return -EADDRNOTAVAIL;
+       
+       ipv6_addr_copy(saddr, &ifa_result->addr);
+       in6_ifa_put(ifa_result);
+       return 0;
 }
 
 
@@ -2950,8 +3090,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
 
 nlmsg_failure:
 rtattr_failure:
-       if (array)
-               kfree(array);
+       kfree(array);
        skb_trim(skb, b - skb->data);
        return -1;
 }
index 4fcc5a7acf6e446ce2715df397d37d78b3b34354..1bf6d9a769e61fa2a54a1838c9f26a0aaf502127 100644 (file)
@@ -127,56 +127,6 @@ 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;
@@ -296,11 +246,11 @@ insert_above:
 
        /* find 1st bit in difference between the 2 addrs.
 
-          See comment in addr_diff: bit may be an invalid value,
+          See comment in __ipv6_addr_diff: bit may be an invalid value,
           but if it is >= plen, the value is ignored in any case.
         */
        
-       bit = addr_diff(addr, &key->addr, addrlen);
+       bit = __ipv6_addr_diff(addr, &key->addr, addrlen);
 
        /* 
         *              (intermediate)[in]      
index 614296a920c6ab189b58607726eea55bee4d0426..dbd9767b32e45ee3373e94ae20afee2b5449a83c 100644 (file)
@@ -587,8 +587,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                        skb->next = NULL;
                }
 
-               if (tmp_hdr)
-                       kfree(tmp_hdr);
+               kfree(tmp_hdr);
 
                if (err == 0) {
                        IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
@@ -1186,10 +1185,8 @@ int ip6_push_pending_frames(struct sock *sk)
 
 out:
        inet->cork.flags &= ~IPCORK_OPT;
-       if (np->cork.opt) {
-               kfree(np->cork.opt);
-               np->cork.opt = NULL;
-       }
+       kfree(np->cork.opt);
+       np->cork.opt = NULL;
        if (np->cork.rt) {
                dst_release(&np->cork.rt->u.dst);
                np->cork.rt = NULL;
@@ -1214,10 +1211,8 @@ void ip6_flush_pending_frames(struct sock *sk)
 
        inet->cork.flags &= ~IPCORK_OPT;
 
-       if (np->cork.opt) {
-               kfree(np->cork.opt);
-               np->cork.opt = NULL;
-       }
+       kfree(np->cork.opt);
+       np->cork.opt = NULL;
        if (np->cork.rt) {
                dst_release(&np->cork.rt->u.dst);
                np->cork.rt = NULL;
index cf94372d1af39980b108f3161fd8d94837e0f94c..e6b0e3954c02be114b6bba4f2e14007ff069d1db 100644 (file)
@@ -756,8 +756,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        ip6_tnl_dst_store(t, dst);
 
-       if (opt)
-               kfree(opt);
+       kfree(opt);
 
        t->recursion--;
        return 0;
@@ -766,8 +765,7 @@ tx_err_link_failure:
        dst_link_failure(skb);
 tx_err_dst_release:
        dst_release(dst);
-       if (opt)
-               kfree(opt);
+       kfree(opt);
 tx_err:
        stats->tx_errors++;
        stats->tx_dropped++;
index 85bfbc69b2c3dc716618f6e528dfcb63658e96b5..55917fb170949cfdcd5dd427dc8baf7201c14a17 100644 (file)
@@ -130,8 +130,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
 out_put_cpu:
        put_cpu();
 out:
-       if (tmp_hdr)
-               kfree(tmp_hdr);
+       kfree(tmp_hdr);
        if (err)
                goto error_out;
        return nexthdr;
index 8567873d0dd85fabd972537eccce7d79d8107611..003fd99ff597d6f4332008c90f6bdcb2b9e80493 100644 (file)
@@ -80,8 +80,7 @@ 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);
-                               if (new_ra)
-                                       kfree(new_ra);
+                               kfree(new_ra);
                                return -EADDRINUSE;
                        }
 
index 37a4a99c9fe9e1837e5cd82f686ff3736fd94daa..16482785bdfddf322fad974dfe3e407285549ee2 100644 (file)
@@ -7,7 +7,7 @@
 #include <net/ip6_route.h>
 #include <net/xfrm.h>
 
-EXPORT_SYMBOL(ipv6_addr_type);
+EXPORT_SYMBOL(__ipv6_addr_type);
 EXPORT_SYMBOL(icmpv6_send);
 EXPORT_SYMBOL(icmpv6_statistics);
 EXPORT_SYMBOL(icmpv6_err_convert);
index c4ba5fa1446a47da6ba85981cc8c4a7e693e73ad..3fefc822c1c087c2cebd4baadb646ef771442784 100644 (file)
@@ -194,8 +194,7 @@ 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);
-                       if (curr)
-                               kfree(curr);
+                       kfree(curr);
                }
        }
 
index 6fec428b45123df937bff9b6bc177a24fa793d41..75f2666e863056d7255875285c5188fee69042cd 100644 (file)
@@ -122,8 +122,7 @@ static void __irias_delete_attrib(struct ias_attrib *attrib)
        IRDA_ASSERT(attrib != NULL, return;);
        IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;);
 
-       if (attrib->name)
-               kfree(attrib->name);
+       kfree(attrib->name);
 
        irias_delete_value(attrib->value);
        attrib->magic = ~IAS_ATTRIB_MAGIC;
@@ -136,8 +135,7 @@ void __irias_delete_object(struct ias_object *obj)
        IRDA_ASSERT(obj != NULL, return;);
        IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
 
-       if (obj->name)
-               kfree(obj->name);
+       kfree(obj->name);
 
        hashbin_delete(obj->attribs, (FREE_FUNC) __irias_delete_attrib);
 
@@ -562,14 +560,12 @@ void irias_delete_value(struct ias_value *value)
                /* No need to deallocate */
                break;
        case IAS_STRING:
-               /* If string, deallocate string */
-               if (value->t.string != NULL)
-                       kfree(value->t.string);
+               /* Deallocate string */
+               kfree(value->t.string);
                break;
        case IAS_OCT_SEQ:
-               /* If byte stream, deallocate byte stream */
-                if (value->t.oct_seq != NULL)
-                        kfree(value->t.oct_seq);
+               /* Deallocate byte stream */
+                kfree(value->t.oct_seq);
                 break;
        default:
                IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
index b18fe504301944d8514816df8d6eb90f715b048d..8631b65a7312c830d35e4d843163024432bac54e 100644 (file)
@@ -240,8 +240,7 @@ 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);
-               if (rose_neigh->digipeat != NULL)
-                       kfree(rose_neigh->digipeat);
+               kfree(rose_neigh->digipeat);
                kfree(rose_neigh);
                return;
        }
@@ -250,8 +249,7 @@ 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);
-                       if (rose_neigh->digipeat != NULL)
-                               kfree(rose_neigh->digipeat);
+                       kfree(rose_neigh->digipeat);
                        kfree(rose_neigh);
                        return;
                }
index 29d8b9a4d162f2aa72b38f3df3f68e9f1ffe625e..75470486e4050edb23e4db439a3228adfbfc170e 100644 (file)
@@ -298,8 +298,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
        return 0;
 
 errout:
-       if (f)
-               kfree(f);
+       kfree(f);
        return err;
 }
 
index 02996ac05c75d11b738649fd3069abeb17b82bdd..520ff716dab2f0d744845747366f320dd83f9434 100644 (file)
@@ -525,8 +525,7 @@ reinsert:
        return 0;
 
 errout:
-       if (f)
-               kfree(f);
+       kfree(f);
        return err;
 }
 
index 006168d6937654d7ece5493fad1b96cad9e0806b..572f06be3b02a181447c1e125056a833687ef017 100644 (file)
@@ -555,8 +555,7 @@ insert:
        goto insert;
 
 errout:
-       if (f)
-               kfree(f);
+       kfree(f);
 errout2:
        tcf_exts_destroy(tp, &e);
        return err;
index 404d9d83a7fab040efab32341db2732b31626cf9..9f921174c8ab39d33e9544c9b78051b3b8a12cdf 100644 (file)
@@ -194,8 +194,7 @@ found:
        }
        tcf_unbind_filter(tp, &r->res);
        tcf_exts_destroy(tp, &r->exts);
-       if (f)
-               kfree(f);
+       kfree(f);
        return 0;
 }
 
@@ -442,10 +441,8 @@ static void tcindex_destroy(struct tcf_proto *tp)
        walker.skip = 0;
        walker.fn = &tcindex_destroy_element;
        tcindex_walk(tp,&walker);
-       if (p->perfect)
-               kfree(p->perfect);
-       if (p->h)
-               kfree(p->h);
+       kfree(p->perfect);
+       kfree(p->h);
        kfree(p);
        tp->root = NULL;
 }
index 364b87d86455dc8671d17d8fbeceb4ae9d1d51e8..2b670479dde1d68ea192e641dbe69ffb754bf9f4 100644 (file)
@@ -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 && (NULL != n->pf))
+       if (n)
                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 && (NULL != n->pf))
+       if (n)
                kfree(n->pf);
 #endif
        kfree(n);
index cf68a59fdc5a4d4d6ac2bfbd5b63f99cd4574cee..700844d49d795d36acffd22815b5fb4f15ec3ce9 100644 (file)
@@ -561,8 +561,7 @@ static int meta_var_change(struct meta_value *dst, struct rtattr *rta)
 
 static void meta_var_destroy(struct meta_value *v)
 {
-       if (v->val)
-               kfree((void *) v->val);
+       kfree((void *) v->val);
 }
 
 static void meta_var_apply_extras(struct meta_value *v,
index ebfe2e7d21bdff98494baf479c2cca37c4175b99..64b047c65568cafe0912b92f7bb18b7e56031c25 100644 (file)
@@ -298,6 +298,11 @@ 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;
 
index 12b0f582a66b29707941da349b3f63582e5c0407..8c8ddf7f9b61c7c9ca7a804f8cbf8101fc151aa9 100644 (file)
@@ -344,9 +344,7 @@ void sctp_association_free(struct sctp_association *asoc)
        }
 
        /* Free peer's cached cookie. */
-       if (asoc->peer.cookie) {
-               kfree(asoc->peer.cookie);
-       }
+       kfree(asoc->peer.cookie);
 
        /* Release the transport structures. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
index 660c61bdf16423c883dff5291fd60e2067b552d9..f9573eba5c7aa2f5507c12c0ff55a75e0e700490 100644 (file)
@@ -254,8 +254,7 @@ 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:
-       if (addrs.v)
-               kfree(addrs.v);
+       kfree(addrs.v);
        return retval;
 }
 
@@ -347,8 +346,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
 nomem_chunk:
        kfree(cookie);
 nomem_cookie:
-       if (addrs.v)
-               kfree(addrs.v);
+       kfree(addrs.v);
        return retval;
 }
 
index 13f8ae9794542d436f82274bff2e38c0a7724f18..d0dfdfd5e79efa926140d23e10ecba89e16cc381 100644 (file)
@@ -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:
-       if (md5cksum.data) kfree(md5cksum.data);
+       kfree(md5cksum.data);
        return GSS_S_FAILURE;
 }
index 2030475d98ed26b22632a6dc6f01068ef6f92947..db055fd7d7789c22ef62e4e8faab7ebac7cafebd 100644 (file)
@@ -176,6 +176,6 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
 
        ret = GSS_S_COMPLETE;
 out:
-       if (md5cksum.data) kfree(md5cksum.data);
+       kfree(md5cksum.data);
        return ret;
 }
index b048bf672da2bbffbe35953b3e47a57b7e2383d3..f8bac6ccd524008a669c4e603d8526b9dabb006b 100644 (file)
@@ -60,8 +60,7 @@ gss_mech_free(struct gss_api_mech *gm)
 
        for (i = 0; i < gm->gm_pf_num; i++) {
                pf = &gm->gm_pfs[i];
-               if (pf->auth_domain_name)
-                       kfree(pf->auth_domain_name);
+               kfree(pf->auth_domain_name);
                pf->auth_domain_name = NULL;
        }
 }
index 148201e929d08de77ca44f6b6dfbe8da20ab7e04..d1e12b25d6e21f2b4e205c49b3ddd0d0fb7580b6 100644 (file)
@@ -122,8 +122,7 @@ spkm3_make_token(struct spkm3_ctx *ctx,
 
        return  GSS_S_COMPLETE;
 out_err:
-       if (md5cksum.data) 
-               kfree(md5cksum.data);
+       kfree(md5cksum.data);
        token->data = NULL;
        token->len = 0;
        return GSS_S_FAILURE;
index 46c08a0710f62e147f0a4c6b4e6502be5a89ebbd..1f824578d773691c17c67daa6f76e9096730a789 100644 (file)
@@ -259,8 +259,7 @@ spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen, unsigned char **ck
 
        ret = GSS_S_COMPLETE;
 out:
-       if (spkm3_ctx_id.data)
-               kfree(spkm3_ctx_id.data);
+       kfree(spkm3_ctx_id.data);
        return ret;
 }
 
index c3c0d95861039958305e89f437174b8c3bc13272..241d5b30dfcbcfb851093856f88b79698da35a81 100644 (file)
@@ -120,9 +120,7 @@ spkm3_read_token(struct spkm3_ctx *ctx,
        /* XXX: need to add expiration and sequencing */
        ret = GSS_S_COMPLETE;
 out:
-       if (md5cksum.data) 
-               kfree(md5cksum.data);
-       if (wire_cksum.data) 
-               kfree(wire_cksum.data);
+       kfree(md5cksum.data);
+       kfree(wire_cksum.data);
        return ret;
 }
index 5a220b2bb376f4669ecf4d267d1fa261d0b5b847..e4296c8b861eba85fead5bf1d839aa212e59ac7c 100644 (file)
@@ -196,12 +196,9 @@ svc_exit_thread(struct svc_rqst *rqstp)
        struct svc_serv *serv = rqstp->rq_server;
 
        svc_release_buffer(rqstp);
-       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->rq_resp);
+       kfree(rqstp->rq_argp);
+       kfree(rqstp->rq_auth_data);
        kfree(rqstp);
 
        /* Release the server */
index 32df43372ee97cc277ed54d058f77667c8985160..aaf08cdd19f09fad9b9a36e7cdd8041606dbfd6e 100644 (file)
@@ -992,8 +992,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
        err = 0;
 
 out:
-       if (elem)
-               kfree(elem);
+       kfree(elem);
        if (ppages)
                kunmap(*ppages);
        return err;
index 596cb96e5f471227c348ce214d46dce63f5cf4a7..59fec59b2132df1ab43e782d2a469a84bf373dd0 100644 (file)
@@ -1099,7 +1099,7 @@ static void release_driver(struct sock *sk)
        sock_reset_flag(sk, SOCK_ZAPPED);
        wp = wp_sk(sk);
 
-       if (wp && wp->mbox) {
+       if (wp) {
                kfree(wp->mbox);
                wp->mbox = NULL;
        }
@@ -1186,10 +1186,8 @@ static void wanpipe_kill_sock_timer (unsigned long data)
                return;
        }
 
-       if (wp_sk(sk)) {
-               kfree(wp_sk(sk));
-               wp_sk(sk) = NULL;
-       }
+       kfree(wp_sk(sk));
+       wp_sk(sk) = NULL;
 
        if (atomic_read(&sk->sk_refcnt) != 1) {
                atomic_set(&sk->sk_refcnt, 1);
@@ -1219,10 +1217,8 @@ static void wanpipe_kill_sock_accept (struct sock *sk)
        sk->sk_socket = NULL;
 
 
-       if (wp_sk(sk)) {
-               kfree(wp_sk(sk));
-               wp_sk(sk) = NULL;
-       }
+       kfree(wp_sk(sk));
+       wp_sk(sk) = NULL;
 
        if (atomic_read(&sk->sk_refcnt) != 1) {
                atomic_set(&sk->sk_refcnt, 1);
@@ -1243,10 +1239,8 @@ static void wanpipe_kill_sock_irq (struct sock *sk)
 
        sk->sk_socket = NULL;
 
-       if (wp_sk(sk)) {
-               kfree(wp_sk(sk));
-               wp_sk(sk) = NULL;
-       }
+       kfree(wp_sk(sk));
+       wp_sk(sk) = NULL;
 
        if (atomic_read(&sk->sk_refcnt) != 1) {
                atomic_set(&sk->sk_refcnt, 1);
index 13b650ad22e21a6a6bec891d5bfe8ce4efb52236..bcf7b3faa76a4020d6308f5998fead39cce7b961 100644 (file)
@@ -714,10 +714,8 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
        }
 
        /* This code has moved from del_if() function */
-       if (dev->priv) {
-               kfree(dev->priv);
-               dev->priv = NULL;
-       }
+       kfree(dev->priv);
+       dev->priv = NULL;
 
 #ifdef CONFIG_WANPIPE_MULTPPP
        if (cnf->config_id == WANCONFIG_MPPP)
@@ -851,10 +849,8 @@ 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.*/
-       if (dev->priv){
-               kfree(dev->priv);
-               dev->priv=NULL;
-       }
+       kfree(dev->priv);
+       dev->priv=NULL;
 
        unregister_netdev(dev);
 
index 8b9a4747417d00bbf4c6b9050f59f7ca4eb24951..7cf48aa6c95bdb48a9438c6c4a3159fefe403869 100644 (file)
@@ -62,14 +62,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
 {
        if (del_timer(&x->timer))
                BUG();
-       if (x->aalg)
-               kfree(x->aalg);
-       if (x->ealg)
-               kfree(x->ealg);
-       if (x->calg)
-               kfree(x->calg);
-       if (x->encap)
-               kfree(x->encap);
+       kfree(x->aalg);
+       kfree(x->ealg);
+       kfree(x->calg);
+       kfree(x->encap);
        if (x->type) {
                x->type->destructor(x);
                xfrm_put_type(x->type);