Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cec5eb7b authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds
Browse files

pcmcia: Fix broken abuse of dev->driver_data



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.

As its close to the final release just move the hack so it works out,
hopefully someone will be sufficiently embarrassed to produce a nice rework
for 2.6.28.

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ae911191
Loading
Loading
Loading
Loading
+14 −9
Original line number Original line Diff line number Diff line
@@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev)
	p_drv = to_pcmcia_drv(dev->driver);
	p_drv = to_pcmcia_drv(dev->driver);
	s = p_dev->socket;
	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,
	ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
	       p_drv->drv.name);
	       p_drv->drv.name);


@@ -455,13 +467,6 @@ static int pcmcia_device_probe(struct device * dev)
		goto put_module;
		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) &&
	if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
	    (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
		pcmcia_add_device_later(p_dev->socket, 0);
		pcmcia_add_device_later(p_dev->socket, 0);