2008-11-12 00:26:14

by Greg KH

[permalink] [raw]
Subject: [patch 00/49] 2.6.27.5 stable review

This is the start of the stable review cycle for the 2.6.27.5 release.
There are 49 patches in this series, all will be posted as a response to
this one. If anyone has any issues with these being applied, please let
us know. If anyone is a maintainer of the proper subsystem, and wants
to add a Signed-off-by: line to the patch, please respond with it.

These patches are sent out with a number of different people on the Cc:
line. If you wish to be a reviewer, please email [email protected] to
add your name to the list. If you want to be off the reviewer list,
also email us.

Responses should be made by Friday, November 14, 00:00:01 UTC. Anything
received after that time might be too late.

The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.5-rc1.gz
and the diffstat can be found below.


thanks,

greg k-h

------------
Documentation/cciss.txt | 2
Makefile | 2
arch/arm/mach-pxa/include/mach/reset.h | 9 +
arch/arm/mach-pxa/reset.c | 9 +
arch/arm/mach-pxa/spitz.c | 2
arch/arm/mach-pxa/tosa.c | 2
arch/arm/mm/cache-xsc3l2.c | 4
arch/x86/Kconfig | 20 ++++
arch/x86/kernel/setup.c | 41 ++++++++
arch/x86/kernel/tsc.c | 8 -
drivers/acpi/dock.c | 5 -
drivers/ata/libata-eh.c | 21 ++--
drivers/block/cciss.c | 28 +++++
drivers/block/cpqarray.c | 7 +
drivers/dca/dca-core.c | 2
drivers/dma/ioat_dma.c | 11 +-
drivers/dma/iovlock.c | 17 +--
drivers/hid/hidraw.c | 2
drivers/md/linear.c | 2
drivers/md/raid10.c | 2
drivers/mmc/core/core.c | 6 +
drivers/mtd/chips/cfi_cmdset_0002.c | 13 --
drivers/mtd/chips/jedec_probe.c | 10 --
drivers/net/r8169.c | 134 ++++++++++++++--------------
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 7 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 63 +------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 57 ++++++++---
drivers/net/wireless/iwlwifi/iwl-calib.c | 60 ++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 27 +----
drivers/net/wireless/iwlwifi/iwl-core.h | 8 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 15 +--
drivers/net/wireless/iwlwifi/iwl-power.c | 39 +++++++-
drivers/net/wireless/iwlwifi/iwl-power.h | 4
drivers/net/wireless/iwlwifi/iwl-scan.c | 8 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +
drivers/net/wireless/zd1211rw/zd_usb.c | 2
fs/ext3/super.c | 11 +-
fs/hfs/catalog.c | 4
fs/hfsplus/bitmap.c | 12 ++
fs/hfsplus/catalog.c | 5 +
fs/jffs2/background.c | 10 +-
fs/jffs2/compr_lzo.c | 15 +--
include/asm-generic/memory_model.h | 2
include/linux/mtd/cfi.h | 22 +++-
include/net/af_unix.h | 1
kernel/cgroup.c | 1
mm/hugetlb.c | 49 +++++++++-
mm/internal.h | 29 ++++++
mm/page_alloc.c | 28 ++++-
net/unix/af_unix.c | 31 +++++-
net/unix/garbage.c | 49 +++++++---
security/keys/internal.h | 1
security/keys/process_keys.c | 2
security/keys/request_key.c | 4
sound/pci/hda/patch_sigmatel.c | 15 +--
55 files changed, 647 insertions(+), 300 deletions(-)


2008-11-12 00:26:41

by Greg KH

[permalink] [raw]
Subject: [patch 01/49] ext3: wait on all pending commits in ext3_sync_fs

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Arthur Jones <[email protected]>

commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream

In ext3_sync_fs, we only wait for a commit to finish if we started it, but
there may be one already in progress which will not be synced.

In the case of a data=ordered umount with pending long symlinks which are
delayed due to a long list of other I/O on the backing block device, this
causes the buffer associated with the long symlinks to not be moved to the
inode dirty list in the second phase of fsync_super. Then, before they
can be dirtied again, kjournald exits, seeing the UMOUNT flag and the
dirty pages are never written to the backing block device, causing long
symlink corruption and exposing new or previously freed block data to
userspace.

This can be reproduced with a script created
by Eric Sandeen <[email protected]>:

#!/bin/bash

umount /mnt/test2
mount /dev/sdb4 /mnt/test2
rm -f /mnt/test2/*
dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
touch
/mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
ln -s
/mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
/mnt/test2/link
umount /mnt/test2
mount /dev/sdb4 /mnt/test2
ls /mnt/test2/
umount /mnt/test2

To ensure all commits are synced, we flush all journal commits now when
sync_fs'ing ext3.

Signed-off-by: Arthur Jones <[email protected]>
Cc: Eric Sandeen <[email protected]>
Cc: Theodore Ts'o <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/ext3/super.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup

static int ext3_sync_fs(struct super_block *sb, int wait)
{
- tid_t target;
-
sb->s_dirt = 0;
- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
- if (wait)
- log_wait_commit(EXT3_SB(sb)->s_journal, target);
- }
+ if (wait)
+ ext3_force_commit(sb);
+ else
+ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
+
return 0;
}


--

2008-11-12 00:27:45

by Greg KH

[permalink] [raw]
Subject: [patch 04/49] x86: add X86_RESERVE_LOW_64K

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Ingo Molnar <[email protected]>

commit fc38151947477596aa27df6c4306ad6008dc6711 upstream.

This bugzilla:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

Documents a wide range of systems where the BIOS utilizes the first
64K of physical memory during suspend/resume and other hardware events.

Currently we reserve this memory on all AMI and Phoenix BIOS systems.
Life is too short to hunt subtle memory corruption problems like this,
so we try to be robust by default.

Still, allow this to be overriden: allow users who want that first 64K
of memory to be available to the kernel disable the quirk, via
CONFIG_X86_RESERVE_LOW_64K=n.

Also, allow the early reservation to overlap with other
early reservations.

Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/Kconfig | 20 ++++++++++++++++++++
arch/x86/kernel/setup.c | 4 +++-
2 files changed, 23 insertions(+), 1 deletion(-)

--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1059,6 +1059,26 @@ config HIGHPTE
low memory. Setting this option will put user-space page table
entries in high memory.

+config X86_RESERVE_LOW_64K
+ bool "Reserve low 64K of RAM on AMI/Phoenix BIOSen"
+ default y
+ help
+ Reserve the first 64K of physical RAM on BIOSes that are known
+ to potentially corrupt that memory range. A numbers of BIOSes are
+ known to utilize this area during suspend/resume, so it must not
+ be used by the kernel.
+
+ Set this to N if you are absolutely sure that you trust the BIOS
+ to get all its memory reservations and usages right.
+
+ If you have doubts about the BIOS (e.g. suspend/resume does not
+ work or there's kernel crashes after certain hardware hotplug
+ events) and it's not AMI or Phoenix, then you might want to enable
+ X86_CHECK_BIOS_CORRUPTION=y to allow the kernel to check typical
+ corruption patterns.
+
+ Say Y if unsure.
+
config MATH_EMULATION
bool
prompt "Math emulation" if X86_32
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -584,13 +584,14 @@ static int __init dmi_low_memory_corrupt
"%s detected: BIOS may corrupt low RAM, working it around.\n",
d->ident);

- reserve_early(0x0, 0x10000, "BIOS quirk");
+ reserve_early_overlap_ok(0x0, 0x10000, "BIOS quirk");

return 0;
}

/* List of systems that have known low memory corruption BIOS problems */
static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
+#ifdef CONFIG_X86_RESERVE_LOW_64K
{
.callback = dmi_low_memory_corruption,
.ident = "AMI BIOS",
@@ -606,6 +607,7 @@ static struct dmi_system_id __initdata b
},
},
{}
+#endif
};

/*

--

2008-11-12 00:29:13

by Greg KH

[permalink] [raw]
Subject: [patch 08/49] hugetlb: pull gigantic page initialisation out of the default path

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Andy Whitcroft <[email protected]>

commit 18229df5b613ed0732a766fc37850de2e7988e43 upstream

As we can determine exactly when a gigantic page is in use we can optimise
the common regular page cases by pulling out gigantic page initialisation
into its own function. As gigantic pages are never released to buddy we
do not need a destructor. This effectivly reverts the previous change to
the main buddy allocator. It also adds a paranoid check to ensure we
never release gigantic pages from hugetlbfs to the main buddy.

Signed-off-by: Andy Whitcroft <[email protected]>
Cc: Jon Tollefson <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Nick Piggin <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
mm/hugetlb.c | 12 +++++++++++-
mm/internal.h | 1 +
mm/page_alloc.c | 28 +++++++++++++++++++++-------
3 files changed, 33 insertions(+), 8 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -455,6 +455,8 @@ static void update_and_free_page(struct
{
int i;

+ VM_BUG_ON(h->order >= MAX_ORDER);
+
h->nr_huge_pages--;
h->nr_huge_pages_node[page_to_nid(page)]--;
for (i = 0; i < pages_per_huge_page(h); i++) {
@@ -969,6 +971,14 @@ found:
return 1;
}

+static void prep_compound_huge_page(struct page *page, int order)
+{
+ if (unlikely(order > (MAX_ORDER - 1)))
+ prep_compound_gigantic_page(page, order);
+ else
+ prep_compound_page(page, order);
+}
+
/* Put bootmem huge pages into the standard lists after mem_map is up */
static void __init gather_bootmem_prealloc(void)
{
@@ -979,7 +989,7 @@ static void __init gather_bootmem_preall
struct hstate *h = m->hstate;
__ClearPageReserved(page);
WARN_ON(page_count(page) != 1);
- prep_compound_page(page, h->order);
+ prep_compound_huge_page(page, h->order);
prep_new_huge_page(h, page, page_to_nid(page));
}
}
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -17,6 +17,7 @@ void free_pgtables(struct mmu_gather *tl
unsigned long floor, unsigned long ceiling);

extern void prep_compound_page(struct page *page, unsigned long order);
+extern void prep_compound_gigantic_page(struct page *page, unsigned long order);

static inline void set_page_count(struct page *page, int v)
{
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -268,24 +268,39 @@ void prep_compound_page(struct page *pag
{
int i;
int nr_pages = 1 << order;
+
+ set_compound_page_dtor(page, free_compound_page);
+ set_compound_order(page, order);
+ __SetPageHead(page);
+ for (i = 1; i < nr_pages; i++) {
+ struct page *p = page + i;
+
+ __SetPageTail(p);
+ p->first_page = page;
+ }
+}
+
+#ifdef CONFIG_HUGETLBFS
+void prep_compound_gigantic_page(struct page *page, unsigned long order)
+{
+ int i;
+ int nr_pages = 1 << order;
struct page *p = page + 1;

set_compound_page_dtor(page, free_compound_page);
set_compound_order(page, order);
__SetPageHead(page);
- for (i = 1; i < nr_pages; i++, p++) {
- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
- p = pfn_to_page(page_to_pfn(page) + i);
+ for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) {
__SetPageTail(p);
p->first_page = page;
}
}
+#endif

static void destroy_compound_page(struct page *page, unsigned long order)
{
int i;
int nr_pages = 1 << order;
- struct page *p = page + 1;

if (unlikely(compound_order(page) != order))
bad_page(page);
@@ -293,9 +308,8 @@ static void destroy_compound_page(struct
if (unlikely(!PageHead(page)))
bad_page(page);
__ClearPageHead(page);
- for (i = 1; i < nr_pages; i++, p++) {
- if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0))
- p = pfn_to_page(page_to_pfn(page) + i);
+ for (i = 1; i < nr_pages; i++) {
+ struct page *p = page + i;

if (unlikely(!PageTail(p) |
(p->first_page != page)))

--

2008-11-12 00:28:31

by Greg KH

[permalink] [raw]
Subject: [patch 06/49] x86: fix macro with bad_bios_dmi_table

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Yinghai Lu <[email protected]>

commit a8b71a2810386a5ac8f43d2095fe3355f0d8db37 upstream.

DMI tables need a blank NULL tail.

fixes the crash on Ingo's test box.

Signed-off-by: Yinghai Lu <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -607,8 +607,8 @@ static struct dmi_system_id __initdata b
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
},
},
- {}
#endif
+ {}
};

/*

--

2008-11-12 00:28:50

by Greg KH

[permalink] [raw]
Subject: [patch 07/49] cgroups: fix invalid cgrp->dentry before cgroup has been completely removed

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Li Zefan <[email protected]>

commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream

This fixes an oops when reading /proc/sched_debug.

A cgroup won't be removed completely until finishing cgroup_diput(), so we
shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
group is being removed while cgroup_path() gets called, we may trigger
NULL dereference BUG.

The bug can be reproduced:

# cat test.sh
#!/bin/sh
mount -t cgroup -o cpu xxx /mnt
for (( ; ; ))
{
mkdir /mnt/sub
rmdir /mnt/sub
}
# ./test.sh &
# cat /proc/sched_debug

BUG: unable to handle kernel NULL pointer dereference at 00000038
IP: [<c045a47f>] cgroup_path+0x39/0x90
..
Call Trace:
[<c0420344>] ? print_cfs_rq+0x6e/0x75d
[<c0421160>] ? sched_debug_show+0x72d/0xc1e
..

Signed-off-by: Li Zefan <[email protected]>
Acked-by: Paul Menage <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
kernel/cgroup.c | 1 -
1 file changed, 1 deletion(-)

--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un
list_del(&cgrp->sibling);
spin_lock(&cgrp->dentry->d_lock);
d = dget(cgrp->dentry);
- cgrp->dentry = NULL;
spin_unlock(&d->d_lock);

cgroup_d_remove_dir(d);

--

2008-11-12 00:27:28

by Greg KH

[permalink] [raw]
Subject: [patch 03/49] x86: reserve low 64K on AMI and Phoenix BIOS boxen

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Ingo Molnar <[email protected]>

commit 1e22436eba84edfec9c25e5a25d09062c4f91ca9 upstream

there's multiple reports about suspend/resume related low memory
corruption in this bugzilla:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

the common pattern is that the corruption is caused by the BIOS,
and that it affects some portion of the first 64K of physical RAM.

So add a DMI quirk

This will waste 64K RAM on 'good' systems too, but without knowing
the exact nature of this BIOS memory corruption this is the safest
approach.

This might as well solve a wide range of suspend/resume breakages
under Linux.

Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/setup.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -581,10 +581,10 @@ struct x86_quirks *x86_quirks __initdata
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
{
printk(KERN_NOTICE
- "%s detected: BIOS corrupts 0xc000, working it around.\n",
+ "%s detected: BIOS may corrupt low RAM, working it around.\n",
d->ident);

- reserve_early(0xc000, 0xc400, "BIOS quirk");
+ reserve_early(0x0, 0x10000, "BIOS quirk");

return 0;
}
@@ -598,6 +598,13 @@ static struct dmi_system_id __initdata b
DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
},
},
+ {
+ .callback = dmi_low_memory_corruption,
+ .ident = "Phoenix BIOS",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+ },
+ },
{}
};


--

2008-11-12 00:27:05

by Greg KH

[permalink] [raw]
Subject: [patch 02/49] x86: add DMI quirk for AMI BIOS which corrupts address 0xc000 during resume

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Ingo Molnar <[email protected]>

commit 5649b7c30316a51792808422ac03ee825d26aa5e upstream

Alan Jenkins and Andy Wettstein reported a suspend/resume memory
corruption bug and extensively documented it here:

http://bugzilla.kernel.org/show_bug.cgi?id=11237

The bug is that the BIOS overwrites 1K of memory at 0xc000 physical,
without registering it in e820 as reserved or giving the kernel any
idea about this.

Detect AMI BIOSen and reserve that 1K.

We paint this bug around with a very broad brush (reserving that 1K on all
AMI BIOS systems), as the bug was extremely hard to find and needed several
weeks and lots of debugging and patching.

The bug was found via the CONFIG_X86_CHECK_BIOS_CORRUPTION=y debug feature,
if similar bugs are suspected then this feature can be enabled on other
systems as well to scan low memory for corrupted memory.

Reported-by: Alan Jenkins <[email protected]>
Reported-by: Andy Wettstein <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/setup.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -578,6 +578,29 @@ static struct x86_quirks default_x86_qui

struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;

+static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
+{
+ printk(KERN_NOTICE
+ "%s detected: BIOS corrupts 0xc000, working it around.\n",
+ d->ident);
+
+ reserve_early(0xc000, 0xc400, "BIOS quirk");
+
+ return 0;
+}
+
+/* List of systems that have known low memory corruption BIOS problems */
+static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
+ {
+ .callback = dmi_low_memory_corruption,
+ .ident = "AMI BIOS",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+ },
+ },
+ {}
+};
+
/*
* Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures
@@ -601,6 +624,8 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif

+ dmi_check_system(bad_bios_dmi_table);
+
early_cpu_init();
early_ioremap_init();

@@ -885,3 +910,5 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
}
+
+

--

2008-11-12 00:29:34

by Greg KH

[permalink] [raw]
Subject: [patch 09/49] hugetlbfs: handle pages higher order than MAX_ORDER

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Andy Whitcroft <[email protected]>

commit 69d177c2fc702d402b17fdca2190d5a7e3ca55c5 upstream

When working with hugepages, hugetlbfs assumes that those hugepages are
smaller than MAX_ORDER. Specifically it assumes that the mem_map is
contigious and uses that to optimise access to the elements of the mem_map
that represent the hugepage. Gigantic pages (such as 16GB pages on
powerpc) by definition are of greater order than MAX_ORDER (larger than
MAX_ORDER_NR_PAGES in size). This means that we can no longer make use of
the buddy alloctor guarentees for the contiguity of the mem_map, which
ensures that the mem_map is at least contigious for maximmally aligned
areas of MAX_ORDER_NR_PAGES pages.

This patch adds new mem_map accessors and iterator helpers which handle
any discontiguity at MAX_ORDER_NR_PAGES boundaries. It then uses these to
implement gigantic page versions of copy_huge_page and clear_huge_page,
and to allow follow_hugetlb_page handle gigantic pages.

Signed-off-by: Andy Whitcroft <[email protected]>
Cc: Jon Tollefson <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Nick Piggin <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>

---
mm/hugetlb.c | 37 ++++++++++++++++++++++++++++++++++++-
mm/internal.h | 28 ++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -353,11 +353,26 @@ static int vma_has_reserves(struct vm_ar
return 0;
}

+static void clear_gigantic_page(struct page *page,
+ unsigned long addr, unsigned long sz)
+{
+ int i;
+ struct page *p = page;
+
+ might_sleep();
+ for (i = 0; i < sz/PAGE_SIZE; i++, p = mem_map_next(p, page, i)) {
+ cond_resched();
+ clear_user_highpage(p, addr + i * PAGE_SIZE);
+ }
+}
static void clear_huge_page(struct page *page,
unsigned long addr, unsigned long sz)
{
int i;

+ if (unlikely(sz > MAX_ORDER_NR_PAGES))
+ return clear_gigantic_page(page, addr, sz);
+
might_sleep();
for (i = 0; i < sz/PAGE_SIZE; i++) {
cond_resched();
@@ -365,12 +380,32 @@ static void clear_huge_page(struct page
}
}

+static void copy_gigantic_page(struct page *dst, struct page *src,
+ unsigned long addr, struct vm_area_struct *vma)
+{
+ int i;
+ struct hstate *h = hstate_vma(vma);
+ struct page *dst_base = dst;
+ struct page *src_base = src;
+ might_sleep();
+ for (i = 0; i < pages_per_huge_page(h); ) {
+ cond_resched();
+ copy_user_highpage(dst, src, addr + i*PAGE_SIZE, vma);
+
+ i++;
+ dst = mem_map_next(dst, dst_base, i);
+ src = mem_map_next(src, src_base, i);
+ }
+}
static void copy_huge_page(struct page *dst, struct page *src,
unsigned long addr, struct vm_area_struct *vma)
{
int i;
struct hstate *h = hstate_vma(vma);

+ if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES))
+ return copy_gigantic_page(dst, src, addr, vma);
+
might_sleep();
for (i = 0; i < pages_per_huge_page(h); i++) {
cond_resched();
@@ -2113,7 +2148,7 @@ int follow_hugetlb_page(struct mm_struct
same_page:
if (pages) {
get_page(page);
- pages[i] = page + pfn_offset;
+ pages[i] = mem_map_offset(page, pfn_offset);
}

if (vmas)
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -54,6 +54,34 @@ static inline unsigned long page_order(s
}

/*
+ * Return the mem_map entry representing the 'offset' subpage within
+ * the maximally aligned gigantic page 'base'. Handle any discontiguity
+ * in the mem_map at MAX_ORDER_NR_PAGES boundaries.
+ */
+static inline struct page *mem_map_offset(struct page *base, int offset)
+{
+ if (unlikely(offset >= MAX_ORDER_NR_PAGES))
+ return pfn_to_page(page_to_pfn(base) + offset);
+ return base + offset;
+}
+
+/*
+ * Iterator over all subpages withing the maximally aligned gigantic
+ * page 'base'. Handle any discontiguity in the mem_map.
+ */
+static inline struct page *mem_map_next(struct page *iter,
+ struct page *base, int offset)
+{
+ if (unlikely((offset & (MAX_ORDER_NR_PAGES - 1)) == 0)) {
+ unsigned long pfn = page_to_pfn(base) + offset;
+ if (!pfn_valid(pfn))
+ return NULL;
+ return pfn_to_page(pfn);
+ }
+ return iter + 1;
+}
+
+/*
* FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
* so all functions starting at paging_init should be marked __init
* in those cases. SPARSEMEM, however, allows for memory hotplug,

--

2008-11-12 00:29:53

by Greg KH

[permalink] [raw]
Subject: [patch 10/49] cciss: fix regression firmware not displayed in procfs

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Mike Miller <[email protected]>

commit 22bece00dc1f28dd3374c55e464c9f02eb642876 upstream

This regression was introduced by commit
6ae5ce8e8d4de666f31286808d2285aa6a50fa40 ("cciss: remove redundant code").

This patch fixes a regression where the controller firmware version is not
displayed in procfs. The previous patch would be called anytime something
changed. This will get called only once for each controller.

Signed-off-by: Mike Miller <[email protected]>
Cc: FUJITA Tomonori <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/block/cciss.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)

--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3403,7 +3403,8 @@ static int __devinit cciss_init_one(stru
int i;
int j = 0;
int rc;
- int dac;
+ int dac, return_code;
+ InquiryData_struct *inq_buff = NULL;

i = alloc_cciss_hba();
if (i < 0)
@@ -3509,6 +3510,25 @@ static int __devinit cciss_init_one(stru
/* Turn the interrupts on so we can service requests */
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);

+ /* Get the firmware version */
+ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
+ if (inq_buff == NULL) {
+ printk(KERN_ERR "cciss: out of memory\n");
+ goto clean4;
+ }
+
+ return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff,
+ sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD);
+ if (return_code == IO_OK) {
+ hba[i]->firm_ver[0] = inq_buff->data_byte[32];
+ hba[i]->firm_ver[1] = inq_buff->data_byte[33];
+ hba[i]->firm_ver[2] = inq_buff->data_byte[34];
+ hba[i]->firm_ver[3] = inq_buff->data_byte[35];
+ } else { /* send command failed */
+ printk(KERN_WARNING "cciss: unable to determine firmware"
+ " version of controller\n");
+ }
+
cciss_procinit(i);

hba[i]->cciss_max_sectors = 2048;
@@ -3519,6 +3539,7 @@ static int __devinit cciss_init_one(stru
return 1;

clean4:
+ kfree(inq_buff);
#ifdef CONFIG_CISS_SCSI_TAPE
kfree(hba[i]->scsi_rejects.complete);
#endif

--

2008-11-12 00:30:17

by Greg KH

[permalink] [raw]
Subject: [patch 11/49] cciss: fix sysfs broken symlink regression

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Mike Miller <[email protected]>

commit 404443081ce5e6f68b5f7eda16c959835ff200c0 upstream

Regression introduced by commit 6ae5ce8e8d4de666f31286808d2285aa6a50fa40
("cciss: remove redundant code").

This patch fixes a broken symlink in sysfs that was introduced by the
above commit. We broke it in 2.6.27-rc on or about 20080804. Some
installers are broken if this symlink does not exist and they may not
detect the logical drives configured on the controller. It does not
require being backported into 2.6.26.x or earlier kernels.

Signed-off-by: Mike Miller <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/block/cciss.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1365,6 +1365,7 @@ static void cciss_add_disk(ctlr_info_t *
disk->first_minor = drv_index << NWD_SHIFT;
disk->fops = &cciss_fops;
disk->private_data = &h->drv[drv_index];
+ disk->driverfs_dev = &h->pdev->dev;

/* Set up queue information */
blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);

--

2008-11-12 00:30:41

by Greg KH

[permalink] [raw]
Subject: [patch 12/49] cciss: new hardware support

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Mike Miller <[email protected]>

commit 77ca7286d10b798e4907af941f29672bf484db77 upstream

cciss: new hardware support

Add support for 2 new SAS/SATA controllers.

Signed-off-by: Mike Miller <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
Documentation/cciss.txt | 2 ++
drivers/block/cciss.c | 4 ++++
2 files changed, 6 insertions(+)

--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -26,6 +26,8 @@ This driver is known to work with the fo
* SA P410i
* SA P411
* SA P812
+ * SA P712m
+ * SA P711m

Detecting drive failures:
-------------------------
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -96,6 +96,8 @@ static const struct pci_device_id cciss_
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B},
{PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
{0,}
@@ -133,6 +135,8 @@ static struct board_type products[] = {
{0x3245103C, "Smart Array P410i", &SA5_access},
{0x3247103C, "Smart Array P411", &SA5_access},
{0x3249103C, "Smart Array P812", &SA5_access},
+ {0x324A103C, "Smart Array P712m", &SA5_access},
+ {0x324B103C, "Smart Array P711m", &SA5_access},
{0xFFFF103C, "Unknown Smart Array", &SA5_access},
};


--

2008-11-12 00:28:06

by Greg KH

[permalink] [raw]
Subject: [patch 05/49] x86: fix CONFIG_X86_RESERVE_LOW_64K=y

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Yinghai Lu <[email protected]>

commit 2216d199b1430d1c0affb1498a9ebdbd9c0de439 upstream

The bad_bios_dmi_table() quirk never triggered because we do DMI setup
too late. Move it a bit earlier.

Also change the CONFIG_X86_RESERVE_LOW_64K quirk to operate on the e820
table directly instead of messing with early reservations - this handles
overlaps (which do occur in this low range of RAM) more gracefully.

Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/setup.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -584,7 +584,8 @@ static int __init dmi_low_memory_corrupt
"%s detected: BIOS may corrupt low RAM, working it around.\n",
d->ident);

- reserve_early_overlap_ok(0x0, 0x10000, "BIOS quirk");
+ e820_update_range(0, 0x10000, E820_RAM, E820_RESERVED);
+ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);

return 0;
}
@@ -633,8 +634,6 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "Command line: %s\n", boot_command_line);
#endif

- dmi_check_system(bad_bios_dmi_table);
-
early_cpu_init();
early_ioremap_init();

@@ -733,6 +732,10 @@ void __init setup_arch(char **cmdline_p)

finish_e820_parsing();

+ dmi_scan_machine();
+
+ dmi_check_system(bad_bios_dmi_table);
+
#ifdef CONFIG_X86_32
probe_roms();
#endif
@@ -815,8 +818,6 @@ void __init setup_arch(char **cmdline_p)
vsmp_init();
#endif

- dmi_scan_machine();
-
io_delay_init();

