- Unrevert stable patch from .33.7:
    ssb-handle-netbook-devices-where-the-sprom-address-is-changed.patch
- Drop patches merged in 2.6.33.8:
    ssb_check_for_sprom.patch
This commit is contained in:
Chuck Ebbert 2010-08-15 02:36:50 -04:00
parent 7139dd832a
commit b0632f00ee
4 changed files with 22 additions and 430 deletions

View File

@ -60,13 +60,14 @@ Summary: The Linux kernel
%if 0%{?released_kernel}
# Do we have a -stable update to apply?
%define stable_update 7
%define stable_update 8
# Is it a -stable RC?
%define stable_rc 0
# Set rpm version accordingly
%if 0%{?stable_update}
%define stablerev .%{stable_update}
%define stable_base %{stable_update}
# Set stable_base for incremental stable patches that are not -rc's
%define stable_base 7
%if 0%{?stable_rc}
# stable RCs are incremental patches, so we need the previous stable patch
%define stable_base %(echo $((%{stable_update} - 1)))
@ -590,6 +591,12 @@ Patch00: %{stable_patch_00}
%if 0%{?stable_rc}
%define stable_patch_01 patch-2.6.%{base_sublevel}.%{stable_update}-rc%{stable_rc}.bz2
Patch01: %{stable_patch_01}
%else
# Incremental stable update
%if %{stable_base} != %{stable_update}
%define stable_patch_01 patch-2.6.%{base_sublevel}.%{stable_base}-%{stable_update}.bz2
Patch01: %{stable_patch_01}
%endif
%endif
# non-released_kernel case
@ -796,9 +803,6 @@ Patch12018: neuter_intel_microcode_load.patch
Patch12019: linux-2.6-umh-refactor.patch
# rhbz#533746
Patch12021: ssb_check_for_sprom.patch
# make p54pci usable on slower hardware
Patch12103: linux-2.6-p54pci.patch
@ -1232,6 +1236,11 @@ ApplyPatch %{stable_patch_00}
%endif
%if 0%{?stable_rc}
ApplyPatch %{stable_patch_01}
%else
# Incremental update, not an -rc
%if %{stable_base} != %{stable_update}
ApplyPatch %{stable_patch_01}
%endif
%endif
%if %{using_upstream_branch}
@ -1506,9 +1515,6 @@ ApplyPatch linux-2.6-umh-refactor.patch
ApplyPatch alsa-usbmixer-add-possibility-to-remap-dB-values.patch
# rhbz#533746
ApplyPatch ssb_check_for_sprom.patch
# make p54pci usable on slower hardware
ApplyPatch linux-2.6-p54pci.patch
@ -2207,6 +2213,13 @@ fi
%changelog
* Sun Aug 15 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.33.8-148
- 2.6.33.8 from http://git.kernel.org/?p=linux/kernel/git/jkacur/jk-2.6.git stable/2.6.33.y
- Unrevert stable patch from .33.7:
ssb-handle-netbook-devices-where-the-sprom-address-is-changed.patch
- Drop patches merged in 2.6.33.8:
ssb_check_for_sprom.patch
* Sat Aug 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.33.7-148
- Update to kernel 2.6.33.7
- Drop patches merged in 2.6.33.7:

View File

