Skip to content

Commit

Permalink
pcmcia: Fix broken abuse of dev->driver_data
Browse files Browse the repository at this point in the history
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: Alan Cox <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Alan Cox authored and torvalds committed Sep 22, 2008
1 parent ae91119 commit cec5eb7
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev)
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);

Expand Down Expand Up @@ -455,21 +467,14 @@ static int pcmcia_device_probe(struct device * dev)
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);
Expand Down

0 comments on commit cec5eb7

Please sign in to comment.