/*

--

2008-11-12 00:30:57

by Greg KH

[permalink] [raw]
Subject: [patch 13/49] md: linear: Fix a division by zero bug for very small arrays.

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Andre Noll <[email protected]>

commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream

Date: Thu, 6 Nov 2008 19:41:24 +1100
Subject: [patch 13/49] md: linear: Fix a division by zero bug for very small arrays.

We currently oops with a divide error on starting a linear software
raid array consisting of at least two very small (< 500K) devices.

The bug is caused by the calculation of the hash table size which
tries to compute sector_div(sz, base) with "base" being zero due to
the small size of the component devices of the array.

Fix this by requiring the hash spacing to be at least one which
implies that also "base" is non-zero.

This bug has existed since about 2.6.14.

Signed-off-by: Andre Noll <[email protected]>
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/linear.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_

min_spacing = conf->array_sectors / 2;
sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
+ if (min_spacing == 0)
+ min_spacing = 1;

/* min_spacing is the minimum spacing that will fit the hash
* table in one PAGE. This may be much smaller than needed.

--

2008-11-12 00:31:26

by Greg KH

[permalink] [raw]
Subject: [patch 14/49] md: fix bug in raid10 recovery.

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Neil Brown <[email protected]>

commit a53a6c85756339f82ff19e001e90cfba2d6299a8 upstream

Adding a spare to a raid10 doesn't cause recovery to start.
This is due to an silly type in
commit 6c2fce2ef6b4821c21b5c42c7207cb9cf8c87eda
and so is a bug in 2.6.27 and .28-rc.

Thanks to Thomas Backlund for bisecting to find this.

Cc: Thomas Backlund <[email protected]>
Cc: George Spelvin <[email protected]>
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/md/raid10.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1132,7 +1132,7 @@ static int raid10_add_disk(mddev_t *mdde
if (!enough(conf))
return -EINVAL;

- if (rdev->raid_disk)
+ if (rdev->raid_disk >= 0)
first = last = rdev->raid_disk;

if (rdev->saved_raid_disk >= 0 &&

--

2008-11-12 00:31:43

by Greg KH

[permalink] [raw]
Subject: [patch 15/49] JFFS2: fix race condition in jffs2_lzo_compress()

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Geert Uytterhoeven <[email protected]>

commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream

deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
compressed data from lzo_compress_buf. Correct this by moving the mutex
unlock after the copy.

In addition, document what deflate_mutex actually protects.

Signed-off-by: Geert Uytterhoeven <[email protected]>
Acked-by: Richard Purdie <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/jffs2/compr_lzo.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

--- a/fs/jffs2/compr_lzo.c
+++ b/fs/jffs2/compr_lzo.c
@@ -19,7 +19,7 @@

static void *lzo_mem;
static void *lzo_compress_buf;
-static DEFINE_MUTEX(deflate_mutex);
+static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */

static void free_workspace(void)
{
@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c

mutex_lock(&deflate_mutex);
ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
- mutex_unlock(&deflate_mutex);
-
if (ret != LZO_E_OK)
- return -1;
+ goto fail;

if (compress_size > *dstlen)
- return -1;
+ goto fail;

memcpy(cpage_out, lzo_compress_buf, compress_size);
- *dstlen = compress_size;
+ mutex_unlock(&deflate_mutex);

+ *dstlen = compress_size;
return 0;
+
+ fail:
+ mutex_unlock(&deflate_mutex);
+ return -1;
}

static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,

--

2008-11-12 00:32:01

by Greg KH

[permalink] [raw]
Subject: [patch 16/49] JFFS2: Fix lack of locking in thread_should_wake()

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: David Woodhouse <[email protected]>

commit b27cf88e9592953ae292d05324887f2f44979433 upstream

The thread_should_wake() function trawls through the list of 'very
dirty' eraseblocks, determining whether the background GC thread should
wake. Doing this without holding the appropriate locks is a bad idea.

OLPC Trac #8615

Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/jffs2/background.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(
for (;;) {
allow_signal(SIGHUP);
again:
+ spin_lock(&c->erase_completion_lock);
if (!jffs2_thread_should_wake(c)) {
set_current_state (TASK_INTERRUPTIBLE);
+ spin_unlock(&c->erase_completion_lock);
D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
- matter - We don't care if we miss a wakeup, because the GC thread
- is only an optimisation anyway. */
schedule();
- }
+ } else
+ spin_unlock(&c->erase_completion_lock);
+

/* This thread is purely an optimisation. But if it runs when
other things could be running, it actually makes things a

--

2008-11-12 00:32:29

by Greg KH

[permalink] [raw]
Subject: [patch 17/49] ARM: xsc3: fix xsc3_l2_inv_range


2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Dan Williams <[email protected]>

commit c7cf72dcadbe39c2077b32460f86c9f8167be3be upstream

When 'start' and 'end' are less than a cacheline apart and 'start' is
unaligned we are done after cleaning and invalidating the first
cacheline. So check for (start < end) which will not walk off into
invalid address ranges when (start > end).

This issue was caught by drivers/dma/dmatest.

2.6.27 is susceptible.

Cc: <[email protected]>
Cc: Haavard Skinnemoen <[email protected]>
Cc: Lothar Wafmann <[email protected]>
Cc: Lennert Buytenhek <[email protected]>
Cc: Eric Miao <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/arm/mm/cache-xsc3l2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -97,7 +97,7 @@ static void xsc3_l2_inv_range(unsigned l
/*
* Clean and invalidate partial last cache line.
*/
- if (end & (CACHE_LINE_SIZE - 1)) {
+ if (start < end && (end & (CACHE_LINE_SIZE - 1))) {
xsc3_l2_clean_pa(end & ~(CACHE_LINE_SIZE - 1));
xsc3_l2_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
end &= ~(CACHE_LINE_SIZE - 1);
@@ -106,7 +106,7 @@ static void xsc3_l2_inv_range(unsigned l
/*
* Invalidate all full cache lines between 'start' and 'end'.
*/
- while (start != end) {
+ while (start < end) {
xsc3_l2_inv_pa(start);
start += CACHE_LINE_SIZE;
}

--

2008-11-12 00:33:14

by Greg KH

[permalink] [raw]
Subject: [patch 18/49] MTD: Fix cfi_send_gen_cmd handling of x16 devices in x8 mode (v4)


2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Eric W. Biederman <[email protected]>

commit 467622ef2acb01986eab37ef96c3632b3ea35999 upstream

For "unlock" cycles to 16bit devices in 8bit compatibility mode we need
to use the byte addresses 0xaaa and 0x555. These effectively match
the word address 0x555 and 0x2aa, except the latter has its low bit set.

Most chips don't care about the value of the 'A-1' pin in x8 mode,
but some -- like the ST M29W320D -- do. So we need to be careful to
set it where appropriate.

cfi_send_gen_cmd is only ever passed addresses where the low byte
is 0x00, 0x55 or 0xaa. Of those, only addresses ending 0xaa are
affected by this patch, by masking in the extra low bit when the device
is known to be in compatibility mode.

[dwmw2: Do it only when (cmd_ofs & 0xff) == 0xaa]
v4: Fix stupid typo in cfi_build_cmd_addr that failed to compile
I'm writing this patch way to late at night.
v3: Bring all of the work back into cfi_build_cmd_addr
including calling of map_bankwidth(map) and cfi_interleave(cfi)
So every caller doesn't need to.
v2: Only modified the address if we our device_type is larger than our
bus width.

Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/mtd/chips/cfi_cmdset_0002.c | 13 -------------
drivers/mtd/chips/jedec_probe.c | 10 ++++------
include/linux/mtd/cfi.h | 22 +++++++++++++++++++---
3 files changed, 23 insertions(+), 22 deletions(-)

--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -362,19 +362,6 @@ struct mtd_info *cfi_cmdset_0002(struct
/* Set the default CFI lock/unlock addresses */
cfi->addr_unlock1 = 0x555;
cfi->addr_unlock2 = 0x2aa;
- /* Modify the unlock address if we are in compatibility mode */
- if ( /* x16 in x8 mode */
- ((cfi->device_type == CFI_DEVICETYPE_X8) &&
- (cfi->cfiq->InterfaceDesc ==
- CFI_INTERFACE_X8_BY_X16_ASYNC)) ||
- /* x32 in x16 mode */
- ((cfi->device_type == CFI_DEVICETYPE_X16) &&
- (cfi->cfiq->InterfaceDesc ==
- CFI_INTERFACE_X16_BY_X32_ASYNC)))
- {
- cfi->addr_unlock1 = 0xaaa;
- cfi->addr_unlock2 = 0x555;
- }

} /* CFI mode */
else if (cfi->cfi_mode == CFI_MODE_JEDEC) {
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct
* several first banks can contain 0x7f instead of actual ID
*/
do {
- uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8),
- cfi_interleave(cfi),
- cfi->device_type);
+ uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
mask = (1 << (cfi->device_type * 8)) - 1;
result = map_read(map, base + ofs);
bank++;
@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct m
{
map_word result;
unsigned long mask;
- u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type);
+ u32 ofs = cfi_build_cmd_addr(1, map, cfi);
mask = (1 << (cfi->device_type * 8)) -1;
result = map_read(map, base + ofs);
return result.x[0] & mask;
@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_i

}
/* Ensure the unlock addresses we try stay inside the map */
- probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type);
- probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type);
+ probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi);
+ probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi);
if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
((base + probe_offset2 + map_bankwidth(map)) >= map->size))
goto retry;
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -281,9 +281,25 @@ struct cfi_private {
/*
* Returns the command address according to the given geometry.
*/
-static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type)
+static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
+ struct map_info *map, struct cfi_private *cfi)
{
- return (cmd_ofs * type) * interleave;
+ unsigned bankwidth = map_bankwidth(map);
+ unsigned interleave = cfi_interleave(cfi);
+ unsigned type = cfi->device_type;
+ uint32_t addr;
+
+ addr = (cmd_ofs * type) * interleave;
+
+ /* Modify the unlock address if we are in compatiblity mode.
+ * For 16bit devices on 8 bit busses
+ * and 32bit devices on 16 bit busses
+ * set the low bit of the alternating bit sequence of the address.
+ */
+ if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa))
+ addr |= (type >> 1)*interleave;
+
+ return addr;
}

/*
@@ -429,7 +445,7 @@ static inline uint32_t cfi_send_gen_cmd(
int type, map_word *prev_val)
{
map_word val;
- uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
+ uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);

val = cfi_build_cmd(cmd, map, cfi);


--

2008-11-12 00:33:32

by Greg KH

[permalink] [raw]
Subject: [patch 19/49] x86: dont use tsc_khz to calculate lpj if notsc is passed

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Alok Kataria <[email protected]>

commit 70de9a97049e0ba79dc040868564408d5ce697f9 upstream

Impact: fix udelay when "notsc" boot parameter is passed

With notsc passed on commandline, tsc may not be used for
udelays, make sure that we do not use tsc_khz to calculate
the lpj value in such cases.

Reported-by: Bartlomiej Zolnierkiewicz <[email protected]>
Signed-off-by: Alok N Kataria <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/x86/kernel/tsc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -639,10 +639,6 @@ void __init tsc_init(void)
cpu_khz = calibrate_cpu();
#endif

- lpj = ((u64)tsc_khz * 1000);
- do_div(lpj, HZ);
- lpj_fine = lpj;
-
printk("Detected %lu.%03lu MHz processor.\n",
(unsigned long)cpu_khz / 1000,
(unsigned long)cpu_khz % 1000);
@@ -662,6 +658,10 @@ void __init tsc_init(void)
/* now allow native_sched_clock() to use rdtsc */
tsc_disabled = 0;

+ lpj = ((u64)tsc_khz * 1000);
+ do_div(lpj, HZ);
+ lpj_fine = lpj;
+
use_tsc_delay();
/* Check and install the TSC clocksource */
dmi_check_system(bad_tsc_dmi_table);

--

2008-11-12 00:33:50

by Greg KH

[permalink] [raw]
Subject: [patch 20/49] net: unix: fix inflight counting bug in garbage collector

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Miklos Szeredi <[email protected]>

commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream

Previously I assumed that the receive queues of candidates don't
change during the GC. This is only half true, nothing can be received
from the queues (see comment in unix_gc()), but buffers could be added
through the other half of the socket pair, which may still have file
descriptors referring to it.

This can result in inc_inflight_move_tail() erronously increasing the
"inflight" counter for a unix socket for which dec_inflight() wasn't
previously called. This in turn can trigger the "BUG_ON(total_refs <
inflight_refs)" in a later garbage collection run.

Fix this by only manipulating the "inflight" counter for sockets which
are candidates themselves. Duplicating the file references in
unix_attach_fds() is also needed to prevent a socket becoming a
candidate for GC while the skb that contains it is not yet queued.

Reported-by: Andrea Bittau <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
include/net/af_unix.h | 1 +
net/unix/af_unix.c | 31 ++++++++++++++++++++++++-------
net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------
3 files changed, 62 insertions(+), 19 deletions(-)

