* [PATCH] reduce size of bridge regions for yenta.c
@ 2002-08-24 15:03 Manfred Spraul
2002-08-24 17:18 ` Manfred Spraul
0 siblings, 1 reply; 2+ messages in thread
From: Manfred Spraul @ 2002-08-24 15:03 UTC (permalink / raw)
To: linux-kernel; +Cc: torvalds, dhinds
[-- Attachment #1: Type: text/plain, Size: 529 bytes --]
yenta.c tries to allocate 2 bridge regions, each 4 MB: one for
prefetchable memory, one for non-prefetchable memory.
The size of the regions must be adaptive: in my laptop, the cardbus
bridge sits behind a pci bridge with a 1 MB bridge region :-(
The attached patch:
- limits the memory window to 1/8 of the window of the parent bridge
(max 4 MB, min 16 kB)
- frees the resources during module unload
- adds error checking+printk
Please test it - my laptop now works.
Patch vs. 2.4.19, applies to 2.5.30, too.
--
Manfred
[-- Attachment #2: patch-yenta --]
[-- Type: text/plain, Size: 2732 bytes --]
--- 2.4/drivers/pcmcia/yenta.c Sat Aug 3 02:39:44 2002
+++ build-2.4/drivers/pcmcia/yenta.c Sat Aug 24 16:59:34 2002
@@ -2,6 +2,11 @@
* Regular lowlevel cardbus driver ("yenta")
*
* (C) Copyright 1999, 2000 Linus Torvalds
+ *
+ * Changelog:
+ * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
+ * Dynamically adjust the size of the bridge resource
+ *
*/
#include <linux/init.h>
#include <linux/pci.h>
@@ -704,6 +709,15 @@
return 0;
}
+/*
+ * Use an adaptive allocation for the memory resource,
+ * sometimes the size behind pci bridges is limited:
+ * 1/8 of the size of the io window of the parent.
+ * max 4 MB, min 16 kB.
+ */
+#define BRIDGE_SIZE_MAX 4*1024*1024
+#define BRIDGE_SIZE_MIN 16*1024
+
static void yenta_allocate_res(pci_socket_t *socket, int nr, unsigned type)
{
struct pci_bus *bus;
@@ -735,21 +749,42 @@
if (start && end > start) {
res->start = start;
res->end = end;
- request_resource(root, res);
- return;
+ if (request_resource(root, res) == 0)
+ return;
+ printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
+ socket->dev->slot_name, nr);
+ res->start = res->end = 0;
}
- align = size = 4*1024*1024;
- min = PCIBIOS_MIN_MEM; max = ~0U;
if (type & IORESOURCE_IO) {
align = 1024;
size = 256;
min = 0x4000;
max = 0xffff;
+ } else {
+ unsigned long avail = root->end - root->start;
+ int i;
+ align = size = BRIDGE_SIZE_MAX;
+ if (size > avail/8) {
+ size=(avail+1)/8;
+ /* round size down to next power of 2 */
+ i = 0;
+ while ((size /= 2) != 0)
+ i++;
+ size = 1 << i;
+ }
+ if (size < BRIDGE_SIZE_MIN)
+ size = BRIDGE_SIZE_MIN;
+ align = size;
+ min = PCIBIOS_MIN_MEM; max = ~0U;
}
- if (allocate_resource(root, res, size, min, max, align, NULL, NULL) < 0)
+ if (allocate_resource(root, res, size, min, max, align, NULL, NULL) < 0) {
+ printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
+ socket->dev->slot_name, type);
+ res->start = res->end = 0;
return;
+ }
config_writel(socket, offset, res->start);
config_writel(socket, offset+4, res->end);
@@ -767,6 +802,20 @@
}
/*
+ * Free the bridge mappings for the device..
+ */
+static void yenta_free_resources(pci_socket_t *socket)
+{
+ int i;
+ for (i=0;i<4;i++) {
+ struct resource *res;
+ res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
+ if (res->start != 0 && res->end != 0)
+ release_resource(res);
+ res->start = res->end = 0;
+ }
+}
+/*
* Close it down - release our resources and go home..
*/
static void yenta_close(pci_socket_t *sock)
@@ -782,6 +831,7 @@
if (sock->base)
iounmap(sock->base);
+ yenta_free_resources(sock);
}
#include "ti113x.h"
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] reduce size of bridge regions for yenta.c
2002-08-24 15:03 [PATCH] reduce size of bridge regions for yenta.c Manfred Spraul
@ 2002-08-24 17:18 ` Manfred Spraul
0 siblings, 0 replies; 2+ messages in thread
From: Manfred Spraul @ 2002-08-24 17:18 UTC (permalink / raw)
To: Manfred Spraul; +Cc: linux-kernel, torvalds, dhinds
dhinds pointed me to a recent thread with another possible workaround:
The ICH-3M bridge is actually a transparent bridge that forwards all
memory IO:
<<<< ich-3M datasheet (29071601.pdf)
MEMBASE Memory Base Register (HUB-PCI D30:F0)
Offset Address: 20 21h Attribute: R/W
Default Value: FFF0h Size: 16 bits
This register defines the base of the hub interface to PCI
non-prefetchable memory range. Since the ICH3 will forward all hub
interface memory accesses to PCI, the ICH3 will only use this
information for determining when not to accept cycles as a target. This
register must be initialized by the configuration software. For the
purpose of address decode, address bits A[19:0] are assumed to be 0.
Thus, the bottom of the defined memory address range will be aligned to
a 1-MB boundary.
<<<<
Perhaps a pci-quirk should set
bus->resource[1] = bus->parent->resource[1];
for the ICH-3M.
No patch, I don't understand the pci layer good enough to write such a
quirk.
But IMHO the changes to yenta.c should be applied anyway: allocating 8
MB, without any fallback, without reasonable error output is gross.
--
Manfred
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2002-08-24 17:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-24 15:03 [PATCH] reduce size of bridge regions for yenta.c Manfred Spraul
2002-08-24 17:18 ` Manfred Spraul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox