Skip to content

Commit

Permalink
[PATCH] pcmcia: properly handle pseudo multi-function devices
Browse files Browse the repository at this point in the history
The second pseudo multi-function device of a PCMCIA card may only be
configured once the first one is initialized. Therefore, delay the
registration of the second device until the first one is initialized.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net
  • Loading branch information
Dominik Brodowski committed Mar 1, 2006
1 parent 96789ac commit 82d56e6
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,11 +352,20 @@ static void pcmcia_release_dev(struct device *dev)
kfree(p_dev);
}

static void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
{
if (!s->pcmcia_state.device_add_pending) {
s->pcmcia_state.device_add_pending = 1;
schedule_work(&s->device_add);
}
return;
}

static int pcmcia_device_probe(struct device * dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
struct pcmcia_device_id *did;
struct pcmcia_socket *s;
int ret = 0;

Expand Down Expand Up @@ -392,6 +401,19 @@ static int pcmcia_device_probe(struct device * dev)
}

ret = p_drv->probe(p_dev);
if (ret)
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 = (struct pcmcia_device_id *) p_dev->dev.driver_data;
if ((did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
(p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
pcmcia_add_pseudo_device(p_dev->socket);

put_module:
if (ret)
Expand Down Expand Up @@ -660,15 +682,6 @@ static void pcmcia_delayed_add_pseudo_device(void *data)
s->pcmcia_state.device_add_pending = 0;
}

static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
{
if (!s->pcmcia_state.device_add_pending) {
s->pcmcia_state.device_add_pending = 1;
schedule_work(&s->device_add);
}
return;
}

static int pcmcia_requery(struct device *dev, void * _data)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
Expand Down Expand Up @@ -755,15 +768,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
}

if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
/* 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.
*/
if (dev->device_no == 0)
pcmcia_add_pseudo_device(dev->socket);

if (dev->device_no != did->device_no)
return 0;
}
Expand Down

0 comments on commit 82d56e6

Please sign in to comment.