summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/vmi.c23
-rw-r--r--arch/i386/mm/highmem.c2
-rw-r--r--arch/x86_64/kernel/early-quirks.c2
-rw-r--r--drivers/char/agp/intel-agp.c14
-rw-r--r--drivers/net/tg3.c6
-rw-r--r--drivers/pcmcia/omap_cf.c41
-rw-r--r--fs/fuse/dir.c5
-rw-r--r--fs/fuse/fuse_i.h5
-rw-r--r--fs/fuse/inode.c2
-rw-r--r--include/asm-generic/pgtable.h2
-rw-r--r--include/asm-i386/paravirt.h3
-rw-r--r--include/linux/hrtimer.h3
-rw-r--r--kernel/hrtimer.c12
-rw-r--r--kernel/irq/devres.c2
-rw-r--r--kernel/sched.c36
-rw-r--r--kernel/timer.c2
-rw-r--r--net/ipv4/xfrm4_mode_beet.c26
-rw-r--r--net/ipv6/route.c19
19 files changed, 120 insertions, 87 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index e4408ff4e674..b3ab8ffebd27 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -736,7 +736,7 @@ failed:
return 0;
}
-int __init irqbalance_disable(char *str)
+int __devinit irqbalance_disable(char *str)
{
irqbalance_disabled = 1;
return 1;
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index fb07a1aad225..edc339fa5038 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -69,6 +69,7 @@ struct {
void (*flush_tlb)(int);
void (*set_initial_ap_state)(int, int);
void (*halt)(void);
+ void (*set_lazy_mode)(int mode);
} vmi_ops;
/* XXX move this to alternative.h */
@@ -574,6 +575,26 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip,
}
#endif
+static void vmi_set_lazy_mode(int mode)
+{
+ static DEFINE_PER_CPU(int, lazy_mode);
+
+ if (!vmi_ops.set_lazy_mode)
+ return;
+
+ /* Modes should never nest or overlap */
+ BUG_ON(__get_cpu_var(lazy_mode) && !(mode == PARAVIRT_LAZY_NONE ||
+ mode == PARAVIRT_LAZY_FLUSH));
+
+ if (mode == PARAVIRT_LAZY_FLUSH) {
+ vmi_ops.set_lazy_mode(0);
+ vmi_ops.set_lazy_mode(__get_cpu_var(lazy_mode));
+ } else {
+ vmi_ops.set_lazy_mode(mode);
+ __get_cpu_var(lazy_mode) = mode;
+ }
+}
+
static inline int __init check_vmi_rom(struct vrom_header *rom)
{
struct pci_header *pci;
@@ -804,7 +825,7 @@ static inline int __init activate_vmi(void)
para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack);
para_fill(set_iopl_mask, SetIOPLMask);
para_fill(io_delay, IODelay);
- para_fill(set_lazy_mode, SetLazyMode);
+ para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode);
/* user and kernel flush are just handled with different flags to FlushTLB */
para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB);
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index bb2de1089add..ac70d09df7ee 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -42,6 +42,7 @@ void *kmap_atomic(struct page *page, enum km_type type)
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+ arch_flush_lazy_mmu_mode();
return (void*) vaddr;
}
@@ -82,6 +83,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+ arch_flush_lazy_mmu_mode();
return (void*) vaddr;
}
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index 148c6bcf5bb4..fede55a53995 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -88,7 +88,7 @@ struct chipset {
void (*f)(void);
};
-static struct __initdata chipset early_qrk[] = {
+static struct chipset early_qrk[] __initdata = {
{ PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
{ PCI_VENDOR_ID_VIA, via_bugs },
{ PCI_VENDOR_ID_ATI, ati_bugs },
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index e542a628f1c7..a9fdbf9126ca 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -18,11 +18,14 @@
#define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992
#define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0
#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
+#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
+#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
#define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
extern int agp_memory_reserved;
@@ -1921,7 +1924,13 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
bridge->driver = &intel_845_driver;
name = "965G";
break;
-
+ case PCI_DEVICE_ID_INTEL_82965GM_HB:
+ if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
+ bridge->driver = &intel_i965_driver;
+ else
+ bridge->driver = &intel_845_driver;
+ name = "965GM";
+ break;
case PCI_DEVICE_ID_INTEL_7505_0:
bridge->driver = &intel_7505_driver;
name = "E7505";
@@ -2080,6 +2089,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
ID(PCI_DEVICE_ID_INTEL_82965G_HB),
+ ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
{ }
};
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 0acee9f324e9..256969e1300c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4834,8 +4834,10 @@ static int tg3_chip_reset(struct tg3 *tp)
* sharing or irqpoll.
*/
tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
- tp->hw_status->status = 0;
- tp->hw_status->status_tag = 0;
+ if (tp->hw_status) {
+ tp->hw_status->status = 0;
+ tp->hw_status->status_tag = 0;
+ }
tp->last_tag = 0;
smp_mb();
synchronize_irq(tp->pdev->irq);
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index d77f75129f8a..2df216b00817 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -202,15 +202,14 @@ static struct pccard_operations omap_cf_ops = {
* "what chipselect is used". Boards could want more.
*/
-static int __devinit omap_cf_probe(struct device *dev)
+static int __init omap_cf_probe(struct platform_device *pdev)
{
unsigned seg;
struct omap_cf_socket *cf;
- struct platform_device *pdev = to_platform_device(dev);
int irq;
int status;
- seg = (int) dev->platform_data;
+ seg = (int) pdev->dev.platform_data;
if (seg == 0 || seg > 3)
return -ENODEV;
@@ -227,7 +226,7 @@ static int __devinit omap_cf_probe(struct device *dev)
cf->timer.data = (unsigned long) cf;
cf->pdev = pdev;
- dev_set_drvdata(dev, cf);
+ platform_set_drvdata(pdev, cf);
/* this primarily just shuts up irq handling noise */
status = request_irq(irq, omap_cf_irq, IRQF_SHARED,
@@ -291,7 +290,7 @@ static int __devinit omap_cf_probe(struct device *dev)
omap_cf_present() ? "present" : "(not present)");
cf->socket.owner = THIS_MODULE;
- cf->socket.dev.parent = dev;
+ cf->socket.dev.parent = &pdev->dev;
cf->socket.ops = &omap_cf_ops;
cf->socket.resource_ops = &pccard_static_ops;
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
@@ -318,9 +317,9 @@ fail0:
return status;
}
-static int __devexit omap_cf_remove(struct device *dev)
+static int __exit omap_cf_remove(struct platform_device *pdev)
{
- struct omap_cf_socket *cf = dev_get_drvdata(dev);
+ struct omap_cf_socket *cf = platform_get_drvdata(pdev);
cf->active = 0;
pcmcia_unregister_socket(&cf->socket);
@@ -332,26 +331,36 @@ static int __devexit omap_cf_remove(struct device *dev)
return 0;
}
-static struct device_driver omap_cf_driver = {
- .name = (char *) driver_name,
- .bus = &platform_bus_type,
- .probe = omap_cf_probe,
- .remove = __devexit_p(omap_cf_remove),
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+ return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
+}
+
+static int omap_cf_resume(struct platform_device *pdev)
+{
+ return pcmcia_socket_dev_resume(&pdev->dev);
+}
+
+static struct platform_driver omap_cf_driver = {
+ .driver = {
+ .name = (char *) driver_name,
+ },
+ .remove = __exit_p(omap_cf_remove),
+ .suspend = omap_cf_suspend,
+ .resume = omap_cf_resume,
};
static int __init omap_cf_init(void)
{
if (cpu_is_omap16xx())
- return driver_register(&omap_cf_driver);
+ return platform_driver_probe(&omap_cf_driver, omap_cf_probe);
return -ENODEV;
}
static void __exit omap_cf_exit(void)
{
if (cpu_is_omap16xx())
- driver_unregister(&omap_cf_driver);
+ platform_driver_unregister(&omap_cf_driver);
}
module_init(omap_cf_init);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 406bf61ed510..8890eba1db52 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -195,7 +195,7 @@ static struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
};
-static int valid_mode(int m)
+int fuse_valid_type(int m)
{
return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
@@ -248,7 +248,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
fuse_put_request(fc, req);
/* Zero nodeid is same as -ENOENT, but with valid timeout */
if (!err && outarg.nodeid &&
- (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
+ (invalid_nodeid(outarg.nodeid) ||
+ !fuse_valid_type(outarg.attr.mode)))
err = -EIO;
if (!err && outarg.nodeid) {
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index b98b20de7405..68ae87cbafab 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -552,3 +552,8 @@ int fuse_ctl_add_conn(struct fuse_conn *fc);
* Remove connection from control filesystem
*/
void fuse_ctl_remove_conn(struct fuse_conn *fc);
+
+/**
+ * Is file type valid?
+ */
+int fuse_valid_type(int m);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 5ab8e50e7808..608db81219a0 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -330,6 +330,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
case OPT_ROOTMODE:
if (match_octal(&args[0], &value))
return 0;
+ if (!fuse_valid_type(value))
+ return 0;
d->rootmode = value;
d->rootmode_present = 1;
break;
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 00c23433b39f..6d7e279b1490 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -180,6 +180,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
#define arch_enter_lazy_mmu_mode() do {} while (0)
#define arch_leave_lazy_mmu_mode() do {} while (0)
+#define arch_flush_lazy_mmu_mode() do {} while (0)
#endif
/*
@@ -193,6 +194,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE
#define arch_enter_lazy_cpu_mode() do {} while (0)
#define arch_leave_lazy_cpu_mode() do {} while (0)
+#define arch_flush_lazy_cpu_mode() do {} while (0)
#endif
/*
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h
index 46dc34ca887a..e63f1e444fcf 100644
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -421,14 +421,17 @@ static inline void pmd_clear(pmd_t *pmdp)
#define PARAVIRT_LAZY_NONE 0
#define PARAVIRT_LAZY_MMU 1
#define PARAVIRT_LAZY_CPU 2
+#define PARAVIRT_LAZY_FLUSH 3
#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE
#define arch_enter_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_CPU)
#define arch_leave_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+#define arch_flush_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
#define arch_enter_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_MMU)
#define arch_leave_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+#define arch_flush_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
/* These all sit in the .parainstructions section to tell us what to patch. */
struct paravirt_patch {
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 5bdbc744e773..17c29dca8354 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -206,6 +206,7 @@ struct hrtimer_cpu_base {
struct clock_event_device;
extern void clock_was_set(void);
+extern void hres_timers_resume(void);
extern void hrtimer_interrupt(struct clock_event_device *dev);
/*
@@ -236,6 +237,8 @@ static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer)
*/
static inline void clock_was_set(void) { }
+static inline void hres_timers_resume(void) { }
+
/*
* In non high resolution mode the time reference is taken from
* the base softirq time variable.
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 067ba2c05328..b74860aaf5f1 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -459,6 +459,18 @@ void clock_was_set(void)
}
/*
+ * During resume we might have to reprogram the high resolution timer
+ * interrupt (on the local CPU):
+ */
+void hres_timers_resume(void)
+{
+ WARN_ON_ONCE(num_online_cpus() > 1);
+
+ /* Retrigger the CPU local events: */
+ retrigger_next_event(NULL);
+}
+
+/*
* Check, whether the timer is on the callback pending list
*/
static inline int hrtimer_cb_pending(const struct hrtimer *timer)
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index 85a430da0fb6..d8ee241115f5 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -54,7 +54,7 @@ int devm_request_irq(struct device *dev, unsigned int irq,
rc = request_irq(irq, handler, irqflags, devname, dev_id);
if (rc) {
- kfree(dr);
+ devres_free(dr);
return rc;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index a4ca632c477c..b9a683730148 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4687,32 +4687,10 @@ out_unlock:
return retval;
}
-static inline struct task_struct *eldest_child(struct task_struct *p)
-{
- if (list_empty(&p->children))
- return NULL;
- return list_entry(p->children.next,struct task_struct,sibling);
-}
-
-static inline struct task_struct *older_sibling(struct task_struct *p)
-{
- if (p->sibling.prev==&p->parent->children)
- return NULL;
- return list_entry(p->sibling.prev,struct task_struct,sibling);
-}
-
-static inline struct task_struct *younger_sibling(struct task_struct *p)
-{
- if (p->sibling.next==&p->parent->children)
- return NULL;
- return list_entry(p->sibling.next,struct task_struct,sibling);
-}
-
static const char stat_nam[] = "RSDTtZX";
static void show_task(struct task_struct *p)
{
- struct task_struct *relative;
unsigned long free = 0;
unsigned state;
@@ -4738,19 +4716,7 @@ static void show_task(struct task_struct *p)
free = (unsigned long)n - (unsigned long)end_of_stack(p);
}
#endif
- printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
- if ((relative = eldest_child(p)))
- printk("%5d ", relative->pid);
- else
- printk(" ");
- if ((relative = younger_sibling(p)))
- printk("%7d", relative->pid);
- else
- printk(" ");
- if ((relative = older_sibling(p)))
- printk(" %5d", relative->pid);
- else
- printk(" ");
+ printk("%5lu %5d %6d", free, p->pid, p->parent->pid);
if (!p->mm)
printk(" (L-TLB)\n");
else
diff --git a/kernel/timer.c b/kernel/timer.c
index 440048acaea1..dd6c2c1c561b 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1016,7 +1016,7 @@ static int timekeeping_resume(struct sys_device *dev)
clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
/* Resume hrtimers */
- clock_was_set();
+ hres_timers_resume();
return 0;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 89cf59ea7bbe..f68dfd8a0f5c 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
top_iph = skb->nh.iph;
- hdrlen = iph->ihl * 4 - optlen;
- skb->h.raw += hdrlen;
+ skb->h.raw += sizeof(*iph) - hdrlen;
- memmove(top_iph, iph, hdrlen);
+ memmove(top_iph, iph, sizeof(*iph));
if (unlikely(optlen)) {
struct ip_beet_phdr *ph;
@@ -55,6 +54,8 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
ph->padlen = 4 - (optlen & 4);
ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
ph->nexthdr = top_iph->protocol;
+ if (ph->padlen)
+ memset(ph + 1, IPOPT_NOP, ph->padlen);
top_iph->protocol = IPPROTO_BEETPH;
top_iph->ihl = sizeof(struct iphdr) / 4;
@@ -77,29 +78,32 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
protocol = iph->protocol;
if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
- struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1);
+ struct ip_beet_phdr *ph;
if (!pskb_may_pull(skb, sizeof(*ph)))
goto out;
+ ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
- phlen = ph->hdrlen * 8;
- optlen = phlen - ph->padlen - sizeof(*ph);
+ phlen = sizeof(*ph) + ph->padlen;
+ optlen = ph->hdrlen * 8 - phlen;
if (optlen < 0 || optlen & 3 || optlen > 250)
goto out;
- if (!pskb_may_pull(skb, phlen))
+ if (!pskb_may_pull(skb, phlen + optlen))
goto out;
+ skb->len -= phlen + optlen;
ph_nexthdr = ph->nexthdr;
}
- skb_push(skb, sizeof(*iph) - phlen + optlen);
- memmove(skb->data, skb->nh.raw, sizeof(*iph));
- skb->nh.raw = skb->data;
+ skb->nh.raw = skb->data + (phlen - sizeof(*iph));
+ memmove(skb->nh.raw, iph, sizeof(*iph));
+ skb->h.raw = skb->data + (phlen + optlen);
+ skb->data = skb->h.raw;
iph = skb->nh.iph;
iph->ihl = (sizeof(*iph) + optlen) / 4;
- iph->tot_len = htons(skb->len);
+ iph->tot_len = htons(skb->len + iph->ihl * 4);
iph->daddr = x->sel.daddr.a4;
iph->saddr = x->sel.saddr.a4;
if (ph_nexthdr)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3931b33b25e8..ad9b285692ba 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt)
static inline int rt6_check_dev(struct rt6_info *rt, int oif)
{
struct net_device *dev = rt->rt6i_dev;
- int ret = 0;
-
- if (!oif)
- return 2;
- if (dev->flags & IFF_LOOPBACK) {
- if (!WARN_ON(rt->rt6i_idev == NULL) &&
- rt->rt6i_idev->dev->ifindex == oif)
- ret = 1;
- else
- return 0;
- }
- if (dev->ifindex == oif)
+ if (!oif || dev->ifindex == oif)
return 2;
-
- return ret;
+ if ((dev->flags & IFF_LOOPBACK) &&
+ rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif)
+ return 1;
+ return 0;
}
static inline int rt6_check_neigh(struct rt6_info *rt)