lkml.org 
[lkml]   [2001]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] yet another yenta resource allocation fix

Hi Linus,

I'm asking for application of a patch I'm using since 2.4.0. Issue was the
BIOS of my OB-800 mapped the memory regions of the cardbus bridges into
legacy 1M-area (0xe6000 e.g.). Despite being pretty bogus this used to
work after a reboot just until the first pm-suspend/resume, where the
hostbridge somehow looses access to this area.

Following your suggestion, I've modified pci_socket.c to detect and fix
the wrong mapping. However, I'm not sure whether there is some general
rule if such fixes should be considered cardbus-specific or general
pci-quirks.

Anyway, the patch vs. 2.4.10 below intercepts the cardbus_probe() path to
detect and fix this before any yenta socket gets opened - which would call
pci_enable_device(). Works for me for months now, so I'd like to suggest
to have it included.

Regards
Martin

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

--- linux-2.4.10/drivers/pcmcia/pci_socket.c Sat Aug 4 13:20:45 2001
+++ v2.4.10-md/drivers/pcmcia/pci_socket.c Sun Sep 30 19:11:18 2001
@@ -169,6 +169,72 @@
pci_proc_setup
};

+/* BIOS might have mapped the cardbus memory resource to a bogus location
+ * in legacy memory area and the hostbridge somehow looses this window
+ * after pm-suspend (seen on OB800).
+ * We try to detect and fix this by re-assigning the resource if we
+ * find it mapped to legacy area <1M. But we don't try, if the obsolete
+ * MEM_TYPE_1M flag is set, just in case...
+ * Question remains, whether this quirk is cardbus-specific or general PCI.
+ */
+
+static void __devinit cardbus_validate_bar(struct pci_dev *dev)
+{
+ unsigned long oldstart;
+ u32 temp, extend;
+ struct resource *res;
+
+ if (!(dev->resource[0].flags&IORESOURCE_MEM)) /* not cardbus memory BAR */
+ return;
+
+ oldstart = dev->resource[0].start;
+ if (oldstart >= 0x00100000UL) /* not 1MB legacy area - fine! */
+ return;
+
+ /* we need the device powered but not yet enabled */
+
+ pci_set_power_state(dev,0);
+
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &temp);
+ if (temp & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
+ printk(KERN_DEBUG "%s: cardbus memory has obsolete 1M flag set?\n",
+ __FUNCTION__);
+ return;
+ }
+
+ /* re-read required size and flags from device */
+
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffffffff);
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &temp);
+ if (temp & PCI_BASE_ADDRESS_SPACE_IO) { /* paranoia */
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, oldstart);
+ printk(KERN_WARNING "%s: cardbus memory mutated to io?\n",
+ __FUNCTION__);
+ return;
+ }
+ extend = ~(u32)(temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+ /* Old values lost in case of failure (pretty unlikely anyway).
+ * Could we simply save & restore the content without acquiring the
+ * resource list lock (which is private in kernel/resource.c)?
+ */
+
+ res = &dev->resource[0];
+ release_resource(res);
+
+ res->name = dev->name;
+ res->start = 0;
+ res->end = res->start + extend;
+ res->flags = IORESOURCE_MEM;
+ if (temp & PCI_BASE_ADDRESS_MEM_PREFETCH)
+ res->flags |= IORESOURCE_PREFETCH;
+ res->parent = res->child = res->sibling = NULL;
+ pci_assign_resource(dev,0);
+
+ printk(KERN_INFO "%s: cardbus memory mapping fixed: %08lx --> %08lx\n",
+ __FUNCTION__, oldstart, dev->resource[0].start);
+}
+
static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
{
pci_socket_t *socket = nr + pci_socket_array;
@@ -179,6 +245,10 @@
socket->op = ops;
dev->driver_data = socket;
spin_lock_init(&socket->event_lock);
+
+ /* make sure the resource mapping is right, before it gets opened */
+ cardbus_validate_bar(dev);
+
err = socket->op->open(socket);
if(err)
{
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:03    [W:0.069 / U:1.976 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site