We (the -stable team) are announcing the release of the 2.6.22.2 kernel.
This release has a lot of bugfixes and some security updates so all
users of the 2.6.22 series should update to it.
I'll also be replying to this message with a copy of the patch between
2.6.22.1 and 2.6.22.2
The updated 2.6.22.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-2.6.22.y.git
and can be browsed at the normal kernel.org git web browser:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.22.y.git;a=summary
thanks,
greg k-h
--------
Makefile | 2
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 13 --
arch/i386/kernel/hpet.c | 24 +++
arch/sparc/kernel/entry.S | 14 +-
arch/sparc/lib/memset.S | 2
arch/sparc64/kernel/head.S | 1
arch/um/drivers/ubd_kern.c | 2
arch/um/os-Linux/user_syms.c | 20 +--
block/cfq-iosched.c | 39 +++++-
drivers/acpi/dock.c | 7 +
drivers/ata/ata_piix.c | 2
drivers/ata/libata-core.c | 1
drivers/ata/libata-sff.c | 2
drivers/ata/pata_scc.c | 2
drivers/base/cpu.c | 2
drivers/char/drm/i915_dma.c | 14 +-
drivers/char/drm/i915_drv.h | 1
drivers/char/sx.c | 4
drivers/firewire/fw-ohci.c | 2
drivers/firewire/fw-sbp2.c | 5
drivers/firewire/fw-transaction.c | 4
drivers/firewire/fw-transaction.h | 6
drivers/ieee1394/sbp2.c | 5
drivers/input/mouse/lifebook.c | 2
drivers/kvm/svm.c | 6
drivers/kvm/svm.h | 3
drivers/md/dm-crypt.c | 5
drivers/md/dm-exception-store.c | 11 -
drivers/md/dm-io.c | 5
drivers/md/dm-mpath.c | 3
drivers/md/dm-raid1.c | 4
drivers/md/dm-snap.c | 11 -
drivers/md/dm.c | 9 +
drivers/md/raid10.c | 10 +
drivers/media/video/ivtv/ivtv-driver.c | 1
drivers/media/video/ivtv/ivtv-driver.h | 2
drivers/media/video/ivtv/ivtv-irq.c | 7 -
drivers/media/video/ivtv/ivtv-streams.c | 30 ++--
drivers/media/video/ivtv/ivtv-vbi.c | 31 +---
drivers/media/video/v4l2-common.c | 19 ++
drivers/media/video/wm8739.c | 2
drivers/media/video/wm8775.c | 2
drivers/misc/sony-laptop.c | 30 +++-
drivers/net/forcedeth.c | 162 +++++++++++++++++++++++--
drivers/pcmcia/cs.c | 3
drivers/scsi/aacraid/linit.c | 4
drivers/serial/sunhv.c | 30 ++++
drivers/serial/sunsab.c | 19 ++
drivers/serial/sunsu.c | 14 ++
drivers/serial/sunzilog.c | 17 ++
drivers/usb/class/cdc-acm.c | 12 +
drivers/usb/core/hub.c | 10 -
drivers/usb/serial/ftdi_sio.c | 104 ++++++----------
drivers/usb/serial/io_edgeport.c | 19 +-
drivers/video/backlight/cr_bllcd.c | 2
drivers/video/macmodes.c | 5
drivers/video/macmodes.h | 8 -
fs/9p/conv.c | 1
fs/ecryptfs/inode.c | 5
fs/ext4/extents.c | 2
fs/jbd/commit.c | 3
fs/jbd2/commit.c | 3
fs/nfsd/vfs.c | 2
fs/splice.c | 5
fs/sysfs/file.c | 1
fs/timerfd.c | 6
include/linux/Kbuild | 1
include/linux/ioprio.h | 6
include/linux/netfilter_ipv4/ipt_iprange.h | 2
include/net/bluetooth/rfcomm.h | 1
include/net/xfrm.h | 1
ipc/shm.c | 2
kernel/futex.c | 4
kernel/lockdep_proc.c | 2
kernel/time/timer_list.c | 2
kernel/time/timer_stats.c | 2
kernel/workqueue.c | 11 -
mm/hugetlb.c | 15 +-
mm/mlock.c | 5
mm/readahead.c | 12 +
net/bluetooth/rfcomm/tty.c | 34 ++++-
net/bridge/netfilter/ebt_log.c | 6
net/bridge/netfilter/ebt_ulog.c | 8 -
net/core/gen_estimator.c | 82 +++++++-----
net/core/netpoll.c | 2
net/ieee80211/softmac/ieee80211softmac_assoc.c | 5
net/ipv4/netfilter/ipt_LOG.c | 6
net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 22 ---
net/ipv4/tcp_input.c | 4
net/ipv6/addrconf.c | 1
net/ipv6/anycast.c | 1
net/ipv6/icmp.c | 2
net/ipv6/ip6_tunnel.c | 4
net/ipv6/netfilter/ip6t_LOG.c | 6
net/ipv6/tcp_ipv6.c | 1
net/rfkill/rfkill-input.c | 2
net/sched/sch_api.c | 6
net/sctp/ipv6.c | 4
net/sunrpc/auth_gss/svcauth_gss.c | 9 -
net/xfrm/xfrm_policy.c | 2
100 files changed, 729 insertions(+), 348 deletions(-)
Summary of changes from v2.6.21.2 to v2.6.21.3
============================================
Adam Kropelin (1):
usb-serial: Fix edgeport regression on non-EPiC devices
Adrian Bunk (2):
Missing header include in ipt_iprange.h
drivers/video/macmodes.c:mac_find_mode() mustn't be __devinit
Al Viro (1):
Fix ipv6 tunnel endianness bug.
Alan Cox (1):
aacraid: fix security hole
Alan Stern (2):
USB: cdc-acm: fix sysfs attribute registration bug
USB: fix warning caused by autosuspend counter going negative
Alexander Shmelev (1):
Fix sparc32 memset()
Alexey Dobriyan (2):
Fix leak on /proc/lockdep_stats
Fix leaks on /proc/{*/sched, sched_debug, timer_list, timer_stats}
Andreas Schwab (1):
futex: pass nr_wake2 to futex_wake_op
Arne Redlich (1):
md: handle writes to broken raid10 arrays gracefully
Ayaz Abdulla (3):
forcedeth bug fix: cicada phy
forcedeth bug fix: vitesse phy
forcedeth bug fix: realtek phy
Christian Lamparter (1):
Add a PCI ID for santa rosa's PATA controller.
Chuck Ebbert (1):
ACPI: dock: fix opps after dock driver fails to initialize
Daniel Ritz (1):
pcmcia: give socket time to power down
Dave Airlie (1):
drm/i915: Fix i965 secured batchbuffer usage (CVE-2007-3851)
David S. Miller (2):
Fix console write locking in sparc drivers.
Sparc64 bootup assembler bug
David Stevens (1):
IPV6: /proc/net/anycast6 unbalanced inet6_dev refcnt
Davide Libenzi (1):
make timerfd return a u64 and fix the __put_user
Dmitry Butskoy (1):
Fix error queue socket lookup in ipv6
Dmitry Torokhov (1):
Input: lifebook - fix an oops on Panasonic CF-18
Fengguang Wu (1):
readahead: MIN_RA_PAGES/MAX_RA_PAGES macros
Greg Kroah-Hartman (1):
Linux 2.6.22.2
Hans Verkuil (5):
V4L: Add check for valid control ID to v4l2_ctrl_next
V4L: ivtv: fix broken VBI output support
V4L: ivtv: fix DMA timeout when capturing VBI + another stream
V4L: ivtv: Add locking to ensure stream setup is atomic
V4L: wm8775/wm8739: Fix memory leak when unloading module
Herbert van den Bergh (1):
do not limit locked memory when RLIMIT_MEMLOCK is RLIM_INFINITY
Herton Ronaldo Krzesinski (1):
Include serial_reg.h with userspace headers
Ilpo Järvinen (1):
TCP FRTO retransmit bug fix
Ingo Molnar (1):
Fix rfkill IRQ flags.
J. Bruce Fields (2):
nfsd: fix possible read-ahead cache and export table corruption
nfsd: fix possible oops on re-insertion of rpcsec_gss modules
Jan Kara (2):
jbd commit: fix transaction dropping
jbd2 commit: fix transaction dropping
Jean Tourrilhes (1):
softmac: Fix ESSID problem
Jeff Dike (2):
uml: limit request size on COWed devices
UML: exports for hostfs
Jens Axboe (2):
splice: fix double page unlock
cfq-iosched: fix async queue behaviour
Jesper Juhl (1):
cr_backlight_probe() allocates too little storage for struct cr_panel
Jiri Slaby (1):
sx: switch subven and subid values
Joe Jin (1):
hugetlb: fix race in alloc_fresh_huge_page()
Joerg Roedel (1):
KVM: SVM: Reliably detect if SVM was disabled by BIOS
Jun'ichi Nomura (1):
dm io: fix another panic on large request
Maik Hampel (1):
md: raid10: fix use-after-free of bio
Mariusz Kozlowski (1):
fs: 9p/conv.c error path fix
Mark Fortescue (1):
Fix sparc32 udelay() rounding errors.
Mattia Dongili (1):
sony-laptop: fix bug in event handling
Michael Halcrow (1):
eCryptfs: ecryptfs_setattr() bugfix
Mikko Rapeli (1):
Hangup TTY before releasing rfcomm_dev
Milan Broz (3):
dm io: fix panic on large request
dm raid1: fix status
dm snapshot: permit invalid activation
Mingming Cao (1):
"ext4_ext_put_in_cache" uses __u32 to receive physical block number
Oleg Nesterov (1):
destroy_workqueue() can livelock
Oliver Neukum (1):
USB: fix for ftdi_sio quirk handling
Patrick McHardy (4):
Fix TC deadlock.
Fix IPCOMP crashes.
gen estimator timer unload race
Netfilter: Fix logging regression
Pavel Emelianov (1):
Fix user struct leakage with locked IPC shem segment
Petr Vandrovec (1):
Fix reported task file values in sense data
Ranko Zivojnovic (1):
gen estimator deadlock fix
Satyam Sharma (1):
Netpoll leak
Stefan Bader (1):
dm: disable barriers
Stefan Richter (4):
firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters)
fw-ohci: fix "scheduling while atomic"
firewire: fix memory leak of fw_request instances
ieee1394: revert "sbp2: enforce 32bit DMA mapping"
Tejun Heo (1):
libata: add FUJITSU MHV2080BH to NCQ blacklist
Thomas Gleixner (1):
i386: HPET, check if the counter works
Ulrich Drepper (1):
CPU online file permission
Venki Pallipadi (1):
acpi-cpufreq: Proper ReadModifyWrite of PERF_CTL MSR
Ville Tervo (1):
Keep rfcomm_dev on the list until it is freed
Vlad Yasevich (2):
SCTP scope_id handling fix
Fix ipv6 link down handling.
YOSHIFUJI Hideaki (2):
Fix TCP IPV6 MD5 bug.
sysfs: release mutex when kmalloc() failed in sysfs_open_file().
Yasuyuki Kozakai (1):
nf_conntrack: don't track locally generated special ICMP error
diff --git a/Makefile b/Makefile
index e28395a..1f50543 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 22
-EXTRAVERSION = .1
+EXTRAVERSION = .2
NAME = Holy Dancing Manatees, Batman!
# *DOCUMENTATION*
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 10baa35..18c8b67 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -167,11 +167,13 @@ static void do_drv_read(struct drv_cmd *cmd)
static void do_drv_write(struct drv_cmd *cmd)
{
- u32 h = 0;
+ u32 lo, hi;
switch (cmd->type) {
case SYSTEM_INTEL_MSR_CAPABLE:
- wrmsr(cmd->addr.msr.reg, cmd->val, h);
+ rdmsr(cmd->addr.msr.reg, lo, hi);
+ lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
+ wrmsr(cmd->addr.msr.reg, lo, hi);
break;
case SYSTEM_IO_CAPABLE:
acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
@@ -372,7 +374,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
cpumask_t online_policy_cpus;
struct drv_cmd cmd;
- unsigned int msr;
unsigned int next_state = 0; /* Index into freq_table */
unsigned int next_perf_state = 0; /* Index into perf table */
unsigned int i;
@@ -417,11 +418,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
case SYSTEM_INTEL_MSR_CAPABLE:
cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
- msr =
- (u32) perf->states[next_perf_state].
- control & INTEL_MSR_RANGE;
- cmd.val = get_cur_val(online_policy_cpus);
- cmd.val = (cmd.val & ~INTEL_MSR_RANGE) | msr;
+ cmd.val = (u32) perf->states[next_perf_state].control;
break;
case SYSTEM_IO_CAPABLE:
cmd.type = SYSTEM_IO_CAPABLE;
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
index 17d7345..cbb4751 100644
--- a/arch/i386/kernel/hpet.c
+++ b/arch/i386/kernel/hpet.c
@@ -226,7 +226,8 @@ int __init hpet_enable(void)
{
unsigned long id;
uint64_t hpet_freq;
- u64 tmp;
+ u64 tmp, start, now;
+ cycle_t t1;
if (!is_hpet_capable())
return 0;
@@ -273,6 +274,27 @@ int __init hpet_enable(void)
/* Start the counter */
hpet_start_counter();
+ /* Verify whether hpet counter works */
+ t1 = read_hpet();
+ rdtscll(start);
+
+ /*
+ * We don't know the TSC frequency yet, but waiting for
+ * 200000 TSC cycles is safe:
+ * 4 GHz == 50us
+ * 1 GHz == 200us
+ */
+ do {
+ rep_nop();
+ rdtscll(now);
+ } while ((now - start) < 200000UL);
+
+ if (t1 == read_hpet()) {
+ printk(KERN_WARNING
+ "HPET counter not counting. HPET disabled\n");
+ goto out_nohpet;
+ }
+
/* Initialize and register HPET clocksource
*
* hpet period is in femto seconds per cycle
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 831f540..eac3838 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1749,8 +1749,8 @@ fpload:
__ndelay:
save %sp, -STACKFRAME_SZ, %sp
mov %i0, %o0
- call .umul
- mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ)
+ call .umul ! round multiplier up so large ns ok
+ mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ)
call .umul
mov %i1, %o1 ! udelay_val
ba delay_continue
@@ -1760,11 +1760,17 @@ __ndelay:
__udelay:
save %sp, -STACKFRAME_SZ, %sp
mov %i0, %o0
- sethi %hi(0x10c6), %o1
+ sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok
call .umul
- or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000
+ or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000
call .umul
mov %i1, %o1 ! udelay_val
+ sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32,
+ or %g0, %lo(0x028f4b62), %l0
+ addcc %o0, %l0, %o0 ! 2**32 * 0.009 999
+ bcs,a 3f
+ add %o1, 0x01, %o1
+3:
call .umul
mov HZ, %o0 ! >>32 earlier for wider range
diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S
index a65eba4..1c37ea8 100644
--- a/arch/sparc/lib/memset.S
+++ b/arch/sparc/lib/memset.S
@@ -162,7 +162,7 @@ __bzero:
8:
add %o0, 1, %o0
subcc %o1, 1, %o1
- bne,a 8b
+ bne 8b
EX(stb %g3, [%o0 - 1], add %o1, 1)
0:
retl
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 7725952..35feacb 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -458,7 +458,6 @@ tlb_fixup_done:
or %g6, %lo(init_thread_union), %g6
ldx [%g6 + TI_TASK], %g4
mov %sp, %l6
- mov %o4, %l7
wr %g0, ASI_P, %asi
mov 1, %g1
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 2e09f16..c6acc1a 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -712,6 +712,8 @@ static int ubd_add(int n, char **error_out)
ubd_dev->queue->queuedata = ubd_dev;
blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
+ if(ubd_dev->cow.file != NULL)
+ blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 3f33165..419b2d5 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -5,7 +5,8 @@
* so I *must* declare good prototypes for them and then EXPORT them.
* The kernel code uses the macro defined by include/linux/string.h,
* so I undef macros; the userspace code does not include that and I
- * add an EXPORT for the glibc one.*/
+ * add an EXPORT for the glibc one.
+ */
#undef strlen
#undef strstr
@@ -61,12 +62,18 @@ EXPORT_SYMBOL_PROTO(dup2);
EXPORT_SYMBOL_PROTO(__xstat);
EXPORT_SYMBOL_PROTO(__lxstat);
EXPORT_SYMBOL_PROTO(__lxstat64);
+EXPORT_SYMBOL_PROTO(__fxstat64);
EXPORT_SYMBOL_PROTO(lseek);
EXPORT_SYMBOL_PROTO(lseek64);
EXPORT_SYMBOL_PROTO(chown);
+EXPORT_SYMBOL_PROTO(fchown);
EXPORT_SYMBOL_PROTO(truncate);
+EXPORT_SYMBOL_PROTO(ftruncate64);
EXPORT_SYMBOL_PROTO(utime);
+EXPORT_SYMBOL_PROTO(utimes);
+EXPORT_SYMBOL_PROTO(futimes);
EXPORT_SYMBOL_PROTO(chmod);
+EXPORT_SYMBOL_PROTO(fchmod);
EXPORT_SYMBOL_PROTO(rename);
EXPORT_SYMBOL_PROTO(__xmknod);
@@ -102,14 +109,3 @@ EXPORT_SYMBOL(__stack_smash_handler);
extern long __guard __attribute__((weak));
EXPORT_SYMBOL(__guard);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index baef5fc..a131d41 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -92,6 +92,8 @@ struct cfq_data {
struct cfq_queue *active_queue;
struct cfq_io_context *active_cic;
+ struct cfq_queue *async_cfqq[IOPRIO_BE_NR];
+
struct timer_list idle_class_timer;
sector_t last_position;
@@ -1351,8 +1353,8 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
}
static struct cfq_queue *
-cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
- gfp_t gfp_mask)
+cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync,
+ struct task_struct *tsk, gfp_t gfp_mask)
{
struct cfq_queue *cfqq, *new_cfqq = NULL;
struct cfq_io_context *cic;
@@ -1405,12 +1407,35 @@ retry:
if (new_cfqq)
kmem_cache_free(cfq_pool, new_cfqq);
- atomic_inc(&cfqq->ref);
out:
WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
return cfqq;
}
+static struct cfq_queue *
+cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
+ gfp_t gfp_mask)
+{
+ const int ioprio = task_ioprio(tsk);
+ struct cfq_queue *cfqq = NULL;
+
+ if (!is_sync)
+ cfqq = cfqd->async_cfqq[ioprio];
+ if (!cfqq)
+ cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+
+ /*
+ * pin the queue now that it's allocated, scheduler exit will prune it
+ */
+ if (!is_sync && !cfqd->async_cfqq[ioprio]) {
+ atomic_inc(&cfqq->ref);
+ cfqd->async_cfqq[ioprio] = cfqq;
+ }
+
+ atomic_inc(&cfqq->ref);
+ return cfqq;
+}
+
/*
* We drop cfq io contexts lazily, so we may find a dead one.
*/
@@ -2019,6 +2044,7 @@ static void cfq_exit_queue(elevator_t *e)
{
struct cfq_data *cfqd = e->elevator_data;
request_queue_t *q = cfqd->queue;
+ int i;
cfq_shutdown_timer_wq(cfqd);
@@ -2035,6 +2061,13 @@ static void cfq_exit_queue(elevator_t *e)
__cfq_exit_single_io_context(cfqd, cic);
}
+ /*
+ * Put the async queues
+ */
+ for (i = 0; i < IOPRIO_BE_NR; i++)
+ if (cfqd->async_cfqq[i])
+ cfq_put_queue(cfqd->async_cfqq[i]);
+
spin_unlock_irq(q->queue_lock);
cfq_shutdown_timer_wq(cfqd);
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 4546bf8..9bc340b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -716,6 +716,7 @@ static int dock_add(acpi_handle handle)
if (ret) {
printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
kfree(dock_station);
+ dock_station = NULL;
return ret;
}
ret = device_create_file(&dock_device.dev, &dev_attr_docked);
@@ -723,6 +724,7 @@ static int dock_add(acpi_handle handle)
printk("Error %d adding sysfs file\n", ret);
platform_device_unregister(&dock_device);
kfree(dock_station);
+ dock_station = NULL;
return ret;
}
ret = device_create_file(&dock_device.dev, &dev_attr_undock);
@@ -731,6 +733,7 @@ static int dock_add(acpi_handle handle)
device_remove_file(&dock_device.dev, &dev_attr_docked);
platform_device_unregister(&dock_device);
kfree(dock_station);
+ dock_station = NULL;
return ret;
}
ret = device_create_file(&dock_device.dev, &dev_attr_uid);
@@ -738,6 +741,7 @@ static int dock_add(acpi_handle handle)
printk("Error %d adding sysfs file\n", ret);
platform_device_unregister(&dock_device);
kfree(dock_station);
+ dock_station = NULL;
return ret;
}
@@ -750,6 +754,7 @@ static int dock_add(acpi_handle handle)
dd = alloc_dock_dependent_device(handle);
if (!dd) {
kfree(dock_station);
+ dock_station = NULL;
ret = -ENOMEM;
goto dock_add_err_unregister;
}
@@ -777,6 +782,7 @@ dock_add_err_unregister:
device_remove_file(&dock_device.dev, &dev_attr_undock);
platform_device_unregister(&dock_device);
kfree(dock_station);
+ dock_station = NULL;
return ret;
}
@@ -810,6 +816,7 @@ static int dock_remove(void)
/* free dock station memory */
kfree(dock_station);
+ dock_station = NULL;
return 0;
}
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9c07b88..4847755 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH7/7-R (i945, i975) UDMA 100*/
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+ /* ICH8 Mobile PATA Controller */
+ { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* NOTE: The following PCI ids must be kept in sync with the
* list in drivers/pci/quirks.c.
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 981b397..9ad8caf 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3800,6 +3800,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, },
{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
{ "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
+ { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
/* Devices with NCQ limits */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index fa1c22c..13c1486 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -211,6 +211,8 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
tf->hob_lbal = ioread8(ioaddr->lbal_addr);
tf->hob_lbam = ioread8(ioaddr->lbam_addr);
tf->hob_lbah = ioread8(ioaddr->lbah_addr);
+ iowrite8(tf->ctl, ioaddr->ctl_addr);
+ ap->last_ctl = tf->ctl;
}
}
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 61502bc..63f6e2c 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -352,6 +352,8 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
tf->hob_lbal = in_be32(ioaddr->lbal_addr);
tf->hob_lbam = in_be32(ioaddr->lbam_addr);
tf->hob_lbah = in_be32(ioaddr->lbah_addr);
+ out_be32(ioaddr->ctl_addr, tf->ctl);
+ ap->last_ctl = tf->ctl;
}
}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index fe7ef33..4054507 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -53,7 +53,7 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
ret = count;
return ret;
}
-static SYSDEV_ATTR(online, 0600, show_online, store_online);
+static SYSDEV_ATTR(online, 0644, show_online, store_online);
static void __devinit register_cpu_control(struct cpu *cpu)
{
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index ea52740..786c0d9 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -184,6 +184,8 @@ static int i915_initialize(drm_device_t * dev,
* private backbuffer/depthbuffer usage.
*/
dev_priv->use_mi_batchbuffer_start = 0;
+ if (IS_I965G(dev)) /* 965 doesn't support older method */
+ dev_priv->use_mi_batchbuffer_start = 1;
/* Allow hardware batchbuffers unless told otherwise.
*/
@@ -517,8 +519,13 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev,
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2);
- OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
- OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
+ OUT_RING(batch->start);
+ } else {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
+ OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ }
ADVANCE_LP_RING();
} else {
BEGIN_LP_RING(4);
@@ -735,7 +742,8 @@ static int i915_setparam(DRM_IOCTL_ARGS)
switch (param.param) {
case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
- dev_priv->use_mi_batchbuffer_start = param.value;
+ if (!IS_I965G(dev))
+ dev_priv->use_mi_batchbuffer_start = param.value;
break;
case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
dev_priv->tex_lru_log_granularity = param.value;
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 85e323a..44a0717 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -282,6 +282,7 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller);
#define MI_BATCH_BUFFER_START (0x31<<23)
#define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1)
+#define MI_BATCH_NON_SECURE_I965 (1<<8)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 1da92a6..85a2328 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2721,9 +2721,9 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev)
its because the standard requires it. So check for SUBVENDOR_ID. */
static struct pci_device_id sx_pci_tbl[] = {
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
- .subvendor = 0x0200,.subdevice = PCI_ANY_ID },
+ .subvendor = PCI_ANY_ID, .subdevice = 0x0200 },
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
- .subvendor = 0x0300,.subdevice = PCI_ANY_ID },
+ .subvendor = PCI_ANY_ID, .subdevice = 0x0300 },
{ 0 }
};
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 96c8ac5..05a5ff1 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -586,7 +586,7 @@ static void context_stop(struct context *ctx)
break;
fw_notify("context_stop: still active (0x%08x)\n", reg);
- msleep(1);
+ mdelay(1);
}
}
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index a98d391..a68f7de 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -985,6 +985,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct fw_unit *unit = sd->unit;
struct fw_device *device = fw_device(unit->device.parent);
struct sbp2_command_orb *orb;
+ unsigned max_payload;
/*
* Bidirectional commands are not yet implemented, and unknown
@@ -1023,8 +1024,10 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
* specifies the max payload size as 2 ^ (max_payload + 2), so
* if we set this to max_speed + 7, we get the right value.
*/
+ max_payload = device->node->max_speed + 7;
+ max_payload = min(max_payload, device->card->max_receive - 1);
orb->request.misc =
- COMMAND_ORB_MAX_PAYLOAD(device->node->max_speed + 7) |
+ COMMAND_ORB_MAX_PAYLOAD(max_payload) |
COMMAND_ORB_SPEED(device->node->max_speed) |
COMMAND_ORB_NOTIFY;
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 80d0121..a506a1f 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -605,8 +605,10 @@ fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
* check is sufficient to ensure we don't send response to
* broadcast packets or posted writes.
*/
- if (request->ack != ACK_PENDING)
+ if (request->ack != ACK_PENDING) {
+ kfree(request);
return;
+ }
if (rcode == RCODE_COMPLETE)
fw_fill_response(&request->response, request->request_header,
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index acdc3be..e2b9ca4 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -124,6 +124,10 @@ typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
size_t length,
void *callback_data);
+/*
+ * Important note: The callback must guarantee that either fw_send_response()
+ * or kfree() is called on the @request.
+ */
typedef void (*fw_address_callback_t)(struct fw_card *card,
struct fw_request *request,
int tcode, int destination, int source,
@@ -228,7 +232,7 @@ struct fw_card {
unsigned long reset_jiffies;
unsigned long long guid;
- int max_receive;
+ unsigned max_receive;
int link_speed;
int config_rom_generation;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 3f873cc..c7ff28a 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -774,11 +774,6 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
SBP2_ERR("failed to register lower 4GB address range");
goto failed_alloc;
}
-#else
- if (dma_set_mask(hi->host->device.parent, DMA_32BIT_MASK)) {
- SBP2_ERR("failed to set 4GB DMA mask");
- goto failed_alloc;
- }
#endif
}
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 1740cad..91109b4 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -109,7 +109,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
{
struct lifebook_data *priv = psmouse->private;
struct input_dev *dev1 = psmouse->dev;
- struct input_dev *dev2 = priv->dev2;
+ struct input_dev *dev2 = priv ? priv->dev2 : NULL;
unsigned char *packet = psmouse->packet;
int relative_packet = packet[0] & 0x08;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index fa17d6d..aee952f 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1727,6 +1727,12 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
static int is_disabled(void)
{
+ u64 vm_cr;
+
+ rdmsrl(MSR_VM_CR, vm_cr);
+ if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE))
+ return 1;
+
return 0;
}
diff --git a/drivers/kvm/svm.h b/drivers/kvm/svm.h
index 5e93814..3b1b0f3 100644
--- a/drivers/kvm/svm.h
+++ b/drivers/kvm/svm.h
@@ -175,8 +175,11 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_CPUID_FUNC 0x8000000a
#define MSR_EFER_SVME_MASK (1ULL << 12)
+#define MSR_VM_CR 0xc0010114
#define MSR_VM_HSAVE_PA 0xc0010117ULL
+#define SVM_VM_CR_SVM_DISABLE 4
+
#define SVM_SELECTOR_S_SHIFT 4
#define SVM_SELECTOR_DPL_SHIFT 5
#define SVM_SELECTOR_P_SHIFT 7
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 7b0fcfc..45e1c31 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -920,6 +920,8 @@ static void crypt_dtr(struct dm_target *ti)
{
struct crypt_config *cc = (struct crypt_config *) ti->private;
+ flush_workqueue(_kcryptd_workqueue);
+
bioset_free(cc->bs);
mempool_destroy(cc->page_pool);
mempool_destroy(cc->io_pool);
@@ -941,9 +943,6 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
struct crypt_config *cc = ti->private;
struct crypt_io *io;
- if (bio_barrier(bio))
- return -EOPNOTSUPP;
-
io = mempool_alloc(cc->io_pool, GFP_NOIO);
io->target = ti;
io->base_bio = bio;
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 07e0a0c..4264f69 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -457,11 +457,6 @@ static int persistent_read_metadata(struct exception_store *store)
/*
* Sanity checks.
*/
- if (!ps->valid) {
- DMWARN("snapshot is marked invalid");
- return -EINVAL;
- }
-
if (ps->version != SNAPSHOT_DISK_VERSION) {
DMWARN("unable to handle snapshot disk version %d",
ps->version);
@@ -469,6 +464,12 @@ static int persistent_read_metadata(struct exception_store *store)
}
/*
+ * Metadata are valid, but snapshot is invalidated
+ */
+ if (!ps->valid)
+ return 1;
+
+ /*
* Read the metadata.
*/
r = read_exceptions(ps);
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 352c6fb..f3a7724 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -293,7 +293,10 @@ static void do_region(int rw, unsigned int region, struct io_region *where,
* bvec for bio_get/set_region() and decrement bi_max_vecs
* to hide it from bio_add_page().
*/
- num_bvecs = (remaining / (PAGE_SIZE >> SECTOR_SHIFT)) + 2;
+ num_bvecs = dm_sector_div_up(remaining,
+ (PAGE_SIZE >> SECTOR_SHIFT));
+ num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev),
+ num_bvecs);
bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
bio->bi_sector = where->sector + (where->count - remaining);
bio->bi_bdev = where->bdev;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index de54b39..bfb2ea3 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -798,9 +798,6 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
struct mpath_io *mpio;
struct multipath *m = (struct multipath *) ti->private;
- if (bio_barrier(bio))
- return -EOPNOTSUPP;
-
mpio = mempool_alloc(m->mpio_pool, GFP_NOIO);
dm_bio_record(&mpio->details, bio);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index ef124b7..7113af3 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1288,12 +1288,12 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
for (m = 0; m < ms->nr_mirrors; m++)
DMEMIT("%s ", ms->mirror[m].dev->name);
- DMEMIT("%llu/%llu",
+ DMEMIT("%llu/%llu 0 ",
(unsigned long long)ms->rh.log->type->
get_sync_count(ms->rh.log),
(unsigned long long)ms->nr_regions);
- sz = ms->rh.log->type->status(ms->rh.log, type, result, maxlen);
+ sz += ms->rh.log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
break;
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 0821a2b..3955621 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -522,9 +522,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
/* Metadata must only be loaded into one table at once */
r = s->store.read_metadata(&s->store);
- if (r) {
+ if (r < 0) {
ti->error = "Failed to read snapshot metadata";
goto bad6;
+ } else if (r > 0) {
+ s->valid = 0;
+ DMWARN("Snapshot is marked invalid.");
}
bio_list_init(&s->queued_bios);
@@ -884,9 +887,6 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
if (!s->valid)
return -EIO;
- if (unlikely(bio_barrier(bio)))
- return -EOPNOTSUPP;
-
/* FIXME: should only take write lock if we need
* to copy an exception */
down_write(&s->lock);
@@ -1157,9 +1157,6 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
struct dm_dev *dev = (struct dm_dev *) ti->private;
bio->bi_bdev = dev->bdev;
- if (unlikely(bio_barrier(bio)))
- return -EOPNOTSUPP;
-
/* Only tell snapshots if this is a write */
return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED;
}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 2717a35..75bd2fd 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -802,6 +802,15 @@ static int dm_request(request_queue_t *q, struct bio *bio)
int rw = bio_data_dir(bio);
struct mapped_device *md = q->queuedata;
+ /*
+ * There is no use in forwarding any barrier request since we can't
+ * guarantee it is (or can be) handled by the targets correctly.
+ */
+ if (unlikely(bio_barrier(bio))) {
+ bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+ return 0;
+ }
+
down_read(&md->io_lock);
disk_stat_inc(dm_disk(md), ios[rw]);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 9eb66c1..e0029ea 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -917,6 +917,13 @@ static int make_request(request_queue_t *q, struct bio * bio)
bio_list_add(&bl, mbio);
}
+ if (unlikely(!atomic_read(&r10_bio->remaining))) {
+ /* the array is dead */
+ md_write_end(mddev);
+ raid_end_bio_io(r10_bio);
+ return 0;
+ }
+
bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0);
spin_lock_irqsave(&conf->device_lock, flags);
bio_list_merge(&conf->pending_bio_list, &bl);
@@ -1558,7 +1565,6 @@ static void raid10d(mddev_t *mddev)
bio = r10_bio->devs[r10_bio->read_slot].bio;
r10_bio->devs[r10_bio->read_slot].bio =
mddev->ro ? IO_BLOCKED : NULL;
- bio_put(bio);
mirror = read_balance(conf, r10_bio);
if (mirror == -1) {
printk(KERN_ALERT "raid10: %s: unrecoverable I/O"
@@ -1566,8 +1572,10 @@ static void raid10d(mddev_t *mddev)
bdevname(bio->bi_bdev,b),
(unsigned long long)r10_bio->sector);
raid_end_bio_io(r10_bio);
+ bio_put(bio);
} else {
const int do_sync = bio_sync(r10_bio->master_bio);
+ bio_put(bio);
rdev = conf->mirrors[mirror].rdev;
if (printk_ratelimit())
printk(KERN_ERR "raid10: %s: redirecting sector %llu to"
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index efc6635..5d9de5d 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -622,6 +622,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
+ mutex_init(&itv->serialize_lock);
mutex_init(&itv->i2c_bus_lock);
mutex_init(&itv->udma.lock);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index e6e56f1..65ebdda 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -650,7 +650,6 @@ struct vbi_info {
/* convenience pointer to sliced struct in vbi_in union */
struct v4l2_sliced_vbi_format *sliced_in;
u32 service_set_in;
- u32 service_set_out;
int insert_mpeg;
/* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
@@ -723,6 +722,7 @@ struct ivtv {
int search_pack_header;
spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
+ struct mutex serialize_lock; /* lock used to serialize starting streams */
/* User based DMA for OSD */
struct ivtv_user_dma udma;
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index ba98bf0..e83b496 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -403,6 +403,11 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
/* Mark last buffer size for Interrupt flag */
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
+ if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
+ set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+ else
+ clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+
if (ivtv_use_pio(s)) {
for (i = 0; i < s->SG_length; i++) {
s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
@@ -597,7 +602,6 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
data[0], data[1], data[2]);
return;
}
- clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
s = &itv->streams[ivtv_stream_map[data[0]]];
if (!stream_enc_dma_append(s, data)) {
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
@@ -634,7 +638,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
then start a DMA request for just the VBI data. */
if (!stream_enc_dma_append(s, data) &&
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
- set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 6af88ae..d538efa 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -446,6 +446,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
if (s->v4l2dev == NULL)
return -EINVAL;
+ /* Big serialization lock to ensure no two streams are started
+ simultaneously: that can give all sorts of weird results. */
+ mutex_lock(&itv->serialize_lock);
IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
switch (s->type) {
@@ -487,6 +490,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
0, sizeof(itv->vbi.sliced_mpeg_size));
break;
default:
+ mutex_unlock(&itv->serialize_lock);
return -EINVAL;
}
s->subtype = subtype;
@@ -568,6 +572,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
{
IVTV_DEBUG_WARN( "Error starting capture!\n");
+ mutex_unlock(&itv->serialize_lock);
return -EINVAL;
}
@@ -583,6 +588,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
/* you're live! sit back and await interrupts :) */
atomic_inc(&itv->capturing);
+ mutex_unlock(&itv->serialize_lock);
return 0;
}
@@ -762,17 +768,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
/* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
- /* only run these if we're shutting down the last cap */
- if (atomic_read(&itv->capturing) - 1 == 0) {
- /* event notification (off) */
- if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
- /* type: 0 = refresh */
- /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
- }
- }
-
then = jiffies;
if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
@@ -840,17 +835,30 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
/* Clear capture and no-read bits */
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+ /* ensure these global cleanup actions are done only once */
+ mutex_lock(&itv->serialize_lock);
+
if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
if (atomic_read(&itv->capturing) > 0) {
+ mutex_unlock(&itv->serialize_lock);
return 0;
}
/* Set the following Interrupt mask bits for capture */
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
+ /* event notification (off) */
+ if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
+ /* type: 0 = refresh */
+ /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
+ ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
+ ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
+ }
+
wake_up(&s->waitq);
+ mutex_unlock(&itv->serialize_lock);
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 3ba46e0..a7282a9 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -219,31 +219,23 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
int found_cc = 0;
int cc_pos = itv->vbi.cc_pos;
- if (itv->vbi.service_set_out == 0)
- return -EPERM;
-
while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
switch (p->id) {
case V4L2_SLICED_CAPTION_525:
- if (p->id == V4L2_SLICED_CAPTION_525 &&
- p->line == 21 &&
- (itv->vbi.service_set_out &
- V4L2_SLICED_CAPTION_525) == 0) {
- break;
- }
- found_cc = 1;
- if (p->field) {
- cc[2] = p->data[0];
- cc[3] = p->data[1];
- } else {
- cc[0] = p->data[0];
- cc[1] = p->data[1];
+ if (p->line == 21) {
+ found_cc = 1;
+ if (p->field) {
+ cc[2] = p->data[0];
+ cc[3] = p->data[1];
+ } else {
+ cc[0] = p->data[0];
+ cc[1] = p->data[1];
+ }
}
break;
case V4L2_SLICED_VPS:
- if (p->line == 16 && p->field == 0 &&
- (itv->vbi.service_set_out & V4L2_SLICED_VPS)) {
+ if (p->line == 16 && p->field == 0) {
itv->vbi.vps[0] = p->data[2];
itv->vbi.vps[1] = p->data[8];
itv->vbi.vps[2] = p->data[9];
@@ -255,8 +247,7 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
break;
case V4L2_SLICED_WSS_625:
- if (p->line == 23 && p->field == 0 &&
- (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) {
+ if (p->line == 23 && p->field == 0) {
/* No lock needed for WSS */
itv->vbi.wss = p->data[0] | (p->data[1] << 8);
itv->vbi.wss_found = 1;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 13ee550..d2915d3 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -939,16 +939,25 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
When no more controls are available 0 is returned. */
u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
{
- u32 ctrl_class;
+ u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
const u32 *pctrl;
- /* if no query is desired, then just return the control ID */
- if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0)
- return id;
if (ctrl_classes == NULL)
return 0;
+
+ /* if no query is desired, then check if the ID is part of ctrl_classes */
+ if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
+ /* find class */
+ while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
+ ctrl_classes++;
+ if (*ctrl_classes == NULL)
+ return 0;
+ pctrl = *ctrl_classes;
+ /* find control ID */
+ while (*pctrl && *pctrl != id) pctrl++;
+ return *pctrl ? id : 0;
+ }
id &= V4L2_CTRL_ID_MASK;
- ctrl_class = V4L2_CTRL_ID2CLASS(id);
id++; /* select next control */
/* find first class that matches (or is greater than) the class of
the ID */
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index 8f6741a..1bf4cbe 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -321,12 +321,14 @@ static int wm8739_probe(struct i2c_adapter *adapter)
static int wm8739_detach(struct i2c_client *client)
{
+ struct wm8739_state *state = i2c_get_clientdata(client);
int err;
err = i2c_detach_client(client);
if (err)
return err;
+ kfree(state);
kfree(client);
return 0;
}
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 4df5d30..9f7e894 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -222,12 +222,14 @@ static int wm8775_probe(struct i2c_adapter *adapter)
static int wm8775_detach(struct i2c_client *client)
{
+ struct wm8775_state *state = i2c_get_clientdata(client);
int err;
err = i2c_detach_client(client);
if (err) {
return err;
}
+ kfree(state);
kfree(client);
return 0;
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 8ee0321..ab2ca63 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -908,7 +908,9 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_DEVICE_TYPE2 0x00000002
#define SONYPI_DEVICE_TYPE3 0x00000004
-#define SONY_PIC_EV_MASK 0xff
+#define SONYPI_TYPE1_OFFSET 0x04
+#define SONYPI_TYPE2_OFFSET 0x12
+#define SONYPI_TYPE3_OFFSET 0x12
struct sony_pic_ioport {
struct acpi_resource_io io;
@@ -922,6 +924,7 @@ struct sony_pic_irq {
struct sony_pic_dev {
int model;
+ u16 evport_offset;
u8 camera_power;
u8 bluetooth_power;
u8 wwan_power;
@@ -1998,20 +2001,17 @@ end:
static irqreturn_t sony_pic_irq(int irq, void *dev_id)
{
int i, j;
- u32 port_val = 0;
u8 ev = 0;
u8 data_mask = 0;
u8 device_event = 0;
struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
- acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val,
- dev->cur_ioport->io.address_length);
- ev = port_val & SONY_PIC_EV_MASK;
- data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8));
+ ev = inb_p(dev->cur_ioport->io.minimum);
+ data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
- dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n",
- port_val, ev, data_mask, dev->cur_ioport->io.minimum);
+ dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
+ ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
if (ev == 0x00 || ev == 0xff)
return IRQ_HANDLED;
@@ -2102,6 +2102,20 @@ static int sony_pic_add(struct acpi_device *device)
spic_dev.model = sony_pic_detect_device_type();
mutex_init(&spic_dev.lock);
+ /* model specific characteristics */
+ switch(spic_dev.model) {
+ case SONYPI_DEVICE_TYPE1:
+ spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
+ break;
+ case SONYPI_DEVICE_TYPE3:
+ spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
+ break;
+ case SONYPI_DEVICE_TYPE2:
+ default:
+ spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
+ break;
+ }
+
/* read _PRS resources */
result = sony_pic_possible_resources(device);
if (result) {
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 42ba1c0..a361dba 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -550,6 +550,8 @@ union ring_type {
/* PHY defines */
#define PHY_OUI_MARVELL 0x5043
#define PHY_OUI_CICADA 0x03f1
+#define PHY_OUI_VITESSE 0x01c1
+#define PHY_OUI_REALTEK 0x01c1
#define PHYID1_OUI_MASK 0x03ff
#define PHYID1_OUI_SHFT 6
#define PHYID2_OUI_MASK 0xfc00
@@ -557,12 +559,36 @@ union ring_type {
#define PHYID2_MODEL_MASK 0x03f0
#define PHY_MODEL_MARVELL_E3016 0x220
#define PHY_MARVELL_E3016_INITMASK 0x0300
-#define PHY_INIT1 0x0f000
-#define PHY_INIT2 0x0e00
-#define PHY_INIT3 0x01000
-#define PHY_INIT4 0x0200
-#define PHY_INIT5 0x0004
-#define PHY_INIT6 0x02000
+#define PHY_CICADA_INIT1 0x0f000
+#define PHY_CICADA_INIT2 0x0e00
+#define PHY_CICADA_INIT3 0x01000
+#define PHY_CICADA_INIT4 0x0200
+#define PHY_CICADA_INIT5 0x0004
+#define PHY_CICADA_INIT6 0x02000
+#define PHY_VITESSE_INIT_REG1 0x1f
+#define PHY_VITESSE_INIT_REG2 0x10
+#define PHY_VITESSE_INIT_REG3 0x11
+#define PHY_VITESSE_INIT_REG4 0x12
+#define PHY_VITESSE_INIT_MSK1 0xc
+#define PHY_VITESSE_INIT_MSK2 0x0180
+#define PHY_VITESSE_INIT1 0x52b5
+#define PHY_VITESSE_INIT2 0xaf8a
+#define PHY_VITESSE_INIT3 0x8
+#define PHY_VITESSE_INIT4 0x8f8a
+#define PHY_VITESSE_INIT5 0xaf86
+#define PHY_VITESSE_INIT6 0x8f86
+#define PHY_VITESSE_INIT7 0xaf82
+#define PHY_VITESSE_INIT8 0x0100
+#define PHY_VITESSE_INIT9 0x8f82
+#define PHY_VITESSE_INIT10 0x0
+#define PHY_REALTEK_INIT_REG1 0x1f
+#define PHY_REALTEK_INIT_REG2 0x19
+#define PHY_REALTEK_INIT_REG3 0x13
+#define PHY_REALTEK_INIT1 0x0000
+#define PHY_REALTEK_INIT2 0x8e00
+#define PHY_REALTEK_INIT3 0x0001
+#define PHY_REALTEK_INIT4 0xad17
+
#define PHY_GIGABIT 0x0100
#define PHY_TIMEOUT 0x1
@@ -1096,6 +1122,28 @@ static int phy_init(struct net_device *dev)
return PHY_ERROR;
}
}
+ if (np->phy_oui == PHY_OUI_REALTEK) {
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ }
/* set advertise register */
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
@@ -1141,14 +1189,14 @@ static int phy_init(struct net_device *dev)
/* phy vendor specific configuration */
if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
- phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
- phy_reserved |= (PHY_INIT3 | PHY_INIT4);
+ phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
+ phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
- phy_reserved |= PHY_INIT5;
+ phy_reserved |= PHY_CICADA_INIT5;
if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
@@ -1156,12 +1204,106 @@ static int phy_init(struct net_device *dev)
}
if (np->phy_oui == PHY_OUI_CICADA) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
- phy_reserved |= PHY_INIT6;
+ phy_reserved |= PHY_CICADA_INIT6;
if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
return PHY_ERROR;
}
}
+ if (np->phy_oui == PHY_OUI_VITESSE) {
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+ phy_reserved |= PHY_VITESSE_INIT3;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+ phy_reserved |= PHY_VITESSE_INIT3;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+ phy_reserved &= ~PHY_VITESSE_INIT_MSK2;
+ phy_reserved |= PHY_VITESSE_INIT8;
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ }
+ if (np->phy_oui == PHY_OUI_REALTEK) {
+ /* reset could have cleared these out, set them back */
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+ printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+ return PHY_ERROR;
+ }
+ }
+
/* some phys clear out pause advertisment on reset, set it back */
mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 50cad3a..1e03bbd 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -409,6 +409,9 @@ static void socket_shutdown(struct pcmcia_socket *s)
#endif
s->functions = 0;
+ /* give socket some time to power down */
+ msleep(100);
+
s->ops->get_status(s, &status);
if (status & SS_POWERON) {
printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 5c487ff..ac65ee2 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -597,6 +597,8 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
static int aac_cfg_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
return aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
}
@@ -650,6 +652,8 @@ static int aac_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
static long aac_compat_cfg_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
return aac_compat_do_ioctl((struct aac_dev *)file->private_data, cmd, arg);
}
#endif
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 96557e6..17bcca5 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -440,8 +440,16 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
{
struct uart_port *port = sunhv_port;
unsigned long flags;
+ int locked = 1;
+
+ local_irq_save(flags);
+ if (port->sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&port->lock);
+ } else
+ spin_lock(&port->lock);
- spin_lock_irqsave(&port->lock, flags);
while (n > 0) {
unsigned long ra = __pa(con_write_page);
unsigned long page_bytes;
@@ -469,7 +477,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
ra += written;
}
}
- spin_unlock_irqrestore(&port->lock, flags);
+
+ if (locked)
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
}
static inline void sunhv_console_putchar(struct uart_port *port, char c)
@@ -488,7 +499,15 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
{
struct uart_port *port = sunhv_port;
unsigned long flags;
- int i;
+ int i, locked = 1;
+
+ local_irq_save(flags);
+ if (port->sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&port->lock);
+ } else
+ spin_lock(&port->lock);
spin_lock_irqsave(&port->lock, flags);
for (i = 0; i < n; i++) {
@@ -496,7 +515,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
sunhv_console_putchar(port, '\r');
sunhv_console_putchar(port, *s++);
}
- spin_unlock_irqrestore(&port->lock, flags);
+
+ if (locked)
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
}
static struct console sunhv_console = {
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index deb9ab4..8a0f9e4 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -860,22 +860,31 @@ static int num_channels;
static void sunsab_console_putchar(struct uart_port *port, int c)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *)port;
- unsigned long flags;
-
- spin_lock_irqsave(&up->port.lock, flags);
sunsab_tec_wait(up);
writeb(c, &up->regs->w.tic);
-
- spin_unlock_irqrestore(&up->port.lock, flags);
}
static void sunsab_console_write(struct console *con, const char *s, unsigned n)
{
struct uart_sunsab_port *up = &sunsab_ports[con->index];
+ unsigned long flags;
+ int locked = 1;
+
+ local_irq_save(flags);
+ if (up->port.sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&up->port.lock);
+ } else
+ spin_lock(&up->port.lock);
uart_console_write(&up->port, s, n, sunsab_console_putchar);
sunsab_tec_wait(up);
+
+ if (locked)
+ spin_unlock(&up->port.lock);
+ local_irq_restore(flags);
}
static int sunsab_console_setup(struct console *con, char *options)
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 2a63cdb..26d720b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1288,7 +1288,17 @@ static void sunsu_console_write(struct console *co, const char *s,
unsigned int count)
{
struct uart_sunsu_port *up = &sunsu_ports[co->index];
+ unsigned long flags;
unsigned int ier;
+ int locked = 1;
+
+ local_irq_save(flags);
+ if (up->port.sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&up->port.lock);
+ } else
+ spin_lock(&up->port.lock);
/*
* First save the UER then disable the interrupts
@@ -1304,6 +1314,10 @@ static void sunsu_console_write(struct console *co, const char *s,
*/
wait_for_xmitr(up);
serial_out(up, UART_IER, ier);
+
+ if (locked)
+ spin_unlock(&up->port.lock);
+ local_irq_restore(flags);
}
/*
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 15b6e1c..0a3e10a 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -9,7 +9,7 @@
* C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their
* work there.
*
- * Copyright (C) 2002, 2006 David S. Miller ([email protected])
+ * Copyright (C) 2002, 2006, 2007 David S. Miller ([email protected])
*/
#include <linux/module.h>
@@ -1151,11 +1151,22 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count)
{
struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
unsigned long flags;
+ int locked = 1;
+
+ local_irq_save(flags);
+ if (up->port.sysrq) {
+ locked = 0;
+ } else if (oops_in_progress) {
+ locked = spin_trylock(&up->port.lock);
+ } else
+ spin_lock(&up->port.lock);
- spin_lock_irqsave(&up->port.lock, flags);
uart_console_write(&up->port, s, count, sunzilog_putchar);
udelay(2);
- spin_unlock_irqrestore(&up->port.lock, flags);
+
+ if (locked)
+ spin_unlock(&up->port.lock);
+ local_irq_restore(flags);
}
static int __init sunzilog_console_setup(struct console *con, char *options)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0081c1d..407fb8f 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -919,6 +919,10 @@ skip_normal_probe:
return -EINVAL;
}
}
+
+ /* Accept probe requests only for the control interface */
+ if (intf != control_interface)
+ return -ENODEV;
if (usb_interface_claimed(data_interface)) { /* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available");
@@ -1107,10 +1111,12 @@ static void acm_disconnect(struct usb_interface *intf)
return;
}
if (acm->country_codes){
- device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
- device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
+ device_remove_file(&acm->control->dev,
+ &dev_attr_wCountryCodes);
+ device_remove_file(&acm->control->dev,
+ &dev_attr_iCountryCodeRelDate);
}
- device_remove_file(&intf->dev, &dev_attr_bmCapabilities);
+ device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
acm->dev = NULL;
usb_set_intfdata(acm->control, NULL);
usb_set_intfdata(acm->data, NULL);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24f10a1..a1c1a11 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1388,6 +1388,10 @@ int usb_new_device(struct usb_device *udev)
udev->dev.devt = MKDEV(USB_DEVICE_MAJOR,
(((udev->bus->busnum-1) * 128) + (udev->devnum-1)));
+ /* Increment the parent's count of unsuspended children */
+ if (udev->parent)
+ usb_autoresume_device(udev->parent);
+
/* Register the device. The device driver is responsible
* for adding the device files to sysfs and for configuring
* the device.
@@ -1395,13 +1399,11 @@ int usb_new_device(struct usb_device *udev)
err = device_add(&udev->dev);
if (err) {
dev_err(&udev->dev, "can't device_add, error %d\n", err);
+ if (udev->parent)
+ usb_autosuspend_device(udev->parent);
goto fail;
}
- /* Increment the parent's count of unsuspended children */
- if (udev->parent)
- usb_autoresume_device(udev->parent);
-
exit:
return err;
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index da1c6f7..38c4e97 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -271,26 +271,58 @@ static int debug;
static __u16 vendor = FTDI_VID;
static __u16 product;
+struct ftdi_private {
+ ftdi_chip_type_t chip_type;
+ /* type of the device, either SIO or FT8U232AM */
+ int baud_base; /* baud base clock for divisor setting */
+ int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
+ __u16 last_set_data_urb_value ;
+ /* the last data state set - needed for doing a break */
+ int write_offset; /* This is the offset in the usb data block to write the serial data -
+ * it is different between devices
+ */
+ int flags; /* some ASYNC_xxxx flags are supported */
+ unsigned long last_dtr_rts; /* saved modem control outputs */
+ wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ char prev_status, diff_status; /* Used for TIOCMIWAIT */
+ __u8 rx_flags; /* receive state flags (throttling) */
+ spinlock_t rx_lock; /* spinlock for receive state */
+ struct delayed_work rx_work;
+ struct usb_serial_port *port;
+ int rx_processed;
+ unsigned long rx_bytes;
+
+ __u16 interface; /* FT2232C port interface (0 for FT232/245) */
+
+ int force_baud; /* if non-zero, force the baud rate to this value */
+ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
+
+ spinlock_t tx_lock; /* spinlock for transmit state */
+ unsigned long tx_bytes;
+ unsigned long tx_outstanding_bytes;
+ unsigned long tx_outstanding_urbs;
+};
+
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
int (*probe)(struct usb_serial *);
- void (*setup)(struct usb_serial *); /* Special settings during startup. */
+ void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
};
static int ftdi_olimex_probe (struct usb_serial *serial);
-static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
-static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
+static void ftdi_USB_UIRT_setup (struct ftdi_private *priv);
+static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv);
static struct ftdi_sio_quirk ftdi_olimex_quirk = {
.probe = ftdi_olimex_probe,
};
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
- .setup = ftdi_USB_UIRT_setup,
+ .port_probe = ftdi_USB_UIRT_setup,
};
static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
- .setup = ftdi_HE_TIRA1_setup,
+ .port_probe = ftdi_HE_TIRA1_setup,
};
/*
@@ -567,38 +599,6 @@ static const char *ftdi_chip_name[] = {
#define THROTTLED 0x01
#define ACTUALLY_THROTTLED 0x02
-struct ftdi_private {
- ftdi_chip_type_t chip_type;
- /* type of the device, either SIO or FT8U232AM */
- int baud_base; /* baud base clock for divisor setting */
- int custom_divisor; /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
- __u16 last_set_data_urb_value ;
- /* the last data state set - needed for doing a break */
- int write_offset; /* This is the offset in the usb data block to write the serial data -
- * it is different between devices
- */
- int flags; /* some ASYNC_xxxx flags are supported */
- unsigned long last_dtr_rts; /* saved modem control outputs */
- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
- char prev_status, diff_status; /* Used for TIOCMIWAIT */
- __u8 rx_flags; /* receive state flags (throttling) */
- spinlock_t rx_lock; /* spinlock for receive state */
- struct delayed_work rx_work;
- struct usb_serial_port *port;
- int rx_processed;
- unsigned long rx_bytes;
-
- __u16 interface; /* FT2232C port interface (0 for FT232/245) */
-
- int force_baud; /* if non-zero, force the baud rate to this value */
- int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
-
- spinlock_t tx_lock; /* spinlock for transmit state */
- unsigned long tx_bytes;
- unsigned long tx_outstanding_bytes;
- unsigned long tx_outstanding_urbs;
-};
-
/* Used for TIOCMIWAIT */
#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
@@ -609,7 +609,6 @@ struct ftdi_private {
/* function prototypes for a FTDI serial converter */
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
-static int ftdi_sio_attach (struct usb_serial *serial);
static void ftdi_shutdown (struct usb_serial *serial);
static int ftdi_sio_port_probe (struct usb_serial_port *port);
static int ftdi_sio_port_remove (struct usb_serial_port *port);
@@ -663,7 +662,6 @@ static struct usb_serial_driver ftdi_sio_device = {
.ioctl = ftdi_ioctl,
.set_termios = ftdi_set_termios,
.break_ctl = ftdi_break_ctl,
- .attach = ftdi_sio_attach,
.shutdown = ftdi_shutdown,
};
@@ -1198,6 +1196,8 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
static int ftdi_sio_port_probe(struct usb_serial_port *port)
{
struct ftdi_private *priv;
+ struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
+
dbg("%s",__FUNCTION__);
@@ -1214,6 +1214,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
than queue a task to deliver them */
priv->flags = ASYNC_LOW_LATENCY;
+ if (quirk && quirk->port_probe)
+ quirk->port_probe(priv);
+
/* Increase the size of read buffers */
kfree(port->bulk_in_buffer);
port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
@@ -1244,29 +1247,13 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
return 0;
}
-/* attach subroutine */
-static int ftdi_sio_attach (struct usb_serial *serial)
-{
- /* Check for device requiring special set up. */
- struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
-
- if (quirk && quirk->setup)
- quirk->setup(serial);
-
- return 0;
-} /* ftdi_sio_attach */
-
-
/* Setup for the USB-UIRT device, which requires hardwired
* baudrate (38400 gets mapped to 312500) */
/* Called from usbserial:serial_probe */
-static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
+static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
{
- struct ftdi_private *priv;
-
dbg("%s",__FUNCTION__);
- priv = usb_get_serial_port_data(serial->port[0]);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 77;
priv->force_baud = B38400;
@@ -1274,13 +1261,10 @@ static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
/* Setup for the HE-TIRA1 device, which requires hardwired
* baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */
-static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
+static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
{
- struct ftdi_private *priv;
-
dbg("%s",__FUNCTION__);
- priv = usb_get_serial_port_data(serial->port[0]);
priv->flags |= ASYNC_SPD_CUST;
priv->custom_divisor = 240;
priv->force_baud = B38400;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 056e192..0f99e07 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2366,9 +2366,8 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
int status;
unsigned char number = edge_port->port->number - edge_port->port->serial->minor;
- if ((!edge_serial->is_epic) ||
- ((edge_serial->is_epic) &&
- (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) {
+ if (edge_serial->is_epic &&
+ !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) {
dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d",
edge_port->port->number, baudRate);
return 0;
@@ -2461,18 +2460,16 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue);
- if ((!edge_serial->is_epic) ||
- ((edge_serial->is_epic) &&
- (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) &&
- (regNum == MCR))) {
+ if (edge_serial->is_epic &&
+ !edge_serial->epic_descriptor.Supports.IOSPWriteMCR &&
+ regNum == MCR) {
dbg("SendCmdWriteUartReg - Not writing to MCR Register");
return 0;
}
- if ((!edge_serial->is_epic) ||
- ((edge_serial->is_epic) &&
- (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) &&
- (regNum == LCR))) {
+ if (edge_serial->is_epic &&
+ !edge_serial->epic_descriptor.Supports.IOSPWriteLCR &&
+ regNum == LCR) {
dbg ("SendCmdWriteUartReg - Not writing to LCR Register");
return 0;
}
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index e9bbc34..1b3f658 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -174,7 +174,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
struct cr_panel *crp;
u8 dev_en;
- crp = kzalloc(sizeof(crp), GFP_KERNEL);
+ crp = kzalloc(sizeof(*crp), GFP_KERNEL);
if (crp == NULL)
return -ENOMEM;
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index ab21495..083f603 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -369,9 +369,8 @@ EXPORT_SYMBOL(mac_map_monitor_sense);
*
*/
-int __devinit mac_find_mode(struct fb_var_screeninfo *var,
- struct fb_info *info, const char *mode_option,
- unsigned int default_bpp)
+int mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
+ const char *mode_option, unsigned int default_bpp)
{
const struct fb_videomode *db = NULL;
unsigned int dbsize = 0;
diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h
index babeb81..b86ba08 100644
--- a/drivers/video/macmodes.h
+++ b/drivers/video/macmodes.h
@@ -55,10 +55,10 @@ extern int mac_vmode_to_var(int vmode, int cmode,
extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
int *cmode);
extern int mac_map_monitor_sense(int sense);
-extern int __devinit mac_find_mode(struct fb_var_screeninfo *var,
- struct fb_info *info,
- const char *mode_option,
- unsigned int default_bpp);
+extern int mac_find_mode(struct fb_var_screeninfo *var,
+ struct fb_info *info,
+ const char *mode_option,
+ unsigned int default_bpp);
/*
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index a3ed571..923d75c 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -742,6 +742,7 @@ struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
if (err) {
kfree(fc);
fc = ERR_PTR(err);
+ goto error;
}
if (buf_check_overflow(bufp)) {
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 83e94fe..9c6877c 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -902,8 +902,9 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
mutex_lock(&crypt_stat->cs_mutex);
if (S_ISDIR(dentry->d_inode->i_mode))
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
- else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
- || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
+ else if (S_ISREG(dentry->d_inode->i_mode)
+ && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
+ || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
struct vfsmount *lower_mnt;
struct file *lower_file = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index b9ce241..fd10229 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1445,7 +1445,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block,
static void
ext4_ext_put_in_cache(struct inode *inode, __u32 block,
- __u32 len, __u32 start, int type)
+ __u32 len, ext4_fsblk_t start, int type)
{
struct ext4_ext_cache *cex;
BUG_ON(len == 0);
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 1facfaf..a003d50 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -887,7 +887,8 @@ restart_loop:
journal->j_committing_transaction = NULL;
spin_unlock(&journal->j_state_lock);
- if (commit_transaction->t_checkpoint_list == NULL) {
+ if (commit_transaction->t_checkpoint_list == NULL &&
+ commit_transaction->t_checkpoint_io_list == NULL) {
__journal_drop_transaction(journal, commit_transaction);
} else {
if (journal->j_checkpoint_transactions == NULL) {
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 2856e11..c0f59d1 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -896,7 +896,8 @@ restart_loop:
journal->j_committing_transaction = NULL;
spin_unlock(&journal->j_state_lock);
- if (commit_transaction->t_checkpoint_list == NULL) {
+ if (commit_transaction->t_checkpoint_list == NULL &&
+ commit_transaction->t_checkpoint_io_list == NULL) {
__jbd2_journal_drop_transaction(journal, commit_transaction);
} else {
if (journal->j_checkpoint_transactions == NULL) {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7e6aa24..9a68061 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1890,7 +1890,7 @@ nfsd_racache_init(int cache_size)
raparm_hash[i].pb_head = NULL;
spin_lock_init(&raparm_hash[i].pb_lock);
}
- nperbucket = cache_size >> RAPARM_HASH_BITS;
+ nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
for (i = 0; i < cache_size - 1; i++) {
if (i % nperbucket == 0)
raparm_hash[j++].pb_head = raparml + i;
diff --git a/fs/splice.c b/fs/splice.c
index e7d7080..d3c6668 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -601,7 +601,7 @@ find_page:
ret = add_to_page_cache_lru(page, mapping, index,
GFP_KERNEL);
if (unlikely(ret))
- goto out;
+ goto out_release;
}
ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
@@ -657,8 +657,9 @@ find_page:
*/
mark_page_accessed(page);
out:
- page_cache_release(page);
unlock_page(page);
+out_release:
+ page_cache_release(page);
out_ret:
return ret;
}
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index b502c71..1f64ce5 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -283,6 +283,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
mutex_lock(&inode->i_mutex);
if (!(set = inode->i_private)) {
if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
+ mutex_unlock(&inode->i_mutex);
error = -ENOMEM;
goto Done;
} else {
diff --git a/fs/timerfd.c b/fs/timerfd.c
index af9eca5..61983f3 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -95,7 +95,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
{
struct timerfd_ctx *ctx = file->private_data;
ssize_t res;
- u32 ticks = 0;
+ u64 ticks = 0;
DECLARE_WAITQUEUE(wait, current);
if (count < sizeof(ticks))
@@ -130,7 +130,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
* callback to avoid DoS attacks specifying a very
* short timer period.
*/
- ticks = (u32)
+ ticks = (u64)
hrtimer_forward(&ctx->tmr,
hrtimer_cb_get_time(&ctx->tmr),
ctx->tintv);
@@ -140,7 +140,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
}
spin_unlock_irq(&ctx->wqh.lock);
if (ticks)
- res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks);
+ res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);
return res;
}
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index f317c27..b9c4d9e 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -137,6 +137,7 @@ header-y += radeonfb.h
header-y += raw.h
header-y += resource.h
header-y += rose.h
+header-y += serial_reg.h
header-y += smbno.h
header-y += snmp.h
header-y += sockios.h
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 8e2042b..2eaa142 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -47,8 +47,10 @@ enum {
#define IOPRIO_NORM (4)
static inline int task_ioprio(struct task_struct *task)
{
- WARN_ON(!ioprio_valid(task->ioprio));
- return IOPRIO_PRIO_DATA(task->ioprio);
+ if (ioprio_valid(task->ioprio))
+ return IOPRIO_PRIO_DATA(task->ioprio);
+
+ return IOPRIO_NORM;
}
static inline int task_nice_ioprio(struct task_struct *task)
diff --git a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h
index 34ab0fb..a92fefc 100644
--- a/include/linux/netfilter_ipv4/ipt_iprange.h
+++ b/include/linux/netfilter_ipv4/ipt_iprange.h
@@ -1,6 +1,8 @@
#ifndef _IPT_IPRANGE_H
#define _IPT_IPRANGE_H
+#include <linux/types.h>
+
#define IPRANGE_SRC 0x01 /* Match source IP address */
#define IPRANGE_DST 0x02 /* Match destination IP address */
#define IPRANGE_SRC_INV 0x10 /* Negate the condition */
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 3c563f0..25aa575 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -323,6 +323,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc
#define RFCOMM_RELEASE_ONHUP 1
#define RFCOMM_HANGUP_NOW 2
#define RFCOMM_TTY_ATTACHED 3
+#define RFCOMM_TTY_RELEASED 4
struct rfcomm_dev_req {
s16 dev_id;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 311f25a..4d56e16 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -577,7 +577,6 @@ static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ct
struct xfrm_dst
{
union {
- struct xfrm_dst *next;
struct dst_entry dst;
struct rtable rt;
struct rt6_info rt6;
diff --git a/ipc/shm.c b/ipc/shm.c
index 0852f20..3bdcb9a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -716,7 +716,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
struct user_struct * user = current->user;
if (!is_file_hugepages(shp->shm_file)) {
err = shmem_lock(shp->shm_file, 1, user);
- if (!err) {
+ if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){
shp->shm_perm.mode |= SHM_LOCKED;
shp->mlock_user = user;
}
diff --git a/kernel/futex.c b/kernel/futex.c
index 45490be..9b57f7e 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -2061,8 +2061,10 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val,
}
/*
* requeue parameter in 'utime' if cmd == FUTEX_REQUEUE.
+ * number of waiters to wake in 'utime' if cmd == FUTEX_WAKE_OP.
*/
- if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
+ cmd == FUTEX_WAKE_OP)
val2 = (u32) (unsigned long) utime;
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index 58f35e5..96f0417 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -339,7 +339,7 @@ static const struct file_operations proc_lockdep_stats_operations = {
.open = lockdep_stats_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = single_release,
};
static int __init lockdep_proc_init(void)
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 8bbcfb7..7ea87d9 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -267,7 +267,7 @@ static struct file_operations timer_list_fops = {
.open = timer_list_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = single_release,
};
static int __init init_timer_list_procfs(void)
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 3216937..7bb561d 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -391,7 +391,7 @@ static struct file_operations tstats_fops = {
.read = seq_read,
.write = tstats_write,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = single_release,
};
void __init init_timer_stats(void)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3bebf73..3831f88 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -739,18 +739,17 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
if (cwq->thread == NULL)
return;
+ flush_cpu_workqueue(cwq);
/*
- * If the caller is CPU_DEAD the single flush_cpu_workqueue()
- * is not enough, a concurrent flush_workqueue() can insert a
- * barrier after us.
+ * If the caller is CPU_DEAD and cwq->worklist was not empty,
+ * a concurrent flush_workqueue() can insert a barrier after us.
+ * However, in that case run_workqueue() won't return and check
+ * kthread_should_stop() until it flushes all work_struct's.
* When ->worklist becomes empty it is safe to exit because no
* more work_structs can be queued on this cwq: flush_workqueue
* checks list_empty(), and a "normal" queue_work() can't use
* a dead CPU.
*/
- while (flush_cpu_workqueue(cwq))
- ;
-
kthread_stop(cwq->thread);
cwq->thread = NULL;
}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index a45d1f0..5fb38f1 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -101,13 +101,20 @@ static void free_huge_page(struct page *page)
static int alloc_fresh_huge_page(void)
{
- static int nid = 0;
+ static int prev_nid;
struct page *page;
- page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
- HUGETLB_PAGE_ORDER);
- nid = next_node(nid, node_online_map);
+ static DEFINE_SPINLOCK(nid_lock);
+ int nid;
+
+ spin_lock(&nid_lock);
+ nid = next_node(prev_nid, node_online_map);
if (nid == MAX_NUMNODES)
nid = first_node(node_online_map);
+ prev_nid = nid;
+ spin_unlock(&nid_lock);
+
+ page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
+ HUGETLB_PAGE_ORDER);
if (page) {
set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock);
diff --git a/mm/mlock.c b/mm/mlock.c
index 4d3fea2..7b26560 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -244,9 +244,12 @@ int user_shm_lock(size_t size, struct user_struct *user)
locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+ if (lock_limit == RLIM_INFINITY)
+ allowed = 1;
lock_limit >>= PAGE_SHIFT;
spin_lock(&shmlock_user_lock);
- if (locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
+ if (!allowed &&
+ locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
goto out;
get_uid(user);
user->locked_shm += locked;
diff --git a/mm/readahead.c b/mm/readahead.c
index 9861e88..1448e53 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -21,8 +21,16 @@ void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
}
EXPORT_SYMBOL(default_unplug_io_fn);
+/*
+ * Convienent macros for min/max read-ahead pages.
+ * Note that MAX_RA_PAGES is rounded down, while MIN_RA_PAGES is rounded up.
+ * The latter is necessary for systems with large page size(i.e. 64k).
+ */
+#define MAX_RA_PAGES (VM_MAX_READAHEAD*1024 / PAGE_CACHE_SIZE)
+#define MIN_RA_PAGES DIV_ROUND_UP(VM_MIN_READAHEAD*1024, PAGE_CACHE_SIZE)
+
struct backing_dev_info default_backing_dev_info = {
- .ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
+ .ra_pages = MAX_RA_PAGES,
.state = 0,
.capabilities = BDI_CAP_MAP_COPY,
.unplug_io_fn = default_unplug_io_fn,
@@ -51,7 +59,7 @@ static inline unsigned long get_max_readahead(struct file_ra_state *ra)
static inline unsigned long get_min_readahead(struct file_ra_state *ra)
{
- return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE;
+ return MIN_RA_PAGES;
}
static inline void reset_ahead_window(struct file_ra_state *ra)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index b2b1cce..23ba61a 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
BT_DBG("dev %p dlc %p", dev, dlc);
+ write_lock_bh(&rfcomm_dev_lock);
+ list_del_init(&dev->list);
+ write_unlock_bh(&rfcomm_dev_lock);
+
rfcomm_dlc_lock(dlc);
/* Detach DLC if it's owned by this dev */
if (dlc->owner == dev)
@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
read_lock(&rfcomm_dev_lock);
dev = __rfcomm_dev_get(id);
- if (dev)
- rfcomm_dev_hold(dev);
+
+ if (dev) {
+ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+ dev = NULL;
+ else
+ rfcomm_dev_hold(dev);
+ }
read_unlock(&rfcomm_dev_lock);
@@ -265,6 +274,12 @@ out:
dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
+ if (IS_ERR(dev->tty_dev)) {
+ list_del(&dev->list);
+ kfree(dev);
+ return PTR_ERR(dev->tty_dev);
+ }
+
return dev->id;
}
@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
{
BT_DBG("dev %p", dev);
- write_lock_bh(&rfcomm_dev_lock);
- list_del_init(&dev->list);
- write_unlock_bh(&rfcomm_dev_lock);
-
+ set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
rfcomm_dev_put(dev);
}
@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
- BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
+ BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
return -EPERM;
@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __user *arg)
if (copy_from_user(&req, arg, sizeof(req)))
return -EFAULT;
- BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
+ BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
if (!(dev = rfcomm_dev_get(req.dev_id)))
return -ENODEV;
@@ -383,6 +395,10 @@ static int rfcomm_release_dev(void __user *arg)
if (req.flags & (1 << RFCOMM_HANGUP_NOW))
rfcomm_dlc_close(dev->dlc, 0);
+ /* Shut down TTY synchronously before freeing rfcomm_dev */
+ if (dev->tty)
+ tty_vhangup(dev->tty);
+
rfcomm_dev_del(dev);
rfcomm_dev_put(dev);
return 0;
@@ -415,6 +431,8 @@ static int rfcomm_get_dev_list(void __user *arg)
list_for_each(p, &rfcomm_dev_list) {
struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
+ if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+ continue;
(di + n)->id = dev->id;
(di + n)->flags = dev->flags;
(di + n)->state = dev->dlc->state;
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 031bfa4..984e9c6 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -196,10 +196,8 @@ static int __init ebt_log_init(void)
ret = ebt_register_watcher(&log);
if (ret < 0)
return ret;
- ret = nf_log_register(PF_BRIDGE, &ebt_log_logger);
- if (ret < 0 && ret != -EEXIST)
- ebt_unregister_watcher(&log);
- return ret;
+ nf_log_register(PF_BRIDGE, &ebt_log_logger);
+ return 0;
}
static void __exit ebt_log_fini(void)
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 9411db6..6fec352 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -308,12 +308,8 @@ static int __init ebt_ulog_init(void)
else if ((ret = ebt_register_watcher(&ulog)))
sock_release(ebtulognl->sk_socket);
- if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
- printk(KERN_WARNING "ebt_ulog: not logging via ulog "
- "since somebody else already registered for PF_BRIDGE\n");
- /* we cannot make module load fail here, since otherwise
- * ebtables userspace would abort */
- }
+ if (ret == 0)
+ nf_log_register(PF_BRIDGE, &ebt_ulog_logger);
return ret;
}
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 17daf4c..590a767 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -79,27 +79,27 @@
struct gen_estimator
{
- struct gen_estimator *next;
+ struct list_head list;
struct gnet_stats_basic *bstats;
struct gnet_stats_rate_est *rate_est;
spinlock_t *stats_lock;
- unsigned interval;
int ewma_log;
u64 last_bytes;
u32 last_packets;
u32 avpps;
u32 avbps;
+ struct rcu_head e_rcu;
};
struct gen_estimator_head
{
struct timer_list timer;
- struct gen_estimator *list;
+ struct list_head list;
};
static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
-/* Estimator array lock */
+/* Protects against NULL dereference */
static DEFINE_RWLOCK(est_lock);
static void est_timer(unsigned long arg)
@@ -107,13 +107,17 @@ static void est_timer(unsigned long arg)
int idx = (int)arg;
struct gen_estimator *e;
- read_lock(&est_lock);
- for (e = elist[idx].list; e; e = e->next) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(e, &elist[idx].list, list) {
u64 nbytes;
u32 npackets;
u32 rate;
spin_lock(e->stats_lock);
+ read_lock(&est_lock);
+ if (e->bstats == NULL)
+ goto skip;
+
nbytes = e->bstats->bytes;
npackets = e->bstats->packets;
rate = (nbytes - e->last_bytes)<<(7 - idx);
@@ -125,11 +129,14 @@ static void est_timer(unsigned long arg)
e->last_packets = npackets;
e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
e->rate_est->pps = (e->avpps+0x1FF)>>10;
+skip:
+ read_unlock(&est_lock);
spin_unlock(e->stats_lock);
}
- mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
- read_unlock(&est_lock);
+ if (!list_empty(&elist[idx].list))
+ mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+ rcu_read_unlock();
}
/**
@@ -146,12 +153,17 @@ static void est_timer(unsigned long arg)
* &rate_est with the statistics lock grabed during this period.
*
* Returns 0 on success or a negative error code.
+ *
+ * NOTE: Called under rtnl_mutex
*/
int gen_new_estimator(struct gnet_stats_basic *bstats,
- struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock, struct rtattr *opt)
+ struct gnet_stats_rate_est *rate_est,
+ spinlock_t *stats_lock,
+ struct rtattr *opt)
{
struct gen_estimator *est;
struct gnet_estimator *parm = RTA_DATA(opt);
+ int idx;
if (RTA_PAYLOAD(opt) < sizeof(*parm))
return -EINVAL;
@@ -163,7 +175,7 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
if (est == NULL)
return -ENOBUFS;
- est->interval = parm->interval + 2;
+ idx = parm->interval + 2;
est->bstats = bstats;
est->rate_est = rate_est;
est->stats_lock = stats_lock;
@@ -173,20 +185,25 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
est->last_packets = bstats->packets;
est->avpps = rate_est->pps<<10;
- est->next = elist[est->interval].list;
- if (est->next == NULL) {
- init_timer(&elist[est->interval].timer);
- elist[est->interval].timer.data = est->interval;
- elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
- elist[est->interval].timer.function = est_timer;
- add_timer(&elist[est->interval].timer);
+ if (!elist[idx].timer.function) {
+ INIT_LIST_HEAD(&elist[idx].list);
+ setup_timer(&elist[idx].timer, est_timer, idx);
}
- write_lock_bh(&est_lock);
- elist[est->interval].list = est;
- write_unlock_bh(&est_lock);
+
+ if (list_empty(&elist[idx].list))
+ mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+
+ list_add_rcu(&est->list, &elist[idx].list);
return 0;
}
+static void __gen_kill_estimator(struct rcu_head *head)
+{
+ struct gen_estimator *e = container_of(head,
+ struct gen_estimator, e_rcu);
+ kfree(e);
+}
+
/**
* gen_kill_estimator - remove a rate estimator
* @bstats: basic statistics
@@ -194,31 +211,32 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
*
* Removes the rate estimator specified by &bstats and &rate_est
* and deletes the timer.
+ *
+ * NOTE: Called under rtnl_mutex
*/
void gen_kill_estimator(struct gnet_stats_basic *bstats,
struct gnet_stats_rate_est *rate_est)
{
int idx;
- struct gen_estimator *est, **pest;
+ struct gen_estimator *e, *n;
for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
- int killed = 0;
- pest = &elist[idx].list;
- while ((est=*pest) != NULL) {
- if (est->rate_est != rate_est || est->bstats != bstats) {
- pest = &est->next;
+
+ /* Skip non initialized indexes */
+ if (!elist[idx].timer.function)
+ continue;
+
+ list_for_each_entry_safe(e, n, &elist[idx].list, list) {
+ if (e->rate_est != rate_est || e->bstats != bstats)
continue;
- }
write_lock_bh(&est_lock);
- *pest = est->next;
+ e->bstats = NULL;
write_unlock_bh(&est_lock);
- kfree(est);
- killed++;
+ list_del_rcu(&e->list);
+ call_rcu(&e->e_rcu, __gen_kill_estimator);
}
- if (killed && elist[idx].list == NULL)
- del_timer(&elist[idx].timer);
}
}
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a0efdd7..5df8cf4 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -781,7 +781,6 @@ void netpoll_cleanup(struct netpoll *np)
spin_unlock_irqrestore(&npinfo->rx_lock, flags);
}
- np->dev->npinfo = NULL;
if (atomic_dec_and_test(&npinfo->refcnt)) {
skb_queue_purge(&npinfo->arp_tx);
skb_queue_purge(&npinfo->txq);
@@ -794,6 +793,7 @@ void netpoll_cleanup(struct netpoll *np)
kfree_skb(skb);
}
kfree(npinfo);
+ np->dev->npinfo = NULL;
}
}
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index cc8110b..afb6c66 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -271,8 +271,11 @@ ieee80211softmac_assoc_work(struct work_struct *work)
*/
dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
- if (ieee80211softmac_start_scan(mac))
+ if (ieee80211softmac_start_scan(mac)) {
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
+ mac->associnfo.associating = 0;
+ mac->associnfo.associated = 0;
+ }
goto out;
} else {
mac->associnfo.associating = 0;
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index a42c5cd..361be2b 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -477,10 +477,8 @@ static int __init ipt_log_init(void)
ret = xt_register_target(&ipt_log_reg);
if (ret < 0)
return ret;
- ret = nf_log_register(PF_INET, &ipt_log_logger);
- if (ret < 0 && ret != -EEXIST)
- xt_unregister_target(&ipt_log_reg);
- return ret;
+ nf_log_register(PF_INET, &ipt_log_logger);
+ return 0;
}
static void __exit ipt_log_fini(void)
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index f4fc657..474b4ce 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -189,25 +189,13 @@ icmp_error_message(struct sk_buff *skb,
h = nf_conntrack_find_get(&innertuple, NULL);
if (!h) {
- /* Locally generated ICMPs will match inverted if they
- haven't been SNAT'ed yet */
- /* FIXME: NAT code has to handle half-done double NAT --RR */
- if (hooknum == NF_IP_LOCAL_OUT)
- h = nf_conntrack_find_get(&origtuple, NULL);
-
- if (!h) {
- DEBUGP("icmp_error_message: no match\n");
- return -NF_ACCEPT;
- }
-
- /* Reverse direction from that found */
- if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
- *ctinfo += IP_CT_IS_REPLY;
- } else {
- if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
- *ctinfo += IP_CT_IS_REPLY;
+ DEBUGP("icmp_error_message: no match\n");
+ return -NF_ACCEPT;
}
+ if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+ *ctinfo += IP_CT_IS_REPLY;
+
/* Update skb to refer to this connection */
skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
skb->nfctinfo = *ctinfo;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 69f9f1e..4e5884a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1398,7 +1398,9 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
* waiting for the first ACK and did not get it)...
*/
if ((tp->frto_counter == 1) && !(flag&FLAG_DATA_ACKED)) {
- tp->retrans_out += tcp_skb_pcount(skb);
+ /* For some reason this R-bit might get cleared? */
+ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
+ tp->retrans_out += tcp_skb_pcount(skb);
/* ...enter this if branch just for the first segment */
flag |= FLAG_DATA_ACKED;
} else {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f96ed76..2cc3728 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2472,6 +2472,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
write_unlock_bh(&idev->lock);
__ipv6_ifa_notify(RTM_DELADDR, ifa);
+ atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
in6_ifa_put(ifa);
write_lock_bh(&idev->lock);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 9b81264..2f49578 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -66,6 +66,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev)
break;
}
read_unlock_bh(&idev->lock);
+ in6_dev_put(idev);
}
rcu_read_unlock();
return onlink;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e9bcce9..c956037 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -604,7 +604,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
read_lock(&raw_v6_lock);
if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
- while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr,
+ while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
IP6CB(skb)->iif))) {
rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
sk = sk_next(sk);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a0902fb..31f9252 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -962,8 +962,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
dsfield = ipv4_get_dsfield(iph);
if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
- fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT)
- & IPV6_TCLASS_MASK);
+ fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
+ & IPV6_TCLASS_MASK;
err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
if (err != 0) {
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 5bb9cd3..a7a2517 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -490,10 +490,8 @@ static int __init ip6t_log_init(void)
ret = xt_register_target(&ip6t_log_reg);
if (ret < 0)
return ret;
- ret = nf_log_register(PF_INET6, &ip6t_logger);
- if (ret < 0 && ret != -EEXIST)
- xt_unregister_target(&ip6t_log_reg);
- return ret;
+ nf_log_register(PF_INET6, &ip6t_logger);
+ return 0;
}
static void __exit ip6t_log_fini(void)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 193d9d6..17bbdc3 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -644,6 +644,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
if (tp->md5sig_info->entries6 == 0) {
kfree(tp->md5sig_info->keys6);
tp->md5sig_info->keys6 = NULL;
+ tp->md5sig_info->alloced6 = 0;
tcp_free_md5sig_pool();
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index e5c840c..230e35c 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -55,7 +55,7 @@ static void rfkill_task_handler(struct work_struct *work)
static void rfkill_schedule_toggle(struct rfkill_task *task)
{
- unsigned int flags;
+ unsigned long flags;
spin_lock_irqsave(&task->lock, flags);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index bec600a..7a6b0b7 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -290,11 +290,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
wd->qdisc->flags &= ~TCQ_F_THROTTLED;
smp_wmb();
- if (spin_trylock(&dev->queue_lock)) {
- qdisc_run(dev);
- spin_unlock(&dev->queue_lock);
- } else
- netif_schedule(dev);
+ netif_schedule(dev);
return HRTIMER_NORESTART;
}
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 2c29394..2164b51 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -875,6 +875,10 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
dev = dev_get_by_index(addr->v6.sin6_scope_id);
if (!dev)
return 0;
+ if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+ dev_put(dev);
+ return 0;
+ }
dev_put(dev);
}
af = opt->pf->af;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 099a983..805e725 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -760,11 +760,12 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
new->h.flavour = &svcauthops_gss;
new->pseudoflavor = pseudoflavor;
+ stat = 0;
test = auth_domain_lookup(name, &new->h);
- if (test != &new->h) { /* XXX Duplicate registration? */
- auth_domain_put(&new->h);
- /* dangling ref-count... */
- goto out;
+ if (test != &new->h) { /* Duplicate registration */
+ auth_domain_put(test);
+ kfree(new->h.name);
+ goto out_free_dom;
}
return 0;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 157bfbd..b48f06f 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2141,7 +2141,7 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
if (last == first)
break;
- last = last->u.next;
+ last = (struct xfrm_dst *)last->u.dst.next;
last->child_mtu_cached = mtu;
}
Hi,
I just noticed that PHY_OUI_VITESSE == PHY_OUI_REALTEK. Is that really
intentional?
> diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
> index 42ba1c0..a361dba 100644
> --- a/drivers/net/forcedeth.c
> +++ b/drivers/net/forcedeth.c
> @@ -550,6 +550,8 @@ union ring_type {
> /* PHY defines */
> #define PHY_OUI_MARVELL 0x5043
> #define PHY_OUI_CICADA 0x03f1
> +#define PHY_OUI_VITESSE 0x01c1
> +#define PHY_OUI_REALTEK 0x01c1
-
(?= =?)
//\ Prakash Punnoor /\\
V_/ \_V
--- old/drivers/net/forcedeth.c 2007-08-09 17:37:12.000000000 -0400
+++ new/drivers/net/forcedeth.c 2007-08-09 17:37:07.000000000 -0400
@@ -551,7 +551,7 @@
#define PHY_OUI_MARVELL 0x5043
#define PHY_OUI_CICADA 0x03f1
#define PHY_OUI_VITESSE 0x01c1
-#define PHY_OUI_REALTEK 0x01c1
+#define PHY_OUI_REALTEK 0x0732
#define PHYID1_OUI_MASK 0x03ff
#define PHYID1_OUI_SHFT 6
#define PHYID2_OUI_MASK 0xfc00
On Thu, Aug 09, 2007 at 05:40:16PM -0400, Ayaz Abdulla wrote:
> Yes, you are right. Copy and paste error. I have attached a patch which will
> fix this issue.
>
> Thanks for catching it.
> Ayaz
>
> Signed-off-by: Ayaz Abdulla <[email protected]>
>
>
> Prakash Punnoor wrote:
> > Hi,
> > I just noticed that PHY_OUI_VITESSE == PHY_OUI_REALTEK. Is that really
> > intentional?
> >> diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
> >> index 42ba1c0..a361dba 100644
> >> --- a/drivers/net/forcedeth.c
> >> +++ b/drivers/net/forcedeth.c
> >> @@ -550,6 +550,8 @@ union ring_type {
> >> /* PHY defines */
> >> #define PHY_OUI_MARVELL 0x5043
> >> #define PHY_OUI_CICADA 0x03f1
> >> +#define PHY_OUI_VITESSE 0x01c1
> >> +#define PHY_OUI_REALTEK 0x01c1
> > - (?= =?)
> > //\ Prakash Punnoor /\\
> > V_/ \_V
> --- old/drivers/net/forcedeth.c 2007-08-09 17:37:12.000000000 -0400
> +++ new/drivers/net/forcedeth.c 2007-08-09 17:37:07.000000000 -0400
> @@ -551,7 +551,7 @@
> #define PHY_OUI_MARVELL 0x5043
> #define PHY_OUI_CICADA 0x03f1
> #define PHY_OUI_VITESSE 0x01c1
> -#define PHY_OUI_REALTEK 0x01c1
> +#define PHY_OUI_REALTEK 0x0732
> #define PHYID1_OUI_MASK 0x03ff
> #define PHYID1_OUI_SHFT 6
> #define PHYID2_OUI_MASK 0xfc00
Is this something that really matters for this driver? And if so, care
to send this patch to mainline as well as to the [email protected] team
with a proper changelog?
thanks,
greg k-h