Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband:
IB/iser: Handle aborting a command after it is sent
IB/mthca: Fix thinko in init_mr_table()
RDMA/cxgb3: Fix resource leak in cxio_hal_init_ctrl_qp()
diff --git a/Documentation/networking/ax25.txt b/Documentation/networking/ax25.txt
index 37c25b0..8257dbf 100644
--- a/Documentation/networking/ax25.txt
+++ b/Documentation/networking/ax25.txt
@@ -1,16 +1,10 @@
To use the amateur radio protocols within Linux you will need to get a
-suitable copy of the AX.25 Utilities. More detailed information about these
-and associated programs can be found on http://zone.pspt.fi/~jsn/.
-
-For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
-the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au>
-who is also the AX.25 Utilities maintainer.
+suitable copy of the AX.25 Utilities. More detailed information about
+AX.25, NET/ROM and ROSE, associated programs and and utilities can be
+found on http://www.linux-ax25.org.
There is an active mailing list for discussing Linux amateur radio matters
-called linux-hams. To subscribe to it, send a message to
+called linux-hams@vger.kernel.org. To subscribe to it, send a message to
majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
-of the message, the subject field is ignored.
-
-Jonathan G4KLX
-
-g4klx@g4klx.demon.co.uk
+of the message, the subject field is ignored. You don't need to be
+subscribed to post but of course that means you might miss an answer.
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
index c750f9f..b6a3cbf 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -102,31 +102,28 @@
--------------
Usage:
- pci_save_state(dev, buffer);
+ pci_save_state(struct pci_dev *dev);
Description:
- Save first 64 bytes of PCI config space. Buffer must be allocated by
- caller.
+ Save first 64 bytes of PCI config space, along with any additional
+ PCI-Express or PCI-X information.
pci_restore_state
-----------------
Usage:
- pci_restore_state(dev, buffer);
+ pci_restore_state(struct pci_dev *dev);
Description:
- Restore previously saved config space. (First 64 bytes only);
-
- If buffer is NULL, then restore what information we know about the
- device from bootup: BARs and interrupt line.
+ Restore previously saved config space.
pci_set_power_state
-------------------
Usage:
- pci_set_power_state(dev, state);
+ pci_set_power_state(struct pci_dev *dev, pci_power_t state);
Description:
Transition device to low power state using PCI PM Capabilities
@@ -142,7 +139,7 @@
---------------
Usage:
- pci_enable_wake(dev, state, enable);
+ pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
Description:
Enable device to generate PME# during low power state using PCI PM
diff --git a/MAINTAINERS b/MAINTAINERS
index dd6978b..8c8090e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1585,12 +1585,6 @@
T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
S: Maintained
-I2O
-P: Markus Lidel
-M: markus.lidel@shadowconnect.com
-W: http://i2o.shadowconnect.com/
-S: Maintained
-
i386 BOOT CODE
P: Riley H. Williams
M: Riley@Williams.Name
@@ -2928,9 +2922,12 @@
S: Maintained
SCTP PROTOCOL
+P: Vlad Yasevich
+M: vladislav.yasevich@hp.com
P: Sridhar Samudrala
M: sri@us.ibm.com
L: lksctp-developers@lists.sourceforge.net
+W: http://lksctp.sourceforge.net
S: Supported
SCx200 CPU SUPPORT
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
index a2b9c60..5b79a7a 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -100,7 +100,9 @@
if ((err = pcibios_enable_resources(dev, mask)) < 0)
return err;
- return pcibios_enable_irq(dev);
+ if (!dev->msi_enabled)
+ pcibios_enable_irq(dev);
+ return 0;
}
int pcibios_assign_resources(void)
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index f7279d7..0b581e3 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -466,6 +466,7 @@
if ((err = pcibios_enable_resources(dev, mask)) < 0)
return err;
- pcibios_enable_irq(dev);
+ if (!dev->msi_enabled)
+ pcibios_enable_irq(dev);
return 0;
}
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
index f3ab61e..76afea6 100644
--- a/arch/i386/kernel/hpet.c
+++ b/arch/i386/kernel/hpet.c
@@ -197,7 +197,7 @@
cnt += delta;
hpet_writel(cnt, HPET_T0_CMP);
- return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0);
+ return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
}
/*
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 1bb0693..3f78d4d 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -193,6 +193,14 @@
},
{
.callback = set_bf_sort,
+ .ident = "Dell PowerEdge R900",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
+ },
+ },
+ {
+ .callback = set_bf_sort,
.ident = "HP ProLiant BL20p G3",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
@@ -426,11 +434,13 @@
if ((err = pcibios_enable_resources(dev, mask)) < 0)
return err;
- return pcibios_enable_irq(dev);
+ if (!dev->msi_enabled)
+ return pcibios_enable_irq(dev);
+ return 0;
}
void pcibios_disable_device (struct pci_dev *dev)
{
- if (pcibios_disable_irq)
+ if (!dev->msi_enabled && pcibios_disable_irq)
pcibios_disable_irq(dev);
}
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 474d179..f8bcccd 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -557,14 +557,18 @@
if (ret < 0)
return ret;
- return acpi_pci_irq_enable(dev);
+ if (!dev->msi_enabled)
+ return acpi_pci_irq_enable(dev);
+ return 0;
}
void
pcibios_disable_device (struct pci_dev *dev)
{
BUG_ON(atomic_read(&dev->enable_cnt));
- acpi_pci_irq_disable(dev);
+ if (!dev->msi_enabled)
+ acpi_pci_irq_disable(dev);
+ return 0;
}
void
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 8af549e..993f353 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -167,7 +167,7 @@
* shall not cross any page boundaries (vmalloc area!) when writing
* the new instruction.
*/
- addr = (u32 *)ALIGN((unsigned long)args->ptr, 4);
+ addr = (u32 *)((unsigned long)args->ptr & -4UL);
if ((unsigned long)args->ptr & 2)
instr = ((*addr) & 0xffff0000) | args->new;
else
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index fe1b276..6e0d10f 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -82,9 +82,6 @@
DECLARE_EXPORT(__movmem_i4_even);
DECLARE_EXPORT(__movmem_i4_odd);
DECLARE_EXPORT(__movmemSI12_i4);
-DECLARE_EXPORT(__sdivsi3_i4i);
-DECLARE_EXPORT(__udiv_qrnnd_16);
-DECLARE_EXPORT(__udivsi3_i4i);
#else /* GCC 3.x */
DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 66cb400..62403bd 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -104,10 +104,6 @@
#endif
#ifdef UML_CONFIG_MODE_SKAS
struct skas_regs {
- /* x86_64 ptrace uses sizeof(user_regs_struct) as its register
- * file size, while i386 uses FRAME_SIZE. Therefore, we need
- * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE.
- */
unsigned long regs[MAX_REG_NR];
unsigned long fp[HOST_FP_SIZE];
struct faultinfo faultinfo;
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index b3c11cf..9383e87 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -48,7 +48,7 @@
static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
{
unsigned long regs[MAX_REG_NR];
- int n;
+ int n, i;
long ret, offset;
unsigned long * data;
unsigned long * syscall;
@@ -66,9 +66,13 @@
(unsigned long) &__syscall_stub_start);
n = ptrace_setregs(pid, regs);
- if(n < 0)
+ if(n < 0){
+ printk("Registers - \n");
+ for(i = 0; i < MAX_REG_NR; i++)
+ printk("\t%d\t0x%lx\n", i, regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
- n);
+ -n);
+ }
wait_stub_done(pid, 0, "do_syscall_stub");
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index dda0678..0564422 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -67,7 +67,7 @@
if((n < 0) || !WIFSTOPPED(status) ||
(WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
- unsigned long regs[HOST_FRAME_SIZE];
+ unsigned long regs[MAX_REG_NR];
if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
printk("Failed to get registers from stub, "
@@ -76,7 +76,7 @@
int i;
printk("Stub registers -\n");
- for(i = 0; i < HOST_FRAME_SIZE; i++)
+ for(i = 0; i < ARRAY_SIZE(regs); i++)
printk("\t%d - %lx\n", i, regs[i]);
}
panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
@@ -328,7 +328,7 @@
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[HOST_FRAME_SIZE];
+ unsigned long regs[MAX_REG_NR];
unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 79cd93c..84b44f9 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -15,7 +15,7 @@
/* These are set once at boot time and not changed thereafter */
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[HOST_FP_SIZE];
static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
static int have_fpx_regs = 1;
@@ -101,6 +101,7 @@
{
int err;
+ memset(exec_regs, 0, sizeof(exec_regs));
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
if(err)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
@@ -124,7 +125,7 @@
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ memcpy(regs, exec_regs, sizeof(exec_regs));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a2d7e0c..e6fc217 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -14,7 +14,7 @@
/* These are set once at boot time and not changed thereafter */
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[HOST_FP_SIZE];
void init_thread_registers(union uml_pt_regs *to)
@@ -72,7 +72,7 @@
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ memcpy(regs, exec_regs, sizeof(exec_regs));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c
index 23178ce..e1548fb 100644
--- a/arch/x86_64/kernel/acpi/sleep.c
+++ b/arch/x86_64/kernel/acpi/sleep.c
@@ -66,8 +66,10 @@
{
pgd_t *slot0 = pgd_offset(current->mm, 0UL);
low_ptr = *slot0;
+ /* FIXME: We're playing with the current task's page tables here, which
+ * is potentially dangerous on SMP systems.
+ */
set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET));
- WARN_ON(num_online_cpus() != 1);
local_flush_tlb();
}
diff --git a/block/elevator.c b/block/elevator.c
index 25f6ef2..96a00c8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -964,17 +964,18 @@
int elv_register(struct elevator_type *e)
{
+ char *def = "";
spin_lock_irq(&elv_list_lock);
BUG_ON(elevator_find(e->elevator_name));
list_add_tail(&e->list, &elv_list);
spin_unlock_irq(&elv_list_lock);
- printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
if (!strcmp(e->elevator_name, chosen_elevator) ||
(!*chosen_elevator &&
!strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
- printk(" (default)");
- printk("\n");
+ def = " (default)";
+
+ printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def);
return 0;
}
EXPORT_SYMBOL_GPL(elv_register);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 38c293b..3de0695 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1221,7 +1221,7 @@
* considered part of another segment, since that might
* change with the bounce page.
*/
- high = page_to_pfn(bv->bv_page) >= q->bounce_pfn;
+ high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
if (high || highprv)
goto new_hw_segment;
if (cluster) {
@@ -3658,8 +3658,8 @@
open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
register_hotcpu_notifier(&blk_cpu_notifier);
- blk_max_low_pfn = max_low_pfn;
- blk_max_pfn = max_pfn;
+ blk_max_low_pfn = max_low_pfn - 1;
+ blk_max_pfn = max_pfn - 1;
return 0;
}
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index dc7b562..fd27227 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -80,6 +80,7 @@
board_ahci_pi = 1,
board_ahci_vt8251 = 2,
board_ahci_ign_iferr = 3,
+ board_ahci_sb600 = 4,
/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
@@ -168,6 +169,7 @@
AHCI_FLAG_NO_NCQ = (1 << 24),
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
+ AHCI_FLAG_IGN_SERR_INTERNAL = (1 << 27), /* ignore SERR_INTERNAL */
};
struct ahci_cmd_hdr {
@@ -362,6 +364,18 @@
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
+ /* board_ahci_sb600 */
+ {
+ .sht = &ahci_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_SKIP_D2H_BSY |
+ AHCI_FLAG_IGN_SERR_INTERNAL,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &ahci_ops,
+ },
+
};
static const struct pci_device_id ahci_pci_tbl[] = {
@@ -399,7 +413,7 @@
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
/* ATI */
- { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
+ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
{ PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
/* VIA */
@@ -1067,8 +1081,11 @@
if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
irq_stat &= ~PORT_IRQ_IF_ERR;
- if (irq_stat & PORT_IRQ_TF_ERR)
+ if (irq_stat & PORT_IRQ_TF_ERR) {
err_mask |= AC_ERR_DEV;
+ if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
+ serror &= ~SERR_INTERNAL;
+ }
if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
err_mask |= AC_ERR_HOST_BUS;
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index c428a56..03a0acf 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -305,7 +305,7 @@
*gtf_address = 0UL;
*obj_loc = 0UL;
- if (noacpi)
+ if (libata_noacpi)
return 0;
if (ata_msg_probe(ap))
@@ -531,7 +531,7 @@
ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
__FUNCTION__, ap->port_no);
- if (noacpi || !(ap->cbl == ATA_CBL_SATA))
+ if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
return 0;
if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
@@ -574,7 +574,7 @@
unsigned long gtf_address;
unsigned long obj_loc;
- if (noacpi)
+ if (libata_noacpi)
return 0;
/*
* TBD - implement PATA support. For now,
@@ -636,7 +636,7 @@
struct acpi_object_list input;
union acpi_object in_params[1];
- if (noacpi)
+ if (libata_noacpi)
return 0;
if (ata_msg_probe(ap))
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bf327d4..f1f595f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -93,8 +93,8 @@
module_param(ata_probe_timeout, int, 0444);
MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
-int noacpi;
-module_param(noacpi, int, 0444);
+int libata_noacpi = 1;
+module_param_named(noacpi, libata_noacpi, int, 0444);
MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
MODULE_AUTHOR("Jeff Garzik");
@@ -3359,6 +3359,8 @@
{ "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
/* http://thread.gmane.org/gmane.linux.ide/14907 */
{ "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
+ /* NCQ is broken */
+ { "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
/* Devices with NCQ limits */
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 361953a..c89664a 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1743,12 +1743,17 @@
{
struct ata_eh_context *ehc = &ap->eh_context;
struct ata_device *dev;
+ unsigned int new_mask = 0;
unsigned long flags;
int i, rc = 0;
DPRINTK("ENTER\n");
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ /* For PATA drive side cable detection to work, IDENTIFY must
+ * be done backwards such that PDIAG- is released by the slave
+ * device before the master device is identified.
+ */
+ for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
unsigned int action, readid_flags = 0;
dev = &ap->device[i];
@@ -1760,13 +1765,13 @@
if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
if (ata_port_offline(ap)) {
rc = -EIO;
- break;
+ goto err;
}
ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
rc = ata_dev_revalidate(dev, readid_flags);
if (rc)
- break;
+ goto err;
ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
@@ -1784,40 +1789,53 @@
rc = ata_dev_read_id(dev, &dev->class, readid_flags,
dev->id);
- if (rc == 0) {
- ehc->i.flags |= ATA_EHI_PRINTINFO;
- rc = ata_dev_configure(dev);
- ehc->i.flags &= ~ATA_EHI_PRINTINFO;
- } else if (rc == -ENOENT) {
+ switch (rc) {
+ case 0:
+ new_mask |= 1 << i;
+ break;
+ case -ENOENT:
/* IDENTIFY was issued to non-existent
* device. No need to reset. Just
* thaw and kill the device.
*/
ata_eh_thaw_port(ap);
dev->class = ATA_DEV_UNKNOWN;
- rc = 0;
- }
-
- if (rc) {
- dev->class = ATA_DEV_UNKNOWN;
break;
- }
-
- if (ata_dev_enabled(dev)) {
- spin_lock_irqsave(ap->lock, flags);
- ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
- spin_unlock_irqrestore(ap->lock, flags);
-
- /* new device discovered, configure xfermode */
- ehc->i.flags |= ATA_EHI_SETMODE;
+ default:
+ dev->class = ATA_DEV_UNKNOWN;
+ goto err;
}
}
}
- if (rc)
- *r_failed_dev = dev;
+ /* Configure new devices forward such that user doesn't see
+ * device detection messages backwards.
+ */
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ dev = &ap->device[i];
- DPRINTK("EXIT\n");
+ if (!(new_mask & (1 << i)))
+ continue;
+
+ ehc->i.flags |= ATA_EHI_PRINTINFO;
+ rc = ata_dev_configure(dev);
+ ehc->i.flags &= ~ATA_EHI_PRINTINFO;
+ if (rc)
+ goto err;
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* new device discovered, configure xfermode */
+ ehc->i.flags |= ATA_EHI_SETMODE;
+ }
+
+ return 0;
+
+ err:
+ *r_failed_dev = dev;
+ DPRINTK("EXIT rc=%d\n", rc);
return rc;
}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index c426714..1f1e3a5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -56,7 +56,7 @@
extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
-extern int noacpi;
+extern int libata_noacpi;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index acdc52c..0a14933 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -195,7 +195,7 @@
/* Cases the state machine will not complete correctly without help */
if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
{
- len = qc->nbytes;
+ len = qc->nbytes / 2;
if (tf->flags & ATA_TFLAG_WRITE)
len |= 0x06000000;
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 337bbcd..8ea0275 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -710,12 +710,6 @@
}
-static unsigned int gs_baudrates[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
-
void gs_set_termios (struct tty_struct * tty,
struct ktermios * old_termios)
{
@@ -771,7 +765,6 @@
baudrate = tty_get_baud_rate(tty);
- baudrate = gs_baudrates[baudrate];
if ((tiosp->c_cflag & CBAUD) == B38400) {
if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baudrate = 57600;
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index d42060e..5ac309e 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -90,7 +90,7 @@
static inline void acpi_pm_need_workaround(void)
{
clocksource_acpi_pm.read = acpi_pm_read_slow;
- clocksource_acpi_pm.rating = 110;
+ clocksource_acpi_pm.rating = 120;
}
/*
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f52facc..3162010 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1015,6 +1015,10 @@
{
unsigned int cpu = sys_dev->id;
int retval;
+
+ if (cpu_is_offline(cpu))
+ return 0;
+
if (unlikely(lock_policy_rwsem_write(cpu)))
BUG();
diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c
index 9e91362..74edb1d 100644
--- a/drivers/eisa/pci_eisa.c
+++ b/drivers/eisa/pci_eisa.c
@@ -19,8 +19,8 @@
/* There is only *one* pci_eisa device per machine, right ? */
static struct eisa_root_device pci_eisa_root;
-static int __devinit pci_eisa_init (struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int __init pci_eisa_init(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
int rc;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8f1fd01..ca2e4f8 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -103,8 +103,10 @@
---help---
There are two drivers for Serial ATA controllers.
- The main driver, "libata", exists inside the SCSI subsystem
- and supports most modern SATA controllers.
+ The main driver, "libata", uses the SCSI subsystem
+ and supports most modern SATA controllers. In order to use it
+ you may take a look at "Serial ATA (prod) and Parallel ATA
+ (experimental) drivers".
The IDE driver (which you are currently configuring) supports
a few first-generation SATA controllers.
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index c193553..0e02800 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -519,21 +519,24 @@
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
try_to_flush_leftover_data(drive);
- if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
- /* force an abort */
- hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
-
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
ide_kill_rq(drive, rq);
- else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
- ++rq->errors;
+ return ide_stopped;
}
+
+ if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+ rq->errors |= ERROR_RESET;
+
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
return ide_stopped;
}
@@ -1025,6 +1028,13 @@
if (!drive->special.all) {
ide_driver_t *drv;
+ /*
+ * We reset the drive so we need to issue a SETFEATURES.
+ * Do it _after_ do_special() restored device parameters.
+ */
+ if (drive->current_speed == 0xff)
+ ide_config_drive_speed(drive, drive->desired_speed);
+
if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
rq->cmd_type == REQ_TYPE_ATA_TASK ||
rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index bd513f5..1ee53a5 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -583,8 +583,12 @@
if(!(drive->id->hw_config & 0x4000))
return 0;
#endif /* CONFIG_IDEDMA_IVB */
- if (!(drive->id->hw_config & 0x2000))
- return 0;
+ /*
+ * FIXME:
+ * - change master/slave IDENTIFY order
+ * - force bit13 (80c cable present) check
+ * (unless the slave device is pre-ATA3)
+ */
return 1;
}
@@ -1090,6 +1094,9 @@
if (HWIF(drive)->pre_reset != NULL)
HWIF(drive)->pre_reset(drive);
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
}
/*
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 695610f..a6f098f 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1124,17 +1124,40 @@
static int set_using_dma (ide_drive_t *drive, int arg)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
+ ide_hwif_t *hwif = drive->hwif;
+ int err = -EPERM;
+
if (!drive->id || !(drive->id->capability & 1))
- return -EPERM;
- if (HWIF(drive)->ide_dma_check == NULL)
- return -EPERM;
+ goto out;
+
+ if (hwif->ide_dma_check == NULL)
+ goto out;
+
+ err = -EBUSY;
+ if (ide_spin_wait_hwgroup(drive))
+ goto out;
+ /*
+ * set ->busy flag, unlock and let it ride
+ */
+ hwif->hwgroup->busy = 1;
+ spin_unlock_irq(&ide_lock);
+
+ err = 0;
+
if (arg) {
- if (ide_set_dma(drive))
- return -EIO;
- if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
+ if (ide_set_dma(drive) || hwif->ide_dma_on(drive))
+ err = -EIO;
} else
ide_dma_off(drive);
- return 0;
+
+ /*
+ * lock, clear ->busy flag and unlock before leaving
+ */
+ spin_lock_irq(&ide_lock);
+ hwif->hwgroup->busy = 0;
+ spin_unlock_irq(&ide_lock);
+out:
+ return err;
#else
return -EPERM;
#endif
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 6ceb25b..ace9892 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -255,7 +255,7 @@
printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
}
- if (drive->media != ide_disk)
+ if (drive->media != ide_disk && drive->media != ide_cdrom)
return 0;
if (id->capability & 4) {
@@ -545,6 +545,7 @@
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ hwif->atapi_dma = 1;
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 0741c6d..f2a40ae 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -814,7 +814,7 @@
queue_work(ipoib_workqueue, &priv->restart_task);
}
-static void ipoib_neigh_destructor(struct neighbour *n)
+static void ipoib_neigh_cleanup(struct neighbour *n)
{
struct ipoib_neigh *neigh;
struct ipoib_dev_priv *priv = netdev_priv(n->dev);
@@ -822,7 +822,7 @@
struct ipoib_ah *ah = NULL;
ipoib_dbg(priv,
- "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
+ "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
IPOIB_QPN(n->ha),
IPOIB_GID_RAW_ARG(n->ha + 4));
@@ -874,7 +874,7 @@
static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
{
- parms->neigh_destructor = ipoib_neigh_destructor;
+ parms->neigh_cleanup = ipoib_neigh_cleanup;
return 0;
}
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 9df9e35..c547a66 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -440,7 +440,7 @@
{
struct BCState *bcs = container_of(work, struct BCState, tqueue);
- BChannel_bh(bcs);
+ BChannel_bh(work);
if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event))
ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR);
if (test_and_clear_bit(B_LL_CONNECT, &bcs->event))
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index bfa0ce4..fbbf9d6 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -618,7 +618,7 @@
{
struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
- if (vmcs_readl(sf->base) == save->base) {
+ if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) {
vmcs_write16(sf->selector, save->selector);
vmcs_writel(sf->base, save->base);
vmcs_write32(sf->limit, save->limit);
@@ -1888,6 +1888,27 @@
[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
: "cc", "memory" );
+ /*
+ * Reload segment selectors ASAP. (it's needed for a functional
+ * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64
+ * relies on having 0 in %gs for the CPU PDA to work.)
+ */
+ if (fs_gs_ldt_reload_needed) {
+ load_ldt(ldt_sel);
+ load_fs(fs_sel);
+ /*
+ * If we have to reload gs, we must take care to
+ * preserve our gs base.
+ */
+ local_irq_disable();
+ load_gs(gs_sel);
+#ifdef CONFIG_X86_64
+ wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
+#endif
+ local_irq_enable();
+
+ reload_tss();
+ }
++kvm_stat.exits;
save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
@@ -1905,22 +1926,6 @@
kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
r = 0;
} else {
- if (fs_gs_ldt_reload_needed) {
- load_ldt(ldt_sel);
- load_fs(fs_sel);
- /*
- * If we have to reload gs, we must take care to
- * preserve our gs base.
- */
- local_irq_disable();
- load_gs(gs_sel);
-#ifdef CONFIG_X86_64
- wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
-#endif
- local_irq_enable();
-
- reload_tss();
- }
/*
* Profile KVM exit RIPs:
*/
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6c06e82..2a9b6a0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1318,6 +1318,7 @@
char b[BDEVNAME_SIZE];
struct kobject *ko;
char *s;
+ int err;
if (rdev->mddev) {
MD_BUG();
@@ -1352,20 +1353,29 @@
while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL)
*s = '!';
- list_add(&rdev->same_set, &mddev->disks);
rdev->mddev = mddev;
printk(KERN_INFO "md: bind<%s>\n", b);
rdev->kobj.parent = &mddev->kobj;
- kobject_add(&rdev->kobj);
+ if ((err = kobject_add(&rdev->kobj)))
+ goto fail;
if (rdev->bdev->bd_part)
ko = &rdev->bdev->bd_part->kobj;
else
ko = &rdev->bdev->bd_disk->kobj;
- sysfs_create_link(&rdev->kobj, ko, "block");
+ if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) {
+ kobject_del(&rdev->kobj);
+ goto fail;
+ }
+ list_add(&rdev->same_set, &mddev->disks);
bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk);
return 0;
+
+ fail:
+ printk(KERN_WARNING "md: failed to register dev-%s for %s\n",
+ b, mdname(mddev));
+ return err;
}
static void unbind_rdev_from_array(mdk_rdev_t * rdev)
@@ -2966,7 +2976,9 @@
mddev->kobj.k_name = NULL;
snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
mddev->kobj.ktype = &md_ktype;
- kobject_register(&mddev->kobj);
+ if (kobject_register(&mddev->kobj))
+ printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
+ disk->disk_name);
return NULL;
}
@@ -3144,9 +3156,12 @@
bitmap_destroy(mddev);
return err;
}
- if (mddev->pers->sync_request)
- sysfs_create_group(&mddev->kobj, &md_redundancy_group);
- else if (mddev->ro == 2) /* auto-readonly not meaningful */
+ if (mddev->pers->sync_request) {
+ if (sysfs_create_group(&mddev->kobj, &md_redundancy_group))
+ printk(KERN_WARNING
+ "md: cannot register extra attributes for %s\n",
+ mdname(mddev));
+ } else if (mddev->ro == 2) /* auto-readonly not meaningful */
mddev->ro = 0;
atomic_set(&mddev->writes_pending,0);
@@ -3160,7 +3175,9 @@
if (rdev->raid_disk >= 0) {
char nm[20];
sprintf(nm, "rd%d", rdev->raid_disk);
- sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
+ if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm))
+ printk("md: cannot register %s for %s\n",
+ nm, mdname(mddev));
}
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -3325,6 +3342,7 @@
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
mddev->queue->issue_flush_fn = NULL;
+ mddev->queue->backing_dev_info.congested_fn = NULL;
if (mddev->pers->sync_request)
sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
@@ -5385,8 +5403,12 @@
if (mddev->pers->hot_add_disk(mddev,rdev)) {
char nm[20];
sprintf(nm, "rd%d", rdev->raid_disk);
- sysfs_create_link(&mddev->kobj,
- &rdev->kobj, nm);
+ if (sysfs_create_link(&mddev->kobj,
+ &rdev->kobj, nm))
+ printk(KERN_WARNING
+ "md: cannot register "
+ "%s for %s\n",
+ nm, mdname(mddev));
spares++;
md_new_event(mddev);
} else
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 54a1ad5..8d59914 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3642,12 +3642,15 @@
}
/* Ok, everything is just fine now */
- sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
+ if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group))
+ printk(KERN_WARNING
+ "raid5: failed to create sysfs attributes for %s\n",
+ mdname(mddev));
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->issue_flush_fn = raid5_issue_flush;
- mddev->queue->backing_dev_info.congested_fn = raid5_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
+ mddev->queue->backing_dev_info.congested_fn = raid5_congested;
mddev->array_size = mddev->size * (conf->previous_raid_disks -
conf->max_degraded);
@@ -3678,6 +3681,7 @@
mddev->thread = NULL;
shrink_stripes(conf);
kfree(conf->stripe_hashtbl);
+ mddev->queue->backing_dev_info.congested_fn = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
kfree(conf->disks);
@@ -3950,7 +3954,12 @@
added_devices++;
rdev->recovery_offset = 0;
sprintf(nm, "rd%d", rdev->raid_disk);
- sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
+ if (sysfs_create_link(&mddev->kobj,
+ &rdev->kobj, nm))
+ printk(KERN_WARNING
+ "raid5: failed to create "
+ " link %s for %s\n",
+ nm, mdname(mddev));
} else
break;
}
@@ -4104,6 +4113,10 @@
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
+#ifdef CONFIG_MD_RAID5_RESHAPE
+ .check_reshape = raid5_check_reshape,
+ .start_reshape = raid5_start_reshape,
+#endif
.quiesce = raid5_quiesce,
};
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index cbf7c05..fcb1941 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -310,13 +310,15 @@
tv.tv_usec - ir->base_time.tv_usec;
}
- /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
+ /* signal we're ready to start a new code */
+ ir->active = 0;
+
+ /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
if (gap < 28000) {
dprintk(1, "ir-common: spurious timer_end\n");
return;
}
- ir->active = 0;
if (ir->last_bit < 20) {
/* ignore spurious codes (caused by light/other remotes) */
dprintk(1, "ir-common: short code: %x\n", ir->code);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index fc77de4..a5c0e1a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -180,8 +180,7 @@
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
- if (mutex_lock_interruptible(&dmxdev->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dmxdev->mutex);
if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
dmxdev->demux->disconnect_frontend(dmxdev->demux);
@@ -673,13 +672,8 @@
static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
struct dmxdev_filter *dmxdevfilter)
{
- if (mutex_lock_interruptible(&dmxdev->mutex))
- return -ERESTARTSYS;
-
- if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
- mutex_unlock(&dmxdev->mutex);
- return -ERESTARTSYS;
- }
+ mutex_lock(&dmxdev->mutex);
+ mutex_lock(&dmxdevfilter->mutex);
dvb_dmxdev_filter_stop(dmxdevfilter);
dvb_dmxdev_filter_reset(dmxdevfilter);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index fcff5ea..6d8d1c3d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -673,8 +673,7 @@
struct dvb_demux *demux = feed->demux;
int ret;
- if (mutex_lock_interruptible(&demux->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&demux->mutex);
if (feed->state < DMX_STATE_GO) {
mutex_unlock(&demux->mutex);
@@ -748,8 +747,7 @@
struct dvb_demux *demux = (struct dvb_demux *)dmx;
struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
- if (mutex_lock_interruptible(&demux->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&demux->mutex);
if (feed->state == DMX_STATE_FREE) {
mutex_unlock(&demux->mutex);
@@ -916,8 +914,7 @@
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
int ret;
- if (mutex_lock_interruptible(&dvbdmx->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdmx->mutex);
if (!dvbdmx->stop_feed) {
mutex_unlock(&dvbdmx->mutex);
@@ -942,8 +939,7 @@
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- if (mutex_lock_interruptible(&dvbdmx->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdmx->mutex);
if (dvbdmxfilter->feed != dvbdmxfeed) {
mutex_unlock(&dvbdmx->mutex);
@@ -1016,8 +1012,7 @@
struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
- if (mutex_lock_interruptible(&dvbdmx->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdmx->mutex);
if (dvbdmxfeed->state == DMX_STATE_FREE) {
mutex_unlock(&dvbdmx->mutex);
@@ -1126,8 +1121,7 @@
if (demux->frontend)
return -EINVAL;
- if (mutex_lock_interruptible(&dvbdemux->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdemux->mutex);
demux->frontend = frontend;
mutex_unlock(&dvbdemux->mutex);
@@ -1138,8 +1132,7 @@
{
struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
- if (mutex_lock_interruptible(&dvbdemux->mutex))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdemux->mutex);
demux->frontend = NULL;
mutex_unlock(&dvbdemux->mutex);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 490337b..14a372a 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -203,8 +203,7 @@
int id;
- if (mutex_lock_interruptible(&dvbdev_register_lock))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdev_register_lock);
if ((id = dvbdev_get_free_id (adap, type)) < 0){
mutex_unlock(&dvbdev_register_lock);
@@ -294,8 +293,7 @@
{
int num;
- if (mutex_lock_interruptible(&dvbdev_register_lock))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdev_register_lock);
if ((num = dvbdev_get_free_adapter_num ()) < 0) {
mutex_unlock(&dvbdev_register_lock);
@@ -323,8 +321,7 @@
int dvb_unregister_adapter(struct dvb_adapter *adap)
{
- if (mutex_lock_interruptible(&dvbdev_register_lock))
- return -ERESTARTSYS;
+ mutex_lock(&dvbdev_register_lock);
list_del (&adap->list_head);
mutex_unlock(&dvbdev_register_lock);
return 0;
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
index ef31936..c967148 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -122,6 +122,7 @@
/* detect if it is present or not */
if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
kfree(isl6421);
+ fe->sec_priv = NULL;
return NULL;
}
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 920b63f..af66a5d 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -3,7 +3,7 @@
#
menu "Radio Adapters"
- depends on VIDEO_DEV!=n
+ depends on VIDEO_DEV
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 2fb9fe6..ba1af3c 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -780,18 +780,16 @@
return 0;
}
-static int msp_suspend(struct device * dev, pm_message_t state)
+static int msp_suspend(struct i2c_client *client, pm_message_t state)
{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
v4l_dbg(1, msp_debug, client, "suspend\n");
msp_reset(client);
return 0;
}
-static int msp_resume(struct device * dev)
+static int msp_resume(struct i2c_client *client)
{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
v4l_dbg(1, msp_debug, client, "resume\n");
msp_wake_thread(client);
@@ -825,7 +823,7 @@
if (msp_reset(client) == -1) {
v4l_dbg(1, msp_debug, client, "msp3400 not found\n");
kfree(client);
- return -1;
+ return 0;
}
state = kmalloc(sizeof(*state), GFP_KERNEL);
@@ -859,7 +857,7 @@
v4l_dbg(1, msp_debug, client, "not an msp3400 (cannot read chip version)\n");
kfree(state);
kfree(client);
- return -1;
+ return 0;
}
msp_set_audio(client);
@@ -996,11 +994,11 @@
.id = I2C_DRIVERID_MSP3400,
.attach_adapter = msp_probe,
.detach_client = msp_detach,
+ .suspend = msp_suspend,
+ .resume = msp_resume,
.command = msp_command,
.driver = {
.name = "msp3400",
- .suspend = msp_suspend,
- .resume = msp_resume,
},
};
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 7735b67..4d5bbd8 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -961,7 +961,7 @@
reg |= 0x10;
} else if (std == V4L2_STD_NTSC_M_JP) {
reg |= 0x40;
- } else if (std == V4L2_STD_SECAM) {
+ } else if (std & V4L2_STD_SECAM) {
reg |= 0x50;
}
saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 7be73e3..15dbc6b 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -804,9 +804,8 @@
return 0;
}
-static int tuner_suspend(struct device *dev, pm_message_t state)
+static int tuner_suspend(struct i2c_client *c, pm_message_t state)
{
- struct i2c_client *c = container_of (dev, struct i2c_client, dev);
struct tuner *t = i2c_get_clientdata (c);
tuner_dbg ("suspend\n");
@@ -814,9 +813,8 @@
return 0;
}
-static int tuner_resume(struct device *dev)
+static int tuner_resume(struct i2c_client *c)
{
- struct i2c_client *c = container_of (dev, struct i2c_client, dev);
struct tuner *t = i2c_get_clientdata (c);
tuner_dbg ("resume\n");
@@ -837,10 +835,10 @@
.attach_adapter = tuner_probe,
.detach_client = tuner_detach,
.command = tuner_command,
+ .suspend = tuner_suspend,
+ .resume = tuner_resume,
.driver = {
.name = "tuner",
- .suspend = tuner_suspend,
- .resume = tuner_resume,
},
};
static struct i2c_client client_template = {
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 404c014..1d2d03f 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -815,7 +815,7 @@
static int
mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ MPT_SCSI_HOST *hd;
struct mptsas_target_reset_event *target_reset_list, *n;
int rc;
@@ -827,7 +827,10 @@
if (reset_phase != MPT_IOC_POST_RESET)
goto out;
- if (!hd || !hd->ioc)
+ if (!ioc->sh || !ioc->sh->hostdata)
+ goto out;
+ hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ if (!hd->ioc)
goto out;
if (list_empty(&hd->target_reset_list))
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index da9859f..b17c4b2 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -390,13 +390,6 @@
return BLKPREP_KILL;
}
- /* request is already processed by us, so return */
- if (blk_special_request(req)) {
- osm_debug("REQ_SPECIAL already set!\n");
- req->cmd_flags |= REQ_DONTPREP;
- return BLKPREP_OK;
- }
-
/* connect the i2o_block_request to the request */
if (!req->special) {
ireq = i2o_block_request_alloc();
@@ -408,11 +401,8 @@
ireq->i2o_blk_dev = i2o_blk_dev;
req->special = ireq;
ireq->req = req;
- } else
- ireq = req->special;
-
+ }
/* do not come back here */
- req->cmd_type = REQ_TYPE_SPECIAL;
req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK;
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 314dbaa..69482e0 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -334,7 +334,6 @@
int i;
crc32 = ether_crc_le(6, mc_addr);
- crc32 = ~crc32;
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 46e1697..d04214e 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2050,9 +2050,10 @@
nv_drain_tx(dev);
nv_init_tx(dev);
setup_hw_rings(dev, NV_SETUP_TX_RING);
- netif_wake_queue(dev);
}
+ netif_wake_queue(dev);
+
/* 4) restart tx engine */
nv_start_tx(dev);
spin_unlock_irq(&np->lock);
@@ -3536,7 +3537,10 @@
pci_push(base);
if (!using_multi_irqs(dev)) {
- nv_nic_irq(0, dev);
+ if (np->desc_ver == DESC_VER_3)
+ nv_nic_irq_optimized(0, dev);
+ else
+ nv_nic_irq(0, dev);
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index c9f55bc..8015a7c 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1379,7 +1379,7 @@
spin_lock_init(&mp->lock);
- port_num = pd->port_number;
+ port_num = mp->port_num = pd->port_number;
/* set default config values */
eth_port_uc_addr_get(dev, dev->dev_addr);
@@ -1411,8 +1411,6 @@
duplex = pd->duplex;
speed = pd->speed;
- mp->port_num = port_num;
-
/* Hook up MII support for ethtool */
mp->mii.dev = dev;
mp->mii.mdio_read = mv643xx_mdio_read;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index b05b20e..c216e6a 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.0-1.226"
+#define MYRI10GE_VERSION_STR "1.3.0-1.227"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -2015,10 +2015,9 @@
mss = 0;
max_segments = MXGEFW_MAX_SEND_DESC;
- if (skb->len > (dev->mtu + ETH_HLEN)) {
+ if (skb_is_gso(skb)) {
mss = skb_shinfo(skb)->gso_size;
- if (mss != 0)
- max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
+ max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
}
if ((unlikely(avail < max_segments))) {
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 11b575f..ef58e41 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2544,6 +2544,9 @@
ppp->active_filter = NULL;
#endif /* CONFIG_PPP_FILTER */
+ if (ppp->xmit_pending)
+ kfree_skb(ppp->xmit_pending);
+
kfree(ppp);
}
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index d3f65da..a8246eb 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1691,6 +1691,27 @@
/*
* Caller holds hw_lock.
*/
+static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev)
+{
+ struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
+ if (qdev->small_buf_release_cnt >= 16) {
+ while (qdev->small_buf_release_cnt >= 16) {
+ qdev->small_buf_q_producer_index++;
+
+ if (qdev->small_buf_q_producer_index ==
+ NUM_SBUFQ_ENTRIES)
+ qdev->small_buf_q_producer_index = 0;
+ qdev->small_buf_release_cnt -= 8;
+ }
+ wmb();
+ writel(qdev->small_buf_q_producer_index,
+ &port_regs->CommonRegs.rxSmallQProducerIndex);
+ }
+}
+
+/*
+ * Caller holds hw_lock.
+ */
static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev)
{
struct bufq_addr_element *lrg_buf_q_ele;
@@ -1732,13 +1753,10 @@
lrg_buf_q_ele = qdev->lrg_buf_q_virt_addr;
}
}
-
+ wmb();
qdev->lrg_buf_next_free = lrg_buf_q_ele;
-
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.
- rxLargeQProducerIndex,
- qdev->lrg_buf_q_producer_index);
+ writel(qdev->lrg_buf_q_producer_index,
+ &port_regs->CommonRegs.rxLargeQProducerIndex);
}
}
@@ -1915,17 +1933,18 @@
u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum);
if (checksum &
(IB_IP_IOCB_RSP_3032_ICE |
- IB_IP_IOCB_RSP_3032_CE |
- IB_IP_IOCB_RSP_3032_NUC)) {
+ IB_IP_IOCB_RSP_3032_CE)) {
printk(KERN_ERR
"%s: Bad checksum for this %s packet, checksum = %x.\n",
__func__,
((checksum &
IB_IP_IOCB_RSP_3032_TCP) ? "TCP" :
"UDP"),checksum);
- } else if (checksum & IB_IP_IOCB_RSP_3032_TCP) {
+ } else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) ||
+ (checksum & IB_IP_IOCB_RSP_3032_UDP &&
+ !(checksum & IB_IP_IOCB_RSP_3032_NUC))) {
skb2->ip_summed = CHECKSUM_UNNECESSARY;
- }
+ }
}
skb2->dev = qdev->ndev;
skb2->protocol = eth_type_trans(skb2, qdev->ndev);
@@ -1944,16 +1963,12 @@
static int ql_tx_rx_clean(struct ql3_adapter *qdev,
int *tx_cleaned, int *rx_cleaned, int work_to_do)
{
- struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
struct net_rsp_iocb *net_rsp;
struct net_device *ndev = qdev->ndev;
- unsigned long hw_flags;
int work_done = 0;
- u32 rsp_producer_index = le32_to_cpu(*(qdev->prsp_producer_index));
-
/* While there are entries in the completion queue. */
- while ((rsp_producer_index !=
+ while ((le32_to_cpu(*(qdev->prsp_producer_index)) !=
qdev->rsp_consumer_index) && (work_done < work_to_do)) {
net_rsp = qdev->rsp_current;
@@ -2009,33 +2024,7 @@
work_done = *tx_cleaned + *rx_cleaned;
}
- if(work_done) {
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-
- ql_update_lrg_bufq_prod_index(qdev);
-
- if (qdev->small_buf_release_cnt >= 16) {
- while (qdev->small_buf_release_cnt >= 16) {
- qdev->small_buf_q_producer_index++;
-
- if (qdev->small_buf_q_producer_index ==
- NUM_SBUFQ_ENTRIES)
- qdev->small_buf_q_producer_index = 0;
- qdev->small_buf_release_cnt -= 8;
- }
-
- wmb();
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.
- rxSmallQProducerIndex,
- qdev->small_buf_q_producer_index);
-
- }
-
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
- }
-
- return *tx_cleaned + *rx_cleaned;
+ return work_done;
}
static int ql_poll(struct net_device *ndev, int *budget)
@@ -2059,9 +2048,10 @@
netif_rx_complete(ndev);
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
- ql_write_common_reg(qdev,
- &port_regs->CommonRegs.rspQConsumerIndex,
- qdev->rsp_consumer_index);
+ ql_update_small_bufq_prod_index(qdev);
+ ql_update_lrg_bufq_prod_index(qdev);
+ writel(qdev->rsp_consumer_index,
+ &port_regs->CommonRegs.rspQConsumerIndex);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
ql_enable_interrupts(qdev);
@@ -2217,12 +2207,7 @@
int seg_cnt, seg = 0;
int frag_cnt = (int)skb_shinfo(skb)->nr_frags;
- seg_cnt = tx_cb->seg_count = ql_get_seg_count(qdev,
- (skb_shinfo(skb)->nr_frags));
- if(seg_cnt == -1) {
- printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
- return NETDEV_TX_BUSY;
- }
+ seg_cnt = tx_cb->seg_count;
/*
* Map the skb buffer first.
*/
@@ -2278,7 +2263,7 @@
pci_unmap_addr_set(&tx_cb->map[seg], mapaddr,
map);
pci_unmap_len_set(&tx_cb->map[seg], maplen,
- len);
+ sizeof(struct oal));
oal_entry = (struct oal_entry *)oal;
oal++;
seg++;
@@ -2380,6 +2365,7 @@
}
mac_iocb_ptr = tx_cb->queue_entry;
+ memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req));
mac_iocb_ptr->opcode = qdev->mac_ob_opcode;
mac_iocb_ptr->flags = OB_MAC_IOCB_REQ_X;
mac_iocb_ptr->flags |= qdev->mb_bit_mask;
@@ -3054,15 +3040,6 @@
goto out;
}
- if (qdev->mac_index)
- ql_write_page0_reg(qdev,
- &port_regs->mac1MaxFrameLengthReg,
- qdev->max_frame_size);
- else
- ql_write_page0_reg(qdev,
- &port_regs->mac0MaxFrameLengthReg,
- qdev->max_frame_size);
-
value = qdev->nvram_data.tcpMaxWindowSize;
ql_write_page0_reg(qdev, &port_regs->tcpMaxWindow, value);
@@ -3082,6 +3059,14 @@
ql_sem_unlock(qdev, QL_FLASH_SEM_MASK);
}
+ if (qdev->mac_index)
+ ql_write_page0_reg(qdev,
+ &port_regs->mac1MaxFrameLengthReg,
+ qdev->max_frame_size);
+ else
+ ql_write_page0_reg(qdev,
+ &port_regs->mac0MaxFrameLengthReg,
+ qdev->max_frame_size);
if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
@@ -3152,7 +3137,8 @@
if (qdev->device_id == QL3032_DEVICE_ID) {
value =
(QL3032_PORT_CONTROL_EF | QL3032_PORT_CONTROL_KIE |
- QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4);
+ QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4 |
+ QL3032_PORT_CONTROL_ET);
ql_write_page0_reg(qdev, &port_regs->functionControl,
((value << 16) | value));
} else {
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 34cd658..0203f88 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1014,8 +1014,7 @@
/* Transmit and Receive Buffers */
#define NUM_LBUFQ_ENTRIES 128
-#define JUMBO_NUM_LBUFQ_ENTRIES \
-(NUM_LBUFQ_ENTRIES/(JUMBO_MTU_SIZE/NORMAL_MTU_SIZE))
+#define JUMBO_NUM_LBUFQ_ENTRIES 32
#define NUM_SBUFQ_ENTRIES 64
#define QL_SMALL_BUFFER_SIZE 32
#define QL_ADDR_ELE_PER_BUFQ_ENTRY \
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index c62e85d..7bee45b 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -336,13 +336,27 @@
/* XXX - leak? */
MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+ if (MEM == NULL) {
+#ifdef CONFIG_SUN3
+ iounmap((void __iomem *)ioaddr);
+#endif
+ printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
+ return 0;
+ }
lp->iobase = (volatile unsigned short *)ioaddr;
dev->base_addr = (unsigned long)ioaddr; /* informational only */
REGA(CSR0) = CSR0_STOP;
- request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev);
+ if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) {
+#ifdef CONFIG_SUN3
+ iounmap((void __iomem *)ioaddr);
+#endif
+ dvma_free((void *)MEM);
+ printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
+ return 0;
+ }
dev->irq = (unsigned short)LANCE_IRQ;
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 616be8d..08ea61d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2530,6 +2530,35 @@
return &gp->net_stats;
}
+static int gem_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct sockaddr *macaddr = (struct sockaddr *) addr;
+ struct gem *gp = dev->priv;
+ unsigned char *e = &dev->dev_addr[0];
+
+ if (!is_valid_ether_addr(macaddr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (!netif_running(dev) || !netif_device_present(dev)) {
+ /* We'll just catch it later when the
+ * device is up'd or resumed.
+ */
+ memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+ return 0;
+ }
+
+ mutex_lock(&gp->pm_mutex);
+ memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+ if (gp->running) {
+ writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0);
+ writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1);
+ writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2);
+ }
+ mutex_unlock(&gp->pm_mutex);
+
+ return 0;
+}
+
static void gem_set_multicast(struct net_device *dev)
{
struct gem *gp = dev->priv;
@@ -3122,6 +3151,7 @@
dev->change_mtu = gem_change_mtu;
dev->irq = pdev->irq;
dev->dma = 0;
+ dev->set_mac_address = gem_set_mac_address;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = gem_poll_controller;
#endif
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8c8f9f4..0acee9f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.74"
-#define DRV_MODULE_RELDATE "February 20, 2007"
+#define DRV_MODULE_VERSION "3.75"
+#define DRV_MODULE_RELDATE "March 23, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -3568,32 +3568,34 @@
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if ((sblk->status & SD_STATUS_UPDATED) ||
- !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
- /*
- * Writing any value to intr-mbox-0 clears PCI INTA# and
- * chip-internal interrupt pending events.
- * Writing non-zero to intr-mbox-0 additional tells the
- * NIC to stop sending us irqs, engaging "in-intr-handler"
- * event coalescing.
- */
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000001);
- if (tg3_irq_sync(tp))
+ if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
+ if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+ handled = 0;
goto out;
- sblk->status &= ~SD_STATUS_UPDATED;
- if (likely(tg3_has_work(tp))) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- netif_rx_schedule(dev); /* schedule NAPI poll */
- } else {
- /* No work, shared interrupt perhaps? re-enable
- * interrupts, and flush that PCI write
- */
- tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000000);
}
- } else { /* shared interrupt */
- handled = 0;
+ }
+
+ /*
+ * Writing any value to intr-mbox-0 clears PCI INTA# and
+ * chip-internal interrupt pending events.
+ * Writing non-zero to intr-mbox-0 additional tells the
+ * NIC to stop sending us irqs, engaging "in-intr-handler"
+ * event coalescing.
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
+ sblk->status &= ~SD_STATUS_UPDATED;
+ if (likely(tg3_has_work(tp))) {
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ netif_rx_schedule(dev); /* schedule NAPI poll */
+ } else {
+ /* No work, shared interrupt perhaps? re-enable
+ * interrupts, and flush that PCI write
+ */
+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+ 0x00000000);
}
out:
return IRQ_RETVAL(handled);
@@ -3611,31 +3613,33 @@
* Reading the PCI State register will confirm whether the
* interrupt is ours and will flush the status block.
*/
- if ((sblk->status_tag != tp->last_tag) ||
- !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
- /*
- * writing any value to intr-mbox-0 clears PCI INTA# and
- * chip-internal interrupt pending events.
- * writing non-zero to intr-mbox-0 additional tells the
- * NIC to stop sending us irqs, engaging "in-intr-handler"
- * event coalescing.
- */
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
- 0x00000001);
- if (tg3_irq_sync(tp))
+ if (unlikely(sblk->status_tag == tp->last_tag)) {
+ if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+ (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+ handled = 0;
goto out;
- if (netif_rx_schedule_prep(dev)) {
- prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- /* Update last_tag to mark that this status has been
- * seen. Because interrupt may be shared, we may be
- * racing with tg3_poll(), so only update last_tag
- * if tg3_poll() is not scheduled.
- */
- tp->last_tag = sblk->status_tag;
- __netif_rx_schedule(dev);
}
- } else { /* shared interrupt */
- handled = 0;
+ }
+
+ /*
+ * writing any value to intr-mbox-0 clears PCI INTA# and
+ * chip-internal interrupt pending events.
+ * writing non-zero to intr-mbox-0 additional tells the
+ * NIC to stop sending us irqs, engaging "in-intr-handler"
+ * event coalescing.
+ */
+ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
+ if (netif_rx_schedule_prep(dev)) {
+ prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+ /* Update last_tag to mark that this status has been
+ * seen. Because interrupt may be shared, we may be
+ * racing with tg3_poll(), so only update last_tag
+ * if tg3_poll() is not scheduled.
+ */
+ tp->last_tag = sblk->status_tag;
+ __netif_rx_schedule(dev);
}
out:
return IRQ_RETVAL(handled);
@@ -4823,6 +4827,19 @@
if (write_op == tg3_write_flush_reg32)
tp->write32 = tg3_write32;
+ /* Prevent the irq handler from reading or writing PCI registers
+ * during chip reset when the memory enable bit in the PCI command
+ * register may be cleared. The chip does not generate interrupt
+ * at this time, but the irq handler may still be called due to irq
+ * sharing or irqpoll.
+ */
+ tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
+ tp->hw_status->status = 0;
+ tp->hw_status->status_tag = 0;
+ tp->last_tag = 0;
+ smp_mb();
+ synchronize_irq(tp->pdev->irq);
+
/* do the reset */
val = GRC_MISC_CFG_CORECLK_RESET;
@@ -4904,6 +4921,8 @@
pci_restore_state(tp->pdev);
+ tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
+
/* Make sure PCI-X relaxed ordering bit is clear. */
pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
val &= ~PCIX_CAPS_RELAXED_ORDERING;
@@ -6321,8 +6340,6 @@
RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
- if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
- rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
/* If statement applies to 5705 and 5750 PCI devices only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
@@ -6495,9 +6512,6 @@
} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
- if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
- val |= (tp->split_mode_max_reqs <<
- PCIX_CAPS_SPLIT_SHIFT);
}
tw32(TG3PCI_X_CAPS, val);
}
@@ -10863,14 +10877,6 @@
grc_misc_cfg = tr32(GRC_MISC_CFG);
grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
- /* Broadcom's driver says that CIOBE multisplit has a bug */
-#if 0
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
- grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
- tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
- tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
- }
-#endif
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
@@ -11968,14 +11974,12 @@
i == 5 ? '\n' : ':');
printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
- "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] "
- "TSOcap[%d] \n",
+ "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
dev->name,
(tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
(tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
(tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
- (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
(tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 086892d..d515ed2 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2223,7 +2223,7 @@
#define TG3_FLAG_40BIT_DMA_BUG 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
-#define TG3_FLAG_SPLIT_MODE 0x40000000
+#define TG3_FLAG_CHIP_RESETTING 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 tg3_flags2;
#define TG3_FLG2_RESTART_TIMER 0x00000001
@@ -2262,9 +2262,6 @@
#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
#define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000
- u32 split_mode_max_reqs;
-#define SPLIT_MODE_5704_MAX_REQ 3
-
struct timer_list timer;
u16 timer_counter;
u16 timer_multiplier;
diff --git a/drivers/net/wan/lmc/lmc_media.h b/drivers/net/wan/lmc/lmc_media.h
deleted file mode 100644
index ddcc004..0000000
--- a/drivers/net/wan/lmc/lmc_media.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _LMC_MEDIA_H_
-#define _LMC_MEDIA_H_
-
-lmc_media_t lmc_ds3_media = {
- lmc_ds3_init, /* special media init stuff */
- lmc_ds3_default, /* reset to default state */
- lmc_ds3_set_status, /* reset status to state provided */
- lmc_dummy_set_1, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_ds3_set_100ft, /* set cable length */
- lmc_ds3_set_scram, /* set scrambler */
- lmc_ds3_get_link_status, /* get link status */
- lmc_dummy_set_1, /* set link status */
- lmc_ds3_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_ds3_watchdog
-};
-
-lmc_media_t lmc_hssi_media = {
- lmc_hssi_init, /* special media init stuff */
- lmc_hssi_default, /* reset to default state */
- lmc_hssi_set_status, /* reset status to state provided */
- lmc_hssi_set_clock, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_hssi_get_link_status, /* get link status */
- lmc_hssi_set_link_status, /* set link status */
- lmc_hssi_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_hssi_watchdog
-};
-
-lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */
- lmc_ssi_default, /* reset to default state */
- lmc_ssi_set_status, /* reset status to state provided */
- lmc_ssi_set_clock, /* set clock source */
- lmc_ssi_set_speed, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_ssi_get_link_status, /* get link status */
- lmc_ssi_set_link_status, /* set link status */
- lmc_ssi_set_crc_length, /* set CRC length */
- lmc_dummy_set_1, /* set T1 or E1 circuit type */
- lmc_ssi_watchdog
-};
-
-lmc_media_t lmc_t1_media = {
- lmc_t1_init, /* special media init stuff */
- lmc_t1_default, /* reset to default state */
- lmc_t1_set_status, /* reset status to state provided */
- lmc_t1_set_clock, /* set clock source */
- lmc_dummy_set2_1, /* set line speed */
- lmc_dummy_set_1, /* set cable length */
- lmc_dummy_set_1, /* set scrambler */
- lmc_t1_get_link_status, /* get link status */
- lmc_dummy_set_1, /* set link status */
- lmc_t1_set_crc_length, /* set CRC length */
- lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */
- lmc_t1_watchdog
-};
-
-
-#endif
-
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index cae8925..d1e89be 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -757,7 +757,7 @@
if (radio->version == 0x2050)
bcm43xx_phy_write(bcm, 0x0038, 0x0667);
- if (phy->type == BCM43xx_PHYTYPE_G) {
+ if (phy->connected) {
if (radio->version == 0x2050) {
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A)
@@ -1192,7 +1192,7 @@
bcm43xx_phy_write(bcm, 0x0811, 0x0400);
bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
}
- if (phy->connected) {
+ if (phy->rev >= 2 && phy->connected) {
tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
if (tmp < 6) {
bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index ee1e7a2..4025dd0 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -458,7 +458,7 @@
bcm43xx_phy_write(bcm, 0x005A, 0x0480);
bcm43xx_phy_write(bcm, 0x0059, 0x0810);
bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->rev == 0) {
+ if (phy->analog == 0) {
bcm43xx_phy_write(bcm, 0x0003, 0x0122);
} else {
bcm43xx_phy_write(bcm, 0x000A,
@@ -570,9 +570,9 @@
nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027);
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->rev >= 2) {
+ if (phy->analog >= 2) {
bcm43xx_write16(bcm, 0x03E6, 0x0040);
- } else if (phy->rev == 0) {
+ } else if (phy->analog == 0) {
bcm43xx_write16(bcm, 0x03E6, 0x0122);
} else {
bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
@@ -596,7 +596,7 @@
bcm43xx_phy_write(bcm, 0x0015, backup[5]);
bcm43xx_phy_write(bcm, 0x002A, backup[6]);
bcm43xx_synth_pu_workaround(bcm, radio->channel);
- if (phy->rev != 0)
+ if (phy->analog != 0)
bcm43xx_write16(bcm, 0x03F4, backup[13]);
bcm43xx_phy_write(bcm, 0x0020, backup[7]);
@@ -692,7 +692,7 @@
bcm43xx_radio_write16(bcm, 0x007A,
bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->rev >= 2) {
+ if (phy->analog >= 2) {
bcm43xx_phy_write(bcm, 0x0003,
(bcm43xx_phy_read(bcm, 0x0003)
& 0xFF9F) | 0x0040);
@@ -1579,7 +1579,7 @@
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
- if (tmp == (data_high[i] << 4 | data_low[j])) {
+ if (tmp == (data_high[i] | data_low[j])) {
bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0);
return;
}
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 00e937e..e7fbac5 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -70,11 +70,12 @@
int alloc_event_buffer(void)
{
int err = -ENOMEM;
+ unsigned long flags;
- spin_lock(&oprofilefs_lock);
+ spin_lock_irqsave(&oprofilefs_lock, flags);
buffer_size = fs_buffer_size;
buffer_watershed = fs_buffer_watershed;
- spin_unlock(&oprofilefs_lock);
+ spin_unlock_irqrestore(&oprofilefs_lock, flags);
if (buffer_watershed >= buffer_size)
return -EINVAL;
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 6e67b42..8543cb2 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -65,6 +65,7 @@
int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
{
char tmpbuf[TMPBUFSIZE];
+ unsigned long flags;
if (!count)
return 0;
@@ -77,9 +78,9 @@
if (copy_from_user(tmpbuf, buf, count))
return -EFAULT;
- spin_lock(&oprofilefs_lock);
+ spin_lock_irqsave(&oprofilefs_lock, flags);
*val = simple_strtoul(tmpbuf, NULL, 0);
- spin_unlock(&oprofilefs_lock);
+ spin_unlock_irqrestore(&oprofilefs_lock, flags);
return 0;
}
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 0be5a0b..df38364 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -93,7 +93,7 @@
if (!dev->irq && dev->pin) {
printk(KERN_WARNING
"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
- __FUNCTION__, dev->device, dev->vendor);
+ __FUNCTION__, dev->vendor, dev->device);
}
if (pcie_port_device_register(dev)) {
pci_disable_device(dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7f94fc0..65d6f23 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -963,6 +963,13 @@
* bridge. Unfortunately, this device has no subvendor/subdevice ID. So it
* becomes necessary to do this tweak in two steps -- I've chosen the Host
* bridge as trigger.
+ *
+ * Note that we used to unhide the SMBus that way on Toshiba laptops
+ * (Satellite A40 and Tecra M2) but then found that the thermal management
+ * was done by SMM code, which could cause unsynchronized concurrent
+ * accesses to the SMBus registers, with potentially bad effects. Thus you
+ * should be very careful when adding new entries: if SMM is accessing the
+ * Intel SMBus, this is a very good reason to leave it hidden.
*/
static int asus_hides_smbus;
@@ -1040,17 +1047,6 @@
case 0x099c: /* HP Compaq nx6110 */
asus_hides_smbus = 1;
}
- } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
- if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
- switch(dev->subsystem_device) {
- case 0x0001: /* Toshiba Satellite A40 */
- asus_hides_smbus = 1;
- }
- else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
- switch(dev->subsystem_device) {
- case 0x0001: /* Toshiba Tecra M2 */
- asus_hides_smbus = 1;
- }
} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
switch(dev->subsystem_device) {
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 551bde5..b693367 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -372,7 +372,7 @@
skt->socket.resource_ops = &pccard_static_ops;
skt->socket.ops = &au1x00_pcmcia_operations;
skt->socket.owner = ops->owner;
- skt->socket.dev.dev = dev;
+ skt->socket.dev.parent = dev;
init_timer(&skt->poll_timer);
skt->poll_timer.function = au1x00_pcmcia_poll_event;
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ab782bb..e810e4a 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -65,7 +65,7 @@
* resulting condition code and DIAG return code. */
static inline int dia250(void *iob, int cmd)
{
- register unsigned long reg0 asm ("0") = (unsigned long) iob;
+ register unsigned long reg2 asm ("2") = (unsigned long) iob;
typedef union {
struct dasd_diag_init_io init_io;
struct dasd_diag_rw_io rw_io;
@@ -74,15 +74,15 @@
rc = 3;
asm volatile(
- " diag 0,%2,0x250\n"
+ " diag 2,%2,0x250\n"
"0: ipm %0\n"
" srl %0,28\n"
- " or %0,1\n"
+ " or %0,3\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc), "=m" (*(addr_type *) iob)
- : "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob)
- : "1", "cc");
+ : "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob)
+ : "3", "cc");
return rc;
}
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 6b1caea..25d99bd 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -263,7 +263,11 @@
cdev_irb->scsw.cpa = irb->scsw.cpa;
/* Accumulate device status, but not the device busy flag. */
cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
- cdev_irb->scsw.dstat |= irb->scsw.dstat;
+ /* dstat is not always valid. */
+ if (irb->scsw.stctl &
+ (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
+ | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
+ cdev_irb->scsw.dstat |= irb->scsw.dstat;
/* Accumulate subchannel status. */
cdev_irb->scsw.cstat |= irb->scsw.cstat;
/* Copy residual count if it is valid. */
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 181b517..bf37cdf 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -505,6 +505,9 @@
spin_lock_bh(&ap_device_lock);
list_del_init(&ap_dev->list);
spin_unlock_bh(&ap_device_lock);
+ spin_lock_bh(&ap_dev->lock);
+ atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+ spin_unlock_bh(&ap_dev->lock);
return 0;
}
@@ -757,10 +760,16 @@
(void *)(unsigned long)qid,
__ap_scan_bus);
rc = ap_query_queue(qid, &queue_depth, &device_type);
- if (dev && rc) {
- put_device(dev);
- device_unregister(dev);
- continue;
+ if (dev) {
+ ap_dev = to_ap_dev(dev);
+ spin_lock_bh(&ap_dev->lock);
+ if (rc || ap_dev->unregistered) {
+ spin_unlock_bh(&ap_dev->lock);
+ put_device(dev);
+ device_unregister(dev);
+ continue;
+ } else
+ spin_unlock_bh(&ap_dev->lock);
}
if (dev) {
put_device(dev);
@@ -861,6 +870,7 @@
case AP_RESPONSE_NO_PENDING_REPLY:
if (status.queue_empty) {
/* The card shouldn't forget requests but who knows. */
+ atomic_sub(ap_dev->queue_count, &ap_poll_requests);
ap_dev->queue_count = 0;
list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
ap_dev->requestq_count += ap_dev->pendingq_count;
@@ -994,7 +1004,7 @@
ap_dev->unregistered = 1;
} else {
ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
- rc = 0;
+ rc = -ENODEV;
}
spin_unlock_bh(&ap_dev->lock);
if (rc == -ENODEV)
@@ -1044,18 +1054,12 @@
*/
static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
{
- int rc;
-
spin_lock(&ap_dev->lock);
if (!ap_dev->unregistered) {
- rc = ap_poll_queue(ap_dev, flags);
- if (rc)
+ if (ap_poll_queue(ap_dev, flags))
ap_dev->unregistered = 1;
- } else
- rc = 0;
+ }
spin_unlock(&ap_dev->lock);
- if (rc)
- device_unregister(&ap_dev->device);
return 0;
}
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 8c81cec..60446b8 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3091,6 +3091,7 @@
cmdp->u.raw64.direction =
gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
memcpy(cmdp->u.raw64.cmd,scp->cmnd,16);
+ cmdp->u.raw64.sg_ranz = 0;
} else {
cmdp->u.raw.reserved = 0;
cmdp->u.raw.mdisc_time = 0;
@@ -3107,6 +3108,7 @@
cmdp->u.raw.direction =
gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
+ cmdp->u.raw.sg_ranz = 0;
}
if (scp->use_sg) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 9d014e5..057fd7e0 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1817,10 +1817,9 @@
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
- if (state == pci_channel_io_perm_failure) {
- lpfc_pci_remove_one(pdev);
+ if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
- }
+
pci_disable_device(pdev);
/*
* There may be I/Os dropped by the firmware.
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 2328128..6657331 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -189,8 +189,8 @@
* this is exported so that for example a USB or parport based adapter
* driver could add devices (which it would learn about out-of-band).
*/
-struct spi_device *__init_or_module
-spi_new_device(struct spi_master *master, struct spi_board_info *chip)
+struct spi_device *spi_new_device(struct spi_master *master,
+ struct spi_board_info *chip)
{
struct spi_device *proxy;
struct device *dev = master->cdev.dev;
@@ -352,8 +352,7 @@
* the master's methods before calling spi_register_master(); and (after errors
* adding the device) calling spi_master_put() to prevent a memory leak.
*/
-struct spi_master * __init_or_module
-spi_alloc_master(struct device *dev, unsigned size)
+struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
{
struct spi_master *master;
@@ -392,8 +391,7 @@
* After a successful return, the caller is responsible for calling
* spi_unregister_master().
*/
-int __init_or_module
-spi_register_master(struct spi_master *master)
+int spi_register_master(struct spi_master *master)
{
static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
struct device *dev = master->cdev.dev;
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 0e5c646..f08ec85 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -30,7 +30,8 @@
static const struct usb_device_id usb_quirk_list[] = {
/* HP 5300/5370C scanner */
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
-
+ /* Seiko Epson Corp - Perfection 1670 */
+ { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Elsa MicroLink 56k (V.250) */
{ USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 8f9a2b6..b394e63 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -296,6 +296,15 @@
/*-------------------------------------------------------------------------*/
+/*
+ * dma-coherent memory allocation (for dma-capable endpoints)
+ *
+ * NOTE: the dma_*_coherent() API calls suck. Most implementations are
+ * (a) page-oriented, so small buffers lose big; and (b) asymmetric with
+ * respect to calls with irqs disabled: alloc is safe, free is not.
+ * We currently work around (b), but not (a).
+ */
+
static void *
omap_alloc_buffer(
struct usb_ep *_ep,
@@ -307,6 +316,9 @@
void *retval;
struct omap_ep *ep;
+ if (!_ep)
+ return NULL;
+
ep = container_of(_ep, struct omap_ep, ep);
if (use_dma && ep->has_dma) {
static int warned;
@@ -326,6 +338,35 @@
return retval;
}
+static DEFINE_SPINLOCK(buflock);
+static LIST_HEAD(buffers);
+
+struct free_record {
+ struct list_head list;
+ struct device *dev;
+ unsigned bytes;
+ dma_addr_t dma;
+};
+
+static void do_free(unsigned long ignored)
+{
+ spin_lock_irq(&buflock);
+ while (!list_empty(&buffers)) {
+ struct free_record *buf;
+
+ buf = list_entry(buffers.next, struct free_record, list);
+ list_del(&buf->list);
+ spin_unlock_irq(&buflock);
+
+ dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma);
+
+ spin_lock_irq(&buflock);
+ }
+ spin_unlock_irq(&buflock);
+}
+
+static DECLARE_TASKLET(deferred_free, do_free, 0);
+
static void omap_free_buffer(
struct usb_ep *_ep,
void *buf,
@@ -333,13 +374,29 @@
unsigned bytes
)
{
- struct omap_ep *ep;
+ if (!_ep) {
+ WARN_ON(1);
+ return;
+ }
- ep = container_of(_ep, struct omap_ep, ep);
- if (use_dma && _ep && ep->has_dma)
- dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma);
- else
- kfree (buf);
+ /* free memory into the right allocator */
+ if (dma != DMA_ADDR_INVALID) {
+ struct omap_ep *ep;
+ struct free_record *rec = buf;
+ unsigned long flags;
+
+ ep = container_of(_ep, struct omap_ep, ep);
+
+ rec->dev = ep->udc->gadget.dev.parent;
+ rec->bytes = bytes;
+ rec->dma = dma;
+
+ spin_lock_irqsave(&buflock, flags);
+ list_add_tail(&rec->list, &buffers);
+ tasklet_schedule(&deferred_free);
+ spin_unlock_irqrestore(&buflock, flags);
+ } else
+ kfree(buf);
}
/*-------------------------------------------------------------------------*/
@@ -1691,12 +1748,38 @@
udc->ep0_pending = 0;
break;
case USB_REQ_GET_STATUS:
+ /* USB_ENDPOINT_HALT status? */
+ if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
+ goto intf_status;
+
+ /* ep0 never stalls */
+ if (!(w_index & 0xf))
+ goto zero_status;
+
+ /* only active endpoints count */
+ ep = &udc->ep[w_index & 0xf];
+ if (w_index & USB_DIR_IN)
+ ep += 16;
+ if (!ep->desc)
+ goto do_stall;
+
+ /* iso never stalls */
+ if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
+ goto zero_status;
+
+ /* FIXME don't assume non-halted endpoints!! */
+ ERR("%s status, can't report\n", ep->ep.name);
+ goto do_stall;
+
+intf_status:
/* return interface status. if we were pedantic,
* we'd detect non-existent interfaces, and stall.
*/
if (u.r.bRequestType
!= (USB_DIR_IN|USB_RECIP_INTERFACE))
goto delegate;
+
+zero_status:
/* return two zero bytes */
UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
UDC_DATA_REG = 0;
@@ -2068,7 +2151,7 @@
/*-------------------------------------------------------------------------*/
-static inline int machine_needs_vbus_session(void)
+static inline int machine_without_vbus_sense(void)
{
return (machine_is_omap_innovator()
|| machine_is_omap_osk()
@@ -2156,7 +2239,7 @@
/* boards that don't have VBUS sensing can't autogate 48MHz;
* can't enter deep sleep while a gadget driver is active.
*/
- if (machine_needs_vbus_session())
+ if (machine_without_vbus_sense())
omap_vbus_session(&udc->gadget, 1);
done:
@@ -2179,7 +2262,7 @@
if (udc->dc_clk != NULL)
omap_udc_enable_clock(1);
- if (machine_needs_vbus_session())
+ if (machine_without_vbus_sense())
omap_vbus_session(&udc->gadget, 0);
if (udc->transceiver)
@@ -2822,7 +2905,7 @@
hmc = HMC_1510;
type = "(unknown)";
- if (machine_is_omap_innovator() || machine_is_sx1()) {
+ if (machine_without_vbus_sense()) {
/* just set up software VBUS detect, and then
* later rig it so we always report VBUS.
* FIXME without really sensing VBUS, we can't
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 8d24d3d..1497371 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -145,7 +145,8 @@
return out - buf;
}
-static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
+static int uhci_show_qh(struct uhci_hcd *uhci,
+ struct uhci_qh *qh, char *buf, int len, int space)
{
char *out = buf;
int i, nurbs;
@@ -190,6 +191,9 @@
if (list_empty(&qh->queue)) {
out += sprintf(out, "%*s queue is empty\n", space, "");
+ if (qh == uhci->skel_async_qh)
+ out += uhci_show_td(uhci->term_td, out,
+ len - (out - buf), 0);
} else {
struct urb_priv *urbp = list_entry(qh->queue.next,
struct urb_priv, node);
@@ -343,6 +347,7 @@
struct list_head *tmp, *head;
int nframes, nerrs;
__le32 link;
+ __le32 fsbr_link;
static const char * const qh_names[] = {
"unlink", "iso", "int128", "int64", "int32", "int16",
@@ -424,21 +429,22 @@
out += sprintf(out, "Skeleton QHs\n");
+ fsbr_link = 0;
for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
int cnt = 0;
- __le32 fsbr_link = 0;
qh = uhci->skelqh[i];
out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
- out += uhci_show_qh(qh, out, len - (out - buf), 4);
+ out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4);
/* Last QH is the Terminating QH, it's different */
if (i == SKEL_TERM) {
if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
out += sprintf(out, " skel_term_qh element is not set to term_td!\n");
- if (link == LINK_TO_QH(uhci->skel_term_qh))
- goto check_qh_link;
- continue;
+ link = fsbr_link;
+ if (!link)
+ link = LINK_TO_QH(uhci->skel_term_qh);
+ goto check_qh_link;
}
head = &qh->node;
@@ -448,7 +454,7 @@
qh = list_entry(tmp, struct uhci_qh, node);
tmp = tmp->next;
if (++cnt <= 10)
- out += uhci_show_qh(qh, out,
+ out += uhci_show_qh(uhci, qh, out,
len - (out - buf), 4);
if (!fsbr_link && qh->skel >= SKEL_FSBR)
fsbr_link = LINK_TO_QH(qh);
@@ -463,8 +469,6 @@
link = LINK_TO_QH(uhci->skel_async_qh);
else if (!uhci->fsbr_is_on)
;
- else if (fsbr_link)
- link = fsbr_link;
else
link = LINK_TO_QH(uhci->skel_term_qh);
check_qh_link:
@@ -573,8 +577,8 @@
static inline void lprintk(char *buf)
{}
-static inline int uhci_show_qh(struct uhci_qh *qh, char *buf,
- int len, int space)
+static inline int uhci_show_qh(struct uhci_hcd *uhci,
+ struct uhci_qh *qh, char *buf, int len, int space)
{
return 0;
}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 44da433..d22da26 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -632,7 +632,8 @@
*/
for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
- uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
+ uhci->skel_async_qh->link = UHCI_PTR_TERM;
+ uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
/* This dummy TD is to work around a bug in Intel PIIX controllers */
uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index f4ebdb3..19a0cc0 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -45,43 +45,27 @@
*/
static void uhci_fsbr_on(struct uhci_hcd *uhci)
{
- struct uhci_qh *fsbr_qh, *lqh, *tqh;
+ struct uhci_qh *lqh;
+ /* The terminating skeleton QH always points back to the first
+ * FSBR QH. Make the last async QH point to the terminating
+ * skeleton QH. */
uhci->fsbr_is_on = 1;
lqh = list_entry(uhci->skel_async_qh->node.prev,
struct uhci_qh, node);
-
- /* Find the first FSBR QH. Linear search through the list is
- * acceptable because normally FSBR gets turned on as soon as
- * one QH needs it. */
- fsbr_qh = NULL;
- list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) {
- if (tqh->skel < SKEL_FSBR)
- break;
- fsbr_qh = tqh;
- }
-
- /* No FSBR QH means we must insert the terminating skeleton QH */
- if (!fsbr_qh) {
- uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
- wmb();
- lqh->link = uhci->skel_term_qh->link;
-
- /* Otherwise loop the last QH to the first FSBR QH */
- } else
- lqh->link = LINK_TO_QH(fsbr_qh);
+ lqh->link = LINK_TO_QH(uhci->skel_term_qh);
}
static void uhci_fsbr_off(struct uhci_hcd *uhci)
{
struct uhci_qh *lqh;
+ /* Remove the link from the last async QH to the terminating
+ * skeleton QH. */
uhci->fsbr_is_on = 0;
lqh = list_entry(uhci->skel_async_qh->node.prev,
struct uhci_qh, node);
-
- /* End the async list normally and unlink the terminating QH */
- lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
+ lqh->link = UHCI_PTR_TERM;
}
static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
@@ -464,9 +448,8 @@
*/
static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
- struct uhci_qh *pqh, *lqh;
+ struct uhci_qh *pqh;
__le32 link_to_new_qh;
- __le32 *extra_link = &link_to_new_qh;
/* Find the predecessor QH for our new one and insert it in the list.
* The list of QHs is expected to be short, so linear search won't
@@ -476,31 +459,17 @@
break;
}
list_add(&qh->node, &pqh->node);
- qh->link = pqh->link;
-
- link_to_new_qh = LINK_TO_QH(qh);
-
- /* If this is now the first FSBR QH, take special action */
- if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
- qh->skel >= SKEL_FSBR) {
- lqh = list_entry(uhci->skel_async_qh->node.prev,
- struct uhci_qh, node);
-
- /* If the new QH is also the last one, we must unlink
- * the terminating skeleton QH and make the new QH point
- * back to itself. */
- if (qh == lqh) {
- qh->link = link_to_new_qh;
- extra_link = &uhci->skel_term_qh->link;
-
- /* Otherwise the last QH must point to the new QH */
- } else
- extra_link = &lqh->link;
- }
/* Link it into the schedule */
+ qh->link = pqh->link;
wmb();
- *extra_link = pqh->link = link_to_new_qh;
+ link_to_new_qh = LINK_TO_QH(qh);
+ pqh->link = link_to_new_qh;
+
+ /* If this is now the first FSBR QH, link the terminating skeleton
+ * QH to it. */
+ if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+ uhci->skel_term_qh->link = link_to_new_qh;
}
/*
@@ -561,31 +530,16 @@
*/
static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
- struct uhci_qh *pqh, *lqh;
+ struct uhci_qh *pqh;
__le32 link_to_next_qh = qh->link;
pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-
- /* If this is the first FSBQ QH, take special action */
- if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
- qh->skel >= SKEL_FSBR) {
- lqh = list_entry(uhci->skel_async_qh->node.prev,
- struct uhci_qh, node);
-
- /* If this QH is also the last one, we must link in
- * the terminating skeleton QH. */
- if (qh == lqh) {
- link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh);
- uhci->skel_term_qh->link = link_to_next_qh;
- wmb();
- qh->link = link_to_next_qh;
-
- /* Otherwise the last QH must point to the new first FSBR QH */
- } else
- lqh->link = link_to_next_qh;
- }
-
pqh->link = link_to_next_qh;
+
+ /* If this was the old first FSBR QH, link the terminating skeleton
+ * QH to the next (new first FSBR) QH. */
+ if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+ uhci->skel_term_qh->link = link_to_next_qh;
mb();
}
@@ -1217,7 +1171,7 @@
if (debug > 1 && errbuf) {
/* Print the chain for debugging */
- uhci_show_qh(urbp->qh, errbuf,
+ uhci_show_qh(uhci, urbp->qh, errbuf,
ERRBUF_LEN, 0);
lprintk(errbuf);
}
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 7538c64..39a4983 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -18,7 +18,6 @@
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
- { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
{ USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
{ },
};
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 1633a0fd..8ff9d54 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -879,6 +879,7 @@
break;
case FT232BM: /* FT232BM chip */
case FT2232C: /* FT2232C chip */
+ case FT232RL:
if (baud <= 3000000) {
div_value = ftdi_232bm_baud_to_divisor(baud);
} else {
@@ -1021,9 +1022,12 @@
/* (It might be a BM because of the iSerialNumber bug,
* but it will still work as an AM device.) */
priv->chip_type = FT8U232AM;
- } else {
+ } else if (version < 0x600) {
/* Assume its an FT232BM (or FT245BM) */
priv->chip_type = FT232BM;
+ } else {
+ /* Assume its an FT232R */
+ priv->chip_type = FT232RL;
}
info("Detected %s", ftdi_chip_name[priv->chip_type]);
}
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 53baeec..4f8282a 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -20,13 +20,14 @@
#include <linux/usb/serial.h>
#include <asm/uaccess.h>
-static int generic_probe(struct usb_interface *interface,
- const struct usb_device_id *id);
-
static int debug;
#ifdef CONFIG_USB_SERIAL_GENERIC
+
+static int generic_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
+
static __u16 vendor = 0x05f9;
static __u16 product = 0xffff;
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 8ada4c5..6a82d39 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -40,7 +40,6 @@
extern struct file_system_type v9fs_fs_type;
extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
-extern const struct file_operations v9fs_cached_file_operations;
extern const struct file_operations v9fs_dir_operations;
extern struct dentry_operations v9fs_dentry_operations;
extern struct dentry_operations v9fs_cached_dentry_operations;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 653dfa5..c7b6772 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -42,6 +42,8 @@
#include "v9fs_vfs.h"
#include "fid.h"
+static const struct file_operations v9fs_cached_file_operations;
+
/**
* v9fs_file_open - open a file (or directory)
* @inode: inode to be opened
@@ -245,7 +247,7 @@
return total;
}
-const struct file_operations v9fs_cached_file_operations = {
+static const struct file_operations v9fs_cached_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
.aio_read = generic_file_aio_read,
diff --git a/fs/aio.c b/fs/aio.c
index 0b4ee0a..e4598d6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -136,7 +136,6 @@
0);
if (IS_ERR((void *)info->mmap_base)) {
up_write(&ctx->mm->mmap_sem);
- printk("mmap err: %ld\n", -info->mmap_base);
info->mmap_size = 0;
aio_free_ring(ctx);
return -EAGAIN;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index c81c958..8b1c5d8 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2553,11 +2553,15 @@
HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
/* wireless */
HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWPRIV, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWSTATS, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWMLME, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWSCAN, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl)
@@ -2565,6 +2569,11 @@
HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWGENIE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWGENIE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWENCODEEXT, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWENCODEEXT, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl)
HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 6f67798..7e4bb0a 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -859,8 +859,8 @@
#define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1)
#define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
static int
-encode_entry(struct readdir_cd *ccd, const char *name,
- int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus)
+encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
+ loff_t offset, ino_t ino, unsigned int d_type, int plus)
{
struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
common);
@@ -880,7 +880,7 @@
*cd->offset1 = htonl(offset64 & 0xffffffff);
cd->offset1 = NULL;
} else {
- xdr_encode_hyper(cd->offset, (u64) offset);
+ xdr_encode_hyper(cd->offset, offset64);
}
}
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 832673b..673a53c 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -228,7 +228,7 @@
struct posix_acl_summary pas;
unsigned short deny;
int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
- NFS4_INHERITANCE_FLAGS : 0);
+ NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0);
BUG_ON(pacl->a_count < 3);
summarize_posix_acl(pacl, &pas);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9e40679..af36070 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -750,9 +750,8 @@
status = nfserr_clid_inuse;
if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
|| conf->cl_addr != sin->sin_addr.s_addr) {
- printk("NFSD: setclientid: string in use by client"
- "(clientid %08x/%08x)\n",
- conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id);
+ dprintk("NFSD: setclientid: string in use by client"
+ "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr));
goto out;
}
}
@@ -3261,7 +3260,6 @@
unhash_delegation(dp);
}
- cancel_delayed_work(&laundromat_work);
nfsd4_shutdown_recdir();
nfs4_init = 0;
}
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index a6b3a8f..bce38e3 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,8 +8,9 @@
proc-$(CONFIG_MMU) := mmu.o task_mmu.o
proc-y += inode.o root.o base.o generic.o array.o \
- proc_tty.o proc_misc.o proc_sysctl.o
+ proc_tty.o proc_misc.o
+proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o
proc-$(CONFIG_PROC_KCORE) += kcore.o
proc-$(CONFIG_PROC_VMCORE) += vmcore.o
proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
diff --git a/fs/splice.c b/fs/splice.c
index 2fca6eb..07f6556 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -576,76 +576,21 @@
if (this_len + offset > PAGE_CACHE_SIZE)
this_len = PAGE_CACHE_SIZE - offset;
- /*
- * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full
- * page.
- */
- if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
- /*
- * If steal succeeds, buf->page is now pruned from the
- * pagecache and we can reuse it. The page will also be
- * locked on successful return.
- */
- if (buf->ops->steal(pipe, buf))
- goto find_page;
-
- page = buf->page;
- if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
- unlock_page(page);
- goto find_page;
- }
-
- page_cache_get(page);
-
- if (!(buf->flags & PIPE_BUF_FLAG_LRU))
- lru_cache_add(page);
- } else {
find_page:
- page = find_lock_page(mapping, index);
- if (!page) {
- ret = -ENOMEM;
- page = page_cache_alloc_cold(mapping);
- if (unlikely(!page))
- goto out_ret;
-
- /*
- * This will also lock the page
- */
- ret = add_to_page_cache_lru(page, mapping, index,
- GFP_KERNEL);
- if (unlikely(ret))
- goto out;
- }
+ page = find_lock_page(mapping, index);
+ if (!page) {
+ ret = -ENOMEM;
+ page = page_cache_alloc_cold(mapping);
+ if (unlikely(!page))
+ goto out_ret;
/*
- * We get here with the page locked. If the page is also
- * uptodate, we don't need to do more. If it isn't, we
- * may need to bring it in if we are not going to overwrite
- * the full page.
+ * This will also lock the page
*/
- if (!PageUptodate(page)) {
- if (this_len < PAGE_CACHE_SIZE) {
- ret = mapping->a_ops->readpage(file, page);
- if (unlikely(ret))
- goto out;
-
- lock_page(page);
-
- if (!PageUptodate(page)) {
- /*
- * Page got invalidated, repeat.
- */
- if (!page->mapping) {
- unlock_page(page);
- page_cache_release(page);
- goto find_page;
- }
- ret = -EIO;
- goto out;
- }
- } else
- SetPageUptodate(page);
- }
+ ret = add_to_page_cache_lru(page, mapping, index,
+ GFP_KERNEL);
+ if (unlikely(ret))
+ goto out;
}
ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
@@ -706,9 +651,9 @@
* key here is the 'actor' worker passed in that actually moves the data
* to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
*/
-static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
- struct file *out, loff_t *ppos, size_t len,
- unsigned int flags, splice_actor *actor)
+ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
+ struct file *out, loff_t *ppos, size_t len,
+ unsigned int flags, splice_actor *actor)
{
int ret, do_wakeup, err;
struct splice_desc sd;
@@ -802,6 +747,7 @@
return ret;
}
+EXPORT_SYMBOL(__splice_from_pipe);
ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
loff_t *ppos, size_t len, unsigned int flags,
diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h
index 12baf1d..2e623769 100644
--- a/include/asm-i386/termbits.h
+++ b/include/asm-i386/termbits.h
@@ -144,7 +144,7 @@
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
-#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CIBAUD 002003600000
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h
index 0a3cd7e..d5a8e7c 100644
--- a/include/asm-s390/checksum.h
+++ b/include/asm-s390/checksum.h
@@ -121,50 +121,21 @@
unsigned short len, unsigned short proto,
__wsum sum)
{
-#ifndef __s390x__
- asm volatile(
- " alr %0,%1\n" /* sum += saddr */
- " brc 12,0f\n"
- " ahi %0,1\n" /* add carry */
- "0:"
- : "+&d" (sum) : "d" (saddr) : "cc");
- asm volatile(
- " alr %0,%1\n" /* sum += daddr */
- " brc 12,1f\n"
- " ahi %0,1\n" /* add carry */
- "1:"
- : "+&d" (sum) : "d" (daddr) : "cc");
- asm volatile(
- " alr %0,%1\n" /* sum += len + proto */
- " brc 12,2f\n"
- " ahi %0,1\n" /* add carry */
- "2:"
- : "+&d" (sum)
- : "d" (len + proto)
- : "cc");
-#else /* __s390x__ */
- asm volatile(
- " lgfr %0,%0\n"
- " algr %0,%1\n" /* sum += saddr */
- " brc 12,0f\n"
- " aghi %0,1\n" /* add carry */
- "0: algr %0,%2\n" /* sum += daddr */
- " brc 12,1f\n"
- " aghi %0,1\n" /* add carry */
- "1: algfr %0,%3\n" /* sum += len + proto */
- " brc 12,2f\n"
- " aghi %0,1\n" /* add carry */
- "2: srlg 0,%0,32\n"
- " alr %0,0\n" /* fold to 32 bits */
- " brc 12,3f\n"
- " ahi %0,1\n" /* add carry */
- "3: llgfr %0,%0"
- : "+&d" (sum)
- : "d" (saddr), "d" (daddr),
- "d" (len + proto)
- : "cc", "0");
-#endif /* __s390x__ */
- return sum;
+ __u32 csum = (__force __u32)sum;
+
+ csum += (__force __u32)saddr;
+ if (csum < (__force __u32)saddr)
+ csum++;
+
+ csum += (__force __u32)daddr;
+ if (csum < (__force __u32)daddr)
+ csum++;
+
+ csum += len + proto;
+ if (csum < len + proto)
+ csum++;
+
+ return (__force __wsum)csum;
}
/*
diff --git a/include/asm-sh/hp6xx.h b/include/asm-sh/hp6xx.h
index f35134c..53ca564 100644
--- a/include/asm-sh/hp6xx.h
+++ b/include/asm-sh/hp6xx.h
@@ -10,9 +10,9 @@
*
*/
-#define HP680_BTN_IRQ IRQ0_IRQ
-#define HP680_TS_IRQ IRQ3_IRQ
-#define HP680_HD64461_IRQ IRQ4_IRQ
+#define HP680_BTN_IRQ 32 /* IRQ0_IRQ */
+#define HP680_TS_IRQ 35 /* IRQ3_IRQ */
+#define HP680_HD64461_IRQ 36 /* IRQ4_IRQ */
#define DAC_LCD_BRIGHTNESS 0
#define DAC_SPEAKER_VOLUME 1
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index b1e42e7..4a6a19f 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -7,6 +7,7 @@
*/
#include <linux/irqflags.h>
+#include <linux/compiler.h>
#include <asm/types.h>
/*
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
index f045451..b16222b 100644
--- a/include/asm-um/common.lds.S
+++ b/include/asm-um/common.lds.S
@@ -15,6 +15,7 @@
PROVIDE (_unprotected_end = .);
. = ALIGN(4096);
+ .note : { *(note.*) }
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index aca6698..3b6949b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -15,8 +15,8 @@
# define __acquire(x) __context__(x,1)
# define __release(x) __context__(x,-1)
# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
-extern void __chk_user_ptr(void __user *);
-extern void __chk_io_ptr(void __iomem *);
+extern void __chk_user_ptr(const void __user *);
+extern void __chk_io_ptr(const void __iomem *);
#else
# define __user
# define __kernel
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index 84cfa8b..d2a96cb 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -31,12 +31,19 @@
/*
* On x86-64 make the 64bit structure have the same alignment as the
* 32bit structure. This makes 32bit emulation easier.
+ *
+ * UML/x86_64 needs the same packing as x86_64 - UML + UML_X86 +
+ * 64_BIT adds up to UML/x86_64.
*/
#ifdef __x86_64__
#define EPOLL_PACKED __attribute__((packed))
#else
+#if defined(CONFIG_UML) && defined(CONFIG_UML_X86) && defined(CONFIG_64BIT)
+#define EPOLL_PACKED __attribute__((packed))
+#else
#define EPOLL_PACKED
#endif
+#endif
struct epoll_event {
__u32 events;
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 34f2676..58564a1 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -615,6 +615,7 @@
u8 init_speed; /* transfer rate set at boot */
u8 pio_speed; /* unused by core, used by some drivers for fallback from DMA */
u8 current_speed; /* current transfer rate set */
+ u8 desired_speed; /* desired transfer rate set */
u8 dn; /* now wide spread use */
u8 wcache; /* status of write cache */
u8 acoustic; /* acoustic management */
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 636094c..6da6772 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -92,19 +92,16 @@
#ifdef CONFIG_SYSVIPC
#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
+extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
#else
#define INIT_IPC_NS(ns)
+static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{ return 0; }
#endif
#ifdef CONFIG_IPC_NS
extern void free_ipc_ns(struct kref *kref);
-extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
-#else
-static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{
- return 0;
-}
#endif
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 2e19478..8bcbc54 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -99,4 +99,8 @@
loff_t *, size_t, unsigned int,
splice_actor *);
+extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *,
+ loff_t *, size_t, unsigned int,
+ splice_actor *);
+
#endif
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index a4555fe..e10267d 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -70,6 +70,8 @@
static inline int copy_utsname(int flags, struct task_struct *tsk)
{
+ if (flags & CLONE_NEWUTS)
+ return -EINVAL;
return 0;
}
static inline void put_uts_ns(struct uts_namespace *ns)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 447c52b..48759b2 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1,10 +1,10 @@
/*
* This file define a set of standard wireless extensions
*
- * Version : 21 14.3.06
+ * Version : 22 16.3.07
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _LINUX_WIRELESS_H
@@ -85,7 +85,7 @@
* (there is some stuff that will be added in the future...)
* I just plan to increment with each new version.
*/
-#define WIRELESS_EXT 21
+#define WIRELESS_EXT 22
/*
* Changes :
@@ -221,6 +221,10 @@
* - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
* - Power/Retry relative values no longer * 100000
* - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
+ *
+ * V21 to V22
+ * ----------
+ * - Prevent leaking of kernel space in stream on 64 bits.
*/
/**************************** CONSTANTS ****************************/
@@ -1085,4 +1089,15 @@
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF)
+/* Size of the Event prefix when packed in stream */
+#define IW_EV_LCP_PK_LEN (4)
+/* Size of the various events when packed in stream */
+#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
+#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
+#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
+#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4)
+
#endif /* _LINUX_WIRELESS_H */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 83fe2e3..50e33b0 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -239,7 +239,8 @@
#define SAA7146_HPS_SYNC_PORT_B 0x01
/* some memory sizes */
-#define SAA7146_CLIPPING_MEM (14*PAGE_SIZE)
+/* max. 16 clipping rectangles */
+#define SAA7146_CLIPPING_MEM (16 * 4 * sizeof(u32))
/* some defines for the various clipping-modes */
#define SAA7146_CLIPPING_RECT 0x4
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index bc3c264..d585ea9 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -34,6 +34,7 @@
int family;
struct list_head list;
int rule_size;
+ int addr_size;
int (*action)(struct fib_rule *,
struct flowi *, int,
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 9eda572..cf355a3 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -58,6 +58,7 @@
__u16 fn_bit; /* bit key */
__u16 fn_flags;
__u32 fn_sernum;
+ struct rt6_info *rr_ptr;
};
#ifndef CONFIG_IPV6_SUBTREES
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 10559e9..8a83018 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -1,10 +1,10 @@
/*
* This file define the new driver API for Wireless Extensions
*
- * Version : 7 18.3.05
+ * Version : 8 16.3.07
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 2001-2007 Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _IW_HANDLER_H
@@ -207,7 +207,7 @@
* will be needed...
* I just plan to increment with each new version.
*/
-#define IW_HANDLER_VERSION 7
+#define IW_HANDLER_VERSION 8
/*
* Changes :
@@ -239,6 +239,10 @@
* - Remove (struct iw_point *)->pointer from events and streams
* - Remove spy_offset from struct iw_handler_def
* - Add "check" version of event macros for ieee802.11 stack
+ *
+ * V7 to V8
+ * ----------
+ * - Prevent leaking of kernel space in stream on 64 bits.
*/
/**************************** CONSTANTS ****************************/
@@ -500,7 +504,11 @@
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- memcpy(stream, (char *) iwe, event_len);
+ /* Beware of alignement issues on 64 bits */
+ memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+ memcpy(stream + IW_EV_LCP_LEN,
+ ((char *) iwe) + IW_EV_LCP_LEN,
+ event_len - IW_EV_LCP_LEN);
stream += event_len;
}
return stream;
@@ -521,10 +529,10 @@
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_LEN);
+ memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+ IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len;
}
@@ -574,7 +582,11 @@
/* Check if it's possible, set error if not */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- memcpy(stream, (char *) iwe, event_len);
+ /* Beware of alignement issues on 64 bits */
+ memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+ memcpy(stream + IW_EV_LCP_LEN,
+ ((char *) iwe) + IW_EV_LCP_LEN,
+ event_len - IW_EV_LCP_LEN);
stream += event_len;
} else
*perr = -E2BIG;
@@ -598,10 +610,10 @@
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_LEN);
+ memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_LCP_LEN,
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+ IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
stream += event_len;
} else
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 3725b93..ad7fe11 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -36,7 +36,7 @@
struct net_device *dev;
struct neigh_parms *next;
int (*neigh_setup)(struct neighbour *);
- void (*neigh_destructor)(struct neighbour *);
+ void (*neigh_cleanup)(struct neighbour *);
struct neigh_table *tbl;
void *sysctl_table;
diff --git a/ipc/util.c b/ipc/util.c
index 08a6479..0b65238 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -144,6 +144,13 @@
shm_exit_ns(ns);
kfree(ns);
}
+#else
+int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+ if (flags & CLONE_NEWIPC)
+ return -EINVAL;
+ return 0;
+}
#endif
/**
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6a7938a..067ba2c 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -814,7 +814,12 @@
timer_stats_hrtimer_set_start_info(timer);
- enqueue_hrtimer(timer, new_base, base == new_base);
+ /*
+ * Only allow reprogramming if the new base is on this CPU.
+ * (it might still be on another CPU if the timer was pending)
+ */
+ enqueue_hrtimer(timer, new_base,
+ new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
unlock_hrtimer_base(timer, &flags);
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index dee0ff4..aec19b0 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -58,7 +58,6 @@
static void power_down(suspend_disk_method_t mode)
{
- disable_nonboot_cpus();
switch(mode) {
case PM_DISK_PLATFORM:
if (pm_ops && pm_ops->enter) {
diff --git a/kernel/power/user.c b/kernel/power/user.c
index bf211fe..7cf6713 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -401,10 +401,9 @@
case PMOPS_ENTER:
if (data->platform_suspend) {
- disable_nonboot_cpus();
kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
error = pm_ops->enter(PM_SUSPEND_DISK);
- enable_nonboot_cpus();
+ error = 0;
}
break;
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 67932ea..76212b2 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -274,72 +274,3 @@
}
EXPORT_SYMBOL_GPL(clockevents_notify);
-#ifdef CONFIG_SYSFS
-
-/**
- * clockevents_show_registered - sysfs interface for listing clockevents
- * @dev: unused
- * @buf: char buffer to be filled with clock events list
- *
- * Provides sysfs interface for listing registered clock event devices
- */
-static ssize_t clockevents_show_registered(struct sys_device *dev, char *buf)
-{
- struct list_head *tmp;
- char *p = buf;
- int cpu;
-
- spin_lock(&clockevents_lock);
-
- list_for_each(tmp, &clockevent_devices) {
- struct clock_event_device *ce;
-
- ce = list_entry(tmp, struct clock_event_device, list);
- p += sprintf(p, "%-20s F:%04x M:%d", ce->name,
- ce->features, ce->mode);
- p += sprintf(p, " C:");
- if (!cpus_equal(ce->cpumask, cpu_possible_map)) {
- for_each_cpu_mask(cpu, ce->cpumask)
- p += sprintf(p, " %d", cpu);
- } else {
- /*
- * FIXME: Add the cpu which is handling this sucker
- */
- }
- p += sprintf(p, "\n");
- }
-
- spin_unlock(&clockevents_lock);
-
- return p - buf;
-}
-
-/*
- * Sysfs setup bits:
- */
-static SYSDEV_ATTR(registered, 0600,
- clockevents_show_registered, NULL);
-
-static struct sysdev_class clockevents_sysclass = {
- set_kset_name("clockevents"),
-};
-
-static struct sys_device clockevents_sys_device = {
- .id = 0,
- .cls = &clockevents_sysclass,
-};
-
-static int __init clockevents_sysfs_init(void)
-{
- int error = sysdev_class_register(&clockevents_sysclass);
-
- if (!error)
- error = sysdev_register(&clockevents_sys_device);
- if (!error)
- error = sysdev_create_file(
- &clockevents_sys_device,
- &attr_registered);
- return error;
-}
-device_initcall(clockevents_sysfs_init);
-#endif
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index eb12509..cb25649 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -32,7 +32,7 @@
/* TIME_ERROR prevents overwriting the CMOS clock */
static int time_state = TIME_OK; /* clock synchronization status */
int time_status = STA_UNSYNC; /* clock status bits */
-static long time_offset; /* time adjustment (ns) */
+static s64 time_offset; /* time adjustment (ns) */
static long time_constant = 2; /* pll time constant */
long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */
long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
@@ -196,7 +196,7 @@
*/
int do_adjtimex(struct timex *txc)
{
- long ltemp, mtemp, save_adjust;
+ long mtemp, save_adjust, rem;
s64 freq_adj, temp64;
int result;
@@ -277,14 +277,14 @@
time_adjust = txc->offset;
}
else if (time_status & STA_PLL) {
- ltemp = txc->offset * NSEC_PER_USEC;
+ time_offset = txc->offset * NSEC_PER_USEC;
/*
* Scale the phase adjustment and
* clamp to the operating range.
*/
- time_offset = min(ltemp, MAXPHASE * NSEC_PER_USEC);
- time_offset = max(time_offset, -MAXPHASE * NSEC_PER_USEC);
+ time_offset = min(time_offset, (s64)MAXPHASE * NSEC_PER_USEC);
+ time_offset = max(time_offset, (s64)-MAXPHASE * NSEC_PER_USEC);
/*
* Select whether the frequency is to be controlled
@@ -297,11 +297,11 @@
mtemp = xtime.tv_sec - time_reftime;
time_reftime = xtime.tv_sec;
- freq_adj = (s64)time_offset * mtemp;
+ freq_adj = time_offset * mtemp;
freq_adj = shift_right(freq_adj, time_constant * 2 +
(SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
- temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL);
+ temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL);
if (time_offset < 0) {
temp64 = -temp64;
do_div(temp64, mtemp);
@@ -314,8 +314,10 @@
freq_adj += time_freq;
freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
- time_offset = (time_offset / NTP_INTERVAL_FREQ)
- << SHIFT_UPDATE;
+ time_offset = div_long_long_rem_signed(time_offset,
+ NTP_INTERVAL_FREQ,
+ &rem);
+ time_offset <<= SHIFT_UPDATE;
} /* STA_PLL */
} /* txc->modes & ADJ_OFFSET */
if (txc->modes & ADJ_TICK)
@@ -328,12 +330,12 @@
result = TIME_ERROR;
if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
- txc->offset = save_adjust;
+ txc->offset = save_adjust;
else
- txc->offset = shift_right(time_offset, SHIFT_UPDATE)
- * NTP_INTERVAL_FREQ / 1000;
- txc->freq = (time_freq / NSEC_PER_USEC)
- << (SHIFT_USEC - SHIFT_NSEC);
+ txc->offset = ((long)shift_right(time_offset, SHIFT_UPDATE)) *
+ NTP_INTERVAL_FREQ / 1000;
+ txc->freq = (time_freq / NSEC_PER_USEC) <<
+ (SHIFT_USEC - SHIFT_NSEC);
txc->maxerror = time_maxerror;
txc->esterror = time_esterror;
txc->status = time_status;
diff --git a/mm/bounce.c b/mm/bounce.c
index 643efbe..ad401fc 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -204,7 +204,7 @@
/*
* is destination page below bounce pfn?
*/
- if (page_to_pfn(page) < q->bounce_pfn)
+ if (page_to_pfn(page) <= q->bounce_pfn)
continue;
/*
diff --git a/net/atm/clip.c b/net/atm/clip.c
index ebb5d0c..8c38258 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -261,14 +261,6 @@
spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
}
-static void clip_neigh_destroy(struct neighbour *neigh)
-{
- DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh);
- if (NEIGH2ENTRY(neigh)->vccs)
- printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n");
- NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD;
-}
-
static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
@@ -342,7 +334,6 @@
/* parameters are copied from ARP ... */
.parms = {
.tbl = &clip_tbl,
- .neigh_destructor = clip_neigh_destroy,
.base_reachable_time = 30 * HZ,
.retrans_time = 1 * HZ,
.gc_staletime = 60 * HZ,
diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig
index a8993a0..43dd86f 100644
--- a/net/ax25/Kconfig
+++ b/net/ax25/Kconfig
@@ -1,30 +1,27 @@
#
# Amateur Radio protocols and AX.25 device configuration
#
-# 19971130 Now in an own category to make correct compilation of the
-# AX.25 stuff easier...
-# Joerg Reuter DL1BKE <jreuter@yaina.de>
-# 19980129 Moved to net/ax25/Config.in, sourcing device drivers.
menuconfig HAMRADIO
depends on NET
bool "Amateur Radio support"
help
If you want to connect your Linux box to an amateur radio, answer Y
- here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and
- the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
+ here. You want to read <http://www.tapr.org/tapr/html/pkthome.html>
+ and more specifically about AX.25 on Linux
+ <http://www.linux-ax25.org/>.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about amateur radio.
comment "Packet Radio protocols"
- depends on HAMRADIO && NET
+ depends on HAMRADIO
config AX25
tristate "Amateur Radio AX.25 Level 2 protocol"
- depends on HAMRADIO && NET
- ---help---
+ depends on HAMRADIO
+ help
This is the protocol used for computer communication over amateur
radio. It is either used by itself for point-to-point links, or to
carry other protocols such as tcp/ip. To use it, you need a device
@@ -52,6 +49,7 @@
config AX25_DAMA_SLAVE
bool "AX.25 DAMA Slave support"
+ default y
depends on AX25
help
DAMA is a mechanism to prevent collisions when doing AX.25
@@ -59,23 +57,38 @@
from clients (called "slaves") and redistributes it to other slaves.
If you say Y here, your Linux box will act as a DAMA slave; this is
transparent in that you don't have to do any special DAMA
- configuration. (Linux cannot yet act as a DAMA server.) If unsure,
- say N.
+ configuration. Linux cannot yet act as a DAMA server. This option
+ only compiles DAMA slave support into the kernel. It still needs to
+ be enabled at runtime. For more about DAMA see
+ <http://www.linux-ax25.org>. If unsure, say Y.
-# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
+# placeholder until implemented
+config AX25_DAMA_MASTER
+ bool 'AX.25 DAMA Master support'
+ depends on AX25_DAMA_SLAVE && BROKEN
+ help
+ DAMA is a mechanism to prevent collisions when doing AX.25
+ networking. A DAMA server (called "master") accepts incoming traffic
+ from clients (called "slaves") and redistributes it to other slaves.
+ If you say Y here, your Linux box will act as a DAMA master; this is
+ transparent in that you don't have to do any special DAMA
+ configuration. Linux cannot yet act as a DAMA server. This option
+ only compiles DAMA slave support into the kernel. It still needs to
+ be explicitly enabled, so if unsure, say Y.
+
config NETROM
tristate "Amateur Radio NET/ROM protocol"
depends on AX25
- ---help---
+ help
NET/ROM is a network layer protocol on top of AX.25 useful for
routing.
A comprehensive listing of all the software for Linux amateur radio
users as well as information about how to configure an AX.25 port is
- contained in the AX25-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. You also might want to
- check out the file <file:Documentation/networking/ax25.txt>. More
- information about digital amateur radio in general is on the WWW at
+ contained in the Linux Ham Wiki, available from
+ <http://www.linux-ax25.org>. You also might want to check out the
+ file <file:Documentation/networking/ax25.txt>. More information about
+ digital amateur radio in general is on the WWW at
<http://www.tapr.org/tapr/html/pkthome.html>.
To compile this driver as a module, choose M here: the
@@ -84,27 +97,25 @@
config ROSE
tristate "Amateur Radio X.25 PLP (Rose)"
depends on AX25
- ---help---
+ help
The Packet Layer Protocol (PLP) is a way to route packets over X.25
connections in general and amateur radio AX.25 connections in
particular, essentially an alternative to NET/ROM.
A comprehensive listing of all the software for Linux amateur radio
users as well as information about how to configure an AX.25 port is
- contained in the AX25-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. You also might want to
- check out the file <file:Documentation/networking/ax25.txt>. More
- information about digital amateur radio in general is on the WWW at
+ contained in the Linux Ham Wiki, available from
+ <http://www.linux-ax25.org>. You also might want to check out the
+ file <file:Documentation/networking/ax25.txt>. More information about
+ digital amateur radio in general is on the WWW at
<http://www.tapr.org/tapr/html/pkthome.html>.
To compile this driver as a module, choose M here: the
module will be called rose.
-
menu "AX.25 network device drivers"
- depends on HAMRADIO && NET && AX25!=n
+ depends on HAMRADIO && AX25
source "drivers/net/hamradio/Kconfig"
endmenu
-
diff --git a/net/core/dev.c b/net/core/dev.c
index cf71614..5984b55 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1750,10 +1750,10 @@
skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
- spin_lock(&dev->ingress_lock);
+ spin_lock(&dev->queue_lock);
if ((q = dev->qdisc_ingress) != NULL)
result = q->enqueue(skb, q);
- spin_unlock(&dev->ingress_lock);
+ spin_unlock(&dev->queue_lock);
}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 3aea4e8..d011819 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -152,6 +152,28 @@
EXPORT_SYMBOL_GPL(fib_rules_lookup);
+static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb,
+ struct fib_rules_ops *ops)
+{
+ int err = -EINVAL;
+
+ if (frh->src_len)
+ if (tb[FRA_SRC] == NULL ||
+ frh->src_len > (ops->addr_size * 8) ||
+ nla_len(tb[FRA_SRC]) != ops->addr_size)
+ goto errout;
+
+ if (frh->dst_len)
+ if (tb[FRA_DST] == NULL ||
+ frh->dst_len > (ops->addr_size * 8) ||
+ nla_len(tb[FRA_DST]) != ops->addr_size)
+ goto errout;
+
+ err = 0;
+errout:
+ return err;
+}
+
int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
struct fib_rule_hdr *frh = nlmsg_data(nlh);
@@ -173,6 +195,10 @@
if (err < 0)
goto errout;
+ err = validate_rulemsg(frh, tb, ops);
+ if (err < 0)
+ goto errout;
+
rule = kzalloc(ops->rule_size, GFP_KERNEL);
if (rule == NULL) {
err = -ENOMEM;
@@ -260,6 +286,10 @@
if (err < 0)
goto errout;
+ err = validate_rulemsg(frh, tb, ops);
+ if (err < 0)
+ goto errout;
+
list_for_each_entry(rule, ops->rules_list, list) {
if (frh->action && (frh->action != rule->action))
continue;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 3183142..cfc6001 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -140,6 +140,8 @@
n->dead = 1;
shrunk = 1;
write_unlock(&n->lock);
+ if (n->parms->neigh_cleanup)
+ n->parms->neigh_cleanup(n);
neigh_release(n);
continue;
}
@@ -211,6 +213,8 @@
NEIGH_PRINTK2("neigh %p is stray.\n", n);
}
write_unlock(&n->lock);
+ if (n->parms->neigh_cleanup)
+ n->parms->neigh_cleanup(n);
neigh_release(n);
}
}
@@ -582,9 +586,6 @@
kfree(hh);
}
- if (neigh->parms->neigh_destructor)
- (neigh->parms->neigh_destructor)(neigh);
-
skb_queue_purge(&neigh->arp_queue);
dev_put(neigh->dev);
@@ -675,6 +676,8 @@
*np = n->next;
n->dead = 1;
write_unlock(&n->lock);
+ if (n->parms->neigh_cleanup)
+ n->parms->neigh_cleanup(n);
neigh_release(n);
continue;
}
@@ -2088,8 +2091,11 @@
} else
np = &n->next;
write_unlock(&n->lock);
- if (release)
+ if (release) {
+ if (n->parms->neigh_cleanup)
+ n->parms->neigh_cleanup(n);
neigh_release(n);
+ }
}
}
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 6055074..33ea8ea 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -621,7 +621,8 @@
if (err < 0)
goto errout;
- iw += IW_EV_POINT_OFF;
+ /* Payload is at an offset in buffer */
+ iw = iw_buf + IW_EV_POINT_OFF;
}
#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 9936ab1..b07fe27 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -2,7 +2,7 @@
* This file implement the Wireless Extensions APIs.
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
*
* (As all part of the Linux kernel, this file is GPL)
*/
@@ -76,6 +76,9 @@
* o Change length in ESSID and NICK to strlen() instead of strlen()+1
* o Make standard_ioctl_num and standard_event_num unsigned
* o Remove (struct net_device *)->get_wireless_stats()
+ *
+ * v10 - 16.3.07 - Jean II
+ * o Prevent leaking of kernel space in stream on 64 bits.
*/
/***************************** INCLUDES *****************************/
@@ -427,6 +430,21 @@
IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
};
+/* Size (in bytes) of various events, as packed */
+static const int event_type_pk_size[] = {
+ IW_EV_LCP_PK_LEN, /* IW_HEADER_TYPE_NULL */
+ 0,
+ IW_EV_CHAR_PK_LEN, /* IW_HEADER_TYPE_CHAR */
+ 0,
+ IW_EV_UINT_PK_LEN, /* IW_HEADER_TYPE_UINT */
+ IW_EV_FREQ_PK_LEN, /* IW_HEADER_TYPE_FREQ */
+ IW_EV_ADDR_PK_LEN, /* IW_HEADER_TYPE_ADDR */
+ 0,
+ IW_EV_POINT_PK_LEN, /* Without variable payload */
+ IW_EV_PARAM_PK_LEN, /* IW_HEADER_TYPE_PARAM */
+ IW_EV_QUAL_PK_LEN, /* IW_HEADER_TYPE_QUAL */
+};
+
/************************ COMMON SUBROUTINES ************************/
/*
* Stuff that may be used in various place or doesn't fit in one
@@ -1217,7 +1235,7 @@
memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
/* Use our own copy of wrqu */
wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
- + IW_EV_LCP_LEN);
+ + IW_EV_LCP_PK_LEN);
/* No extra arguments. Trivial to handle */
ret = handler(dev, &info, wrqu, NULL);
@@ -1229,8 +1247,8 @@
/* Get a temp copy of wrqu (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
- ((char *) request) + IW_EV_LCP_LEN,
- IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+ ((char *) request) + IW_EV_LCP_PK_LEN,
+ IW_EV_POINT_LEN - IW_EV_LCP_PK_LEN);
/* Calculate space needed by arguments. Always allocate
* for max space. Easier, and won't last long... */
@@ -1240,7 +1258,7 @@
(wrqu_point.data.length > descr->max_tokens))
extra_size = (wrqu_point.data.length
* descr->token_size);
- buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
+ buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
#ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
dev->name, extra_size, buffer_size);
@@ -1254,15 +1272,15 @@
/* Put wrqu in the right place (just before extra).
* Leave space for IWE header and dummy pointer...
- * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
+ * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
*/
- memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+ memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
((char *) &wrqu_point) + IW_EV_POINT_OFF,
- IW_EV_POINT_LEN - IW_EV_LCP_LEN);
- wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
+ IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
+ wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
/* Extra comes logically after that. Offset +12 bytes. */
- extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
+ extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
/* Call the handler */
ret = handler(dev, &info, wrqu, extra);
@@ -1270,11 +1288,11 @@
/* Calculate real returned length */
extra_size = (wrqu->data.length * descr->token_size);
/* Re-adjust reply size */
- request->len = extra_size + IW_EV_POINT_LEN;
+ request->len = extra_size + IW_EV_POINT_PK_LEN;
/* Put the iwe header where it should, i.e. scrap the
* dummy pointer. */
- memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
+ memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
#ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
@@ -1331,10 +1349,10 @@
#endif /* WE_RTNETLINK_DEBUG */
/* Extract fixed header from request. This is properly aligned. */
- wrqu = &request->u;
+ wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
/* Check if wrqu is complete */
- hdr_len = event_type_size[descr->header_type];
+ hdr_len = event_type_pk_size[descr->header_type];
if(request_len < hdr_len) {
#ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG
@@ -1359,7 +1377,7 @@
/* Put wrqu in the right place (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
- wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+ wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
/* Don't forget about the event code... */
wrqu = &wrqu_point;
@@ -1483,7 +1501,7 @@
hdr_len = extra_size;
extra_size = 0;
} else {
- hdr_len = IW_EV_POINT_LEN;
+ hdr_len = IW_EV_POINT_PK_LEN;
}
/* Check if wrqu is complete */
@@ -1514,7 +1532,7 @@
memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
/* Use our own copy of wrqu */
wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
- + IW_EV_LCP_LEN);
+ + IW_EV_LCP_PK_LEN);
/* No extra arguments. Trivial to handle */
ret = handler(dev, &info, wrqu, (char *) wrqu);
@@ -1523,7 +1541,7 @@
char * extra;
/* Buffer for full reply */
- buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
+ buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
#ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
@@ -1538,15 +1556,15 @@
/* Put wrqu in the right place (just before extra).
* Leave space for IWE header and dummy pointer...
- * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
+ * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
*/
- memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- ((char *) request) + IW_EV_LCP_LEN,
- IW_EV_POINT_LEN - IW_EV_LCP_LEN);
- wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
+ memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
+ ((char *) request) + IW_EV_LCP_PK_LEN,
+ IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
+ wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
/* Extra comes logically after that. Offset +12 bytes. */
- extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
+ extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
/* Call the handler */
ret = handler(dev, &info, wrqu, extra);
@@ -1556,11 +1574,11 @@
if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
extra_size = adjust_priv_size(descr->get_args, wrqu);
/* Re-adjust reply size */
- request->len = extra_size + IW_EV_POINT_LEN;
+ request->len = extra_size + IW_EV_POINT_PK_LEN;
/* Put the iwe header where it should, i.e. scrap the
* dummy pointer. */
- memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
+ memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
#ifdef WE_RTNETLINK_DEBUG
printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
@@ -1641,14 +1659,14 @@
/* Does it fits in wrqu ? */
if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
(extra_size <= IFNAMSIZ)) {
- hdr_len = IW_EV_LCP_LEN + extra_size;
+ hdr_len = IW_EV_LCP_PK_LEN + extra_size;
extra_size = 0;
} else {
- hdr_len = IW_EV_POINT_LEN;
+ hdr_len = IW_EV_POINT_PK_LEN;
}
/* Extract fixed header from request. This is properly aligned. */
- wrqu = &request->u;
+ wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
/* Check if wrqu is complete */
if(request_len < hdr_len) {
@@ -1675,7 +1693,7 @@
/* Put wrqu in the right place (skip pointer) */
memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
- wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+ wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
/* Does it fits within bounds ? */
if(wrqu_point.data.length > (descr->set_args &
@@ -1738,7 +1756,7 @@
iw_handler handler;
/* Check length */
- if(len < IW_EV_LCP_LEN) {
+ if(len < IW_EV_LCP_PK_LEN) {
printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
dev->name, len);
return -EINVAL;
@@ -1822,7 +1840,7 @@
iw_handler handler;
/* Check length */
- if(len < IW_EV_LCP_LEN) {
+ if(len < IW_EV_LCP_PK_LEN) {
printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
dev->name, len);
return -EINVAL;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index a0e7cd1..e33a9ed 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -191,7 +191,6 @@
const enum dccp_pkt_type pkt_type);
extern void dccp_write_xmit(struct sock *sk, int block);
-extern void dccp_write_xmit_timer(unsigned long data);
extern void dccp_write_space(struct sock *sk);
extern void dccp_init_xmit_timers(struct sock *sk);
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index b038a0a..0197a41 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -262,7 +262,7 @@
}
/* Transmit-delay timer: used by the CCIDs to delay actual send time */
-void dccp_write_xmit_timer(unsigned long data)
+static void dccp_write_xmit_timer(unsigned long data)
{
struct sock *sk = (struct sock *)data;
struct dccp_sock *dp = dccp_sk(sk);
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 3cbfddc..82d58a9 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -63,7 +63,7 @@
{
int error;
u8 scope;
-} dn_fib_props[RTA_MAX+1] = {
+} dn_fib_props[RTN_MAX+1] = {
[RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE },
[RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE },
[RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST },
@@ -276,6 +276,9 @@
struct dn_fib_info *ofi;
int nhs = 1;
+ if (r->rtm_type > RTN_MAX)
+ goto err_inval;
+
if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
goto err_inval;
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index b6c98ac..5e86dd5 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -109,8 +109,6 @@
static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
FRA_GENERIC_POLICY,
- [FRA_SRC] = { .type = NLA_U16 },
- [FRA_DST] = { .type = NLA_U16 },
};
static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
@@ -133,7 +131,7 @@
int err = -EINVAL;
struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
- if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos)
+ if (frh->tos)
goto errout;
if (rule->table == RT_TABLE_UNSPEC) {
@@ -150,10 +148,10 @@
}
}
- if (tb[FRA_SRC])
+ if (frh->src_len)
r->src = nla_get_le16(tb[FRA_SRC]);
- if (tb[FRA_DST])
+ if (frh->dst_len)
r->dst = nla_get_le16(tb[FRA_DST]);
r->src_len = frh->src_len;
@@ -176,10 +174,10 @@
if (frh->dst_len && (r->dst_len != frh->dst_len))
return 0;
- if (tb[FRA_SRC] && (r->src != nla_get_le16(tb[FRA_SRC])))
+ if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC])))
return 0;
- if (tb[FRA_DST] && (r->dst != nla_get_le16(tb[FRA_DST])))
+ if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST])))
return 0;
return 1;
@@ -249,6 +247,7 @@
static struct fib_rules_ops dn_fib_rules_ops = {
.family = AF_DECnet,
.rule_size = sizeof(struct dn_fib_rule),
+ .addr_size = sizeof(u16),
.action = dn_fib_rule_action,
.match = dn_fib_rule_match,
.configure = dn_fib_rule_configure,
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1fba643..fc920f6 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -493,6 +493,11 @@
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
cfg->fc_nlinfo.nlh = nlh;
+ if (cfg->fc_type > RTN_MAX) {
+ err = -EINVAL;
+ goto errout;
+ }
+
nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
switch (attr->nla_type) {
case RTA_DST:
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index b837c33..c660c07 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -171,8 +171,6 @@
static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
FRA_GENERIC_POLICY,
- [FRA_SRC] = { .type = NLA_U32 },
- [FRA_DST] = { .type = NLA_U32 },
[FRA_FLOW] = { .type = NLA_U32 },
};
@@ -183,8 +181,7 @@
int err = -EINVAL;
struct fib4_rule *rule4 = (struct fib4_rule *) rule;
- if (frh->src_len > 32 || frh->dst_len > 32 ||
- (frh->tos & ~IPTOS_TOS_MASK))
+ if (frh->tos & ~IPTOS_TOS_MASK)
goto errout;
if (rule->table == RT_TABLE_UNSPEC) {
@@ -201,10 +198,10 @@
}
}
- if (tb[FRA_SRC])
+ if (frh->src_len)
rule4->src = nla_get_be32(tb[FRA_SRC]);
- if (tb[FRA_DST])
+ if (frh->dst_len)
rule4->dst = nla_get_be32(tb[FRA_DST]);
#ifdef CONFIG_NET_CLS_ROUTE
@@ -242,10 +239,10 @@
return 0;
#endif
- if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC])))
+ if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC])))
return 0;
- if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST])))
+ if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST])))
return 0;
return 1;
@@ -309,6 +306,7 @@
static struct fib_rules_ops fib4_rules_ops = {
.family = AF_INET,
.rule_size = sizeof(struct fib4_rule),
+ .addr_size = sizeof(u32),
.action = fib4_rule_action,
.match = fib4_rule_match,
.configure = fib4_rule_configure,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 2f1fdae..3dad12e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -89,7 +89,7 @@
{
int error;
u8 scope;
-} fib_props[RTA_MAX + 1] = {
+} fib_props[RTN_MAX + 1] = {
{
.error = 0,
.scope = RT_SCOPE_NOWHERE,
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index ada9b3d..214c347 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1123,6 +1123,9 @@
return fa_head;
}
+/*
+ * Caller must hold RTNL.
+ */
static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
{
struct trie *t = (struct trie *) tb->tb_data;
@@ -1540,6 +1543,9 @@
return 1;
}
+/*
+ * Caller must hold RTNL.
+ */
static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
{
struct trie *t = (struct trie *) tb->tb_data;
@@ -1718,6 +1724,9 @@
return NULL; /* Ready. Root of trie */
}
+/*
+ * Caller must hold RTNL.
+ */
static int fn_trie_flush(struct fib_table *tb)
{
struct trie *t = (struct trie *) tb->tb_data;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1b61699..7552663 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -342,6 +342,9 @@
}
#endif
+ if (netif_running(dev) && netif_carrier_ok(dev))
+ ndev->if_flags |= IF_READY;
+
ipv6_mc_init_dev(ndev);
ndev->tstamp = jiffies;
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 0862809..ea3035b 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -131,8 +131,6 @@
static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
FRA_GENERIC_POLICY,
- [FRA_SRC] = { .len = sizeof(struct in6_addr) },
- [FRA_DST] = { .len = sizeof(struct in6_addr) },
};
static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
@@ -142,9 +140,6 @@
int err = -EINVAL;
struct fib6_rule *rule6 = (struct fib6_rule *) rule;
- if (frh->src_len > 128 || frh->dst_len > 128)
- goto errout;
-
if (rule->action == FR_ACT_TO_TBL) {
if (rule->table == RT6_TABLE_UNSPEC)
goto errout;
@@ -155,11 +150,11 @@
}
}
- if (tb[FRA_SRC])
+ if (frh->src_len)
nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
sizeof(struct in6_addr));
- if (tb[FRA_DST])
+ if (frh->dst_len)
nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
sizeof(struct in6_addr));
@@ -186,11 +181,11 @@
if (frh->tos && (rule6->tclass != frh->tos))
return 0;
- if (tb[FRA_SRC] &&
+ if (frh->src_len &&
nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
return 0;
- if (tb[FRA_DST] &&
+ if (frh->dst_len &&
nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
return 0;
@@ -240,6 +235,7 @@
static struct fib_rules_ops fib6_rules_ops = {
.family = AF_INET6,
.rule_size = sizeof(struct fib6_rule),
+ .addr_size = sizeof(struct in6_addr),
.action = fib6_rule_action,
.match = fib6_rule_match,
.configure = fib6_rule_configure,
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f4d7be7..268f476 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -658,6 +658,10 @@
ins = &iter->u.dst.rt6_next;
}
+ /* Reset round-robin state, if necessary */
+ if (ins == &fn->leaf)
+ fn->rr_ptr = NULL;
+
/*
* insert node
*/
@@ -1109,6 +1113,10 @@
rt6_stats.fib_rt_entries--;
rt6_stats.fib_discarded_routes++;
+ /* Reset round-robin state, if necessary */
+ if (fn->rr_ptr == rt)
+ fn->rr_ptr = NULL;
+
/* Adjust walkers */
read_lock(&fib6_walker_lock);
FOR_WALKERS(w) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a6b3117..3931b33 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -363,55 +363,76 @@
return m;
}
-static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
- int strict)
+static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict,
+ int *mpri, struct rt6_info *match)
{
- struct rt6_info *match = NULL, *last = NULL;
- struct rt6_info *rt, *rt0 = *head;
- u32 metric;
+ int m;
+
+ if (rt6_check_expired(rt))
+ goto out;
+
+ m = rt6_score_route(rt, oif, strict);
+ if (m < 0)
+ goto out;
+
+ if (m > *mpri) {
+ if (strict & RT6_LOOKUP_F_REACHABLE)
+ rt6_probe(match);
+ *mpri = m;
+ match = rt;
+ } else if (strict & RT6_LOOKUP_F_REACHABLE) {
+ rt6_probe(rt);
+ }
+
+out:
+ return match;
+}
+
+static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
+ struct rt6_info *rr_head,
+ u32 metric, int oif, int strict)
+{
+ struct rt6_info *rt, *match;
int mpri = -1;
- RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n",
- __FUNCTION__, head, head ? *head : NULL, oif);
+ match = NULL;
+ for (rt = rr_head; rt && rt->rt6i_metric == metric;
+ rt = rt->u.dst.rt6_next)
+ match = find_match(rt, oif, strict, &mpri, match);
+ for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric;
+ rt = rt->u.dst.rt6_next)
+ match = find_match(rt, oif, strict, &mpri, match);
- for (rt = rt0, metric = rt0->rt6i_metric;
- rt && rt->rt6i_metric == metric && (!last || rt != rt0);
- rt = rt->u.dst.rt6_next) {
- int m;
+ return match;
+}
- if (rt6_check_expired(rt))
- continue;
+static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
+{
+ struct rt6_info *match, *rt0;
- last = rt;
+ RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n",
+ __FUNCTION__, fn->leaf, oif);
- m = rt6_score_route(rt, oif, strict);
- if (m < 0)
- continue;
+ rt0 = fn->rr_ptr;
+ if (!rt0)
+ fn->rr_ptr = rt0 = fn->leaf;
- if (m > mpri) {
- if (strict & RT6_LOOKUP_F_REACHABLE)
- rt6_probe(match);
- match = rt;
- mpri = m;
- } else if (strict & RT6_LOOKUP_F_REACHABLE) {
- rt6_probe(rt);
- }
- }
+ match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict);
if (!match &&
- (strict & RT6_LOOKUP_F_REACHABLE) &&
- last && last != rt0) {
+ (strict & RT6_LOOKUP_F_REACHABLE)) {
+ struct rt6_info *next = rt0->u.dst.rt6_next;
+
/* no entries matched; do round-robin */
- static DEFINE_SPINLOCK(lock);
- spin_lock(&lock);
- *head = rt0->u.dst.rt6_next;
- rt0->u.dst.rt6_next = last->u.dst.rt6_next;
- last->u.dst.rt6_next = rt0;
- spin_unlock(&lock);
+ if (!next || next->rt6i_metric != rt0->rt6i_metric)
+ next = fn->leaf;
+
+ if (next != rt0)
+ fn->rr_ptr = next;
}
- RT6_TRACE("%s() => %p, score=%d\n",
- __FUNCTION__, match, mpri);
+ RT6_TRACE("%s() => %p\n",
+ __FUNCTION__, match);
return (match ? match : &ip6_null_entry);
}
@@ -657,7 +678,7 @@
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
restart:
- rt = rt6_select(&fn->leaf, fl->iif, strict | reachable);
+ rt = rt6_select(fn, fl->iif, strict | reachable);
BACKTRACK(&fl->fl6_src);
if (rt == &ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
@@ -752,7 +773,7 @@
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
restart:
- rt = rt6_select(&fn->leaf, fl->oif, strict | reachable);
+ rt = rt6_select(fn, fl->oif, strict | reachable);
BACKTRACK(&fl->fl6_src);
if (rt == &ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
diff --git a/net/sched/Makefile b/net/sched/Makefile
index ff2d6e5..020767a 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -17,7 +17,6 @@
obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
-obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
obj-$(CONFIG_NET_SCH_HFSC) += sch_hfsc.o
obj-$(CONFIG_NET_SCH_RED) += sch_red.o
obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index fad08e5..70fe36e 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -81,6 +81,13 @@
static int basic_init(struct tcf_proto *tp)
{
+ struct basic_head *head;
+
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
+ if (head == NULL)
+ return -ENOBUFS;
+ INIT_LIST_HEAD(&head->flist);
+ tp->root = head;
return 0;
}
@@ -176,15 +183,6 @@
}
err = -ENOBUFS;
- if (head == NULL) {
- head = kzalloc(sizeof(*head), GFP_KERNEL);
- if (head == NULL)
- goto errout;
-
- INIT_LIST_HEAD(&head->flist);
- tp->root = head;
- }
-
f = kzalloc(sizeof(*f), GFP_KERNEL);
if (f == NULL)
goto errout;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 396deb7..407c6fb 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1184,10 +1184,12 @@
sch_tree_lock(sch);
- list_del(&cl->hlist);
list_del(&cl->siblings);
hfsc_adjust_levels(cl->cl_parent);
+
hfsc_purge_queue(sch, cl);
+ list_del(&cl->hlist);
+
if (--cl->refcnt == 0)
hfsc_destroy_class(sch, cl);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 97cbb9a..3c3294d 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1380,15 +1380,15 @@
sch_tree_lock(sch);
- /* delete from hash and active; remainder in destroy_class */
- hlist_del_init(&cl->hlist);
-
if (!cl->level) {
qlen = cl->un.leaf.q->q.qlen;
qdisc_reset(cl->un.leaf.q);
qdisc_tree_decrease_qlen(cl->un.leaf.q, qlen);
}
+ /* delete from hash and active; remainder in destroy_class */
+ hlist_del_init(&cl->hlist);
+
if (cl->prio_activity)
htb_deactivate(q, cl);
diff --git a/net/socket.c b/net/socket.c
index 9566e57..ea8f81a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1381,7 +1381,7 @@
err = sock_attach_fd(newsock, newfile);
if (err < 0)
- goto out_fd;
+ goto out_fd_simple;
err = security_socket_accept(sock, newsock);
if (err)
@@ -1414,6 +1414,11 @@
fput_light(sock->file, fput_needed);
out:
return err;
+out_fd_simple:
+ sock_release(newsock);
+ put_filp(newfile);
+ put_unused_fd(newfd);
+ goto out_put;
out_fd:
fput(newfile);
put_unused_fd(newfd);