Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 25108
b: refs/heads/master
c: d6ff5a8
h: refs/heads/master
v: v3
  • Loading branch information
Dominik Brodowski committed Mar 31, 2006
1 parent cf822ab commit 2389448
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9940ec3617fec1db13e589bbc3f37e37878c7683
refs/heads/master: d6ff5a8532b553e4d85ea65c99eaa0794edf5311
81 changes: 48 additions & 33 deletions trunk/drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,15 +415,61 @@ static int pcmcia_device_probe(struct device * dev)
}


/*
* Removes a PCMCIA card from the device tree and socket list.
*/
static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover)
{
struct pcmcia_device *p_dev;
struct pcmcia_device *tmp;
unsigned long flags;

ds_dbg(2, "unbind_request(%d)\n", s->sock);


if (!leftover)
s->device_count = 0;
else
s->device_count = 1;

/* unregister all pcmcia_devices registered with this socket, except leftover */
list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
if (p_dev == leftover)
continue;

spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
list_del(&p_dev->socket_device_list);
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);

device_unregister(&p_dev->dev);
}

return;
}


static int pcmcia_device_remove(struct device * dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
struct pcmcia_device_id *did;
int i;

/* detach the "instance" */
p_dev = to_pcmcia_dev(dev);
p_drv = to_pcmcia_drv(dev->driver);

/* If we're removing the primary module driving a
* pseudo multi-function card, we need to unbind
* all devices
*/
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 != 0) &&
(p_dev->device_no == 0))
pcmcia_card_remove(p_dev->socket, p_dev);

/* detach the "instance" */
if (!p_drv)
return 0;

Expand All @@ -448,37 +494,6 @@ static int pcmcia_device_remove(struct device * dev)
}


/*
* Removes a PCMCIA card from the device tree and socket list.
*/
static void pcmcia_card_remove(struct pcmcia_socket *s)
{
struct pcmcia_device *p_dev;
unsigned long flags;

ds_dbg(2, "unbind_request(%d)\n", s->sock);

s->device_count = 0;

for (;;) {
/* unregister all pcmcia_devices registered with this socket*/
spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
if (list_empty(&s->devices_list)) {
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
return;
}
p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
list_del(&p_dev->socket_device_list);
p_dev->_removed=1;
spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);

device_unregister(&p_dev->dev);
}

return;
} /* unbind_request */


/*
* pcmcia_device_query -- determine information about a pcmcia device
*/
Expand Down Expand Up @@ -1136,7 +1151,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
switch (event) {
case CS_EVENT_CARD_REMOVAL:
s->pcmcia_state.present = 0;
pcmcia_card_remove(skt);
pcmcia_card_remove(skt, NULL);
handle_event(skt, event);
break;

Expand Down

0 comments on commit 2389448

Please sign in to comment.