--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -54,6 +54,7 @@ struct unix_sock {
atomic_long_t inflight;
spinlock_t lock;
unsigned int gc_candidate : 1;
+ unsigned int gc_maybe_cycle : 1;
wait_queue_head_t peer_wait;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1300,14 +1300,23 @@ static void unix_destruct_fds(struct sk_
sock_wfree(skb);
}

-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
{
int i;
+
+ /*
+ * Need to duplicate file references for the sake of garbage
+ * collection. Otherwise a socket in the fps might become a
+ * candidate for GC while the skb is not yet queued.
+ */
+ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
+ if (!UNIXCB(skb).fp)
+ return -ENOMEM;
+
for (i=scm->fp->count-1; i>=0; i--)
unix_inflight(scm->fp->fp[i]);
- UNIXCB(skb).fp = scm->fp;
skb->destructor = unix_destruct_fds;
- scm->fp = NULL;
+ return 0;
}

/*
@@ -1366,8 +1375,11 @@ static int unix_dgram_sendmsg(struct kio
goto out;

memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
- if (siocb->scm->fp)
- unix_attach_fds(siocb->scm, skb);
+ if (siocb->scm->fp) {
+ err = unix_attach_fds(siocb->scm, skb);
+ if (err)
+ goto out_free;
+ }
unix_get_secdata(siocb->scm, skb);

skb_reset_transport_header(skb);
@@ -1536,8 +1548,13 @@ static int unix_stream_sendmsg(struct ki
size = min_t(int, size, skb_tailroom(skb));

memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
- if (siocb->scm->fp)
- unix_attach_fds(siocb->scm, skb);
+ if (siocb->scm->fp) {
+ err = unix_attach_fds(siocb->scm, skb);
+ if (err) {
+ kfree_skb(skb);
+ goto out_err;
+ }
+ }

if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
kfree_skb(skb);
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x
*/
struct sock *sk = unix_get_socket(*fp++);
if (sk) {
- hit = true;
- func(unix_sk(sk));
+ struct unix_sock *u = unix_sk(sk);
+
+ /*
+ * Ignore non-candidates, they could
+ * have been added to the queues after
+ * starting the garbage collection
+ */
+ if (u->gc_candidate) {
+ hit = true;
+ func(u);
+ }
}
}
if (hit && hitlist != NULL) {
@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc
{
atomic_long_inc(&u->inflight);
/*
- * If this is still a candidate, move it to the end of the
- * list, so that it's checked even if it was already passed
- * over
+ * If this still might be part of a cycle, move it to the end
+ * of the list, so that it's checked even if it was already
+ * passed over
*/
- if (u->gc_candidate)
+ if (u->gc_maybe_cycle)
list_move_tail(&u->link, &gc_candidates);
}

@@ -267,6 +276,7 @@ void unix_gc(void)
struct unix_sock *next;
struct sk_buff_head hitlist;
struct list_head cursor;
+ LIST_HEAD(not_cycle_list);

spin_lock(&unix_gc_lock);

@@ -282,10 +292,14 @@ void unix_gc(void)
*
* Holding unix_gc_lock will protect these candidates from
* being detached, and hence from gaining an external
- * reference. This also means, that since there are no
- * possible receivers, the receive queues of these sockets are
- * static during the GC, even though the dequeue is done
- * before the detach without atomicity guarantees.
+ * reference. Since there are no possible receivers, all
+ * buffers currently on the candidates' queues stay there
+ * during the garbage collection.
+ *
+ * We also know that no new candidate can be added onto the
+ * receive queues. Other, non candidate sockets _can_ be
+ * added to queue, so we must make sure only to touch
+ * candidates.
*/
list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
long total_refs;
@@ -299,6 +313,7 @@ void unix_gc(void)
if (total_refs == inflight_refs) {
list_move_tail(&u->link, &gc_candidates);
u->gc_candidate = 1;
+ u->gc_maybe_cycle = 1;
}
}

@@ -325,14 +340,24 @@ void unix_gc(void)
list_move(&cursor, &u->link);

if (atomic_long_read(&u->inflight) > 0) {
- list_move_tail(&u->link, &gc_inflight_list);
- u->gc_candidate = 0;
+ list_move_tail(&u->link, &not_cycle_list);
+ u->gc_maybe_cycle = 0;
scan_children(&u->sk, inc_inflight_move_tail, NULL);
}
}
list_del(&cursor);

/*
+ * not_cycle_list contains those sockets which do not make up a
+ * cycle. Restore these to the inflight list.
+ */
+ while (!list_empty(&not_cycle_list)) {
+ u = list_entry(not_cycle_list.next, struct unix_sock, link);
+ u->gc_candidate = 0;
+ list_move_tail(&u->link, &gc_inflight_list);
+ }
+
+ /*
* Now gc_candidates contains only garbage. Restore original
* inflight counters for these as well, and remove the skbuffs
* which are creating the cycle(s).

--

2008-11-12 00:34:17

by Greg KH

[permalink] [raw]
Subject: [patch 21/49] r8169: get ethtool settings through the generic mii helper

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Francois Romieu <[email protected]>

Upstream as ccdffb9a88b2907b159538d7bfd6256621db4f84 (post 2.6.27).

It avoids to report unsupported link capabilities with
the fast-ethernet only 8101/8102.

Signed-off-by: Francois Romieu <[email protected]>
Tested-by: Martin Capitanio <[email protected]>
Fixed-by: Ivan Vecera <[email protected]>
Cc: Edward Hsu <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/r8169.c | 97 ++++++++++++++++++++++++----------------------------
1 file changed, 45 insertions(+), 52 deletions(-)

--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -370,8 +370,9 @@ struct ring_info {
};

enum features {
- RTL_FEATURE_WOL = (1 << 0),
- RTL_FEATURE_MSI = (1 << 1),
+ RTL_FEATURE_WOL = (1 << 0),
+ RTL_FEATURE_MSI = (1 << 1),
+ RTL_FEATURE_GMII = (1 << 2),
};

struct rtl8169_private {
@@ -406,13 +407,15 @@ struct rtl8169_private {
struct vlan_group *vlgrp;
#endif
int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
void (*phy_reset_enable)(void __iomem *);
void (*hw_start)(struct net_device *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
struct delayed_work task;
unsigned features;
+
+ struct mii_if_info mii;
};

MODULE_AUTHOR("Realtek and the Linux r8169 crew <[email protected]>");
@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioadd
return value;
}

+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
+ int val)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ mdio_write(ioaddr, location, val);
+}
+
+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ return mdio_read(ioaddr, location);
+}
+
static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
{
RTL_W16(IntrMask, 0x0000);
@@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rt

#endif

-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
@@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_

cmd->speed = SPEED_1000;
cmd->duplex = DUPLEX_FULL; /* Always set */
+
+ return 0;
}

-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
- u8 status;
-
- cmd->supported = SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_TP;
-
- cmd->autoneg = 1;
- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
-
- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
- cmd->advertising |= ADVERTISED_10baseT_Half;
- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
- cmd->advertising |= ADVERTISED_10baseT_Full;
- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
- cmd->advertising |= ADVERTISED_100baseT_Half;
- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
- cmd->advertising |= ADVERTISED_100baseT_Full;
- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
- cmd->advertising |= ADVERTISED_1000baseT_Full;
-
- status = RTL_R8(PHYstatus);
-
- if (status & _1000bpsF)
- cmd->speed = SPEED_1000;
- else if (status & _100bps)
- cmd->speed = SPEED_100;
- else if (status & _10bps)
- cmd->speed = SPEED_10;
-
- if (status & TxFlowCtrl)
- cmd->advertising |= ADVERTISED_Asym_Pause;
- if (status & RxFlowCtrl)
- cmd->advertising |= ADVERTISED_Pause;

- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
- DUPLEX_FULL : DUPLEX_HALF;
+ return mii_ethtool_gset(&tp->mii, cmd);
}

static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct rtl8169_private *tp = netdev_priv(dev);
unsigned long flags;
+ int rc;

spin_lock_irqsave(&tp->lock, flags);

- tp->get_settings(dev, cmd);
+ rc = tp->get_settings(dev, cmd);

spin_unlock_irqrestore(&tp->lock, flags);
- return 0;
+ return rc;
}

static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
unsigned int align;
u16 intr_event;
u16 napi_event;
- unsigned msi;
+ unsigned features;
} rtl_cfg_infos [] = {
[RTL_CFG_0] = {
.hw_start = rtl_hw_start_8169,
@@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .msi = 0
+ .features = RTL_FEATURE_GMII
},
[RTL_CFG_1] = {
.hw_start = rtl_hw_start_8168,
@@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
- .msi = RTL_FEATURE_MSI
+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
},
[RTL_CFG_2] = {
.hw_start = rtl_hw_start_8101,
@@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
- .msi = RTL_FEATURE_MSI
+ .features = RTL_FEATURE_MSI
}
};

@@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_d
u8 cfg2;