@ -1,240 +1,3 @@
From stable-bounces@linux.kernel.org Sun Jul 11 16:26:25 2010
From: Larry Finger <Larry.Finger@lwfinger.net>
Date: Sun, 11 Jul 2010 18:26:15 -0500
Subject: ssb: Handle Netbook devices where the SPROM address is changed
To: Greg KH <gregkh@suse.de>
Cc: linux-stable <stable@kernel.org>
Message-ID: <4C3A5317.3090603@lwfinger.net>
From: Christoph Fritz <chf.fritz@googlemail.com>
For some Netbook computers with Broadcom BCM4312 wireless interfaces,
the SPROM has been moved to a new location. When the ssb driver tries to
read the old location, the systems hangs when trying to read a
non-existent location. Such freezes are particularly bad as they do not
log the failure.
This patch is modified from commit
da1fdb02d9200ff28b6f3a380d21930335fe5429 with some pieces from other
mainline changes so that it can be applied to stable 2.6.34.Y.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/ssb/driver_chipcommon.c | 3 +
drivers/ssb/driver_chipcommon_pmu.c | 17 ++++-------
drivers/ssb/pci.c | 46 ++++++++++++++++++++++++++----
drivers/ssb/sprom.c | 15 +++++++++
include/linux/ssb/ssb.h | 1
include/linux/ssb/ssb_driver_chipcommon.h | 2 +
include/linux/ssb/ssb_regs.h | 3 +
7 files changed, 70 insertions(+), 17 deletions(-)
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -233,6 +233,9 @@ void ssb_chipcommon_init(struct ssb_chip
{
if (!cc->dev)
return; /* We don't have a ChipCommon */
+ if (cc->dev->id.revision >= 11)
+ cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
+ ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
ssb_pmu_init(cc);
chipco_powercontrol_init(cc);
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -495,9 +495,9 @@ static void ssb_pmu_resources_init(struc
chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
}
+/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
void ssb_pmu_init(struct ssb_chipcommon *cc)
{
- struct ssb_bus *bus = cc->dev->bus;
u32 pmucap;
if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
@@ -509,15 +509,12 @@ void ssb_pmu_init(struct ssb_chipcommon
ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
cc->pmu.rev, pmucap);
- if (cc->pmu.rev >= 1) {
- if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) {
- chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
- ~SSB_CHIPCO_PMU_CTL_NOILPONW);
- } else {
- chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
- SSB_CHIPCO_PMU_CTL_NOILPONW);
- }
- }
+ if (cc->pmu.rev == 1)
+ chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
+ ~SSB_CHIPCO_PMU_CTL_NOILPONW);
+ else
+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
+ SSB_CHIPCO_PMU_CTL_NOILPONW);
ssb_pmu_pll_init(cc);
ssb_pmu_resources_init(cc);
}
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -22,6 +22,7 @@
#include "ssb_private.h"
+bool ssb_is_sprom_available(struct ssb_bus *bus);
/* Define the following to 1 to enable a printk on each coreswitch. */
#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
@@ -167,7 +168,7 @@ err_pci:
}
/* Get the word-offset for a SSB_SPROM_XXX define. */
-#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
+#define SPOFF(offset) ((offset) / sizeof(u16))
/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
#define SPEX16(_outvar, _offset, _mask, _shift) \
out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
@@ -252,8 +253,13 @@ static int sprom_do_read(struct ssb_bus
{
int i;
+ /* Check if SPROM can be read */
+ if (ioread16(bus->mmio + bus->sprom_offset) == 0xFFFF) {
+ ssb_printk(KERN_ERR PFX "Unable to read SPROM\n");
+ return -ENODEV;
+ }
for (i = 0; i < bus->sprom_size; i++)
- sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
+ sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
return 0;
}
@@ -284,7 +290,7 @@ static int sprom_do_write(struct ssb_bus
ssb_printk("75%%");
else if (i % 2)
ssb_printk(".");
- writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
+ writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
mmiowb();
msleep(20);
}
@@ -620,21 +626,49 @@ static int ssb_pci_sprom_get(struct ssb_
int err = -ENOMEM;
u16 *buf;
+ if (!ssb_is_sprom_available(bus)) {
+ ssb_printk(KERN_ERR PFX "No SPROM available!\n");
+ return -ENODEV;
+ }
+ if (bus->chipco.dev) { /* can be unavailible! */
+ /*
+ * get SPROM offset: SSB_SPROM_BASE1 except for
+ * chipcommon rev >= 31 or chip ID is 0x4312 and
+ * chipcommon status & 3 == 2
+ */
+ if (bus->chipco.dev->id.revision >= 31)
+ bus->sprom_offset = SSB_SPROM_BASE31;
+ else if (bus->chip_id == 0x4312 &&
+ (bus->chipco.status & 0x03) == 2)
+ bus->sprom_offset = SSB_SPROM_BASE31;
+ else
+ bus->sprom_offset = SSB_SPROM_BASE1;
+ } else {
+ bus->sprom_offset = SSB_SPROM_BASE1;
+ }
+ ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
+
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
if (!buf)
goto out;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
- sprom_do_read(bus, buf);
+ err = sprom_do_read(bus, buf);
+ if (err)
+ goto out_free;
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
/* try for a 440 byte SPROM - revision 4 and higher */
kfree(buf);
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
- if (!buf)
+ if (!buf) {
+ err = -ENOMEM;
goto out;
+ }
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
- sprom_do_read(bus, buf);
+ err = sprom_do_read(bus, buf);
+ if (err)
+ goto out_free;
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
/* All CRC attempts failed.
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -175,3 +175,18 @@ const struct ssb_sprom *ssb_get_fallback
{
return fallback_sprom;
}
+
+/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
+bool ssb_is_sprom_available(struct ssb_bus *bus)
+{
+ /* status register only exists on chipcomon rev >= 11 and we need check
+ for >= 31 only */
+ /* this routine differs from specs as we do not access SPROM directly
+ on PCMCIA */
+ if (bus->bustype == SSB_BUSTYPE_PCI &&
+ bus->chipco.dev && /* can be unavailible! */
+ bus->chipco.dev->id.revision >= 31)
+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
+
+ return true;
+}
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -306,6 +306,7 @@ struct ssb_bus {
u16 chip_id;
u16 chip_rev;
u16 sprom_size; /* number of words in sprom */
+ u16 sprom_offset;
u8 chip_package;
/* List of devices (cores) on the backplane. */
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -46,6 +46,7 @@
#define SSB_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
#define SSB_CHIPCO_CAP_PCTL 0x00040000 /* Power Control */
#define SSB_CHIPCO_CAP_OTPS 0x00380000 /* OTP size */
+#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */
#define SSB_CHIPCO_CAP_OTPS_SHIFT 19
#define SSB_CHIPCO_CAP_OTPS_BASE 5
#define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */
@@ -564,6 +565,7 @@ struct ssb_chipcommon_pmu {
struct ssb_chipcommon {
struct ssb_device *dev;
u32 capabilities;
+ u32 status;
/* Fast Powerup Delay constant */
u16 fast_pwrup_delay;
struct ssb_chipcommon_pmu pmu;
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -170,7 +170,8 @@
#define SSB_SPROMSIZE_WORDS_R4 220
#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
-#define SSB_SPROM_BASE 0x1000
+#define SSB_SPROM_BASE1 0x1000
+#define SSB_SPROM_BASE31 0x0800
#define SSB_SPROM_REVISION 0x107E
#define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */
#define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */
From 5ce8ba7c9279a63f99e1f131602580472b8af968 Mon Sep 17 00:00:00 2001
From: Adam Jackson <ajax@redhat.com>
Date: Thu, 15 Apr 2010 14:03:30 -0400

View File

@ -1,2 +1,3 @@
c3883760b18d50e8d78819c54d579b00 linux-2.6.33.tar.bz2
04b3affb4f7fb3035303a32bd6080baf patch-2.6.33.7.bz2
422e1fc4ee7dde101435f0d8555b51a3 patch-2.6.33.7-8.bz2

View File

@ -1,185 +0,0 @@
From 380bed7aa858cbe2d4eeb783e2bed7d01828518d Mon Sep 17 00:00:00 2001
From: John W. Linville <linville@tuxdriver.com>
Date: Fri, 19 Mar 2010 14:58:01 -0400
Subject: [PATCH v4] ssb: do not read SPROM if it does not exist
Attempting to read registers that don't exist on the SSB bus can cause
hangs on some boxes. At least some b43 devices are 'in the wild' that
don't have SPROMs at all. When the SSB bus support loads, it attempts
to read these (non-existant) SPROMs and causes hard hangs on the box --
no console output, etc.
This patch adds some intelligence to determine whether or not the SPROM
is present before attempting to read it. This avoids those hard hangs
on those devices with no SPROM attached to their SSB bus. The
SSB-attached devices (e.g. b43, et al.) won't work, but at least the box
will survive to test further patches. :-)
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Cc: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Michael Buesch <mb@bu3sch.de>
Cc: stable@kernel.org
---
Version 4, move read of ChipCommon status register to ssb_chipcommon_init
Version 3, add missing semi-colon... :-(
Version 2, check the correct place for ChipCommon core revision... :-)
drivers/ssb/driver_chipcommon.c | 3 +++
drivers/ssb/pci.c | 3 +++
drivers/ssb/sprom.c | 22 ++++++++++++++++++++++
include/linux/ssb/ssb.h | 3 +++
include/linux/ssb/ssb_driver_chipcommon.h | 15 +++++++++++++++
5 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index 9681536..6cf288d 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -233,6 +233,9 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
{
if (!cc->dev)
return; /* We don't have a ChipCommon */
+ if (cc->dev->id.revision >= 11) {
+ cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
+ }
ssb_pmu_init(cc);
chipco_powercontrol_init(cc);
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 9e50896..2f7b16d 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -620,6 +620,9 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
int err = -ENOMEM;
u16 *buf;
+ if (!ssb_is_sprom_available(bus))
+ return -ENODEV;
+
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
if (!buf)
goto out;
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index d0e6762..55eb9b0 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -175,3 +175,25 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void)
{
return fallback_sprom;
}
+
+bool ssb_is_sprom_available(struct ssb_bus *bus)
+{
+ /* status register only exists on chipcomon rev >= 11 */
+ if (bus->chipco.dev->id.revision < 11)
+ return true;
+
+ switch (bus->chip_id) {
+ case 0x4312:
+ return SSB_CHIPCO_CHST_4312_SPROM_PRESENT(bus->chipco.status);
+ case 0x4322:
+ return SSB_CHIPCO_CHST_4322_SPROM_PRESENT(bus->chipco.status);
+ case 0x4325:
+ return SSB_CHIPCO_CHST_4325_SPROM_PRESENT(bus->chipco.status);
+ default:
+ break;
+ }
+ if (bus->chipco.dev->id.revision >= 31)
+ return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
+
+ return true;
+}
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 24f9885..3b4da23 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -394,6 +394,9 @@ extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
extern void ssb_bus_unregister(struct ssb_bus *bus);
+/* Does the device have an SPROM? */
+extern bool ssb_is_sprom_available(struct ssb_bus *bus);
+
/* Set a fallback SPROM.
* See kdoc at the function definition for complete documentation. */
extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 4e27acf..2cdf249 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -53,6 +53,7 @@
#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
#define SSB_CHIPCO_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
#define SSB_CHIPCO_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
+#define SSB_CHIPCO_CAP_SPROM 0x40000000 /* SPROM present */
#define SSB_CHIPCO_CORECTL 0x0008
#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
@@ -385,6 +386,7 @@
/** Chip specific Chip-Status register contents. */
+#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS 0x00000040 /* SPROM present */
#define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL 0x00000003
#define SSB_CHIPCO_CHST_4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */
#define SSB_CHIPCO_CHST_4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */
@@ -398,6 +400,18 @@
#define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT 4
#define SSB_CHIPCO_CHST_4325_PMUTOP_2B 0x00000200 /* 1 for 2b, 0 for to 2a */
+/** Macros to determine SPROM presence based on Chip-Status register. */
+#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \
+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
+ SSB_CHIPCO_CHST_4325_OTP_SEL)
+#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \
+ (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS)
+#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \
+ (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
+ SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \
+ ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
+ SSB_CHIPCO_CHST_4325_OTP_SEL))
+
/** Clockcontrol masks and values **/
@@ -564,6 +578,7 @@ struct ssb_chipcommon_pmu {
struct ssb_chipcommon {
struct ssb_device *dev;
u32 capabilities;
+ u32 status;
/* Fast Powerup Delay constant */
u16 fast_pwrup_delay;
struct ssb_chipcommon_pmu pmu;
--
1.6.2.5
From ec032742062ad1b01dfe75cfccdbc5b850837c23 Mon Sep 17 00:00:00 2001
From: John W. Linville <linville@tuxdriver.com>
Date: Tue, 30 Mar 2010 13:47:39 -0400
Subject: [PATCH] ssb: avoid null ptr deref in ssb_is_sprom_available
Some older devices don't have chipcommon, but they do have SPROM.
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/ssb/sprom.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
index 55eb9b0..874d8f1 100644
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -178,6 +178,10 @@ const struct ssb_sprom *ssb_get_fallback_sprom(void)
bool ssb_is_sprom_available(struct ssb_bus *bus)
{
+ /* some older devices don't have chipcommon, but they have sprom */
+ if (!bus->chipco.dev)
+ return true;
+
/* status register only exists on chipcomon rev >= 11 */
if (bus->chipco.dev->id.revision < 11)
return true;
--
1.6.2.5