pcmcia: split up central event handler

Split up the central event handler for 16bit cards into three individual
functions.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Dominik Brodowski 2010-07-11 10:26:53 +02:00
parent 216d7cdd3b
commit 7b24e79882
3 changed files with 58 additions and 96 deletions

View file

@ -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;
@ -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;
@ -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);
@ -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;
}
@ -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:

View file

@ -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.
@ -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);
};

View file

@ -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>
@ -1208,76 +1208,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
return 0;
}
/*======================================================================
The card status event handler.
======================================================================*/
/* Normally, the event is passed to individual drivers after
* informing userspace. Only for CS_EVENT_CARD_REMOVAL this
* is inversed to maintain historic compatibility.
*/
static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
static int pcmcia_bus_remove(struct pcmcia_socket *skt)
{
struct pcmcia_socket *s = pcmcia_get_socket(skt);
atomic_set(&skt->present, 0);
pcmcia_card_remove(skt, NULL);
if (!s) {
dev_printk(KERN_ERR, &skt->dev,
"PCMCIA obtaining reference to socket " \
"failed, event 0x%x lost!\n", event);
return -ENODEV;
mutex_lock(&skt->ops_mutex);
destroy_cis_cache(skt);
pcmcia_cleanup_irq(skt);
mutex_unlock(&skt->ops_mutex);
return 0;
}
static int pcmcia_bus_add(struct pcmcia_socket *skt)
{
atomic_set(&skt->present, 1);
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);
pcmcia_card_add(skt);
return 0;
}
static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
{
if (!verify_cis_cache(skt)) {
pcmcia_put_socket(skt);
return 0;
}
dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
event, priority, skt);
dev_dbg(&skt->dev, "cis mismatch - different card\n");
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;
/* first, remove the card */
pcmcia_bus_remove(skt);
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;
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);
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;
/* now, add the new card */
pcmcia_bus_add(skt);
return 0;
}
default:
break;
}
pcmcia_put_socket(s);
return 0;
} /* ds_event */
/*
* NOTE: This is racy. There's no guarantee the card will still be
@ -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,
};