cfg2 = RTL_R8(Config2) & ~MSIEnable;
- if (cfg->msi) {
+ if (cfg->features & RTL_FEATURE_MSI) {
if (pci_enable_msi(pdev)) {
dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
} else {
@@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
const unsigned int region = cfg->region;
struct rtl8169_private *tp;
+ struct mii_if_info *mii;
struct net_device *dev;
void __iomem *ioaddr;
unsigned int i;
@@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, c
tp->pci_dev = pdev;
tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);

+ mii = &tp->mii;
+ mii->dev = dev;
+ mii->mdio_read = rtl_mdio_read;
+ mii->mdio_write = rtl_mdio_write;
+ mii->phy_id_mask = 0x1f;
+ mii->reg_num_mask = 0x1f;
+ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
+
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pci_enable_device(pdev);
if (rc < 0) {

--

2008-11-12 00:34:35

by Greg KH

[permalink] [raw]
Subject: [patch 22/49] r8169: fix RxMissed register access

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Francois Romieu <[email protected]>

Upstream as 523a609496dbc3897e530db2a2f27650d125ea00

- the register is defined for the 8169 chipset only and there is
no 8169 beyond RTL_GIGA_MAC_VER_06.
- only the lower 3 bytes of the register are valid

Fixes:
1. http://bugzilla.kernel.org/show_bug.cgi?id=10180
2. http://bugzilla.kernel.org/show_bug.cgi?id=11062 (bits of)

Tested by Hermann Gausterer and Adam Huffman.

Signed-off-by: Francois Romieu <[email protected]>
Cc: Edward Hsu <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/r8169.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)

--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2092,8 +2092,6 @@ static void rtl_hw_start_8168(struct net

RTL_R8(IntrMask);

- RTL_W32(RxMissed, 0);
-
rtl_set_rx_mode(dev);

RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -2136,8 +2134,6 @@ static void rtl_hw_start_8101(struct net

RTL_R8(IntrMask);

- RTL_W32(RxMissed, 0);
-
rtl_set_rx_mode(dev);

RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -2915,6 +2911,17 @@ static int rtl8169_poll(struct napi_stru
return work_done;
}

+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
+{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+ return;
+
+ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
+ RTL_W32(RxMissed, 0);
+}
+
static void rtl8169_down(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -2932,9 +2939,7 @@ core_down:

rtl8169_asic_down(ioaddr);

- /* Update the error counts. */
- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);

spin_unlock_irq(&tp->lock);

@@ -3056,8 +3061,7 @@ static struct net_device_stats *rtl8169_

if (netif_running(dev)) {
spin_lock_irqsave(&tp->lock, flags);
- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irqrestore(&tp->lock, flags);
}

@@ -3082,8 +3086,7 @@ static int rtl8169_suspend(struct pci_de

rtl8169_asic_down(ioaddr);

- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
- RTL_W32(RxMissed, 0);
+ rtl8169_rx_missed(dev, ioaddr);

spin_unlock_irq(&tp->lock);


--

2008-11-12 00:34:54

by Greg KH

[permalink] [raw]
Subject: [patch 23/49] r8169: wake up the PHY of the 8168

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Francois Romieu <[email protected]>

Upstream as a2de6b89b74b28052e293fdb39975a5a03c432e0

This is typically needed when some other OS puts the PHY
to sleep due to the disabling of WOL options in the BIOS
of the system.

Signed-off-by: Francois Romieu <[email protected]>
Tested-by: Chiaki Ishikawa <[email protected]>
Cc: Edward Hsu <[email protected]>
Cc: RyanKao <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/r8169.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -740,9 +740,13 @@ static int rtl8169_set_speed_xmii(struct

auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;

- if ((tp->mac_version == RTL_GIGA_MAC_VER_12) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
- /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
+ if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+ (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
+ /*
+ * Wake up the PHY.
+ * Vendor specific (0x1f) and reserved (0x0e) MII registers.
+ */
mdio_write(ioaddr, 0x1f, 0x0000);
mdio_write(ioaddr, 0x0e, 0x0000);
}

--

2008-11-12 00:35:22

by Greg KH

[permalink] [raw]
Subject: [patch 24/49] I/OAT: fix channel resources free for not allocated channels

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Maciej Sosnowski <[email protected]>

commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream

If the ioatdma driver is loaded but not used it does not allocate descriptors.
Before it frees channel resources it should first be sure
that they have been previously allocated.

Signed-off-by: Maciej Sosnowski <[email protected]>
Tested-by: Tom Picard <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/dma/ioat_dma.c | 7 +++++++
1 file changed, 7 insertions(+)

--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -801,6 +801,12 @@ static void ioat_dma_free_chan_resources
struct ioat_desc_sw *desc, *_desc;
int in_use_descs = 0;

+ /* Before freeing channel resources first check
+ * if they have been previously allocated for this channel.
+ */
+ if (ioat_chan->desccount == 0)
+ return;
+
tasklet_disable(&ioat_chan->cleanup_task);
ioat_dma_memcpy_cleanup(ioat_chan);

@@ -863,6 +869,7 @@ static void ioat_dma_free_chan_resources
ioat_chan->last_completion = ioat_chan->completion_addr = 0;
ioat_chan->pending = 0;
ioat_chan->dmacount = 0;
+ ioat_chan->desccount = 0;
ioat_chan->watchdog_completion = 0;
ioat_chan->last_compl_desc_addr_hw = 0;
ioat_chan->watchdog_tcp_cookie =

--

2008-11-12 00:35:51

by Greg KH

[permalink] [raw]
Subject: [patch 25/49] I/OAT: fix dma_pin_iovec_pages() error handling

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Maciej Sosnowski <[email protected]>

commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream

Error handling needs to be modified in dma_pin_iovec_pages().
It should return NULL instead of ERR_PTR
(pinned_list is checked for NULL in tcp_recvmsg() to determine
if iovec pages have been successfully pinned down).
In case of error for the first iovec,
local_list->nr_iovecs needs to be initialized.

Signed-off-by: Maciej Sosnowski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/dma/iovlock.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)

--- a/drivers/dma/iovlock.c
+++ b/drivers/dma/iovlock.c
@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa
int nr_iovecs = 0;
int iovec_len_used = 0;
int iovec_pages_used = 0;
- long err;

/* don't pin down non-user-based iovecs */
if (segment_eq(get_fs(), KERNEL_DS))
@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa
local_list = kmalloc(sizeof(*local_list)
+ (nr_iovecs * sizeof (struct dma_page_list))
+ (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
- if (!local_list) {
- err = -ENOMEM;
+ if (!local_list)
goto out;
- }

/* list of pages starts right after the page list array */
pages = (struct page **) &local_list->page_list[nr_iovecs];

+ local_list->nr_iovecs = 0;
+
for (i = 0; i < nr_iovecs; i++) {
struct dma_page_list *page_list = &local_list->page_list[i];

len -= iov[i].iov_len;

- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
- err = -EFAULT;
+ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
goto unpin;
- }

page_list->nr_pages = num_pages_spanned(&iov[i]);
page_list->base_address = iov[i].iov_base;
@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa
NULL);
up_read(&current->mm->mmap_sem);

- if (ret != page_list->nr_pages) {
- err = -ENOMEM;
+ if (ret != page_list->nr_pages)
goto unpin;
- }

local_list->nr_iovecs = i + 1;
}
@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa
unpin:
dma_unpin_iovec_pages(local_list);
out:
- return ERR_PTR(err);
+ return NULL;
}

void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)

--

2008-11-12 00:36:15

by Greg KH

[permalink] [raw]
Subject: [patch 26/49] I/OAT: fix async_tx.callback checking

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Maciej Sosnowski <[email protected]>

commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream

async_tx.callback should be checked for the first
not the last descriptor in the chain.

Signed-off-by: Maciej Sosnowski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/dma/ioat_dma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -519,7 +519,7 @@ static dma_cookie_t ioat1_tx_submit(stru
}

hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
- if (new->async_tx.callback) {
+ if (first->async_tx.callback) {
hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
if (first != new) {
/* move callback into to last desc */
@@ -611,7 +611,7 @@ static dma_cookie_t ioat2_tx_submit(stru
}

hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
- if (new->async_tx.callback) {
+ if (first->async_tx.callback) {
hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
if (first != new) {
/* move callback into to last desc */

--

2008-11-12 00:36:37

by Greg KH

[permalink] [raw]
Subject: [patch 27/49] dca: fixup initialization dependency

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Dan Williams <[email protected]>

commit 1207e795568a368928dfd23d6817e47f2e8097e3 upstream

Mark dca_init as a subsys_initcall since it needs to be ready to go
before dependent drivers start registering themselves.

Reported-and-tested-by: Mark Rustad <[email protected]>
Acked-by: Maciej Sosnowski <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/dca/dca-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/dca/dca-core.c
+++ b/drivers/dca/dca-core.c
@@ -270,6 +270,6 @@ static void __exit dca_exit(void)
dca_sysfs_exit();
}

-module_init(dca_init);
+subsys_initcall(dca_init);
module_exit(dca_exit);


--

2008-11-12 00:37:22

by Greg KH

[permalink] [raw]
Subject: [patch 29/49] iwlwifi: allow association on radar channel in power save

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Emmanuel Grumbach <[email protected]>

commit c90a74bae10dc2a4677d1bd06b6400db229d3e1e upstream

This patch disables power save upon association and enables it back
after association. This allows to associate to AP on a radar channel
if power save is enabled.

Radar and passive channels are not allowed for TX (required for association)
unless RX is received but PS may close the radio and no RX will be received
effectively failing association.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 24 +++++++++++++++----
drivers/net/wireless/iwlwifi/iwl-dev.h | 1
drivers/net/wireless/iwlwifi/iwl-power.c | 39 ++++++++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-power.h | 4 ++-
4 files changed, 61 insertions(+), 7 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2486,6 +2486,7 @@ static void iwl4965_post_associate(struc
if (!priv->vif || !priv->is_open)
return;

+ iwl_power_cancel_timeout(priv);
iwl_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);
@@ -2550,10 +2551,6 @@ static void iwl4965_post_associate(struc
break;
}

- /* Enable Rx differential gain and sensitivity calibrations */
- iwl_chain_noise_reset(priv);
- priv->start_calib = 1;
-
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1;

@@ -2561,7 +2558,12 @@ static void iwl4965_post_associate(struc
iwl_activate_qos(priv, 0);
spin_unlock_irqrestore(&priv->lock, flags);

- iwl_power_update_mode(priv, 0);
+ iwl_power_enable_management(priv);
+
+ /* Enable Rx differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
@@ -3548,6 +3550,16 @@ static void iwl4965_mac_reset_tsf(struct
/* Per mac80211.h: This is only used in IBSS mode... */
if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {

+ /* switch to CAM during association period.
+ * the ucode will block any association/authentication
+ * frome during assiciation period if it can not hear
+ * the AP because of PM. the timer enable PM back is
+ * association do not complete
+ */
+ if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
+ IEEE80211_CHAN_RADAR))
+ iwl_power_disable_management(priv, 3000);
+
IWL_DEBUG_MAC80211("leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
@@ -4085,6 +4097,7 @@ static void iwl_setup_deferred_work(stru
/* FIXME : remove when resolved PENDING */
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
iwl_setup_scan_deferred_work(priv);
+ iwl_setup_power_deferred_work(priv);

if (priv->cfg->ops->lib->setup_deferred_work)
priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -4104,6 +4117,7 @@ static void iwl_cancel_deferred_work(str

cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
+ cancel_delayed_work_sync(&priv->set_power_save);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1047,6 +1047,7 @@ struct iwl_priv {

struct tasklet_struct irq_tasklet;

+ struct delayed_work set_power_save;
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -324,7 +324,7 @@ EXPORT_SYMBOL(iwl_power_update_mode);
* this will be usefull for rate scale to disable PM during heavy
* Tx/Rx activities
*/
-int iwl_power_disable_management(struct iwl_priv *priv)
+int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
{
u16 prev_mode;
int ret = 0;
@@ -337,6 +337,11 @@ int iwl_power_disable_management(struct
ret = iwl_power_update_mode(priv, 0);
priv->power_data.power_disabled = 1;
priv->power_data.user_power_setting = prev_mode;
+ cancel_delayed_work(&priv->set_power_save);
+ if (ms)
+ queue_delayed_work(priv->workqueue, &priv->set_power_save,
+ msecs_to_jiffies(ms));
+

return ret;
}
@@ -431,3 +436,35 @@ int iwl_power_temperature_change(struct
return ret;
}
EXPORT_SYMBOL(iwl_power_temperature_change);
+
+static void iwl_bg_set_power_save(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work,
+ struct iwl_priv, set_power_save.work);
+ IWL_DEBUG(IWL_DL_STATE, "update power\n");
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ /* on starting association we disable power managment
+ * until association, if association failed then this
+ * timer will expire and enable PM again.
+ */
+ if (!iwl_is_associated(priv))
+ iwl_power_enable_management(priv);
+
+ mutex_unlock(&priv->mutex);
+}
+void iwl_setup_power_deferred_work(struct iwl_priv *priv)
+{
+ INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
+}
+EXPORT_SYMBOL(iwl_setup_power_deferred_work);
+
+void iwl_power_cancel_timeout(struct iwl_priv *priv)
+{
+ cancel_delayed_work(&priv->set_power_save);
+}
+EXPORT_SYMBOL(iwl_power_cancel_timeout);
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -78,8 +78,10 @@ struct iwl_power_mgr {
u8 power_disabled; /* flag to disable using power saving level */
};

+void iwl_setup_power_deferred_work(struct iwl_priv *priv);
+void iwl_power_cancel_timeout(struct iwl_priv *priv);
int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
-int iwl_power_disable_management(struct iwl_priv *priv);
+int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);

--

2008-11-12 00:36:55

by Greg KH

[permalink] [raw]
Subject: [patch 28/49] iwlwifi: allow consecutive scans in unassociated state

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Ron Rindjunsky <[email protected]>

commit 681c0050ea3ac2e90c83d5af397d73eed848a372 upstream

This patch allows consecutive scans requests when driver is in
unassociated state.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Esti Kummer <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3214,13 +3214,15 @@ static int iwl4965_mac_hw_scan(struct ie

/* we don't schedule scan within next_scan_jiffies period */
if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
+ time_after(priv->next_scan_jiffies, jiffies)) {
+ IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
rc = -EAGAIN;
goto out_unlock;
}
/* if we just finished scan ask for delay */
- if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
- IWL_DELAY_NEXT_SCAN, jiffies)) {
+ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
+ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+ IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
rc = -EAGAIN;
goto out_unlock;
}

--

2008-11-12 00:37:51

by Greg KH

[permalink] [raw]
Subject: [patch 30/49] iwlwifi: remove HT flags from RXON when not in HT anymore

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Emmanuel Grumbach <[email protected]>

commit 42eb7c644afcdbcd7eac4d862046230856fbf531 upstream.

This patch removes the HT flags from RXON when moving from HT to legacy.
This avoids keeping those flags set and possibly miss configuring firmware.

If we are configured in HT, fat channel: channel 1 above, and move later
to legacy channel 11, we need to clear the FAT channel control flags in
RXON. If we don't, the firmware will understand this as channel 11 above
which is not possible due to regulatory constraints, leading to firmware
crash.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Reviewed-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +--
drivers/net/wireless/iwlwifi/iwl-core.c | 8 +++++++-
2 files changed, 8 insertions(+), 3 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2504,8 +2504,7 @@ static void iwl4965_post_associate(struc

priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;

- if (priv->current_ht_config.is_ht)
- iwl_set_rxon_ht(priv, &priv->current_ht_config);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);

iwl_set_rxon_chain(priv);
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *pr
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
u32 val;

- if (!ht_info->is_ht)
+ if (!ht_info->is_ht) {
+ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
+ RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
+ RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
+ RXON_FLG_FAT_PROT_MSK |
+ RXON_FLG_HT_PROT_MSK);
return;
+ }

/* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
if (iwl_is_fat_tx_allowed(priv, NULL))

--

2008-11-12 00:38:15

by Greg KH

[permalink] [raw]
Subject: [patch 31/49] iwlwifi: dont fail if scan is issued too early

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Tomas Winkler <[email protected]>

commit 8d09a5e1c36d0dec5728e6c8b0bb5412de09b27b upstream

This patch returns success and empty scan on scans requests that were
rejected because issued too early. The cached bss list from previous
scanning will be returned by mac80211.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 12 +++++++++---
drivers/net/wireless/iwlwifi/iwl-scan.c | 8 +-------
2 files changed, 10 insertions(+), 10 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3213,20 +3213,26 @@ static int iwl4965_mac_hw_scan(struct ie
goto out_unlock;
}

- /* we don't schedule scan within next_scan_jiffies period */
+ /* We don't schedule scan within next_scan_jiffies period.
+ * Avoid scanning during possible EAPOL exchange, return
+ * success immediately.
+ */
if (priv->next_scan_jiffies &&
time_after(priv->next_scan_jiffies, jiffies)) {
IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
- rc = -EAGAIN;
+ queue_work(priv->workqueue, &priv->scan_completed);
+ rc = 0;
goto out_unlock;
}
/* if we just finished scan ask for delay */
if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
- rc = -EAGAIN;
+ queue_work(priv->workqueue, &priv->scan_completed);
+ rc = 0;
goto out_unlock;
}
+
if (len) {
IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
iwl_escape_essid(ssid, len), (int)len);
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -464,11 +464,6 @@ void iwl_init_scan_params(struct iwl_pri

int iwl_scan_initiate(struct iwl_priv *priv)
{
- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
- IWL_ERROR("APs don't scan.\n");
- return 0;
- }
-
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
return -EIO;
@@ -480,8 +475,7 @@ int iwl_scan_initiate(struct iwl_priv *p
}

if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending. "
- "Queuing.\n");
+ IWL_DEBUG_SCAN("Scan request while abort pending\n");
return -EAGAIN;
}


--

2008-11-12 00:38:32

by Greg KH

[permalink] [raw]
Subject: [patch 32/49] iwlwifi: use correct DMA_MASK

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Tomas Winkler <[email protected]>

commit 093d874c02e8d3091aa38596faf0ff2bfd4f0ceb upstream

Use correct DMA_MASK: 4964 and 5000 support 36 bit addresses for
pci express memory access.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4225,13 +4225,13 @@ static int iwl4965_pci_probe(struct pci_

pci_set_master(pdev);

- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
if (err) {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
/* both attempts failed: */
if (err) {
printk(KERN_WARNING "%s: No suitable DMA available.\n",

--

2008-11-12 00:38:50

by Greg KH

[permalink] [raw]
Subject: [patch 33/49] iwlwifi: fix suspend to RAM in iwlwifi

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Tomas Winkler <[email protected]>

commit 10d0bd56966571d0324dfd9bbb8aa913a60bef5f upstream

This patch fixes suspend to RAM after by moving
notify_mac out of iwlwifi mutex

http://bugzilla.kernel.org/show_bug.cgi?id=11845

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Tested-by: Carlos R. Mafra <[email protected]>
Tested-by: Christian Borntraeger <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2090,7 +2090,6 @@ static void iwl_alive_start(struct iwl_p
iwl4965_error_recovery(priv);

iwl_power_update_mode(priv, 1);
- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);

if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
iwl4965_set_mode(priv, priv->iw_mode);
@@ -2342,6 +2341,7 @@ static void iwl_bg_alive_start(struct wo
mutex_lock(&priv->mutex);
iwl_alive_start(priv);
mutex_unlock(&priv->mutex);
+ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
}

static void iwl4965_bg_rf_kill(struct work_struct *work)

--

2008-11-12 00:39:12

by Greg KH

[permalink] [raw]
Subject: [patch 34/49] iwlwifi: generic init calibrations framework

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Tomas Winkler <[email protected]>

commit 6e21f2c109edd746a10e08186484bae8168cdd0c upstream

This patch allows variable number of init calibrations and allows
addition new HW.

This patch also fixes critical bug. Only last calibration result
was applied. On reception of one calibration result all the calibration
was freed.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 7 +++
drivers/net/wireless/iwlwifi/iwl-5000.c | 63 ++++-------------------------
drivers/net/wireless/iwlwifi/iwl-calib.c | 60 +++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 19 --------
drivers/net/wireless/iwlwifi/iwl-core.h | 8 +++
drivers/net/wireless/iwlwifi/iwl-dev.h | 14 ++----
6 files changed, 90 insertions(+), 81 deletions(-)

--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -445,48 +445,6 @@ static int iwl5000_send_Xtal_calib(struc
sizeof(cal_cmd), &cal_cmd);
}

-static int iwl5000_send_calib_results(struct iwl_priv *priv)
-{
- int ret = 0;
-
- struct iwl_host_cmd hcmd = {
- .id = REPLY_PHY_CALIBRATION_CMD,
- .meta.flags = CMD_SIZE_HUGE,
- };
-
- if (priv->calib_results.lo_res) {
- hcmd.len = priv->calib_results.lo_res_len;
- hcmd.data = priv->calib_results.lo_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- if (priv->calib_results.tx_iq_res) {
- hcmd.len = priv->calib_results.tx_iq_res_len;
- hcmd.data = priv->calib_results.tx_iq_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- if (priv->calib_results.tx_iq_perd_res) {
- hcmd.len = priv->calib_results.tx_iq_perd_res_len;
- hcmd.data = priv->calib_results.tx_iq_perd_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- return 0;
-err:
- IWL_ERROR("Error %d\n", ret);
- return ret;
-}
-
static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
{
struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
@@ -511,33 +469,30 @@ static void iwl5000_rx_calib_result(stru
struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
-
- iwl_free_calib_results(priv);
+ int index;

/* reduce the size of the length field itself */
len -= 4;

+ /* Define the order in which the results will be sent to the runtime
+ * uCode. iwl_send_calib_results sends them in a row according to their
+ * index. We sort them here */
switch (hdr->op_code) {
case IWL5000_PHY_CALIBRATE_LO_CMD:
- priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.lo_res_len = len;
- memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_LO;
break;
case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
- priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.tx_iq_res_len = len;
- memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_TX_IQ;
break;
case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
- priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.tx_iq_perd_res_len = len;
- memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_TX_IQ_PERD;
break;
default:
IWL_ERROR("Unknown calibration notification %d\n",
hdr->op_code);
return;
}
+ iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
}

static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
@@ -832,7 +787,7 @@ static int iwl5000_alive_notify(struct i
iwl5000_send_Xtal_calib(priv);

if (priv->ucode_type == UCODE_RT)
- iwl5000_send_calib_results(priv);
+ iwl_send_calib_results(priv);

return 0;
}
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -129,6 +129,13 @@ struct iwl5000_shared {
__le32 padding2;
} __attribute__ ((packed));

+/* calibrations defined for 5000 */
+/* defines the order in which results should be sent to the runtime uCode */
+enum iwl5000_calib {
+ IWL5000_CALIB_LO,
+ IWL5000_CALIB_TX_IQ,
+ IWL5000_CALIB_TX_IQ_PERD,
+};

#endif /* __iwl_5000_hw_h__ */

--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -66,6 +66,66 @@
#include "iwl-core.h"
#include "iwl-calib.h"

+/*****************************************************************************
+ * INIT calibrations framework
+ *****************************************************************************/
+
+ int iwl_send_calib_results(struct iwl_priv *priv)
+{
+ int ret = 0;
+ int i = 0;
+
+ struct iwl_host_cmd hcmd = {
+ .id = REPLY_PHY_CALIBRATION_CMD,
+ .meta.flags = CMD_SIZE_HUGE,
+ };
+
+ for (i = 0; i < IWL_CALIB_MAX; i++)
+ if (priv->calib_results[i].buf) {
+ hcmd.len = priv->calib_results[i].buf_len;
+ hcmd.data = priv->calib_results[i].buf;
+ ret = iwl_send_cmd_sync(priv, &hcmd);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ IWL_ERROR("Error %d iteration %d\n", ret, i);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_send_calib_results);
+
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
+{
+ if (res->buf_len != len) {
+ kfree(res->buf);
+ res->buf = kzalloc(len, GFP_ATOMIC);
+ }
+ if (unlikely(res->buf == NULL))
+ return -ENOMEM;
+
+ res->buf_len = len;
+ memcpy(res->buf, buf, len);
+ return 0;
+}
+EXPORT_SYMBOL(iwl_calib_set);
+
+void iwl_calib_free_results(struct iwl_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < IWL_CALIB_MAX; i++) {
+ kfree(priv->calib_results[i].buf);
+ priv->calib_results[i].buf = NULL;
+ priv->calib_results[i].buf_len = 0;
+ }
+}
+
+/*****************************************************************************
+ * RUNTIME calibrations framework
+ *****************************************************************************/
+
/* "false alarms" are signals that our DSP tries to lock onto,
* but then determines that they are either noise, or transmissions
* from a distant wireless network (also "noise", really) that get
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -956,22 +956,6 @@ err:
}
EXPORT_SYMBOL(iwl_init_drv);

-void iwl_free_calib_results(struct iwl_priv *priv)
-{
- kfree(priv->calib_results.lo_res);
- priv->calib_results.lo_res = NULL;
- priv->calib_results.lo_res_len = 0;
-
- kfree(priv->calib_results.tx_iq_res);
- priv->calib_results.tx_iq_res = NULL;
- priv->calib_results.tx_iq_res_len = 0;
-
- kfree(priv->calib_results.tx_iq_perd_res);
- priv->calib_results.tx_iq_perd_res = NULL;
- priv->calib_results.tx_iq_perd_res_len = 0;
-}
-EXPORT_SYMBOL(iwl_free_calib_results);
-
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
@@ -999,10 +983,9 @@ int iwl_set_tx_power(struct iwl_priv *pr
}
EXPORT_SYMBOL(iwl_set_tx_power);

-
void iwl_uninit_drv(struct iwl_priv *priv)
{
- iwl_free_calib_results(priv);
+ iwl_calib_free_results(priv);
iwlcore_free_geos(priv);
iwl_free_channel_map(priv);
kfree(priv->scan);
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -186,7 +186,6 @@ struct ieee80211_hw *iwl_alloc_all(struc
void iwl_hw_detect(struct iwl_priv *priv);

void iwl_clear_stations_table(struct iwl_priv *priv);
-void iwl_free_calib_results(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv,
@@ -291,6 +290,13 @@ int iwl_scan_initiate(struct iwl_priv *p
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);

+/*******************************************************************************
+ * Calibrations - implemented in iwl-calib.c
+ ******************************************************************************/
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
+
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -745,13 +745,10 @@ struct statistics_general_data {
u32 beacon_energy_c;
};

-struct iwl_calib_results {
- void *tx_iq_res;
- void *tx_iq_perd_res;
- void *lo_res;
- u32 tx_iq_res_len;
- u32 tx_iq_perd_res_len;
- u32 lo_res_len;
+/* Opaque calibration results */
+struct iwl_calib_result {
+ void *buf;
+ size_t buf_len;
};

enum ucode_type {
@@ -813,6 +810,7 @@ enum {


#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
+#define IWL_CALIB_MAX 3

struct iwl_priv {

@@ -857,7 +855,7 @@ struct iwl_priv {
s32 last_temperature;

/* init calibration results */
- struct iwl_calib_results calib_results;
+ struct iwl_calib_result calib_results[IWL_CALIB_MAX];

/* Scan related variables */
unsigned long last_scan_jiffies;

--

2008-11-12 00:39:39

by Greg KH

[permalink] [raw]
Subject: [patch 35/49] zd1211rw: Add 2 device IDs

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Daniel Drake <[email protected]>

commit 0feec9dfe7b8880ab3b4c38d7cc4107dd706ea7f upstream.

07fa/1196
Bewan BWIFI-USB54AR: Tested by night1308, this device is a ZD1211B with
an AL2230S radio.

0ace/b215
HP 802.11abg: Tested by Robert Philippe

Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/zd1211rw/zd_usb.c | 2 ++
1 file changed, 2 insertions(+)

--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -61,6 +61,7 @@ static struct usb_device_id usb_ids[] =
{ USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
/* ZD1211B */
{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
@@ -82,6 +83,7 @@ static struct usb_device_id usb_ids[] =
{ USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
+ { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
/* "Driverless" devices that need ejecting */
{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },

--

2008-11-12 00:39:58

by Greg KH

[permalink] [raw]
Subject: [patch 36/49] iwl3945: fix deadlock on suspend

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Zhu Yi <[email protected]>

commit d54bc4e3fc5c56600a13c9ebc0a7e1077ac05d59 upstream.

This patch fixes iwl3945 deadlock during suspend by moving notify_mac out
of iwl3945 mutex. This is a portion of the same fix for iwlwifi by Tomas.

Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5761,7 +5761,6 @@ static void iwl3945_alive_start(struct i
if (priv->error_recovering)
iwl3945_error_recovery(priv);

- ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
return;

restart:
@@ -6006,6 +6005,7 @@ static void iwl3945_bg_alive_start(struc
mutex_lock(&priv->mutex);
iwl3945_alive_start(priv);
mutex_unlock(&priv->mutex);
+ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
}

static void iwl3945_bg_rf_kill(struct work_struct *work)

--

2008-11-12 00:40:26

by Greg KH

[permalink] [raw]
Subject: [patch 37/49] iwl3945: do not send scan command if channel count zero

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Reinette Chatre <[email protected]>

commit 14b5433606289dbc5b6fd70ced11462f80e95003 upstream.

Do not send scan command if no channels to scan.

This avoids a Microcode error as reported in:
http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1650
http://bugzilla.kernel.org/show_bug.cgi?id=11806
http://marc.info/?l=linux-wireless&m=122437145211886&w=2

Signed-off-by: Reinette Chatre <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6259,6 +6259,11 @@ static void iwl3945_bg_request_scan(stru
direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);

+ if (scan->channel_count == 0) {
+ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ goto done;
+ }
+
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl3945_scan_channel);
cmd.data = scan;

--

2008-11-12 00:40:48

by Greg KH

[permalink] [raw]
Subject: [patch 38/49] cpqarry: fix return value of cpqarray_init()

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Andrey Borzenkov <[email protected]>

commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream.

As reported by Dick Gevers on Compaq ProLiant:

Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0)
Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init
suspiciously returned 1, it should follow 0/-E convention
Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway...
Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted
2.6.27-desktop-0.rc8.2mnb #1
Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e
Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0
Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb
Oct 13 18:06:51 dvgcpl kernel: =======================

Make it return 0 on success and -ENODEV if no array was found.

Reported-by: Dick Gevers <[email protected]>
Signed-off-by: Andrey Borzenkov <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/block/cpqarray.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
num_cntlrs_reg++;
}

- return(num_cntlrs_reg);
+ if (num_cntlrs_reg)
+ return 0;
+ else {
+ pci_unregister_driver(&cpqarray_pci_driver);
+ return -ENODEV;
+ }
}

/* Function to find the first free pointer into our hba[] array */

--

2008-11-12 00:41:14

by Greg KH

[permalink] [raw]
Subject: [patch 39/49] ACPI: dock: avoid check _STA method

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Shaohua Li <[email protected]>

commit 8b59560a3baf2e7c24e0fb92ea5d09eca92805db upstream.

In some BIOSes, every _STA method call will send a notification again,
this cause freeze. And in some BIOSes, it appears _STA should be called
after _DCK. This tries to avoid calls _STA, and still keep the device
present check.

http://bugzilla.kernel.org/show_bug.cgi?id=10431

Signed-off-by: Shaohua Li <[email protected]>
Signed-off-by: Len Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/acpi/dock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -604,14 +604,17 @@ static int handle_eject_request(struct d
static void dock_notify(acpi_handle handle, u32 event, void *data)
{
struct dock_station *ds = data;
+ struct acpi_device *tmp;

switch (event) {
case ACPI_NOTIFY_BUS_CHECK:
- if (!dock_in_progress(ds) && dock_present(ds)) {
+ if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
+ &tmp)) {
begin_dock(ds);
dock(ds);
if (!dock_present(ds)) {
printk(KERN_ERR PREFIX "Unable to dock!\n");
+ complete_dock(ds);
break;
}
atomic_notifier_call_chain(&dock_notifier_list,

--

2008-11-12 00:41:33

by Greg KH

[permalink] [raw]
Subject: [patch 40/49] ARM: 5300/1: fixup spitz reset during boot

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Dmitry Baryshkov <[email protected]>

commit 69fc7eed5f56bce15b239e5110de2575a6970df4 upstream

Some machines don't have the pullup/down on their reset
pin, so configuring the reset generating pin as input makes
them reset immediately. Fix that by making reset pin direction
configurable.

This fixes the boot problem on Sharp Zaurus c3000

Signed-off-by: Dmitry Baryshkov <[email protected]>
Signed-off-by: Russell King <[email protected]>
Signed-off-by: Pavel Machek <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/arm/mach-pxa/include/mach/reset.h | 9 ++++++---
arch/arm/mach-pxa/reset.c | 9 ++++++---
arch/arm/mach-pxa/spitz.c | 2 +-
arch/arm/mach-pxa/tosa.c | 2 +-
4 files changed, 14 insertions(+), 8 deletions(-)

--- a/arch/arm/mach-pxa/include/mach/reset.h
+++ b/arch/arm/mach-pxa/include/mach/reset.h
@@ -10,9 +10,12 @@
extern unsigned int reset_status;
extern void clear_reset_status(unsigned int mask);

-/*
- * register GPIO as reset generator
+/**
+ * init_gpio_reset() - register GPIO as reset generator
+ *
+ * @gpio - gpio nr
+ * @output - set gpio as out/low instead of input during normal work
*/
-extern int init_gpio_reset(int gpio);
+extern int init_gpio_reset(int gpio, int output);

#endif /* __ASM_ARCH_RESET_H */
--- a/arch/arm/mach-pxa/reset.c
+++ b/arch/arm/mach-pxa/reset.c
@@ -20,7 +20,7 @@ static void do_hw_reset(void);

static int reset_gpio = -1;

-int init_gpio_reset(int gpio)
+int init_gpio_reset(int gpio, int output)
{
int rc;

@@ -30,9 +30,12 @@ int init_gpio_reset(int gpio)
goto out;
}

- rc = gpio_direction_input(gpio);
+ if (output)
+ rc = gpio_direction_output(gpio, 0);
+ else
+ rc = gpio_direction_input(gpio);
if (rc) {
- printk(KERN_ERR "Can't configure reset_gpio for input\n");
+ printk(KERN_ERR "Can't configure reset_gpio\n");
gpio_free(gpio);
goto out;
}
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -548,7 +548,7 @@ static void spitz_restart(char mode)

static void __init common_init(void)
{
- init_gpio_reset(SPITZ_GPIO_ON_RESET);
+ init_gpio_reset(SPITZ_GPIO_ON_RESET, 1);
pm_power_off = spitz_poweroff;
arm_pm_restart = spitz_restart;

--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -781,7 +781,7 @@ static void __init tosa_init(void)
gpio_set_wake(MFP_PIN_GPIO1, 1);
/* We can't pass to gpio-keys since it will drop the Reset altfunc */

- init_gpio_reset(TOSA_GPIO_ON_RESET);
+ init_gpio_reset(TOSA_GPIO_ON_RESET, 0);

pm_power_off = tosa_poweroff;
arm_pm_restart = tosa_restart;

--

2008-11-12 00:41:51

by Greg KH

[permalink] [raw]
Subject: [patch 41/49] KEYS: Make request key instantiate the per-user keyrings

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: David Howells <[email protected]>

commit 1f8f5cf6e4f038552a3e47b66085452c08556d71 upstream

Make request_key() instantiate the per-user keyrings so that it doesn't oops
if it needs to get hold of the user session keyring because there isn't a
session keyring in place.

Signed-off-by: David Howells <[email protected]>
Tested-by: Steve French <[email protected]>
Tested-by: Rutger Nijlunsing <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
security/keys/internal.h | 1 +
security/keys/process_keys.c | 2 +-
security/keys/request_key.c | 4 ++++
3 files changed, 6 insertions(+), 1 deletion(-)

--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings

extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);

+extern int install_user_keyrings(struct task_struct *tsk);
extern int install_thread_keyring(struct task_struct *tsk);
extern int install_process_keyring(struct task_struct *tsk);

--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -40,7 +40,7 @@ struct key_user root_key_user = {
/*
* install user and user session keyrings for a particular UID
*/
-static int install_user_keyrings(struct task_struct *tsk)
+int install_user_keyrings(struct task_struct *tsk)
{
struct user_struct *user = tsk->user;
struct key *uid_keyring, *session_keyring;
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct

kenter("{%d},{%d},%s", key->serial, authkey->serial, op);

+ ret = install_user_keyrings(tsk);
+ if (ret < 0)
+ goto error_alloc;
+
/* allocate a new session keyring */
sprintf(desc, "_req.%u", key->serial);


--

2008-11-12 00:42:16

by Greg KH

[permalink] [raw]
Subject: [patch 42/49] libata: fix last_reset timestamp handling

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Tejun Heo <[email protected]>

commit 19b723218bde79c60a394a3caee9eb156ac2d356 upstream

ehc->last_reset is used to ensure that resets are not issued too
close to each other. It's initialized to jiffies minus one minute
on EH entry. However, when new links are initialized after PMP is
probed, new links have zero for this timestamp resulting in long wait
depending on the current jiffies.

This patch makes last_set considered iff ATA_EHI_DID_RESET is set, in
which case last_reset is always initialized. As an added precaution,
WARN_ON() is added so that warning is printed if last_reset is
in future.

This problem is spotted and debugged by Shane Huang.

Signed-off-by: Tejun Heo <[email protected]>
Cc: Shane Huang <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/ata/libata-eh.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)

--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -604,9 +604,6 @@ void ata_scsi_error(struct Scsi_Host *ho
if (ata_ncq_enabled(dev))
ehc->saved_ncq_enabled |= 1 << devno;
}
-
- /* set last reset timestamp to some time in the past */
- ehc->last_reset = jiffies - 60 * HZ;
}

ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
@@ -2209,17 +2206,21 @@ int ata_eh_reset(struct ata_link *link,
if (link->flags & ATA_LFLAG_NO_SRST)
softreset = NULL;

- now = jiffies;
- deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
- if (time_before(now, deadline))
- schedule_timeout_uninterruptible(deadline - now);
+ /* make sure each reset attemp is at least COOL_DOWN apart */
+ if (ehc->i.flags & ATA_EHI_DID_RESET) {
+ now = jiffies;
+ WARN_ON(time_after(ehc->last_reset, now));
+ deadline = ata_deadline(ehc->last_reset,
+ ATA_EH_RESET_COOL_DOWN);
+ if (time_before(now, deadline))
+ schedule_timeout_uninterruptible(deadline - now);
+ }

spin_lock_irqsave(ap->lock, flags);
ap->pflags |= ATA_PFLAG_RESETTING;
spin_unlock_irqrestore(ap->lock, flags);

ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
- ehc->last_reset = jiffies;

ata_link_for_each_dev(dev, link) {
/* If we issue an SRST then an ATA drive (not ATAPI)
@@ -2285,7 +2286,6 @@ int ata_eh_reset(struct ata_link *link,
/*
* Perform reset
*/
- ehc->last_reset = jiffies;
if (ata_is_host_link(link))
ata_eh_freeze_port(ap);

@@ -2297,6 +2297,7 @@ int ata_eh_reset(struct ata_link *link,
reset == softreset ? "soft" : "hard");

/* mark that this EH session started with reset */
+ ehc->last_reset = jiffies;
if (reset == hardreset)
ehc->i.flags |= ATA_EHI_DID_HARDRESET;
else
@@ -2404,7 +2405,7 @@ int ata_eh_reset(struct ata_link *link,

/* reset successful, schedule revalidation */
ata_eh_done(link, NULL, ATA_EH_RESET);
- ehc->last_reset = jiffies;
+ ehc->last_reset = jiffies; /* update to completion time */
ehc->i.action |= ATA_EH_REVALIDATE;

rc = 0;

--

2008-11-12 00:42:39

by Greg KH

[permalink] [raw]
Subject: [patch 43/49] ALSA: hda: make a STAC_DELL_EQ option


2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Matthew Ranostay <[email protected]>

commit 6b3ab21ef1ac15db4b053ce0ba8eae0ef9361c8a upstream.

Add support for explicitly enabling the EQ distortion hack for
systems without software biquad support.

Signed-off-by: Matthew Ranostay <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
sound/pci/hda/patch_sigmatel.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -67,6 +67,7 @@ enum {
enum {
STAC_92HD73XX_REF,
STAC_DELL_M6,
+ STAC_DELL_EQ,
STAC_92HD73XX_MODELS
};

@@ -560,9 +561,7 @@ static struct hda_verb dell_eq_core_init
};

static struct hda_verb dell_m6_core_init[] = {
- /* set master volume to max value without distortion
- * and direct control */
- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
+ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
/* setup audio connections */
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -1297,11 +1296,13 @@ static unsigned int dell_m6_pin_configs[
static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
[STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
[STAC_DELL_M6] = dell_m6_pin_configs,
+ [STAC_DELL_EQ] = dell_m6_pin_configs,
};

static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
[STAC_92HD73XX_REF] = "ref",
[STAC_DELL_M6] = "dell-m6",
+ [STAC_DELL_EQ] = "dell-eq",
};

static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
@@ -3560,8 +3561,12 @@ again:
spec->gpio_data = 0x01;

switch (spec->board_config) {
- case STAC_DELL_M6:
+ case STAC_DELL_EQ:
spec->init = dell_eq_core_init;
+ /* fallthru */
+ case STAC_DELL_M6:
+ if (!spec->init)
+ spec->init = dell_m6_core_init;
switch (codec->subsystem_id) {
case 0x1028025e: /* Analog Mics */
case 0x1028025f:
@@ -3570,8 +3575,6 @@ again:
break;
case 0x10280271: /* Digital Mics */
case 0x10280272:
- spec->init = dell_m6_core_init;
- /* fall-through */
case 0x10280254:
case 0x10280255:
stac92xx_set_config_reg(codec, 0x13, 0x90A60160);

--

2008-11-12 00:42:54

by Greg KH

[permalink] [raw]
Subject: [patch 44/49] Fix __pfn_to_page(pfn) for CONFIG_DISCONTIGMEM=y

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Rafael J. Wysocki <[email protected]>

commit c5d712433ff57a66d8fb79a57a4fc7a7c3467b97 upstream

Fix the __pfn_to_page(pfn) macro so that it doesn't evaluate its
argument twice in the CONFIG_DISCONTIGMEM=y case, because 'pfn' may
be a result of a funtion call having side effects.

For example, the hibernation code applies pfn_to_page(pfn) to the
result of a function returning the pfn corresponding to the next set
bit in a bitmap and the current bit position is modified on each
call. This leads to "interesting" failures for CONFIG_DISCONTIGMEM=y
due to the current behavior of __pfn_to_page(pfn).

Signed-off-by: Rafael J. Wysocki <[email protected]>
Acked-by: Pavel Machek <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
include/asm-generic/memory_model.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -34,7 +34,7 @@

#define __pfn_to_page(pfn) \
({ unsigned long __pfn = (pfn); \
- unsigned long __nid = arch_pfn_to_nid(pfn); \
+ unsigned long __nid = arch_pfn_to_nid(__pfn); \
NODE_DATA(__nid)->node_mem_map + arch_local_page_offset(__pfn, __nid);\
})


--

2008-11-12 00:43:19

by Greg KH

[permalink] [raw]
Subject: [patch 45/49] mmc: increase SD write timeout for crappy cards

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Pierre Ossman <[email protected]>

commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream.

It seems that some cards are slightly out of spec and occasionally
will not be able to complete a write in the alloted 250 ms [1].
Incease the timeout slightly to allow even these cards to function
properly.

[1] http://lkml.org/lkml/2008/9/23/390

Signed-off-by: Pierre Ossman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/mmc/core/core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat
(card->host->ios.clock / 1000);

if (data->flags & MMC_DATA_WRITE)
- limit_us = 250000;
+ /*
+ * The limit is really 250 ms, but that is
+ * insufficient for some crappy cards.
+ */
+ limit_us = 300000;
else
limit_us = 100000;


--

2008-11-12 00:43:37

by Greg KH

[permalink] [raw]
Subject: [patch 46/49] hfsplus: fix Buffer overflow with a corrupted image (CVE-2008-4933)

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Eric Sesterhenn <[email protected]>

commit efc7ffcb4237f8cb9938909041c4ed38f6e1bf40 upstream

When an hfsplus image gets corrupted it might happen that the catalog
namelength field gets b0rked. If we mount such an image the memcpy() in
hfsplus_cat_build_key_uni() writes more than the 255 that fit in the name
field. Depending on the size of the overwritten data, we either only get
memory corruption or also trigger an oops like this:

[ 221.628020] BUG: unable to handle kernel paging request at c82b0000
[ 221.629066] IP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151
[ 221.629066] *pde = 0ea29163 *pte = 082b0160
[ 221.629066] Oops: 0002 [#1] PREEMPT DEBUG_PAGEALLOC
[ 221.629066] Modules linked in:
[ 221.629066]
[ 221.629066] Pid: 4845, comm: mount Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #28)
[ 221.629066] EIP: 0060:[<c022d4b1>] EFLAGS: 00010206 CPU: 0
[ 221.629066] EIP is at hfsplus_find_cat+0x10d/0x151
[ 221.629066] EAX: 00000029 EBX: 00016210 ECX: 000042c2 EDX: 00000002
[ 221.629066] ESI: c82d70ca EDI: c82b0000 EBP: c82d1bcc ESP: c82d199c
[ 221.629066] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[ 221.629066] Process mount (pid: 4845, ti=c82d1000 task=c8224060 task.ti=c82d1000)
[ 221.629066] Stack: c080b3c4 c82aa8f8 c82d19c2 00016210 c080b3be c82d1bd4 c82aa8f0 00000300
[ 221.629066] 01000000 750008b1 74006e00 74006900 65006c00 c82d6400 c013bd35 c8224060
[ 221.629066] 00000036 00000046 c82d19f0 00000082 c8224548 c8224060 00000036 c0d653cc
[ 221.629066] Call Trace:
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
[ 221.629066] [<c01302d2>] ? __kernel_text_address+0x1b/0x27
[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
[ 221.629066] [<c0109e32>] ? save_stack_address+0x0/0x2c
[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
[ 221.629066] [<c013553d>] ? down+0xc/0x2f
[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
[ 221.629066] [<c013da5d>] ? mark_held_locks+0x43/0x5a
[ 221.629066] [<c013dc3a>] ? trace_hardirqs_on+0xb/0xd
[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
[ 221.629066] [<c06abec8>] ? _spin_unlock_irqrestore+0x42/0x58
[ 221.629066] [<c013555c>] ? down+0x2b/0x2f
[ 221.629066] [<c022aa68>] ? hfsplus_iget+0xa0/0x154
[ 221.629066] [<c022b0b9>] ? hfsplus_fill_super+0x280/0x447
[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[ 221.629066] [<c041c9e4>] ? string+0x2b/0x74
[ 221.629066] [<c041cd16>] ? vsnprintf+0x2e9/0x512
[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
[ 221.629066] [<c01354d3>] ? up+0xc/0x2f
[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
[ 221.629066] [<c041cfb7>] ? snprintf+0x1b/0x1d
[ 221.629066] [<c01ba466>] ? disk_name+0x25/0x67
[ 221.629066] [<c0183960>] ? get_sb_bdev+0xcd/0x10b
[ 221.629066] [<c016ad92>] ? kstrdup+0x2a/0x4c
[ 221.629066] [<c022a7b3>] ? hfsplus_get_sb+0x13/0x15
[ 221.629066] [<c022ae39>] ? hfsplus_fill_super+0x0/0x447
[ 221.629066] [<c0183583>] ? vfs_kern_mount+0x3b/0x76
[ 221.629066] [<c0183602>] ? do_kern_mount+0x32/0xba
[ 221.629066] [<c01960d4>] ? do_new_mount+0x46/0x74
[ 221.629066] [<c0196277>] ? do_mount+0x175/0x193
[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
[ 221.629066] [<c01663b2>] ? __get_free_pages+0x1e/0x24
[ 221.629066] [<c06ac07b>] ? lock_kernel+0x19/0x8c
[ 221.629066] [<c01962e6>] ? sys_mount+0x51/0x9b
[ 221.629066] [<c01962f9>] ? sys_mount+0x64/0x9b
[ 221.629066] [<c01038bd>] ? sysenter_do_call+0x12/0x31
[ 221.629066] =======================
[ 221.629066] Code: 89 c2 c1 e2 08 c1 e8 08 09 c2 8b 85 e8 fd ff ff 66 89 50 06 89 c7 53 83 c7 08 56 57 68 c4 b3 80 c0 e8 8c 5c ef ff 89 d9 c1 e9 02 <f3> a5 89 d9 83 e1 03 74 02 f3 a4 83 c3 06 8b 95 e8 fd ff ff 0f
[ 221.629066] EIP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151 SS:ESP 0068:c82d199c
[ 221.629066] ---[ end trace e417a1d67f0d0066 ]---

Since hfsplus_cat_build_key_uni() returns void and only has one callsite,
the check is performed at the callsite.

Signed-off-by: Eric Sesterhenn <[email protected]>
Reviewed-by: Pekka Enberg <[email protected]>
Cc: Roman Zippel <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/hfsplus/catalog.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block
return -EIO;
}

+ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
+ printk(KERN_ERR "hfs: catalog name length corrupted\n");
+ return -EIO;
+ }
+
hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
&tmp.thread.nodeName);
return hfs_brec_find(fd);

--

2008-11-12 00:43:53

by Greg KH

[permalink] [raw]
Subject: [patch 49/49] HID: fix incorrent length condition in hidraw_write()

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Jiri Kosina <[email protected]>

upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a

From: Jiri Kosina <[email protected]>

The bound check on the buffer length

if (count > HID_MIN_BUFFER_SIZE)

is of course incorrent, the proper check is

if (count > HID_MAX_BUFFER_SIZE)

Fix it.

Reported-by: Jerry Ryle <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Cc: Paul Stoffregen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/hid/hidraw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file
if (!dev->hid_output_raw_report)
return -ENODEV;

- if (count > HID_MIN_BUFFER_SIZE) {
+ if (count > HID_MAX_BUFFER_SIZE) {
printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
task_pid_nr(current));
return -EINVAL;

--

2008-11-12 00:44:25

by Greg KH

[permalink] [raw]
Subject: [patch 48/49] hfs: fix namelength memory corruption (CVE-2008-5025)

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Eric Sesterhenn <[email protected]>

commit d38b7aa7fc3371b52d036748028db50b585ade2e upstream

Fix a stack corruption caused by a corrupted hfs filesystem. If the
catalog name length is corrupted the memcpy overwrites the catalog btree
structure. Since the field is limited to HFS_NAMELEN bytes in the
structure and the file format, we throw an error if it is too long.

Cc: Roman Zippel <[email protected]>
Signed-off-by: Eric Sesterhenn <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/hfs/catalog.c | 4 ++++
1 file changed, 4 insertions(+)

--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block

fd->search_key->cat.ParID = rec.thread.ParID;
len = fd->search_key->cat.CName.len = rec.thread.CName.len;
+ if (len > HFS_NAMELEN) {
+ printk(KERN_ERR "hfs: bad catalog namelength\n");
+ return -EIO;
+ }
memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
return hfs_brec_find(fd);
}

--

2008-11-12 00:44:40

by Greg KH

[permalink] [raw]
Subject: [patch 47/49] hfsplus: check read_mapping_page() return value (CVE-2008-4934)

2.6.27-stable review patch. If anyone has any objections, please let us know.

------------------

From: Eric Sesterhenn <[email protected]>

commit 649f1ee6c705aab644035a7998d7b574193a598a upstream.

While testing more corrupted images with hfsplus, i came across
one which triggered the following bug:

[15840.675016] BUG: unable to handle kernel paging request at fffffffb
[15840.675016] IP: [<c0116a4f>] kmap+0x15/0x56
[15840.675016] *pde = 00008067 *pte = 00000000
[15840.675016] Oops: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
[15840.675016] Modules linked in:
[15840.675016]
[15840.675016] Pid: 11575, comm: ln Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #29)
[15840.675016] EIP: 0060:[<c0116a4f>] EFLAGS: 00010202 CPU: 0
[15840.675016] EIP is at kmap+0x15/0x56
[15840.675016] EAX: 00000246 EBX: fffffffb ECX: 00000000 EDX: cab919c0
[15840.675016] ESI: 000007dd EDI: cab0bcf4 EBP: cab0bc98 ESP: cab0bc94
[15840.675016] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[15840.675016] Process ln (pid: 11575, ti=cab0b000 task=cab919c0 task.ti=cab0b000)
[15840.675016] Stack: 00000000 cab0bcdc c0231cfb 00000000 cab0bce0 00000800 ca9290c0 fffffffb
[15840.675016] cab145d0 cab919c0 cab15998 22222222 22222222 22222222 00000001 cab15960
[15840.675016] 000007dd cab0bcf4 cab0bd04 c022cb3a cab0bcf4 cab15a6c ca9290c0 00000000
[15840.675016] Call Trace:
[15840.675016] [<c0231cfb>] ? hfsplus_block_allocate+0x6f/0x2d3
[15840.675016] [<c022cb3a>] ? hfsplus_file_extend+0xc4/0x1db
[15840.675016] [<c022ce41>] ? hfsplus_get_block+0x8c/0x19d
[15840.675016] [<c06adde4>] ? sub_preempt_count+0x9d/0xab
[15840.675016] [<c019ece6>] ? __block_prepare_write+0x147/0x311
[15840.675016] [<c0161934>] ? __grab_cache_page+0x52/0x73
[15840.675016] [<c019ef4f>] ? block_write_begin+0x79/0xd5
[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
[15840.675016] [<c019f22a>] ? cont_write_begin+0x27f/0x2af
[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
[15840.675016] [<c0139ebe>] ? tick_program_event+0x28/0x4c
[15840.675016] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
[15840.675016] [<c022b723>] ? hfsplus_write_begin+0x2d/0x32
[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
[15840.675016] [<c0161988>] ? pagecache_write_begin+0x33/0x107
[15840.675016] [<c01879e5>] ? __page_symlink+0x3c/0xae
[15840.675016] [<c019ad34>] ? __mark_inode_dirty+0x12f/0x137
[15840.675016] [<c0187a70>] ? page_symlink+0x19/0x1e
[15840.675016] [<c022e6eb>] ? hfsplus_symlink+0x41/0xa6
[15840.675016] [<c01886a9>] ? vfs_symlink+0x99/0x101
[15840.675016] [<c018a2f6>] ? sys_symlinkat+0x6b/0xad
[15840.675016] [<c018a348>] ? sys_symlink+0x10/0x12
[15840.675016] [<c01038bd>] ? sysenter_do_call+0x12/0x31
[15840.675016] =======================
[15840.675016] Code: 00 00 75 10 83 3d 88 2f ec c0 02 75 07 89 d0 e8 12 56 05 00 5d c3 55 ba 06 00 00 00 89 e5 53 89 c3 b8 3d eb 7e c0 e8 16 74 00 00 <8b> 03 c1 e8 1e 69 c0 d8 02 00 00 05 b8 69 8e c0 2b 80 c4 02 00
[15840.675016] EIP: [<c0116a4f>] kmap+0x15/0x56 SS:ESP 0068:cab0bc94
[15840.675016] ---[ end trace 4fea40dad6b70e5f ]---

This happens because the return value of read_mapping_page() is passed on
to kmap unchecked. The bug is triggered after the first
read_mapping_page() in hfsplus_block_allocate(), this patch fixes all
three usages in this functions but leaves the ones further down in the
file unchanged.

Signed-off-by: Eric Sesterhenn <[email protected]>
Cc: Roman Zippel <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/hfsplus/bitmap.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_
mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
pptr = kmap(page);
curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
i = offset % 32;
@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_
break;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
curr = pptr = kmap(page);
if ((size ^ offset) / PAGE_CACHE_BITS)
end = pptr + PAGE_CACHE_BITS / 32;
@@ -120,6 +128,10 @@ found:
offset += PAGE_CACHE_BITS;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
pptr = kmap(page);
curr = pptr;
end = pptr + PAGE_CACHE_BITS / 32;

--

2008-11-12 00:47:39

by Gabriel C

[permalink] [raw]
Subject: Re: [patch 00/49] 2.6.27.5 stable review

Greg KH wrote:

> This is the start of the stable review cycle for the 2.6.27.5 release.
> There are 49 patches in this series, all will be posted as a response to
> this one.


Hmm , again 2.6.27.5 ?:) I guess you mean 2.6.27.6 ?

2008-11-12 00:57:51

by Willy Tarreau

[permalink] [raw]
Subject: Re: [patch 00/49] 2.6.27.5 stable review

On Tue, Nov 11, 2008 at 04:22:15PM -0800, Greg KH wrote:
> This is the start of the stable review cycle for the 2.6.27.5 release.

Greg, this should be 2.6.27.6 !

> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.27.5-rc1.gz

Same here.

Regards,
Willy

2008-11-12 01:10:18

by Greg KH

[permalink] [raw]
Subject: Re: [patch 00/49] 2.6.27.5 stable review

On Wed, Nov 12, 2008 at 01:44:37AM +0100, Gabriel C wrote:
> Greg KH wrote:
>
> > This is the start of the stable review cycle for the 2.6.27.5 release.
> > There are 49 patches in this series, all will be posted as a response to
> > this one.
>
>
> Hmm , again 2.6.27.5 ?:) I guess you mean 2.6.27.6 ?

Oh crap.

I did all of this on an older git tree that was based on 2.6.27.4. So
it was really 2.6.27.5 I was working with...

I've updated the patch now, the hfsplus patches were already in 2.6.27.5
so they dropped out. It can be found as patch-2.6.27.6-rc1.gz in the
same location, with the diffstat below.

Sorry for the confusion, this release was tough to get out as it kept
crashing my boxes until I got all of the needed fixes added.

It's time for a beer...

greg k-h

-------------------

Documentation/cciss.txt | 2
Makefile | 2
arch/arm/mach-pxa/include/mach/reset.h | 9 +
arch/arm/mach-pxa/reset.c | 9 +
arch/arm/mach-pxa/spitz.c | 2
arch/arm/mach-pxa/tosa.c | 2
arch/arm/mm/cache-xsc3l2.c | 4
arch/x86/Kconfig | 20 ++++
arch/x86/kernel/setup.c | 41 ++++++++
arch/x86/kernel/tsc.c | 8 -
drivers/acpi/dock.c | 5 -
drivers/ata/libata-eh.c | 21 ++--
drivers/block/cciss.c | 28 +++++
drivers/block/cpqarray.c | 7 +
drivers/dca/dca-core.c | 2
drivers/dma/ioat_dma.c | 11 +-
drivers/dma/iovlock.c | 17 +--
drivers/hid/hidraw.c | 2
drivers/md/linear.c | 2
drivers/md/raid10.c | 2
drivers/mmc/core/core.c | 6 +
drivers/mtd/chips/cfi_cmdset_0002.c | 13 --
drivers/mtd/chips/jedec_probe.c | 10 --
drivers/net/r8169.c | 134 ++++++++++++++--------------
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 7 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 63 +------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 57 ++++++++---
drivers/net/wireless/iwlwifi/iwl-calib.c | 60 ++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 27 +----
drivers/net/wireless/iwlwifi/iwl-core.h | 8 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 15 +--
drivers/net/wireless/iwlwifi/iwl-power.c | 39 +++++++-
drivers/net/wireless/iwlwifi/iwl-power.h | 4
drivers/net/wireless/iwlwifi/iwl-scan.c | 8 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +
drivers/net/wireless/zd1211rw/zd_usb.c | 2
fs/ext3/super.c | 11 +-
fs/hfs/catalog.c | 4
fs/jffs2/background.c | 10 +-
fs/jffs2/compr_lzo.c | 15 +--
include/asm-generic/memory_model.h | 2
include/linux/mtd/cfi.h | 22 +++-
include/net/af_unix.h | 1
kernel/cgroup.c | 1
mm/hugetlb.c | 49 +++++++++-
mm/internal.h | 29 ++++++
mm/page_alloc.c | 28 ++++-
net/unix/af_unix.c | 31 +++++-
net/unix/garbage.c | 49 +++++++---
security/keys/internal.h | 1
security/keys/process_keys.c | 2
security/keys/request_key.c | 4
sound/pci/hda/patch_sigmatel.c | 15 +--
53 files changed, 630 insertions(+), 300 deletions(-)

2008-11-12 14:09:15

by Frans Pop

[permalink] [raw]
Subject: Re: [patch 00/49] 2.6.27.5 stable review

Would it be possible to include the commit below now that it's been
accepted into mainline?

Thanks,
FJP

commit bf1b36445dc868cbbde194aa1dd87e38fe24cf16
Author: Jonathan McDowell <[email protected]>
Date: Sat Sep 13 17:08:31 2008 +0100

kbuild: Fixup deb-pkg target to generate separate firmware deb

2008-11-12 17:07:46

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 00/49] 2.6.27.5 stable review

On Wed, Nov 12, 2008 at 03:08:55PM +0100, Frans Pop wrote:
> Would it be possible to include the commit below now that it's been
> accepted into mainline?
>
> Thanks,
> FJP
>
> commit bf1b36445dc868cbbde194aa1dd87e38fe24cf16
> Author: Jonathan McDowell <[email protected]>
> Date: Sat Sep 13 17:08:31 2008 +0100
>
> kbuild: Fixup deb-pkg target to generate separate firmware deb

I will queue it up for the next -stable release after this one.

thanks,

greg k-h

2008-11-13 22:15:35

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 00/49] 2.6.27.5 stable review

On Wed, Nov 12, 2008 at 03:08:55PM +0100, Frans Pop wrote:
> Would it be possible to include the commit below now that it's been
> accepted into mainline?
>
> Thanks,
> FJP
>
> commit bf1b36445dc868cbbde194aa1dd87e38fe24cf16
> Author: Jonathan McDowell <[email protected]>
> Date: Sat Sep 13 17:08:31 2008 +0100
>
> kbuild: Fixup deb-pkg target to generate separate firmware deb

Now queued up.

thanks,

greg k-h