--- /dev/null
+From linux@dominikbrodowski.net Thu Oct 2 13:39:56 2008
+From: Alan Cox <alan@redhat.com>
+Date: Thu, 2 Oct 2008 09:53:38 +0200
+Subject: pcmcia: Fix broken abuse of dev->driver_data
+To: stable@kernel.org
+Message-ID: <20081002075338.GA27413@isilmar.linta.de>
+Content-Disposition: inline
+
+
+From: Alan Cox <alan@redhat.com>
+
+[ Upstream commit: cec5eb7be3a104fffd27ca967ee8e15a123050e2 ]
+
+PCMCIA abuses dev->private_data in the probe methods. Unfortunately it
+continues to abuse it after calling drv->probe() which leads to crashes and
+other nasties (such as bogus probes of multifunction devices) giving errors like
+
+pcmcia: registering new device pcmcia0.1
+kernel: 0.1: GetNextTuple: No more items
+
+Extract the passed data before calling the driver probe function that way
+we don't blow up when the driver reuses dev->private_data as its right.
+
+Signed-off-by: Alan Cox <alan@redhat.com>
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pcmcia/ds.c | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+--- a/drivers/pcmcia/ds.c
++++ b/drivers/pcmcia/ds.c
+@@ -428,6 +428,18 @@ static int pcmcia_device_probe(struct de
+ p_drv = to_pcmcia_drv(dev->driver);
+ s = p_dev->socket;
+
++ /* The PCMCIA code passes the match data in via dev->driver_data
++ * which is an ugly hack. Once the driver probe is called it may
++ * and often will overwrite the match data so we must save it first
++ *
++ * handle pseudo multifunction devices:
++ * there are at most two pseudo multifunction devices.
++ * if we're matching against the first, schedule a
++ * call which will then check whether there are two
++ * pseudo devices, and if not, add the second one.
++ */
++ did = p_dev->dev.driver_data;
++
+ ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
+ p_drv->drv.name);
+
+@@ -456,21 +468,14 @@ static int pcmcia_device_probe(struct de
+ goto put_module;
+ }
+
+- /* handle pseudo multifunction devices:
+- * there are at most two pseudo multifunction devices.
+- * if we're matching against the first, schedule a
+- * call which will then check whether there are two
+- * pseudo devices, and if not, add the second one.
+- */
+- did = p_dev->dev.driver_data;
+ if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
+ (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
+ pcmcia_add_device_later(p_dev->socket, 0);
+
+- put_module:
++put_module:
+ if (ret)
+ module_put(p_drv->owner);
+- put_dev:
++put_dev:
+ if (ret)
+ put_device(dev);
+ return (ret);