Skip to content

Commit

Permalink
pcmcia: split up central event handler
Browse files Browse the repository at this point in the history
Split up the central event handler for 16bit cards into three individual
functions.

Signed-off-by: Dominik Brodowski <[email protected]>
  • Loading branch information
Dominik Brodowski committed Jul 30, 2010
1 parent 216d7cd commit 7b24e79
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 92 deletions.
36 changes: 7 additions & 29 deletions drivers/pcmcia/cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,30 +252,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr)
}
EXPORT_SYMBOL(pcmcia_get_socket_by_nr);

/*
* The central event handler. Send_event() sends an event to the
* 16-bit subsystem, which then calls the relevant device drivers.
* Parse_events() interprets the event bits from
* a card status change report. Do_shutdown() handles the high
* priority stuff associated with a card removal.
*/

/* NOTE: send_event needs to be called with skt->sem held. */

static int send_event(struct pcmcia_socket *s, event_t event, int priority)
{
if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL))
return 0;

dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
event, priority, s->callback);

if (!s->callback)
return 0;

return s->callback->event(s, event, priority);
}

static int socket_reset(struct pcmcia_socket *skt)
{
int status, i;
Expand Down Expand Up @@ -318,7 +294,8 @@ static void socket_shutdown(struct pcmcia_socket *s)

dev_dbg(&s->dev, "shutdown\n");

send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
if (s->callback)
s->callback->remove(s);

mutex_lock(&s->ops_mutex);
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
Expand Down Expand Up @@ -469,7 +446,8 @@ static int socket_insert(struct pcmcia_socket *skt)
dev_dbg(&skt->dev, "insert done\n");
mutex_unlock(&skt->ops_mutex);

send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
skt->callback->add(skt);
} else {
mutex_unlock(&skt->ops_mutex);
socket_shutdown(skt);
Expand Down Expand Up @@ -546,8 +524,8 @@ static int socket_late_resume(struct pcmcia_socket *skt)
return 0;
}
#endif

send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
skt->callback->early_resume(skt);
return 0;
}

Expand Down Expand Up @@ -766,7 +744,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
s->callback = c;

if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
s->callback->add(s);
} else
s->callback = NULL;
err:
Expand Down
7 changes: 4 additions & 3 deletions drivers/pcmcia/cs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
* (C) 2003 - 2008 Dominik Brodowski
* (C) 2003 - 2010 Dominik Brodowski
*
*
* This file contains definitions _only_ needed by the PCMCIA core modules.
Expand Down Expand Up @@ -106,11 +106,12 @@ void cb_free(struct pcmcia_socket *s);

struct pcmcia_callback{
struct module *owner;
int (*event) (struct pcmcia_socket *s,
event_t event, int priority);
int (*add) (struct pcmcia_socket *s);
int (*remove) (struct pcmcia_socket *s);
void (*requery) (struct pcmcia_socket *s);
int (*validate) (struct pcmcia_socket *s, unsigned int *i);
int (*suspend) (struct pcmcia_socket *s);
int (*early_resume) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s);
};

Expand Down
103 changes: 43 additions & 60 deletions drivers/pcmcia/ds.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
*
* (C) 1999 David A. Hinds
* (C) 2003 - 2006 Dominik Brodowski
* (C) 2003 - 2010 Dominik Brodowski
*/

#include <linux/kernel.h>
Expand Down Expand Up @@ -1208,76 +1208,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
return 0;
}

static int pcmcia_bus_remove(struct pcmcia_socket *skt)
{
atomic_set(&skt->present, 0);
pcmcia_card_remove(skt, NULL);

/*======================================================================
mutex_lock(&skt->ops_mutex);
destroy_cis_cache(skt);
pcmcia_cleanup_irq(skt);
mutex_unlock(&skt->ops_mutex);

The card status event handler.
return 0;
}

======================================================================*/
static int pcmcia_bus_add(struct pcmcia_socket *skt)
{
atomic_set(&skt->present, 1);

/* Normally, the event is passed to individual drivers after
* informing userspace. Only for CS_EVENT_CARD_REMOVAL this
* is inversed to maintain historic compatibility.
*/
mutex_lock(&skt->ops_mutex);
skt->pcmcia_state.has_pfc = 0;
destroy_cis_cache(skt); /* to be on the safe side... */
mutex_unlock(&skt->ops_mutex);

static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
{
struct pcmcia_socket *s = pcmcia_get_socket(skt);
pcmcia_card_add(skt);

if (!s) {
dev_printk(KERN_ERR, &skt->dev,
"PCMCIA obtaining reference to socket " \
"failed, event 0x%x lost!\n", event);
return -ENODEV;
}
return 0;
}

dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
{
if (!verify_cis_cache(skt)) {
pcmcia_put_socket(skt);
return 0;
}

switch (event) {
case CS_EVENT_CARD_REMOVAL:
atomic_set(&skt->present, 0);
pcmcia_card_remove(skt, NULL);
mutex_lock(&s->ops_mutex);
destroy_cis_cache(s);
pcmcia_cleanup_irq(s);
mutex_unlock(&s->ops_mutex);
break;
dev_dbg(&skt->dev, "cis mismatch - different card\n");

case CS_EVENT_CARD_INSERTION:
atomic_set(&skt->present, 1);
mutex_lock(&s->ops_mutex);
s->pcmcia_state.has_pfc = 0;
destroy_cis_cache(s); /* to be on the safe side... */
mutex_unlock(&s->ops_mutex);
pcmcia_card_add(skt);
break;

case CS_EVENT_PM_RESUME:
if (verify_cis_cache(skt) != 0) {
dev_dbg(&skt->dev, "cis mismatch - different card\n");
/* first, remove the card */
ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
mutex_lock(&s->ops_mutex);
destroy_cis_cache(skt);
kfree(skt->fake_cis);
skt->fake_cis = NULL;
s->functions = 0;
mutex_unlock(&s->ops_mutex);
/* now, add the new card */
ds_event(skt, CS_EVENT_CARD_INSERTION,
CS_EVENT_PRI_LOW);
}
break;
/* first, remove the card */
pcmcia_bus_remove(skt);

default:
break;
}
mutex_lock(&skt->ops_mutex);
destroy_cis_cache(skt);
kfree(skt->fake_cis);
skt->fake_cis = NULL;
skt->functions = 0;
mutex_unlock(&skt->ops_mutex);

pcmcia_put_socket(s);
/* now, add the new card */
pcmcia_bus_add(skt);
return 0;
}

return 0;
} /* ds_event */

/*
* NOTE: This is racy. There's no guarantee the card will still be
Expand Down Expand Up @@ -1306,10 +1287,12 @@ EXPORT_SYMBOL(pcmcia_dev_present);

static struct pcmcia_callback pcmcia_bus_callback = {
.owner = THIS_MODULE,
.event = ds_event,
.add = pcmcia_bus_add,
.remove = pcmcia_bus_remove,
.requery = pcmcia_requery,
.validate = pccard_validate_cis,
.suspend = pcmcia_bus_suspend,
.early_resume = pcmcia_bus_early_resume,
.resume = pcmcia_bus_resume,
};

Expand Down

0 comments on commit 7b24e79

Please sign in to comment.