All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
	Zwane Mwaikambo <zwane@arm.linux.org.uk>,
	Theodore Ts'o <tytso@mit.edu>,
	Randy Dunlap <rdunlap@xenotime.net>,
	Dave Jones <davej@redhat.com>,
	Chuck Wolber <chuckw@quantumlinux.com>,
	Chris Wedgwood <reviews@ml.cw.f00f.org>,
	Michael Krufky <mkrufky@linuxtv.org>,
	Chuck Ebbert <cebbert@redhat.com>,
	Domenico Andreoli <cavokz@gmail.com>,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, linux-wireless@vger.kernel.org,
	bcm43xx-dev@lists.berlios.de, Michael Buesch <mb@bu3sch.de>,
	"John W. Linville" <linville@tuxdriver.com>
Subject: [25/37] b43: Workaround DMA quirks
Date: Tue, 29 Apr 2008 10:18:55 -0700	[thread overview]
Message-ID: <20080429171855.GZ14724@suse.de> (raw)
In-Reply-To: <20080429171730.GA14724@suse.de>

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

------------------
From: Michael Buesch <mb@bu3sch.de>

commit 1033b3ea11820ea1fb1b877207bd6724e9aaedc3 upstream

Some mainboards/CPUs don't allow DMA masks bigger than a certain limit.
Some VIA crap^h^h^h^hdevices have an upper limit of 0xFFFFFFFF. So in this
case a 64-bit b43 device would always fail to acquire the mask.
Implement a workaround to fallback to lower DMA mask, as we can always
also support a lower mask.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>


---
 drivers/net/wireless/b43/dma.c |   73 +++++++++++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 21 deletions(-)

--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -822,6 +822,18 @@ static u64 supported_dma_mask(struct b43
 	return DMA_30BIT_MASK;
 }
 
+static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
+{
+	if (dmamask == DMA_30BIT_MASK)
+		return B43_DMA_30BIT;
+	if (dmamask == DMA_32BIT_MASK)
+		return B43_DMA_32BIT;
+	if (dmamask == DMA_64BIT_MASK)
+		return B43_DMA_64BIT;
+	B43_WARN_ON(1);
+	return B43_DMA_30BIT;
+}
+
 /* Main initialization function. */
 static
 struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
@@ -982,6 +994,42 @@ void b43_dma_free(struct b43_wldev *dev)
 	dma->tx_ring0 = NULL;
 }
 
