aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ax25.txt18
-rw-r--r--Documentation/power/pci.txt17
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/cris/arch-v32/drivers/pci/bios.c4
-rw-r--r--arch/frv/mb93090-mb00/pci-vdk.c3
-rw-r--r--arch/i386/kernel/hpet.c2
-rw-r--r--arch/i386/pci/common.c14
-rw-r--r--arch/ia64/pci/pci.c8
-rw-r--r--arch/s390/kernel/kprobes.c2
-rw-r--r--arch/sh/kernel/sh_ksyms.c3
-rw-r--r--arch/sparc/lib/atomic32.c2
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h4
-rw-r--r--arch/um/os-Linux/skas/mem.c10
-rw-r--r--arch/um/os-Linux/skas/process.c6
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c5
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c4
-rw-r--r--arch/x86_64/kernel/acpi/sleep.c4
-rw-r--r--block/elevator.c7
-rw-r--r--block/ll_rw_blk.c6
-rw-r--r--drivers/ata/ahci.c21
-rw-r--r--drivers/ata/libata-acpi.c8
-rw-r--r--drivers/ata/libata-core.c6
-rw-r--r--drivers/ata/libata-eh.c66
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_pdc202xx_old.c2
-rw-r--r--drivers/char/drm/Makefile2
-rw-r--r--drivers/char/drm/ffb_context.c544
-rw-r--r--drivers/char/drm/ffb_drv.c355
-rw-r--r--drivers/char/drm/ffb_drv.h379
-rw-r--r--drivers/char/generic_serial.c7
-rw-r--r--drivers/clocksource/acpi_pm.c2
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/eisa/pci_eisa.c4
-rw-r--r--drivers/ide/Kconfig6
-rw-r--r--drivers/ide/ide-io.c32
-rw-r--r--drivers/ide/ide-iops.c11
-rw-r--r--drivers/ide/ide.c37
-rw-r--r--drivers/ide/pci/pdc202xx_new.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c6
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c17
-rw-r--r--drivers/isdn/hisax/isar.c2
-rw-r--r--drivers/kvm/vmx.c39
-rw-r--r--drivers/md/md.c42
-rw-r--r--drivers/md/raid5.c19
-rw-r--r--drivers/media/common/ir-functions.c6
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c12
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c21
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c9
-rw-r--r--drivers/media/dvb/frontends/isl6421.c1
-rw-r--r--drivers/media/radio/Kconfig2
-rw-r--r--drivers/media/video/msp3400-driver.c14
-rw-r--r--drivers/media/video/saa7115.c2
-rw-r--r--drivers/media/video/tuner-core.c10
-rw-r--r--drivers/message/fusion/mptsas.c7
-rw-r--r--drivers/message/i2o/i2o_block.c12
-rw-r--r--drivers/net/atl1/atl1_hw.c1
-rw-r--r--drivers/net/forcedeth.c8
-rw-r--r--drivers/net/mv643xx_eth.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c7
-rw-r--r--drivers/net/ppp_generic.c3
-rwxr-xr-xdrivers/net/qla3xxx.c110
-rwxr-xr-xdrivers/net/qla3xxx.h3
-rw-r--r--drivers/net/sun3lance.c16
-rw-r--r--drivers/net/sungem.c30
-rw-r--r--drivers/net/tg3.c134
-rw-r--r--drivers/net/tg3.h5
-rw-r--r--drivers/net/wan/lmc/lmc_media.h65
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c12
-rw-r--r--drivers/oprofile/event_buffer.c5
-rw-r--r--drivers/oprofile/oprofilefs.c5
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pci/quirks.c18
-rw-r--r--drivers/pcmcia/au1000_generic.c2
-rw-r--r--drivers/s390/block/dasd_diag.c10
-rw-r--r--drivers/s390/cio/device_status.c6
-rw-r--r--drivers/s390/crypto/ap_bus.c30
-rw-r--r--drivers/scsi/gdth.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c5
-rw-r--r--drivers/spi/spi.c10
-rw-r--r--drivers/usb/core/quirks.c3
-rw-r--r--drivers/usb/gadget/omap_udc.c103
-rw-r--r--drivers/usb/host/uhci-debug.c26
-rw-r--r--drivers/usb/host/uhci-hcd.c3
-rw-r--r--drivers/usb/host/uhci-q.c94
-rw-r--r--drivers/usb/serial/airprime.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.c6
-rw-r--r--drivers/usb/serial/generic.c7
-rw-r--r--drivers/video/cg3.c26
-rw-r--r--drivers/video/ffb.c84
-rw-r--r--fs/9p/v9fs_vfs.h1
-rw-r--r--fs/9p/vfs_file.c4
-rw-r--r--fs/aio.c1
-rw-r--r--fs/compat_ioctl.c9
-rw-r--r--fs/nfsd/nfs3xdr.c6
-rw-r--r--fs/nfsd/nfs4acl.c2
-rw-r--r--fs/nfsd/nfs4state.c6
-rw-r--r--fs/proc/Makefile3
-rw-r--r--fs/splice.c84
-rw-r--r--include/asm-i386/termbits.h2
-rw-r--r--include/asm-s390/checksum.h59
-rw-r--r--include/asm-sh/hp6xx.h6
-rw-r--r--include/asm-sh/system.h1
-rw-r--r--include/asm-sparc/mostek.h2
-rw-r--r--include/asm-sparc64/mostek.h2
-rw-r--r--include/asm-um/common.lds.S1
-rw-r--r--include/linux/compiler.h4
-rw-r--r--include/linux/eventpoll.h7
-rw-r--r--include/linux/ide.h1
-rw-r--r--include/linux/ipc.h9
-rw-r--r--include/linux/pipe_fs_i.h4
-rw-r--r--include/linux/utsname.h2
-rw-r--r--include/linux/wireless.h21
-rw-r--r--include/media/saa7146_vv.h3
-rw-r--r--include/net/fib_rules.h1
-rw-r--r--include/net/ip6_fib.h1
-rw-r--r--include/net/iw_handler.h30
-rw-r--r--include/net/neighbour.h2
-rw-r--r--ipc/util.c7
-rw-r--r--kernel/hrtimer.c7
-rw-r--r--kernel/power/disk.c1
-rw-r--r--kernel/power/user.c3
-rw-r--r--kernel/time/clockevents.c69
-rw-r--r--kernel/time/ntp.c30
-rw-r--r--mm/bounce.c2
-rw-r--r--net/atm/clip.c9
-rw-r--r--net/ax25/Kconfig61
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/fib_rules.c30
-rw-r--r--net/core/neighbour.c14
-rw-r--r--net/core/rtnetlink.c3
-rw-r--r--net/core/wireless.c82
-rw-r--r--net/dccp/dccp.h1
-rw-r--r--net/dccp/proto.c4
-rw-r--r--net/dccp/timer.c2
-rw-r--r--net/decnet/dn_fib.c5
-rw-r--r--net/decnet/dn_rules.c13
-rw-r--r--net/ipv4/fib_frontend.c5
-rw-r--r--net/ipv4/fib_rules.c14
-rw-r--r--net/ipv4/fib_semantics.c2
-rw-r--r--net/ipv4/fib_trie.c9
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/fib6_rules.c14
-rw-r--r--net/ipv6/ip6_fib.c8
-rw-r--r--net/ipv6/route.c97
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/cls_basic.c16
-rw-r--r--net/sched/sch_hfsc.c4
-rw-r--r--net/sched/sch_htb.c6
-rw-r--r--net/socket.c7
152 files changed, 1205 insertions, 2308 deletions
diff --git a/Documentation/networking/ax25.txt b/Documentation/networking/ax25.txt
index 37c25b0925f..8257dbf9be5 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 c750f9f2e76..b6a3cbf7e84 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -102,31 +102,28 @@ pci_save_state
--------------
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 @@ pci_enable_wake
---------------
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 dd6978b1e8f..8c8090e02d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1585,12 +1585,6 @@ L: i2c@lm-sensors.org
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 @@ L: linux-scsi@vger.kernel.org
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 a2b9c60c277..5b79a7a772d 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -100,7 +100,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
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 f7279d78995..0b581e3cf7c 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -466,6 +466,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
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 f3ab61ee749..76afea67f69 100644
--- a/arch/i386/kernel/hpet.c
+++ b/arch/i386/kernel/hpet.c
@@ -197,7 +197,7 @@ static int hpet_next_event(unsigned long delta,
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 1bb06937214..3f78d4d8ecf 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -193,6 +193,14 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
},
{
.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 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
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 474d179966d..f8bcccd6d41 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -557,14 +557,18 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
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 8af549e9573..993f3538149 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -167,7 +167,7 @@ static int __kprobes swap_instruction(void *aref)
* 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 fe1b276c97c..6e0d10fac4a 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -82,9 +82,6 @@ DECLARE_EXPORT(__movstr);
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/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 53ddcd9d1e6..559335f4917 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -52,6 +52,7 @@ int atomic_cmpxchg(atomic_t *v, int old, int new)
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
return ret;
}
+EXPORT_SYMBOL(atomic_cmpxchg);
int atomic_add_unless(atomic_t *v, int a, int u)
{
@@ -65,6 +66,7 @@ int atomic_add_unless(atomic_t *v, int a, int u)
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
return ret != u;
}
+EXPORT_SYMBOL(atomic_add_unless);
/* Atomic operations are already serializing */
void atomic_set(atomic_t *v, int i)
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 66cb400c2c9..62403bd9966 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -104,10 +104,6 @@ union uml_pt_regs {
#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 b3c11cfa995..9383e8751ae 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -48,7 +48,7 @@ int multi_op_count = 0;
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 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
(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 dda06789bcb..0564422c155 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname)
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 @@ void wait_stub_done(int pid, int sig, char * fname)
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 @@ void userspace(union uml_pt_regs *regs)
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 79cd93c8c5e..84b44f9cd42 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 @@ void init_registers(int pid)
{
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 init_registers(int pid)
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 a2d7e0c603f..e6fc2179d1b 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 init_registers(int pid)
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 23178ce6c78..e1548fbe95a 100644
--- a/arch/x86_64/kernel/acpi/sleep.c
+++ b/arch/x86_64/kernel/acpi/sleep.c
@@ -66,8 +66,10 @@ static void init_low_mapping(void)
{
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 25f6ef28e3b..96a00c82274 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -964,17 +964,18 @@ void elv_unregister_queue(struct request_queue *q)
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 38c293b987b..3de06953ac3 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1221,7 +1221,7 @@ void blk_recount_segments(request_queue_t *q, struct bio *bio)
* 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 @@ int __init blk_dev_init(void)
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 dc7b5622592..fd27227771b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -80,6 +80,7 @@ enum {
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 @@ enum {
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 @@ static const struct ata_port_info ahci_port_info[] = {
.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 @@ static const struct pci_device_id ahci_pci_tbl[] = {
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 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
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 c428a56e6f3..03a0acff6cf 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -305,7 +305,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
*gtf_address = 0UL;
*obj_loc = 0UL;
- if (noacpi)
+ if (libata_noacpi)
return 0;
if (ata_msg_probe(ap))
@@ -531,7 +531,7 @@ static int do_drive_set_taskfiles(struct ata_port *ap,
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 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
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 @@ int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
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 bf327d473ce..f1f595f53d9 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -93,8 +93,8 @@ static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
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 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "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 361953a5020..c89664a77a9 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1743,12 +1743,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
{
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 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
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 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
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;
+ default:
+ dev->class = ATA_DEV_UNKNOWN;
+ goto err;
}
+ }
+ }
- if (ata_dev_enabled(dev)) {
- spin_lock_irqsave(ap->lock, flags);
- ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
- spin_unlock_irqrestore(ap->lock, flags);
+ /* 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];
- /* new device discovered, configure xfermode */
- ehc->i.flags |= ATA_EHI_SETMODE;
- }
- }
+ 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;
}
- if (rc)
- *r_failed_dev = dev;
+ return 0;
- DPRINTK("EXIT\n");
+ 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 c42671493e8..1f1e3a51f85 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -56,7 +56,7 @@ extern struct workqueue_struct *ata_aux_wq;
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 acdc52cbe38..0a149339891 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -195,7 +195,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
/* 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/drm/Makefile b/drivers/char/drm/Makefile
index 3ad0f648c6b..6915a0599df 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -15,7 +15,6 @@ i810-objs := i810_drv.o i810_dma.o
i830-objs := i830_drv.o i830_dma.o i830_irq.o
i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
-ffb-objs := ffb_drv.o ffb_context.o
sis-objs := sis_drv.o sis_mm.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
@@ -36,7 +35,6 @@ obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
obj-$(CONFIG_DRM_I830) += i830.o
obj-$(CONFIG_DRM_I915) += i915.o
-obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_SIS) += sis.o
obj-$(CONFIG_DRM_SAVAGE)+= savage.o
obj-$(CONFIG_DRM_VIA) +=via.o
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
deleted file mode 100644
index ac9ab40d57a..00000000000
--- a/drivers/char/drm/ffb_context.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/* $Id: ffb_context.c,v 1.5 2001/08/09 17:47:51 davem Exp $
- * ffb_context.c: Creator/Creator3D DRI/DRM context switching.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- *
- * Almost entirely stolen from tdfx_context.c, see there
- * for authors.
- */
-
-#include <asm/upa.h>
-
-#include "ffb.h"
-#include "drmP.h"
-
-#include "ffb_drv.h"
-
-static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) {
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
- int i;
-
- for (i = 0; i < FFB_MAX_CTXS; i++) {
- if (fpriv->hw_state[i] == NULL)
- break;
- }
- if (i == FFB_MAX_CTXS)
- return -1;
-
- fpriv->hw_state[i] = kmalloc(sizeof(struct ffb_hw_context), GFP_KERNEL);
- if (fpriv->hw_state[i] == NULL)
- return -1;
-
- fpriv->hw_state[i]->is_2d_only = is_2d_only;
-
- /* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
- return i + 1;
-}
-
-static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx)
-{
- ffb_fbcPtr ffb = fpriv->regs;
- struct ffb_hw_context *ctx;
- int i;
-
- ctx = fpriv->hw_state[idx - 1];
- if (idx == 0 || ctx == NULL)
- return;
-
- if (ctx->is_2d_only) {
- /* 2D applications only care about certain pieces
- * of state.
- */
- ctx->drawop = upa_readl(&ffb->drawop);
- ctx->ppc = upa_readl(&ffb->ppc);
- ctx->wid = upa_readl(&ffb->wid);
- ctx->fg = upa_readl(&ffb->fg);
- ctx->bg = upa_readl(&ffb->bg);
- ctx->xclip = upa_readl(&ffb->xclip);
- ctx->fbc = upa_readl(&ffb->fbc);
- ctx->rop = upa_readl(&ffb->rop);
- ctx->cmp = upa_readl(&ffb->cmp);
- ctx->matchab = upa_readl(&ffb->matchab);
- ctx->magnab = upa_readl(&ffb->magnab);
- ctx->pmask = upa_readl(&ffb->pmask);
- ctx->xpmask = upa_readl(&ffb->xpmask);
- ctx->lpat = upa_readl(&ffb->lpat);
- ctx->fontxy = upa_readl(&ffb->fontxy);
- ctx->fontw = upa_readl(&ffb->fontw);
- ctx->fontinc = upa_readl(&ffb->fontinc);
-
- /* stencil/stencilctl only exists on FFB2+ and later
- * due to the introduction of 3DRAM-III.
- */
- if (fpriv->ffb_type == ffb2_vertical_plus ||
- fpriv->ffb_type == ffb2_horizontal_plus) {
- ctx->stencil = upa_readl(&ffb->stencil);
- ctx->stencilctl = upa_readl(&ffb->stencilctl);
- }
-
- for (i = 0; i < 32; i++)
- ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
- ctx->ucsr = upa_readl(&ffb->ucsr);
- return;
- }
-
- /* Fetch drawop. */
- ctx->drawop = upa_readl(&ffb->drawop);
-
- /* If we were saving the vertex registers, this is where
- * we would do it. We would save 32 32-bit words starting
- * at ffb->suvtx.
- */
-
- /* Capture rendering attributes. */
-
- ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
- ctx->wid = upa_readl(&ffb->wid); /* Current WID */
- ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
- ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
- ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
- ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
- ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
- ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
- ctx->vclipmin = upa_readl(&ffb->vclipmin); /* Primary XY clip, minimum */
- ctx->vclipmax = upa_readl(&ffb->vclipmax); /* Primary XY clip, maximum */
- ctx->vclipzmin = upa_readl(&ffb->vclipzmin); /* Primary Z clip, minimum */
- ctx->vclipzmax = upa_readl(&ffb->vclipzmax); /* Primary Z clip, maximum */
- ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
- ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
- ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
- ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
- ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
- ctx->blendc1 = upa_readl(&ffb->blendc1); /* Alpha Blend Color 1 */
- ctx->blendc2 = upa_readl(&ffb->blendc2); /* Alpha Blend Color 2 */
- ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
- ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
- ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
- ctx->matchab = upa_readl(&ffb->matchab); /* Buffer A/B Match Ops */
- ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
- ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
- ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
- ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
- ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
- ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
- ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
-
- /* Auxiliary Clips. */
- ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
- ctx->auxclip0max = upa_readl(&ffb->auxclip[0].max);
- ctx->auxclip1min = upa_readl(&ffb->auxclip[1].min);
- ctx->auxclip1max = upa_readl(&ffb->auxclip[1].max);
- ctx->auxclip2min = upa_readl(&ffb->auxclip[2].min);
- ctx->auxclip2max = upa_readl(&ffb->auxclip[2].max);
- ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
- ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
-
- ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
- ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
- ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
- ctx->fontinc = upa_readl(&ffb->fontinc); /* Font X/Y Increment */
-
- /* These registers/features only exist on FFB2 and later chips. */
- if (fpriv->ffb_type >= ffb2_prototype) {
- ctx->dcss1 = upa_readl(&ffb->dcss1); /* Depth Cue Scale Slope 1 */
- ctx->dcss2 = upa_readl(&ffb->dcss2); /* Depth Cue Scale Slope 2 */
- ctx->dcss2 = upa_readl(&ffb->dcss3); /* Depth Cue Scale Slope 3 */
- ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
- ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
- ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
- ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
- ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
- ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
-
- /* And stencil/stencilctl only exists on FFB2+ and later
- * due to the introduction of 3DRAM-III.
- */
- if (fpriv->ffb_type == ffb2_vertical_plus ||
- fpriv->ffb_type == ffb2_horizontal_plus) {
- ctx->stencil = upa_readl(&ffb->stencil);
- ctx->stencilctl = upa_readl(&ffb->stencilctl);
- }
- }
-
- /* Save the 32x32 area pattern. */
- for (i = 0; i < 32; i++)
- ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
-
- /* Finally, stash away the User Constol/Status Register. */
- ctx->ucsr = upa_readl(&ffb->ucsr);
-}
-
-static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx)
-{
- ffb_fbcPtr ffb = fpriv->regs;
- struct ffb_hw_context *ctx;
- int i;
-
- ctx = fpriv->hw_state[idx - 1];
- if (idx == 0 || ctx == NULL)
- return;
-
- if (ctx->is_2d_only) {
- /* 2D applications only care about certain pieces
- * of state.
- */
- upa_writel(ctx->drawop, &ffb->drawop);
-
- /* If we were restoring the vertex registers, this is where
- * we would do it. We would restore 32 32-bit words starting
- * at ffb->suvtx.
- */
-
- upa_writel(ctx->ppc, &ffb->ppc);
- upa_writel(ctx->wid, &ffb->wid);
- upa_writel(ctx->fg, &ffb->fg);
- upa_writel(ctx->bg, &ffb->bg);
- upa_writel(ctx->xclip, &ffb->xclip);
- upa_writel(ctx->fbc, &ffb->fbc);
- upa_writel(ctx->rop, &ffb->rop);
- upa_writel(ctx->cmp, &ffb->cmp);
- upa_writel(ctx->matchab, &ffb->matchab);
- upa_writel(ctx->magnab, &ffb->magnab);
- upa_writel(ctx->pmask, &ffb->pmask);
- upa_writel(ctx->xpmask, &ffb->xpmask);
- upa_writel(ctx->lpat, &ffb->lpat);
- upa_writel(ctx->fontxy, &ffb->fontxy);
- upa_writel(ctx->fontw, &ffb->fontw);
- upa_writel(ctx->fontinc, &ffb->fontinc);
-
- /* stencil/stencilctl only exists on FFB2+ and later
- * due to the introduction of 3DRAM-III.
- */
- if (fpriv->ffb_type == ffb2_vertical_plus ||
- fpriv->ffb_type == ffb2_horizontal_plus) {
- upa_writel(ctx->stencil, &ffb->stencil);
- upa_writel(ctx->stencilctl, &ffb->stencilctl);
- upa_writel(0x80000000, &ffb->fbc);
- upa_writel((ctx->stencilctl | 0x80000),
- &ffb->rawstencilctl);
- upa_writel(ctx->fbc, &ffb->fbc);
- }
-
- for (i = 0; i < 32; i++)
- upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
- upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
- return;
- }
-
- /* Restore drawop. */
- upa_writel(ctx->drawop, &ffb->drawop);
-
- /* If we were restoring the vertex registers, this is where
- * we would do it. We would restore 32 32-bit words starting
- * at ffb->suvtx.
- */
-
- /* Restore rendering attributes. */
-
- upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
- upa_writel(ctx->wid, &ffb->wid); /* Current WID */
- upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
- upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
- upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
- upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
- upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
- upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
- upa_writel(ctx->vclipmin, &ffb->vclipmin); /* Primary XY clip, minimum */
- upa_writel(ctx->vclipmax, &ffb->vclipmax); /* Primary XY clip, maximum */
- upa_writel(ctx->vclipzmin, &ffb->vclipzmin); /* Primary Z clip, minimum */
- upa_writel(ctx->vclipzmax, &ffb->vclipzmax); /* Primary Z clip, maximum */
- upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
- upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
- upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
- upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
- upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
- upa_writel(ctx->blendc1, &ffb->blendc1); /* Alpha Blend Color 1 */
- upa_writel(ctx->blendc2, &ffb->blendc2); /* Alpha Blend Color 2 */
- upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
- upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
- upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
- upa_writel(ctx->matchab, &ffb->matchab); /* Buffer A/B Match Ops */
- upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
- upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
- upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
- upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
- upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
- upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
- upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
-
- /* Auxiliary Clips. */
- upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
- upa_writel(ctx->auxclip0max, &ffb->auxclip[0].max);
- upa_writel(ctx->auxclip1min, &ffb->auxclip[1].min);
- upa_writel(ctx->auxclip1max, &ffb->auxclip[1].max);
- upa_writel(ctx->auxclip2min, &ffb->auxclip[2].min);
- upa_writel(ctx->auxclip2max, &ffb->auxclip[2].max);
- upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
- upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
-
- upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
- upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
- upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
- upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */
-
- /* These registers/features only exist on FFB2 and later chips. */
- if (fpriv->ffb_type >= ffb2_prototype) {
- upa_writel(ctx->dcss1, &ffb->dcss1); /* Depth Cue Scale Slope 1 */
- upa_writel(ctx->dcss2, &ffb->dcss2); /* Depth Cue Scale Slope 2 */
- upa_writel(ctx->dcss3, &ffb->dcss2); /* Depth Cue Scale Slope 3 */
- upa_writel(ctx->dcs2, &ffb->dcs2); /* Depth Cue Scale 2 */
- upa_writel(ctx->dcs3, &ffb->dcs3); /* Depth Cue Scale 3 */
- upa_writel(ctx->dcs4, &ffb->dcs4); /* Depth Cue Scale 4 */
- upa_writel(ctx->dcd2, &ffb->dcd2); /* Depth Cue Depth 2 */
- upa_writel(ctx->dcd3, &ffb->dcd3); /* Depth Cue Depth 3 */
- upa_writel(ctx->dcd4, &ffb->dcd4); /* Depth Cue Depth 4 */
-
- /* And stencil/stencilctl only exists on FFB2+ and later
- * due to the introduction of 3DRAM-III.
- */
- if (fpriv->ffb_type == ffb2_vertical_plus ||
- fpriv->ffb_type == ffb2_horizontal_plus) {
- /* Unfortunately, there is a hardware bug on
- * the FFB2+ chips which prevents a normal write
- * to the stencil control register from working
- * as it should.
- *
- * The state controlled by the FFB stencilctl register
- * really gets transferred to the per-buffer instances
- * of the stencilctl register in the 3DRAM chips.
- *
- * The bug is that FFB does not update buffer C correctly,
- * so we have to do it by hand for them.
- */
-
- /* This will update buffers A and B. */
- upa_writel(ctx->stencil, &ffb->stencil);
- upa_writel(ctx->stencilctl, &ffb->stencilctl);
-
- /* Force FFB to use buffer C 3dram regs. */
- upa_writel(0x80000000, &ffb->fbc);
- upa_writel((ctx->stencilctl | 0x80000),
- &ffb->rawstencilctl);
-
- /* Now restore the correct FBC controls. */
- upa_writel(ctx->fbc, &ffb->fbc);
- }
- }
-
- /* Restore the 32x32 area pattern. */
- for (i = 0; i < 32; i++)
- upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
-
- /* Finally, stash away the User Constol/Status Register.
- * The only state we really preserve here is the picking
- * control.
- */
- upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
-}
-
-#define FFB_UCSR_FB_BUSY 0x01000000
-#define FFB_UCSR_RP_BUSY 0x02000000
-#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
-
-static void FFBWait(ffb_fbcPtr ffb)
-{
- int limit = 100000;
-
- do {
- u32 regval = upa_readl(&ffb->ucsr);
-
- if ((regval & FFB_UCSR_ALL_BUSY) == 0)
- break;
- } while (--limit);
-}
-
-int ffb_driver_context_switch(drm_device_t * dev, int old, int new)
-{
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-
-#ifdef DRM_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
-#endif
-
- DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
- if (new == dev->last_context || dev->last_context == 0) {
- dev->last_context = new;
- return 0;
- }
-
- FFBWait(fpriv->regs);
- ffb_save_context(fpriv, old);
- ffb_restore_context(fpriv, old, new);
- FFBWait(fpriv->regs);
-
- dev->last_context = new;
-
- return 0;
-}
-
-int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_ctx_res_t res;
- drm_ctx_t ctx;
- int i;
-
- DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
- if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res)))
- return -EFAULT;
- if (res.count >= DRM_RESERVED_CONTEXTS) {
- memset(&ctx, 0, sizeof(ctx));
- for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
- ctx.handle = i;
- if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
- return -EFAULT;
- }
- }
- res.count = DRM_RESERVED_CONTEXTS;
- if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res)))
- return -EFAULT;
- return 0;
-}
-
-int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
- int idx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
- idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
- if (idx < 0)
- return -ENFILE;
-
- DRM_DEBUG("%d\n", ctx.handle);
- ctx.handle = idx;
- if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
- return -EFAULT;
- return 0;
-}
-
-int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
- struct ffb_hw_context *hwctx;
- drm_ctx_t ctx;
- int idx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
-
- idx = ctx.handle;
- if (idx <= 0 || idx >= FFB_MAX_CTXS)
- return -EINVAL;
-
- hwctx = fpriv->hw_state[idx - 1];
- if (hwctx == NULL)
- return -EINVAL;
-
- if ((ctx.flags & _DRM_CONTEXT_2DONLY) == 0)
- hwctx->is_2d_only = 0;
- else
- hwctx->is_2d_only = 1;
-
- return 0;
-}
-
-int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
- struct ffb_hw_context *hwctx;
- drm_ctx_t ctx;
- int idx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
-
- idx = ctx.handle;
- if (idx <= 0 || idx >= FFB_MAX_CTXS)
- return -EINVAL;
-
- hwctx = fpriv->hw_state[idx - 1];
- if (hwctx == NULL)
- return -EINVAL;
-
- if (hwctx->is_2d_only != 0)
- ctx.flags = _DRM_CONTEXT_2DONLY;
- else
- ctx.flags = 0;
-
- if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
- return -EFAULT;
-
- return 0;
-}
-
-int ffb_driver_switchctx(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
- return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
-
- return 0;
-}
-
-int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_ctx_t ctx;
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
- int idx;
-
- if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
-
- idx = ctx.handle - 1;
- if (idx < 0 || idx >= FFB_MAX_CTXS)
- return -EINVAL;
-
- kfree(fpriv->hw_state[idx]);
- fpriv->hw_state[idx] = NULL;
- return 0;
-}
-
-void ffb_set_context_ioctls(void)
-{
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)].func = ffb_driver_addctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func =
- ffb_driver_switchctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
- DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
-
-}
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
deleted file mode 100644
index 9a19879e3b6..00000000000
--- a/drivers/char/drm/ffb_drv.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* $Id: ffb_drv.c,v 1.16 2001/10/18 16:00:24 davem Exp $
- * ffb_drv.c: Creator/Creator3D direct rendering driver.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-
-#include "ffb.h"
-#include "drmP.h"
-
-#include "ffb_drv.h"
-
-#include <linux/smp_lock.h>
-#include <asm/shmparam.h>
-#include <asm/oplib.h>
-#include <asm/upa.h>
-
-#define DRIVER_AUTHOR "David S. Miller"
-
-#define DRIVER_NAME "ffb"
-#define DRIVER_DESC "Creator/Creator3D"
-#define DRIVER_DATE "20000517"
-
-#define DRIVER_MAJOR 0
-#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 1
-
-typedef struct _ffb_position_t {
- int node;
- int root;
-} ffb_position_t;
-
-static ffb_position_t *ffb_position;
-
-static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance)
-{
- volatile unsigned char *strap_bits;
- unsigned char val;
-
- strap_bits = (volatile unsigned char *)
- (ffb_priv->card_phys_base + 0x00200000UL);
-
- /* Don't ask, you have to read the value twice for whatever
- * reason to get correct contents.
- */
- val = upa_readb(strap_bits);
- val = upa_readb(strap_bits);
- switch (val & 0x78) {
- case (0x0 << 5) | (0x0 << 3):
- ffb_priv->ffb_type = ffb1_prototype;
- printk("ffb%d: Detected FFB1 pre-FCS prototype\n", instance);
- break;
- case (0x0 << 5) | (0x1 << 3):
- ffb_priv->ffb_type = ffb1_standard;
- printk("ffb%d: Detected FFB1\n", instance);
- break;
- case (0x0 << 5) | (0x3 << 3):
- ffb_priv->ffb_type = ffb1_speedsort;
- printk("ffb%d: Detected FFB1-SpeedSort\n", instance);
- break;
- case (0x1 << 5) | (0x0 << 3):
- ffb_priv->ffb_type = ffb2_prototype;
- printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n",
- instance);
- break;
- case (0x1 << 5) | (0x1 << 3):
- ffb_priv->ffb_type = ffb2_vertical;
- printk("ffb%d: Detected FFB2/vertical\n", instance);
- break;
- case (0x1 << 5) | (0x2 << 3):
- ffb_priv->ffb_type = ffb2_vertical_plus;
- printk("ffb%d: Detected FFB2+/vertical\n", instance);
- break;
- case (0x2 << 5) | (0x0 << 3):
- ffb_priv->ffb_type = ffb2_horizontal;
- printk("ffb%d: Detected FFB2/horizontal\n", instance);
- break;
- case (0x2 << 5) | (0x2 << 3):
- ffb_priv->ffb_type = ffb2_horizontal;
- printk("ffb%d: Detected FFB2+/horizontal\n", instance);
- break;
- default:
- ffb_priv->ffb_type = ffb2_vertical;
- printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n",
- instance, val);
- break;
- };
-}
-
-static void ffb_apply_upa_parent_ranges(int parent,
- struct linux_prom64_registers *regs)
-{
- struct linux_prom64_ranges ranges[PROMREG_MAX];
- char name[128];
- int len, i;
-
- prom_getproperty(parent, "name", name, sizeof(name));
- if (strcmp(name, "upa") != 0)
- return;
-
- len =
- prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges));
- if (len <= 0)
- return;
-
- len /= sizeof(struct linux_prom64_ranges);
- for (i = 0; i < len; i++) {
- struct linux_prom64_ranges *rng = &ranges[i];
- u64 phys_addr = regs->phys_addr;
-
- if (phys_addr >= rng->ot_child_base &&
- phys_addr < (rng->ot_child_base + rng->or_size)) {
- regs->phys_addr -= rng->ot_child_base;
- regs->phys_addr += rng->ot_parent_base;
- return;
- }
- }
-
- return;
-}
-
-static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node,
- int instance)
-{
- struct linux_prom64_registers regs[2 * PROMREG_MAX];
- ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
- int i;
-
- ffb_priv->prom_node = prom_node;
- if (prom_getproperty(ffb_priv->prom_node, "reg",
- (void *)regs, sizeof(regs)) <= 0) {
- return -EINVAL;
- }
- ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
- ffb_priv->card_phys_base = regs[0].phys_addr;
- ffb_priv->regs = (ffb_fbcPtr)
- (regs[0].phys_addr + 0x00600000UL);
- get_ffb_type(ffb_priv, instance);
- for (i = 0; i < FFB_MAX_CTXS; i++)
- ffb_priv->hw_state[i] = NULL;
-
- return 0;
-}
-
-static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev;
- drm_map_list_t *r_list;
- struct list_head *list;
- drm_map_t *map;
-
- if (!priv || (dev = priv->dev) == NULL)
- return NULL;
-
- list_for_each(list, &dev->maplist->head) {
- r_list = (drm_map_list_t *) list;
- map = r_list->map;
- if (!map)
- continue;
- if (r_list->user_token == off)
- return map;
- }
-
- return NULL;
-}
-
-unsigned long ffb_get_unmapped_area(struct file *filp,
- unsigned long hint,
- unsigned long len,
- unsigned long pgoff, unsigned long flags)
-{
- drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
- unsigned long addr = -ENOMEM;
-
- if (!map)
- return get_unmapped_area(NULL, hint, len, pgoff, flags);
-
- if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) {
-#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
- addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
-#else
- addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
-#endif
- } else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
- unsigned long slack = SHMLBA - PAGE_SIZE;
-
- addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
- if (!(addr & ~PAGE_MASK)) {
- unsigned long kvirt = (unsigned long)map->handle;
-
- if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
- unsigned long koff, aoff;
-
- koff = kvirt & (SHMLBA - 1);
- aoff = addr & (SHMLBA - 1);
- if (koff < aoff)
- koff += SHMLBA;
-
- addr += (koff - aoff);
- }
- }
- } else {
- addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
- }
-
- return addr;
-}
-
-static int ffb_presetup(drm_device_t * dev)
-{
- ffb_dev_priv_t *ffb_priv;
- int ret = 0;
- int i = 0;
-
- /* Check for the case where no device was found. */
- if (ffb_position == NULL)
- return -ENODEV;
-
- /* code used to use numdevs no numdevs anymore */
- ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
- if (!ffb_priv)
- return -ENOMEM;
- memset(ffb_priv, 0, sizeof(*ffb_priv));
- dev->dev_private = ffb_priv;
-
- ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i);
- return ret;
-}
-
-static void ffb_driver_release(drm_device_t * dev, struct file *filp)
-{
- ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
- int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
- int idx;
-
- idx = context - 1;
- if (fpriv &&
- context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) {
- kfree(fpriv->hw_state[idx]);
- fpriv->hw_state[idx] = NULL;
- }
-}
-
-static void ffb_driver_pretakedown(drm_device_t * dev)
-{
- kfree(dev->dev_private);
-}
-
-static int ffb_driver_postcleanup(drm_device_t * dev)
-{
- kfree(ffb_position);
- return 0;
-}
-
-static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev,
- drm_lock_t * lock)
-{
- dev->lock.filp = 0;
- {
- __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
- unsigned int old, new, prev, ctx;
-
- ctx = lock->context;
- do {
- old = *plock;
- new = ctx;
- prev = cmpxchg(plock, old, new);
- } while (prev != old);
- }
- wake_up_interruptible(&dev->lock.lock_queue);
-}
-
-static unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
-{
- return (map->offset & 0xffffffff);
-}
-
-static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
-{
- ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
-
- if (ffb_priv)
- return ffb_priv->card_phys_base;
-
- return 0;
-}
-
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
- DRIVER_NAME,
- DRIVER_MAJOR,
- DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor);
- return 0;
-}
-
-static int version(drm_version_t * version)
-{
- int len;
-
- version->version_major = DRIVER_MAJOR;
- version->version_minor = DRIVER_MINOR;
- version->version_patchlevel = DRIVER_PATCHLEVEL;
- DRM_COPY(version->name, DRIVER_NAME);
- DRM_COPY(version->date, DRIVER_DATE);
- DRM_COPY(version->desc, DRIVER_DESC);
- return 0;
-}
-
-static drm_ioctl_desc_t ioctls[] = {
-
-};
-
-static struct drm_driver driver = {
- .driver_features = 0,
- .dev_priv_size = sizeof(u32),
- .release = ffb_driver_release,
- .presetup = ffb_presetup,
- .pretakedown = ffb_driver_pretakedown,
- .postcleanup = ffb_driver_postcleanup,
- .kernel_context_switch = ffb_driver_context_switch,
- .kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock,
- .get_map_ofs = ffb_driver_get_map_ofs,
- .get_reg_ofs = ffb_driver_get_reg_ofs,
- .postinit = postinit,
- .version = version,
- .ioctls = ioctls,
- .num_ioctls = DRM_ARRAY_SIZE(ioctls),
- .fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- }
- ,
-};
-
-static int __init ffb_init(void)
-{
- return -ENODEV;
-}
-
-static void __exit ffb_exit(void)
-{
-}
-
-module_init(ffb_init);
-module_exit(ffb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h
deleted file mode 100644
index 582afa6dd2b..00000000000
--- a/drivers/char/drm/ffb_drv.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* $Id: ffb_drv.h,v 1.1 2000/06/01 04:24:39 davem Exp $
- * ffb_drv.h: Creator/Creator3D direct rendering driver.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-
-/* Auxilliary clips. */
-typedef struct {
- volatile unsigned int min;
- volatile unsigned int max;
-} ffb_auxclip, *ffb_auxclipPtr;
-
-/* FFB register set. */
-typedef struct _ffb_fbc {
- /* Next vertex registers, on the right we list which drawops
- * use said register and the logical name the register has in
- * that context.
- *//* DESCRIPTION DRAWOP(NAME) */
- /*0x00*/ unsigned int pad1[3];
- /* Reserved */
- /*0x0c*/ volatile unsigned int alpha;
- /* ALPHA Transparency */
- /*0x10*/ volatile unsigned int red;
- /* RED */
- /*0x14*/ volatile unsigned int green;
- /* GREEN */
- /*0x18*/ volatile unsigned int blue;
- /* BLUE */
- /*0x1c*/ volatile unsigned int z;
- /* DEPTH */
- /*0x20*/ volatile unsigned int y;
- /* Y triangle(DOYF) */
- /* aadot(DYF) */
- /* ddline(DYF) */
- /* aaline(DYF) */
- /*0x24*/ volatile unsigned int x;
- /* X triangle(DOXF) */
- /* aadot(DXF) */
- /* ddline(DXF) */
- /* aaline(DXF) */
- /*0x28*/ unsigned int pad2[2];
- /* Reserved */
- /*0x30*/ volatile unsigned int ryf;
- /* Y (alias to DOYF) ddline(RYF) */
- /* aaline(RYF) */
- /* triangle(RYF) */
- /*0x34*/ volatile unsigned int rxf;
- /* X ddline(RXF) */
- /* aaline(RXF) */
- /* triangle(RXF) */
- /*0x38*/ unsigned int pad3[2];
- /* Reserved */
- /*0x40*/ volatile unsigned int dmyf;
- /* Y (alias to DOYF) triangle(DMYF) */
- /*0x44*/ volatile unsigned int dmxf;
- /* X triangle(DMXF) */
- /*0x48*/ unsigned int pad4[2];
- /* Reserved */
- /*0x50*/ volatile unsigned int ebyi;
- /* Y (alias to RYI) polygon(EBYI) */
- /*0x54*/ volatile unsigned int ebxi;
- /* X polygon(EBXI) */
- /*0x58*/ unsigned int pad5[2];
- /* Reserved */
- /*0x60*/ volatile unsigned int by;
- /* Y brline(RYI) */
- /* fastfill(OP) */
- /* polygon(YI) */
- /* rectangle(YI) */
- /* bcopy(SRCY) */
- /* vscroll(SRCY) */
- /*0x64*/ volatile unsigned int bx;
- /* X brline(RXI) */
- /* polygon(XI) */
- /* rectangle(XI) */
- /* bcopy(SRCX) */
- /* vscroll(SRCX) */
- /* fastfill(GO) */
- /*0x68*/ volatile unsigned int dy;
- /* destination Y fastfill(DSTY) */
- /* bcopy(DSRY) */
- /* vscroll(DSRY) */
- /*0x6c*/ volatile unsigned int dx;
- /* destination X fastfill(DSTX) */
- /* bcopy(DSTX) */
- /* vscroll(DSTX) */
- /*0x70*/ volatile unsigned int bh;
- /* Y (alias to RYI) brline(DYI) */
- /* dot(DYI) */
- /* polygon(ETYI) */
- /* Height fastfill(H) */
- /* bcopy(H) */
- /* vscroll(H) */
- /* Y count fastfill(NY) */
- /*0x74*/ volatile unsigned int bw;
- /* X dot(DXI) */
- /* brline(DXI) */
- /* polygon(ETXI) */
- /* fastfill(W) */
- /* bcopy(W) */
- /* vscroll(W) */
- /* fastfill(NX) */
- /*0x78*/ unsigned int pad6[2];
- /* Reserved */
- /*0x80*/ unsigned int pad7[32];
- /* Reserved */
-
- /* Setup Unit's vertex state register */
-/*100*/ volatile unsigned int suvtx;
- /*104*/ unsigned int pad8[63];
- /* Reserved */
-
- /* Frame Buffer Control Registers */
- /*200*/ volatile unsigned int ppc;
- /* Pixel Processor Control */
- /*204*/ volatile unsigned int wid;
- /* Current WID */
- /*208*/ volatile unsigned int fg;
- /* FG data */
- /*20c*/ volatile unsigned int bg;
- /* BG data */
- /*210*/ volatile unsigned int consty;
- /* Constant Y */
- /*214*/ volatile unsigned int constz;
- /* Constant Z */
- /*218*/ volatile unsigned int xclip;
- /* X Clip */
- /*21c*/ volatile unsigned int dcss;
- /* Depth Cue Scale Slope */
- /*220*/ volatile unsigned int vclipmin;
- /* Viewclip XY Min Bounds */
- /*224*/ volatile unsigned int vclipmax;
- /* Viewclip XY Max Bounds */
- /*228*/ volatile unsigned int vclipzmin;
- /* Viewclip Z Min Bounds */
- /*22c*/ volatile unsigned int vclipzmax;
- /* Viewclip Z Max Bounds */
- /*230*/ volatile unsigned int dcsf;
- /* Depth Cue Scale Front Bound */
- /*234*/ volatile unsigned int dcsb;
- /* Depth Cue Scale Back Bound */
- /*238*/ volatile unsigned int dczf;
- /* Depth Cue Z Front */
- /*23c*/ volatile unsigned int dczb;
- /* Depth Cue Z Back */
- /*240*/ unsigned int pad9;
- /* Reserved */
- /*244*/ volatile unsigned int blendc;
- /* Alpha Blend Control */
- /*248*/ volatile unsigned int blendc1;
- /* Alpha Blend Color 1 */
- /*24c*/ volatile unsigned int blendc2;
- /* Alpha Blend Color 2 */
- /*250*/ volatile unsigned int fbramitc;
- /* FB RAM Interleave Test Control */
- /*254*/ volatile unsigned int fbc;
- /* Frame Buffer Control */
- /*258*/ volatile unsigned int rop;
- /* Raster OPeration */
- /*25c*/ volatile unsigned int cmp;
- /* Frame Buffer Compare */
- /*260*/ volatile unsigned int matchab;
- /* Buffer AB Match Mask */
- /*264*/ volatile unsigned int matchc;
- /* Buffer C(YZ) Match Mask */
- /*268*/ volatile unsigned int magnab;
- /* Buffer AB Magnitude Mask */
- /*26c*/ volatile unsigned int magnc;
- /* Buffer C(YZ) Magnitude Mask */
- /*270*/ volatile unsigned int fbcfg0;
- /* Frame Buffer Config 0 */
- /*274*/ volatile unsigned int fbcfg1;
- /* Frame Buffer Config 1 */
- /*278*/ volatile unsigned int fbcfg2;
- /* Frame Buffer Config 2 */
- /*27c*/ volatile unsigned int fbcfg3;
- /* Frame Buffer Config 3 */
- /*280*/ volatile unsigned int ppcfg;
- /* Pixel Processor Config */
- /*284*/ volatile unsigned int pick;
- /* Picking Control */
- /*288*/ volatile unsigned int fillmode;
- /* FillMode */
- /*28c*/ volatile unsigned int fbramwac;
- /* FB RAM Write Address Control */
- /*290*/ volatile unsigned int pmask;
- /* RGB PlaneMask */
- /*294*/ volatile unsigned int xpmask;
- /* X PlaneMask */
- /*298*/ volatile unsigned int ypmask;
- /* Y PlaneMask */
- /*29c*/ volatile unsigned int zpmask;
- /* Z PlaneMask */
- /*2a0*/ ffb_auxclip auxclip[4];
- /* Auxilliary Viewport Clip */
-
- /* New 3dRAM III support regs */
-/*2c0*/ volatile unsigned int rawblend2;
-/*2c4*/ volatile unsigned int rawpreblend;
-/*2c8*/ volatile unsigned int rawstencil;
-/*2cc*/ volatile unsigned int rawstencilctl;
-/*2d0*/ volatile unsigned int threedram1;
-/*2d4*/ volatile unsigned int threedram2;
-/*2d8*/ volatile unsigned int passin;
-/*2dc*/ volatile unsigned int rawclrdepth;
-/*2e0*/ volatile unsigned int rawpmask;
-/*2e4*/ volatile unsigned int rawcsrc;
-/*2e8*/ volatile unsigned int rawmatch;
-/*2ec*/ volatile unsigned int rawmagn;
-/*2f0*/ volatile unsigned int rawropblend;
-/*2f4*/ volatile unsigned int rawcmp;
-/*2f8*/ volatile unsigned int rawwac;
-/*2fc*/ volatile unsigned int fbramid;
-
- /*300*/ volatile unsigned int drawop;
- /* Draw OPeration */
- /*304*/ unsigned int pad10[2];
- /* Reserved */
- /*30c*/ volatile unsigned int lpat;
- /* Line Pattern control */
- /*310*/ unsigned int pad11;
- /* Reserved */
- /*314*/ volatile unsigned int fontxy;
- /* XY Font coordinate */
- /*318*/ volatile unsigned int fontw;
- /* Font Width */
- /*31c*/ volatile unsigned int fontinc;
- /* Font Increment */
- /*320*/ volatile unsigned int font;
- /* Font bits */
- /*324*/ unsigned int pad12[3];
- /* Reserved */
-/*330*/ volatile unsigned int blend2;
-/*334*/ volatile unsigned int preblend;
-/*338*/ volatile unsigned int stencil;
-/*33c*/ volatile unsigned int stencilctl;
-
- /*340*/ unsigned int pad13[4];
- /* Reserved */
- /*350*/ volatile unsigned int dcss1;
- /* Depth Cue Scale Slope 1 */
- /*354*/ volatile unsigned int dcss2;
- /* Depth Cue Scale Slope 2 */
- /*358*/ volatile unsigned int dcss3;
- /* Depth Cue Scale Slope 3 */
-/*35c*/ volatile unsigned int widpmask;
-/*360*/ volatile unsigned int dcs2;
-/*364*/ volatile unsigned int dcs3;
-/*368*/ volatile unsigned int dcs4;
- /*36c*/ unsigned int pad14;
- /* Reserved */
-/*370*/ volatile unsigned int dcd2;
-/*374*/ volatile unsigned int dcd3;
-/*378*/ volatile unsigned int dcd4;
- /*37c*/ unsigned int pad15;
- /* Reserved */
- /*380*/ volatile unsigned int pattern[32];
- /* area Pattern */
- /*400*/ unsigned int pad16[8];
- /* Reserved */
- /*420*/ volatile unsigned int reset;
- /* chip RESET */
- /*424*/ unsigned int pad17[247];
- /* Reserved */
- /*800*/ volatile unsigned int devid;
- /* Device ID */
- /*804*/ unsigned int pad18[63];
- /* Reserved */
- /*900*/ volatile unsigned int ucsr;
- /* User Control & Status Register */
- /*904*/ unsigned int pad19[31];
- /* Reserved */
- /*980*/ volatile unsigned int mer;
- /* Mode Enable Register */
- /*984*/ unsigned int pad20[1439];
- /* Reserved */
-} ffb_fbc, *ffb_fbcPtr;
-
-struct ffb_hw_context {
- int is_2d_only;
-
- unsigned int ppc;
- unsigned int wid;
- unsigned int fg;
- unsigned int bg;
- unsigned int consty;
- unsigned int constz;
- unsigned int xclip;
- unsigned int dcss;
- unsigned int vclipmin;
- unsigned int vclipmax;
- unsigned int vclipzmin;
- unsigned int vclipzmax;
- unsigned int dcsf;
- unsigned int dcsb;
- unsigned int dczf;
- unsigned int dczb;
- unsigned int blendc;
- unsigned int blendc1;
- unsigned int blendc2;
- unsigned int fbc;
- unsigned int rop;
- unsigned int cmp;
- unsigned int matchab;
- unsigned int matchc;
- unsigned int magnab;
- unsigned int magnc;
- unsigned int pmask;
- unsigned int xpmask;
- unsigned int ypmask;
- unsigned int zpmask;
- unsigned int auxclip0min;
- unsigned int auxclip0max;
- unsigned int auxclip1min;
- unsigned int auxclip1max;
- unsigned int auxclip2min;
- unsigned int auxclip2max;
- unsigned int auxclip3min;
- unsigned int auxclip3max;
- unsigned int drawop;
- unsigned int lpat;
- unsigned int fontxy;
- unsigned int fontw;
- unsigned int fontinc;
- unsigned int area_pattern[32];
- unsigned int ucsr;
- unsigned int stencil;
- unsigned int stencilctl;
- unsigned int dcss1;
- unsigned int dcss2;
- unsigned int dcss3;
- unsigned int dcs2;
- unsigned int dcs3;
- unsigned int dcs4;
- unsigned int dcd2;
- unsigned int dcd3;
- unsigned int dcd4;
- unsigned int mer;
-};
-
-#define FFB_MAX_CTXS 32
-
-enum ffb_chip_type {
- ffb1_prototype = 0, /* Early pre-FCS FFB */
- ffb1_standard, /* First FCS FFB, 100Mhz UPA, 66MHz gclk */
- ffb1_speedsort, /* Second FCS FFB, 100Mhz UPA, 75MHz gclk */
- ffb2_prototype, /* Early pre-FCS vertical FFB2 */
- ffb2_vertical, /* First FCS FFB2/vertical, 100Mhz UPA, 100MHZ gclk,
- 75(SingleBuffer)/83(DoubleBuffer) MHz fclk */
- ffb2_vertical_plus, /* Second FCS FFB2/vertical, same timings */
- ffb2_horizontal, /* First FCS FFB2/horizontal, same timings as FFB2/vert */
- ffb2_horizontal_plus, /* Second FCS FFB2/horizontal, same timings */
- afb_m3, /* FCS Elite3D, 3 float chips */
- afb_m6 /* FCS Elite3D, 6 float chips */
-};
-
-typedef struct ffb_dev_priv {
- /* Misc software state. */
- int prom_node;
- enum ffb_chip_type ffb_type;
- u64 card_phys_base;
- struct miscdevice miscdev;
-
- /* Controller registers. */
- ffb_fbcPtr regs;
-
- /* Context table. */
- struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
-} ffb_dev_priv_t;
-
-extern unsigned long ffb_get_unmapped_area(struct file *filp,
- unsigned long hint,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags);
-extern void ffb_set_context_ioctls(void);
-extern drm_ioctl_desc_t DRM(ioctls)[];
-
-extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new);
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 337bbcdcf13..8ea02755b1c 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -710,12 +710,6 @@ void gs_close(struct tty_struct * tty, struct file * filp)
}
-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 @@ void gs_set_termios (struct tty_struct * tty,
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 d42060ede93..5ac309ee7f0 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -90,7 +90,7 @@ __setup("acpi_pm_good", acpi_pm_good_setup);
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 f52facc570f..3162010900c 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1015,6 +1015,10 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
{
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 9e913629ef3..74edb1d0110 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 8f1fd017679..ca2e4f830c3 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -103,8 +103,10 @@ config BLK_DEV_IDE_SATA
---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 c193553f6fe..0e0280076fc 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -519,21 +519,24 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
try_to_flush_leftover_data(drive);
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
- /* force an abort */
- hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
+ rq->errors |= ERROR_RESET;
- 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;
+ 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 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
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 bd513f5a232..1ee53a551c3 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -583,8 +583,12 @@ u8 eighty_ninty_three (ide_drive_t *drive)
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 @@ static void pre_reset(ide_drive_t *drive)
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 695610f0e3e..a6f098fda88 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1124,17 +1124,40 @@ static int set_io_32bit(ide_drive_t *drive, int arg)
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 6ceb25bc5a7..ace98929cc3 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -255,7 +255,7 @@ static int config_chipset_for_dma(ide_drive_t *drive)
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 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
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/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 818cf1aee8c..f5e9aeec6f6 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -498,9 +498,9 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
u64 sge_cmd, ctx0, ctx1;
u64 base_addr;
struct t3_modify_qp_wr *wqe;
- struct sk_buff *skb = alloc_skb(sizeof(*wqe), GFP_KERNEL);
-
+ struct sk_buff *skb;
+ skb = alloc_skb(sizeof(*wqe), GFP_KERNEL);
if (!skb) {
PDBG("%s alloc_skb failed\n", __FUNCTION__);
return -ENOMEM;
@@ -508,7 +508,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
err = cxio_hal_init_ctrl_cq(rdev_p);
if (err) {
PDBG("%s err %d initializing ctrl_cq\n", __FUNCTION__, err);
- return err;
+ goto err;
}
rdev_p->ctrl_qp.workq = dma_alloc_coherent(
&(rdev_p->rnic_info.pdev->dev),
@@ -518,7 +518,8 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
GFP_KERNEL);
if (!rdev_p->ctrl_qp.workq) {
PDBG("%s dma_alloc_coherent failed\n", __FUNCTION__);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err;
}
pci_unmap_addr_set(&rdev_p->ctrl_qp, mapping,
rdev_p->ctrl_qp.dma_addr);
@@ -556,6 +557,9 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
skb->priority = CPL_PRIORITY_CONTROL;
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+err:
+ kfree_skb(skb);
+ return err;
}
static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p)
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 8e4846b5c64..fdb576dcfaa 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -881,8 +881,8 @@ int mthca_init_mr_table(struct mthca_dev *dev)
}
mpts = mtts = 1 << i;
} else {
- mpts = dev->limits.num_mtt_segs;
- mtts = dev->limits.num_mpts;
+ mtts = dev->limits.num_mtt_segs;
+ mpts = dev->limits.num_mpts;
}
if (!mthca_is_memfree(dev) &&
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 0741c6d1337..f2a40ae8e7d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -814,7 +814,7 @@ static void ipoib_set_mcast_list(struct net_device *dev)
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 @@ static void ipoib_neigh_destructor(struct neighbour *n)
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 @@ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
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/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 89e37283c83..278fcbccc2d 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -658,6 +658,7 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
{
int deferred;
int is_rdma_aligned = 1;
+ struct iser_regd_buf *regd;
/* if we were reading, copy back to unaligned sglist,
* anyway dma_unmap and free the copy
@@ -672,20 +673,20 @@ void iser_ctask_rdma_finalize(struct iscsi_iser_cmd_task *iser_ctask)
}
if (iser_ctask->dir[ISER_DIR_IN]) {
- deferred = iser_regd_buff_release
- (&iser_ctask->rdma_regd[ISER_DIR_IN]);
+ regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
+ deferred = iser_regd_buff_release(regd);
if (deferred) {
- iser_err("References remain for BUF-IN rdma reg\n");
- BUG();
+ iser_err("%d references remain for BUF-IN rdma reg\n",
+ atomic_read(&regd->ref_count));
}
}
if (iser_ctask->dir[ISER_DIR_OUT]) {
- deferred = iser_regd_buff_release
- (&iser_ctask->rdma_regd[ISER_DIR_OUT]);
+ regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+ deferred = iser_regd_buff_release(regd);
if (deferred) {
- iser_err("References remain for BUF-OUT rdma reg\n");
- BUG();
+ iser_err("%d references remain for BUF-OUT rdma reg\n",
+ atomic_read(&regd->ref_count));
}
}
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 9df9e3548cf..c547a666505 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -440,7 +440,7 @@ isar_bh(struct work_struct *work)
{
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 bfa0ce42ea9..fbbf9d6b299 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -618,7 +618,7 @@ static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save)
{
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 @@ again:
[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 @@ again:
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 6c06e825cff..2a9b6a07e3a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1318,6 +1318,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
char b[BDEVNAME_SIZE];
struct kobject *ko;
char *s;
+ int err;
if (rdev->mddev) {
MD_BUG();
@@ -1352,20 +1353,29 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
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 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
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 @@ static int do_md_run(mddev_t * mddev)
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 @@ static int do_md_run(mddev_t * mddev)
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 @@ static int do_md_stop(mddev_t * mddev, int mode)
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 @@ static int remove_and_add_spares(mddev_t *mddev)
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 54a1ad5eef4..8d59914f205 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3642,12 +3642,15 @@ static int run(mddev_t *mddev)
}
/* 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 @@ static int stop(mddev_t *mddev)
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 @@ static int raid5_start_reshape(mddev_t *mddev)
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 @@ static struct mdk_personality raid4_personality =
.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 cbf7c056488..fcb19413562 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -310,13 +310,15 @@ void ir_rc5_timer_end(unsigned long data)
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 fc77de45ca4..a5c0e1a3e6d 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -180,8 +180,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
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_demux_open(struct inode *inode, struct file *file)
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 fcff5eab21a..6d8d1c3df86 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -673,8 +673,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed)
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 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
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 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed)
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 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed,
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 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
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 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux,
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 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux)
{
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 490337b5ee3..14a372a0fe8 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -203,8 +203,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
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 dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu
{
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 @@ EXPORT_SYMBOL(dvb_register_adapter);
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 ef319369ec2..c967148a594 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -122,6 +122,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
/* 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 920b63f8cf0..af66a5d5ecd 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 2fb9fe6a1ae..ba1af3c8525 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -780,18 +780,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
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 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
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 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
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 @@ static struct i2c_driver i2c_driver = {
.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 7735b675892..4d5bbd859de 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -961,7 +961,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
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 7be73e3763d..15dbc6bf42a 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -804,9 +804,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
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 @@ static int tuner_suspend(struct device *dev, pm_message_t state)
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 @@ static struct i2c_driver driver = {
.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 404c014db1b..1d2d03f7789 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -815,7 +815,7 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
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 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
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 da9859f2caf..b17c4b2bc9e 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -390,13 +390,6 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
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 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
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 314dbaabb64..69482e0d849 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -334,7 +334,6 @@ u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
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 46e1697d9cf..d04214e4e58 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2050,9 +2050,10 @@ static void nv_tx_timeout(struct net_device *dev)
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 @@ static void nv_do_nic_poll(unsigned long data)
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 c9f55bc57ed..8015a7c5b0c 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1379,7 +1379,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
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 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
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 b05b20ef8c0..c216e6a5d23 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 @@ again:
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 11b575f8985..ef58e412878 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2544,6 +2544,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
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 d3f65dab306..a8246eb2f8d 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1691,6 +1691,27 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
/*
* 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 @@ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev)
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 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
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 void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
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 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev,
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 @@ quit_polling:
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 @@ static int ql_send_map(struct ql3_adapter *qdev,
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 @@ static int ql_send_map(struct ql3_adapter *qdev,
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 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
}
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 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
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 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
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 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
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 34cd6580fd0..0203f88f054 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1014,8 +1014,7 @@ struct eeprom_data {
/* 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 c62e85d89f4..7bee45b42a2 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -336,13 +336,27 @@ static int __init lance_probe( struct net_device *dev)
/* 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 616be8d0fa8..08ea61db46f 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2530,6 +2530,35 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
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 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
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 8c8f9f4d47a..0acee9f324e 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 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
* 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 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* 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 @@ static int tg3_chip_reset(struct tg3 *tp)
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 @@ static int tg3_chip_reset(struct tg3 *tp)
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 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
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 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
} 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 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
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 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
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 086892d8c1f..d515ed23841 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2223,7 +2223,7 @@ struct tg3 {
#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 @@ struct tg3 {
#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 ddcc0040356..00000000000
--- 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 cae89258a64..d1e89be965c 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -757,7 +757,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
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 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
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 ee1e7a2afc0..4025dd0089d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -458,7 +458,7 @@ static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm)
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 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
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 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
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 @@ void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
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 @@ void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm)
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 00e937e9240..e7fbac52993 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -70,11 +70,12 @@ void wake_up_buffer_waiter(void)
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 6e67b42ca46..8543cb26cf3 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -65,6 +65,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t co
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 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz
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 0be5a0b3072..df383645e36 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -93,7 +93,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
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 7f94fc098cd..65d6f23ead4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -963,6 +963,13 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
* 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 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
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 551bde5d943..b693367d38c 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -372,7 +372,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
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 ab782bb46ac..e810e4a44ed 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
* 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 @@ static inline int dia250(void *iob, int cmd)
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 6b1caea622e..25d99bd2808 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb)
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 181b51772b1..bf37cdf43fa 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -505,6 +505,9 @@ static int ap_device_remove(struct device *dev)
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 @@ static void ap_scan_bus(struct work_struct *unused)
(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 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
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 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
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 void ap_poll_timeout(unsigned long unused)
*/
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 8c81cec8529..60446b88f72 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3091,6 +3091,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
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 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
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 9d014e5a81c..057fd7e0e37 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1817,10 +1817,9 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
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 2328128728b..6657331eed9 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -189,8 +189,8 @@ static DECLARE_MUTEX(board_lock);
* 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 @@ static struct class spi_master_class = {
* 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 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
* 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 0e5c646cb4f..f08ec85a6d6 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 8f9a2b61542..b394e63894d 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -296,6 +296,15 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req)
/*-------------------------------------------------------------------------*/
+/*
+ * 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 @@ omap_alloc_buffer(
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 @@ omap_alloc_buffer(
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 @@ static void omap_free_buffer(
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 @@ ep0out_status_stage:
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 irqreturn_t omap_udc_iso_irq(int irq, void *_dev)
/*-------------------------------------------------------------------------*/
-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 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
/* 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 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
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 @@ static int __init omap_udc_probe(struct platform_device *pdev)
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 8d24d3dc0a6..1497371583b 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -145,7 +145,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space)
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 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
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 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len)
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 @@ check_link:
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 @@ check_link:
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 @@ check_link:
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 const struct file_operations uhci_debug_operations = {
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 44da4334f1d..d22da26ff16 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -632,7 +632,8 @@ static int uhci_start(struct usb_hcd *hcd)
*/
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 f4ebdb3e488..19a0cc02b9a 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -45,43 +45,27 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
*/
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_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
*/
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 @@ static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
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_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
*/
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 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb)
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 7538c64a509..39a49836259 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 1633a0fd48e..8ff9d54b21e 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -879,6 +879,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
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 @@ static void ftdi_determine_type(struct usb_serial_port *port)
/* (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 53baeec8f26..4f8282ad772 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/drivers/video/cg3.c b/drivers/video/cg3.c
index ada6f7e3a89..767c850f8eb 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -186,8 +186,7 @@ static int cg3_setcolreg(unsigned regno,
* @blank_mode: the blank mode we want.
* @info: frame buffer structure that represents a single frame buffer
*/
-static int
-cg3_blank(int blank, struct fb_info *info)
+static int cg3_blank(int blank, struct fb_info *info)
{
struct cg3_par *par = (struct cg3_par *) info->par;
struct cg3_regs __iomem *regs = par->regs;
@@ -251,8 +250,8 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
* Initialisation
*/
-static void
-cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
+static void __devinit cg3_init_fix(struct fb_info *info, int linebytes,
+ struct device_node *dp)
{
strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
@@ -264,8 +263,8 @@ cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
info->fix.accel = FB_ACCEL_SUN_CGTHREE;
}
-static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
- struct device_node *dp)
+static void __devinit cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
+ struct device_node *dp)
{
char *params;
char *p;
@@ -287,36 +286,36 @@ static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
}
}
-static u8 cg3regvals_66hz[] __initdata = { /* 1152 x 900, 66 Hz */
+static u8 cg3regvals_66hz[] __devinitdata = { /* 1152 x 900, 66 Hz */
0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x20, 0
};
-static u8 cg3regvals_76hz[] __initdata = { /* 1152 x 900, 76 Hz */
+static u8 cg3regvals_76hz[] __devinitdata = { /* 1152 x 900, 76 Hz */
0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x24, 0
};
-static u8 cg3regvals_rdi[] __initdata = { /* 640 x 480, cgRDI */
+static u8 cg3regvals_rdi[] __devinitdata = { /* 640 x 480, cgRDI */
0x14, 0x70, 0x15, 0x20, 0x16, 0x08, 0x17, 0x10,
0x18, 0x06, 0x19, 0x02, 0x1a, 0x31, 0x1b, 0x51,
0x1c, 0x06, 0x1d, 0x0c, 0x1e, 0xff, 0x1f, 0x01,
0x10, 0x22, 0
};
-static u8 *cg3_regvals[] __initdata = {
+static u8 *cg3_regvals[] __devinitdata = {
cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
};
-static u_char cg3_dacvals[] __initdata = {
+static u_char cg3_dacvals[] __devinitdata = {
4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0
};
-static void cg3_do_default_mode(struct cg3_par *par)
+static void __devinit cg3_do_default_mode(struct cg3_par *par)
{
enum cg3_type type;
u8 *p;
@@ -433,7 +432,8 @@ static int __devinit cg3_init_one(struct of_device *op)
return 0;
}
-static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit cg3_probe(struct of_device *dev,
+ const struct of_device_id *match)
{
struct of_device *op = to_of_device(&dev->dev);
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 15854aec318..1d4e8354b56 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -336,14 +336,30 @@ struct ffb_dac {
u32 value2;
};
+#define FFB_DAC_UCTRL 0x1001 /* User Control */
+#define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */
+#define FFB_DAC_UCTRL_MANREV_SHIFT 8
+#define FFB_DAC_TGEN 0x6000 /* Timing Generator */
+#define FFB_DAC_TGEN_VIDE 0x00000001 /* Video Enable */
+#define FFB_DAC_DID 0x8000 /* Device Identification */
+#define FFB_DAC_DID_PNUM 0x0ffff000 /* Device Part Number */
+#define FFB_DAC_DID_PNUM_SHIFT 12
+#define FFB_DAC_DID_REV 0xf0000000 /* Device Revision */
+#define FFB_DAC_DID_REV_SHIFT 28
+
+#define FFB_DAC_CUR_CTRL 0x100
+#define FFB_DAC_CUR_CTRL_P0 0x00000001
+#define FFB_DAC_CUR_CTRL_P1 0x00000002
+
struct ffb_par {
spinlock_t lock;
struct ffb_fbc __iomem *fbc;
struct ffb_dac __iomem *dac;
u32 flags;
-#define FFB_FLAG_AFB 0x00000001
-#define FFB_FLAG_BLANKED 0x00000002
+#define FFB_FLAG_AFB 0x00000001 /* AFB m3 or m6 */
+#define FFB_FLAG_BLANKED 0x00000002 /* screen is blanked */
+#define FFB_FLAG_INVCURSOR 0x00000004 /* DAC has inverted cursor logic */
u32 fg_cache __attribute__((aligned (8)));
u32 bg_cache;
@@ -354,7 +370,6 @@ struct ffb_par {
unsigned long physbase;
unsigned long fbsize;
- int dac_rev;
int board_type;
};
@@ -426,11 +441,12 @@ static void ffb_switch_from_graph(struct ffb_par *par)
FFBWait(par);
/* Disable cursor. */
- upa_writel(0x100, &dac->type2);
- if (par->dac_rev <= 2)
+ upa_writel(FFB_DAC_CUR_CTRL, &dac->type2);
+ if (par->flags & FFB_FLAG_INVCURSOR)
upa_writel(0, &dac->value2);
else
- upa_writel(3, &dac->value2);
+ upa_writel((FFB_DAC_CUR_CTRL_P0 |
+ FFB_DAC_CUR_CTRL_P1), &dac->value2);
spin_unlock_irqrestore(&par->lock, flags);
}
@@ -664,18 +680,18 @@ ffb_blank(int blank, struct fb_info *info)
struct ffb_par *par = (struct ffb_par *) info->par;
struct ffb_dac __iomem *dac = par->dac;
unsigned long flags;
- u32 tmp;
+ u32 val;
+ int i;
spin_lock_irqsave(&par->lock, flags);
FFBWait(par);
+ upa_writel(FFB_DAC_TGEN, &dac->type);
+ val = upa_readl(&dac->value);
switch (blank) {
case FB_BLANK_UNBLANK: /* Unblanking */
- upa_writel(0x6000, &dac->type);
- tmp = (upa_readl(&dac->value) | 0x1);
- upa_writel(0x6000, &dac->type);
- upa_writel(tmp, &dac->value);
+ val |= FFB_DAC_TGEN_VIDE;
par->flags &= ~FFB_FLAG_BLANKED;
break;
@@ -683,13 +699,16 @@ ffb_blank(int blank, struct fb_info *info)
case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
case FB_BLANK_POWERDOWN: /* Poweroff */
- upa_writel(0x6000, &dac->type);
- tmp = (upa_readl(&dac->value) & ~0x1);
- upa_writel(0x6000, &dac->type);
- upa_writel(tmp, &dac->value);
+ val &= ~FFB_DAC_TGEN_VIDE;
par->flags |= FFB_FLAG_BLANKED;
break;
}
+ upa_writel(FFB_DAC_TGEN, &dac->type);
+ upa_writel(val, &dac->value);
+ for (i = 0; i < 10; i++) {
+ upa_writel(FFB_DAC_TGEN, &dac->type);
+ upa_readl(&dac->value);
+ }
spin_unlock_irqrestore(&par->lock, flags);
@@ -894,6 +913,7 @@ static int ffb_init_one(struct of_device *op)
struct ffb_dac __iomem *dac;
struct all_info *all;
int err;
+ u32 dac_pnum, dac_rev, dac_mrev;
all = kzalloc(sizeof(*all), GFP_KERNEL);
if (!all)
@@ -948,17 +968,31 @@ static int ffb_init_one(struct of_device *op)
if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
- ffb_switch_from_graph(&all->par);
-
dac = all->par.dac;
- upa_writel(0x8000, &dac->type);
- all->par.dac_rev = upa_readl(&dac->value) >> 0x1c;
+ upa_writel(FFB_DAC_DID, &dac->type);
+ dac_pnum = upa_readl(&dac->value);
+ dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
+ dac_pnum = (dac_pnum & FFB_DAC_DID_PNUM) >> FFB_DAC_DID_PNUM_SHIFT;
+
+ upa_writel(FFB_DAC_UCTRL, &dac->type);
+ dac_mrev = upa_readl(&dac->value);
+ dac_mrev = (dac_mrev & FFB_DAC_UCTRL_MANREV) >>
+ FFB_DAC_UCTRL_MANREV_SHIFT;
/* Elite3D has different DAC revision numbering, and no DAC revisions
- * have the reversed meaning of cursor enable.
+ * have the reversed meaning of cursor enable. Otherwise, Pacifica 1
+ * ramdacs with manufacturing revision less than 3 have inverted
+ * cursor logic. We identify Pacifica 1 as not Pacifica 2, the
+ * latter having a part number value of 0x236e.
*/
- if (all->par.flags & FFB_FLAG_AFB)
- all->par.dac_rev = 10;
+ if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
+ all->par.flags &= ~FFB_FLAG_INVCURSOR;
+ } else {
+ if (dac_mrev < 3)
+ all->par.flags |= FFB_FLAG_INVCURSOR;
+ }
+
+ ffb_switch_from_graph(&all->par);
/* Unblank it just to be sure. When there are multiple
* FFB/AFB cards in the system, or it is not the OBP
@@ -993,10 +1027,12 @@ static int ffb_init_one(struct of_device *op)
dev_set_drvdata(&op->dev, all);
- printk("%s: %s at %016lx, type %d, DAC revision %d\n",
+ printk("%s: %s at %016lx, type %d, "
+ "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
dp->full_name,
((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
- all->par.physbase, all->par.board_type, all->par.dac_rev);
+ all->par.physbase, all->par.board_type,
+ dac_pnum, dac_rev, dac_mrev);
return 0;
}
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 8ada4c5c5d7..6a82d39dc49 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 653dfa5b253..c7b67725384 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 @@ v9fs_file_write(struct file *filp, const char __user * data,
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 0b4ee0a5c83..e4598d6d49d 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -136,7 +136,6 @@ static int aio_setup_ring(struct kioctx *ctx)
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 c81c958b3e1..8b1c5d8bf4e 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2553,11 +2553,15 @@ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
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(SIOCSIWNICKN, do_wireless_ioctl)
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 6f677988c71..7e4bb0af24d 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -859,8 +859,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
#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 @@ encode_entry(struct readdir_cd *ccd, const char *name,
*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 832673b1458..673a53c014a 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -228,7 +228,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
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 9e406799920..af360705e55 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -750,9 +750,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
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 @@ __nfs4_state_shutdown(void)
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 a6b3a8f878f..bce38e3f06c 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o
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 2fca6ebf4cc..07f6556add0 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -576,76 +576,21 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
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 @@ out_ret:
* 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 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
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 12baf1d6343..2e623769381 100644
--- a/include/asm-i386/termbits.h
+++ b/include/asm-i386/termbits.h
@@ -144,7 +144,7 @@ struct ktermios {
#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 0a3cd7ec845..d5a8e7c1477 100644
--- a/include/asm-s390/checksum.h
+++ b/include/asm-s390/checksum.h
@@ -121,50 +121,21 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
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 f35134c159d..53ca5643d9c 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 b1e42e7f998..4a6a19f4f8a 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-sparc/mostek.h b/include/asm-sparc/mostek.h
index bd92a78f493..958d0513a6d 100644
--- a/include/asm-sparc/mostek.h
+++ b/include/asm-sparc/mostek.h
@@ -87,7 +87,7 @@ extern void __iomem *mstk48t02_regs;
#define MSTK_DOW_MASK 0x07
#define MSTK_DOM_MASK 0x3f
#define MSTK_MONTH_MASK 0x1f
-#define MSTK_YEAR_MASK 0xff
+#define MSTK_YEAR_MASK 0xffU
/* Binary coded decimal conversion macros. */
#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h
index 09b5aba6678..d14dd898816 100644
--- a/include/asm-sparc64/mostek.h
+++ b/include/asm-sparc64/mostek.h
@@ -89,7 +89,7 @@ extern void __iomem *mstk48t02_regs;
#define MSTK_DOW_MASK 0x07
#define MSTK_DOM_MASK 0x3f
#define MSTK_MONTH_MASK 0x1f
-#define MSTK_YEAR_MASK 0xff
+#define MSTK_YEAR_MASK 0xffU
/* Binary coded decimal conversion macros. */
#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
index f0454516dd3..b16222b4282 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 aca66984aaf..3b6949b4174 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 84cfa8bbdc3..d2a96cbf4f0 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 34f2676b3c6..58564a19986 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -615,6 +615,7 @@ typedef struct ide_drive_s {
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 636094c29b1..6da6772c19f 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -92,19 +92,16 @@ extern struct ipc_namespace init_ipc_ns;
#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 2e19478e9e8..8bcbc54e1b4 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -99,4 +99,8 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
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 a4555fe3754..e10267d402c 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -70,6 +70,8 @@ static inline int unshare_utsname(unsigned long unshare_flags,
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 447c52beb69..48759b2f57d 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 @@ struct iw_event
#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 83fe2e3d1e2..50e33b0e934 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -239,7 +239,8 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits);
#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 bc3c26494c3..d585ea9fa97 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -34,6 +34,7 @@ struct fib_rules_ops
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 9eda572a2a6..cf355a3c2ad 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -58,6 +58,7 @@ struct fib6_node
__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 10559e937d2..8a830188354 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 @@ iwe_stream_add_event(char * stream, /* Stream of events */
/* 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 @@ iwe_stream_add_point(char * stream, /* Stream of events */
/* 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 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */
/* 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 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
/* 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 3725b93c52f..ad7fe112141 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -36,7 +36,7 @@ struct neigh_parms
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 08a647965b9..0b652387d16 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -144,6 +144,13 @@ void free_ipc_ns(struct kref *kref)
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 6a7938a0d51..067ba2c0532 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -814,7 +814,12 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
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 dee0ff40bef..aec19b063e3 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -58,7 +58,6 @@ static inline int platform_prepare(void)
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 bf211fee122..7cf6713b232 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -401,10 +401,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
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 67932ea78c1..76212b2a99d 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -274,72 +274,3 @@ void clockevents_notify(unsigned long reason, void *arg)
}
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 eb12509e00b..cb25649c6f5 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -32,7 +32,7 @@ static u64 tick_length, tick_length_base;
/* 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 @@ void __attribute__ ((weak)) notify_arch_cmos_timer(void)
*/
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 @@ int do_adjtimex(struct timex *txc)
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 @@ int do_adjtimex(struct timex *txc)
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 @@ int do_adjtimex(struct timex *txc)
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 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
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 643efbe8240..ad401fc5744 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -204,7 +204,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig,
/*
* 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 ebb5d0ce8b6..8c382581608 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -261,14 +261,6 @@ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
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 @@ static struct neigh_table clip_tbl = {
/* 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 a8993a04172..43dd86fca4d 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
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 @@ config AX25_DAMA_SLAVE
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.
+
+# 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.
-# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
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 NETROM
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 cf71614dae9..5984b55311a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1750,10 +1750,10 @@ static int ing_filter(struct sk_buff *skb)
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 3aea4e87d3d..d011819a805 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -152,6 +152,28 @@ out:
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 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
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 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
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 3183142c604..cfc60019cf9 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -140,6 +140,8 @@ static int neigh_forced_gc(struct neigh_table *tbl)
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 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
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 @@ void neigh_destroy(struct neighbour *neigh)
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 @@ static void neigh_periodic_timer(unsigned long arg)
*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 @@ void __neigh_for_each_release(struct neigh_table *tbl,
} 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 6055074c4b8..33ea8eac7fe 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -621,7 +621,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
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 9936ab11e6e..b07fe270a50 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 @@ static const int event_type_size[] = {
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 @@ static int rtnetlink_standard_get(struct net_device * dev,
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 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* 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 @@ static int rtnetlink_standard_get(struct net_device * dev,
(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 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* 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 @@ static int rtnetlink_standard_get(struct net_device * dev,
/* 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 @@ static inline int rtnetlink_standard_set(struct net_device * dev,
#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 @@ static inline int rtnetlink_standard_set(struct net_device * dev,
/* 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 @@ static inline int rtnetlink_private_get(struct net_device * dev,
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 @@ static inline int rtnetlink_private_get(struct net_device * dev,
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 @@ static inline int rtnetlink_private_get(struct net_device * dev,
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 @@ static inline int rtnetlink_private_get(struct net_device * dev,
/* 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 @@ static inline int rtnetlink_private_get(struct net_device * dev,
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 @@ static inline int rtnetlink_private_set(struct net_device * dev,
/* 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 @@ static inline int rtnetlink_private_set(struct net_device * dev,
/* 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 @@ int wireless_rtnetlink_get(struct net_device * dev,
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 @@ int wireless_rtnetlink_set(struct net_device * dev,
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 a0e7cd183a5..e33a9edb403 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -191,7 +191,6 @@ extern void dccp_send_sync(struct sock *sk, const u64 seq,
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/proto.c b/net/dccp/proto.c
index cf28c53a389..6607b7b14f3 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -575,7 +575,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- if (len < sizeof(int))
+ if (len < (int)sizeof(int))
return -EINVAL;
dp = dccp_sk(sk);
@@ -589,9 +589,11 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
(__be32 __user *)optval, optlen);
case DCCP_SOCKOPT_SEND_CSCOV:
val = dp->dccps_pcslen;
+ len = sizeof(val);
break;
case DCCP_SOCKOPT_RECV_CSCOV:
val = dp->dccps_pcrlen;
+ len = sizeof(val);
break;
case 128 ... 191:
return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index b038a0a3ad4..0197a41c256 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -262,7 +262,7 @@ out:
}
/* 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 3cbfddc9843..82d58a977e6 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -63,7 +63,7 @@ static struct
{
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 *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta
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 b6c98ac93dc..5e86dd54230 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -109,8 +109,6 @@ errout:
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 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
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 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
}
}
- 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 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
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 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
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 1fba6439fc5..fc920f63452 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -493,6 +493,11 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
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 b837c33e040..c660c074c76 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -171,8 +171,6 @@ static struct fib_table *fib_empty_table(void)
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 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
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 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
}
}
- 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 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
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 size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
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 2f1fdae6efa..3dad12ee76c 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -89,7 +89,7 @@ static const struct
{
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 ada9b3db507..214c34732e8 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1123,6 +1123,9 @@ err:
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 @@ static int trie_leaf_remove(struct trie *t, t_key key)
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 @@ up:
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 1b616992d91..7552663aa12 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -342,6 +342,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
}
#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 0862809ffcf..ea3035b4e3e 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -131,8 +131,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
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 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
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 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
}
}
- 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 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
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 size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
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 f4d7be77eb0..268f476ef3d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -658,6 +658,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
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 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
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 a6b3117df54..3931b33b25e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -363,55 +363,76 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
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 @@ restart_2:
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 @@ restart_2:
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 ff2d6e5e282..020767a204d 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -17,7 +17,6 @@ obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
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 fad08e521c2..70fe36eb66a 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -81,6 +81,13 @@ static void basic_put(struct tcf_proto *tp, unsigned long f)
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 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
}
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 396deb71480..407c6fb1ba1 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1184,10 +1184,12 @@ hfsc_delete_class(struct Qdisc *sch, unsigned long arg)
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 97cbb9aec94..3c3294d0104 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1380,15 +1380,15 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
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 9566e57ac7f..ea8f81abc45 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1381,7 +1381,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
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 @@ out_put:
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);