+static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
+{
+	u64 orig_mask = mask;
+	bool fallback = 0;
+	int err;
+
+	/* Try to set the DMA mask. If it fails, try falling back to a
+	 * lower mask, as we can always also support a lower one. */
+	while (1) {
+		err = ssb_dma_set_mask(dev->dev, mask);
+		if (!err)
+			break;
+		if (mask == DMA_64BIT_MASK) {
+			mask = DMA_32BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		if (mask == DMA_32BIT_MASK) {
+			mask = DMA_30BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		b43err(dev->wl, "The machine/kernel does not support "
+		       "the required %u-bit DMA mask\n",
+		       (unsigned int)dma_mask_to_engine_type(orig_mask));
+		return -EOPNOTSUPP;
+	}
+	if (fallback) {
+		b43info(dev->wl, "DMA mask fallback from %u-bit to %u-bit\n",
+			(unsigned int)dma_mask_to_engine_type(orig_mask),
+			(unsigned int)dma_mask_to_engine_type(mask));
+	}
+
+	return 0;
+}
+
 int b43_dma_init(struct b43_wldev *dev)
 {
 	struct b43_dma *dma = &dev->dma;
@@ -991,27 +1039,10 @@ int b43_dma_init(struct b43_wldev *dev)
 	enum b43_dmatype type;
 
 	dmamask = supported_dma_mask(dev);
-	switch (dmamask) {
-	default:
-		B43_WARN_ON(1);
-	case DMA_30BIT_MASK:
-		type = B43_DMA_30BIT;
-		break;
-	case DMA_32BIT_MASK:
-		type = B43_DMA_32BIT;
-		break;
-	case DMA_64BIT_MASK:
-		type = B43_DMA_64BIT;
-		break;
-	}
-	err = ssb_dma_set_mask(dev->dev, dmamask);
-	if (err) {
-		b43err(dev->wl, "The machine/kernel does not support "
-		       "the required DMA mask (0x%08X%08X)\n",
-		       (unsigned int)((dmamask & 0xFFFFFFFF00000000ULL) >> 32),
-		       (unsigned int)(dmamask & 0x00000000FFFFFFFFULL));
-		return -EOPNOTSUPP;
-	}
+	type = dma_mask_to_engine_type(dmamask);
+	err = b43_dma_set_mask(dev, dmamask);
+	if (err)
+		return err;
 
 	err = -ENOMEM;
 	/* setup TX DMA channels. */

-- 

WARNING: multiple messages have this Message-ID (diff)
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
	Zwane Mwaikambo <zwane@arm.linux.org.uk>,
	"Theodore Ts'o" <tytso@mit.edu>,
	Randy Dunlap <rdunlap@xenotime.net>,
	Dave Jones <davej@redhat.com>,
	Chuck Wolber <chuckw@quantumlinux.com>,
	Chris Wedgwood <reviews@ml.cw.f00f.org>,
	Michael Krufky <mkrufky@linuxtv.org>,
	Chuck Ebbert <cebbert@redhat.com>,
	Domenico Andreoli <cavokz@gmail.com>,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, linux-wireless@vger.kernel.org,
	bcm43xx-dev@lists.berlios.de, Michael Buesch <mb@bu3sch.de>,
	"John W. Linville" <linville@tuxdriver.com>
Subject: [25/37] b43: Workaround DMA quirks
Date: Tue, 29 Apr 2008 10:18:55 -0700	[thread overview]
Message-ID: <20080429171855.GZ14724@suse.de> (raw)
In-Reply-To: <20080429171730.GA14724@suse.de>

[-- Attachment #1: b43-workaround-dma-quirks.patch --]
[-- Type: text/plain, Size: 3240 bytes --]

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

------------------
From: Michael Buesch <mb@bu3sch.de>

commit 1033b3ea11820ea1fb1b877207bd6724e9aaedc3 upstream

Some mainboards/CPUs don't allow DMA masks bigger than a certain limit.
Some VIA crap^h^h^h^hdevices have an upper limit of 0xFFFFFFFF. So in this
case a 64-bit b43 device would always fail to acquire the mask.
Implement a workaround to fallback to lower DMA mask, as we can always
also support a lower mask.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>


---
 drivers/net/wireless/b43/dma.c |   73 +++++++++++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 21 deletions(-)

--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -822,6 +822,18 @@ static u64 supported_dma_mask(struct b43
 	return DMA_30BIT_MASK;
 }
 
+static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
+{
+	if (dmamask == DMA_30BIT_MASK)
+		return B43_DMA_30BIT;
+	if (dmamask == DMA_32BIT_MASK)
+		return B43_DMA_32BIT;
+	if (dmamask == DMA_64BIT_MASK)
+		return B43_DMA_64BIT;
+	B43_WARN_ON(1);
+	return B43_DMA_30BIT;
+}
+
 /* Main initialization function. */
 static
 struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
@@ -982,6 +994,42 @@ void b43_dma_free(struct b43_wldev *dev)
 	dma->tx_ring0 = NULL;
 }
 
+static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
+{
+	u64 orig_mask = mask;
+	bool fallback = 0;
+	int err;
+
+	/* Try to set the DMA mask. If it fails, try falling back to a
+	 * lower mask, as we can always also support a lower one. */
+	while (1) {
+		err = ssb_dma_set_mask(dev->dev, mask);
+		if (!err)
+			break;
+		if (mask == DMA_64BIT_MASK) {
+			mask = DMA_32BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		if (mask == DMA_32BIT_MASK) {
+			mask = DMA_30BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		b43err(dev->wl, "The machine/kernel does not support "
+		       "the required %u-bit DMA mask\n",
+		       (unsigned int)dma_mask_to_engine_type(orig_mask));
+		return -EOPNOTSUPP;
+	}
+	if (fallback) {
+		b43info(dev->wl, "DMA mask fallback from %u-bit to %u-bit\n",
+			(unsigned int)dma_mask_to_engine_type(orig_mask),
+			(unsigned int)dma_mask_to_engine_type(mask));
+	}
+
+	return 0;
+}
+
 int b43_dma_init(struct b43_wldev *dev)
 {
 	struct b43_dma *dma = &dev->dma;
@@ -991,27 +1039,10 @@ int b43_dma_init(struct b43_wldev *dev)
 	enum b43_dmatype type;
 
 	dmamask = supported_dma_mask(dev);
-	switch (dmamask) {
-	default:
-		B43_WARN_ON(1);
-	case DMA_30BIT_MASK:
-		type = B43_DMA_30BIT;
-		break;
-	case DMA_32BIT_MASK:
-		type = B43_DMA_32BIT;
-		break;
-	case DMA_64BIT_MASK:
-		type = B43_DMA_64BIT;
-		break;
-	}
-	err = ssb_dma_set_mask(dev->dev, dmamask);
-	if (err) {
-		b43err(dev->wl, "The machine/kernel does not support "
-		       "the required DMA mask (0x%08X%08X)\n",
-		       (unsigned int)((dmamask & 0xFFFFFFFF00000000ULL) >> 32),
-		       (unsigned int)(dmamask & 0x00000000FFFFFFFFULL));
-		return -EOPNOTSUPP;
-	}
+	type = dma_mask_to_engine_type(dmamask);
+	err = b43_dma_set_mask(dev, dmamask);
+	if (err)
+		return err;
 
 	err = -ENOMEM;
 	/* setup TX DMA channels. */

-- 

  parent reply	other threads:[~2008-04-29 17:21 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20080429171222.073929148@mini.kroah.org>
2008-04-29 17:17 ` [00/37] 2.6.25-stable review Greg KH
2008-04-29 17:17   ` [01/37] USB: log an error message when USB enumeration fails Greg KH
2008-04-29 17:17   ` [02/37] USB: Add HP hs2300 Broadband Wireless Module to sierra.c Greg KH
2008-04-29 17:17   ` [03/37] JFFS2: Fix free space leak with in-band cleanmarkers Greg KH
2008-04-29 17:17     ` Greg KH
2008-04-29 17:18   ` [04/37] tg3: 5701 DMA corruption fix Greg KH
2008-04-29 17:18   ` [05/37] tcp: tcp_probe buffer overflow and incorrect return value Greg KH
2008-04-29 17:18   ` [07/37] RTNETLINK: Fix bogus ASSERT_RTNL warning Greg KH
2008-04-29 17:18   ` [08/37] rose: Socket lock was not released before returning to user space Greg KH
2008-04-29 17:18   ` [09/37] net: Fix wrong interpretation of some copy_to_user() results Greg KH
2008-04-29 17:18   ` [10/37] IPSEC: Fix catch-22 with algorithm IDs above 31 Greg KH
2008-04-29 17:18   ` [11/37] USB: OHCI: fix bug in controller resume Greg KH
2008-04-29 17:18   ` [12/37] dm snapshot: fix chunksize sector conversion Greg KH
2008-04-29 17:18   ` [13/37] cgroup: fix a race condition in manipulating tsk->cg_list Greg KH
2008-04-29 17:18   ` [14/37] RDMA/nes: Free IRQ before killing tasklet Greg KH
2008-04-29 17:18   ` [15/37] V4L: Fix VIDIOCGAP corruption in ivtv Greg KH
2008-04-29 17:18   ` [16/37] V4L: tea5761: bugzilla #10462: tea5761 autodetection code were broken Greg KH
2008-04-29 17:18   ` [17/37] V4L: cx88: enable radio GPIO correctly Greg KH
2008-04-29 17:18   ` [18/37] S2io: Fix memory leak during free_tx_buffers Greg KH
2008-04-29 17:18   ` [19/37] S2io: Version update for memory leak fix " Greg KH
2008-04-29 17:18   ` [20/37] SELinux: no BUG_ON(!ss_initialized) in selinux_clone_mnt_opts Greg KH
2008-04-29 17:18     ` Greg KH
2008-04-29 17:18   ` [21/37] x86, pci: fix off-by-one errors in some pirq warnings Greg KH
2008-04-29 17:18   ` [22/37] ssb: Fix all-ones boardflags Greg KH
2008-04-29 17:18     ` Greg KH
2008-04-29 17:18   ` [23/37] b43: Workaround invalid bluetooth settings Greg KH
2008-04-29 17:18     ` Greg KH
2008-04-29 17:18   ` [24/37] b43: Add more btcoexist workarounds Greg KH
2008-04-29 17:18     ` Greg KH
2008-04-29 17:18   ` Greg KH [this message]
2008-04-29 17:18     ` [25/37] b43: Workaround DMA quirks Greg KH
2008-04-29 17:18   ` [26/37] tehuti: check register size (CVE-2008-1675) Greg KH
2008-04-29 17:19   ` [27/37] tehuti: move ioctl perm check closer to function start (CVE-2008-1675) Greg KH
2008-04-29 18:13     ` Alan Cox
2008-04-29 18:55       ` Greg KH
2008-04-29 19:02         ` Linus Torvalds
2008-04-30 16:39           ` [stable] " Greg KH
2008-04-29 17:19   ` [28/37] aio: io_getevents() should return if io_destroy() is invoked Greg KH
2008-04-29 17:19   ` [29/37] rtc-pcf8583 build fix Greg KH
2008-04-29 17:19   ` [30/37] dz: test after postfix decrement fails in dz_console_putchar() Greg KH
2008-04-29 17:19   ` [31/37] mm: fix possible off-by-one in walk_pte_range() Greg KH
2008-04-29 17:19   ` [32/37] hrtimer: timeout too long when using HRTIMER_CB_SOFTIRQ Greg KH
2008-04-29 17:19   ` [33/37] RDMA/nes: Fix adapter reset after PXE boot Greg KH
2008-04-29 17:19   ` [34/37] SCSI: qla2xxx: Correct regression in relogin code Greg KH
2008-04-29 17:19   ` [35/37] alpha: unbreak OSF/1 (a.out) binaries Greg KH
2008-04-29 17:19   ` [36/37] x86: Fix 32-bit x86 MSI-X allocation leakage Greg KH
2008-04-29 17:19   ` [37/37] hrtimer: raise softirq unlocked to avoid circular lock dependency Greg KH
2008-04-30  7:58   ` [00/37] 2.6.25-stable review Andre Noll
2008-05-01  0:25     ` [stable] " Chris Wright

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080429171855.GZ14724@suse.de \
    --to=gregkh@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=bcm43xx-dev@lists.berlios.de \
    --cc=cavokz@gmail.com \
    --cc=cebbert@redhat.com \
    --cc=chuckw@quantumlinux.com \
    --cc=davej@redhat.com \
    --cc=jmforbes@linuxtx.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=mb@bu3sch.de \
    --cc=mkrufky@linuxtv.org \
    --cc=rdunlap@xenotime.net \
    --cc=reviews@ml.cw.f00f.org \
    --cc=stable@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=tytso@mit.edu \
    --cc=zwane@arm.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.