Commit 7b24e798 authored by Dominik Brodowski's avatar Dominik Brodowski

pcmcia: split up central event handler

Split up the central event handler for 16bit cards into three individual
functions.
Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent 216d7cdd
...@@ -252,30 +252,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr) ...@@ -252,30 +252,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr)
} }
EXPORT_SYMBOL(pcmcia_get_socket_by_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) static int socket_reset(struct pcmcia_socket *skt)
{ {
int status, i; int status, i;
...@@ -318,7 +294,8 @@ static void socket_shutdown(struct pcmcia_socket *s) ...@@ -318,7 +294,8 @@ static void socket_shutdown(struct pcmcia_socket *s)
dev_dbg(&s->dev, "shutdown\n"); 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); mutex_lock(&s->ops_mutex);
s->state &= SOCKET_INUSE | SOCKET_PRESENT; s->state &= SOCKET_INUSE | SOCKET_PRESENT;
...@@ -469,7 +446,8 @@ static int socket_insert(struct pcmcia_socket *skt) ...@@ -469,7 +446,8 @@ static int socket_insert(struct pcmcia_socket *skt)
dev_dbg(&skt->dev, "insert done\n"); dev_dbg(&skt->dev, "insert done\n");
mutex_unlock(&skt->ops_mutex); 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 { } else {
mutex_unlock(&skt->ops_mutex); mutex_unlock(&skt->ops_mutex);
socket_shutdown(skt); socket_shutdown(skt);
...@@ -546,8 +524,8 @@ static int socket_late_resume(struct pcmcia_socket *skt) ...@@ -546,8 +524,8 @@ static int socket_late_resume(struct pcmcia_socket *skt)
return 0; return 0;
} }
#endif #endif
if (!(skt->state & SOCKET_CARDBUS) && (skt->callback))
send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); skt->callback->early_resume(skt);
return 0; return 0;
} }
...@@ -766,7 +744,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) ...@@ -766,7 +744,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
s->callback = c; s->callback = c;
if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) 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 } else
s->callback = NULL; s->callback = NULL;
err: err:
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
* *
* (C) 1999 David A. Hinds * (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. * This file contains definitions _only_ needed by the PCMCIA core modules.
...@@ -106,11 +106,12 @@ void cb_free(struct pcmcia_socket *s); ...@@ -106,11 +106,12 @@ void cb_free(struct pcmcia_socket *s);
struct pcmcia_callback{ struct pcmcia_callback{
struct module *owner; struct module *owner;
int (*event) (struct pcmcia_socket *s, int (*add) (struct pcmcia_socket *s);
event_t event, int priority); int (*remove) (struct pcmcia_socket *s);
void (*requery) (struct pcmcia_socket *s); void (*requery) (struct pcmcia_socket *s);
int (*validate) (struct pcmcia_socket *s, unsigned int *i); int (*validate) (struct pcmcia_socket *s, unsigned int *i);
int (*suspend) (struct pcmcia_socket *s); int (*suspend) (struct pcmcia_socket *s);
int (*early_resume) (struct pcmcia_socket *s);
int (*resume) (struct pcmcia_socket *s); int (*resume) (struct pcmcia_socket *s);
}; };
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
* *
* (C) 1999 David A. Hinds * (C) 1999 David A. Hinds
* (C) 2003 - 2006 Dominik Brodowski * (C) 2003 - 2010 Dominik Brodowski
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -1208,76 +1208,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt) ...@@ -1208,76 +1208,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
return 0; 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 mutex_lock(&skt->ops_mutex);
* informing userspace. Only for CS_EVENT_CARD_REMOVAL this skt->pcmcia_state.has_pfc = 0;
* is inversed to maintain historic compatibility. 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) pcmcia_card_add(skt);
{
struct pcmcia_socket *s = pcmcia_get_socket(skt);
if (!s) { return 0;
dev_printk(KERN_ERR, &skt->dev, }
"PCMCIA obtaining reference to socket " \
"failed, event 0x%x lost!\n", event);
return -ENODEV;
}
dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
event, priority, skt); {
if (!verify_cis_cache(skt)) {
pcmcia_put_socket(skt);
return 0;
}
switch (event) { dev_dbg(&skt->dev, "cis mismatch - different card\n");
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;
case CS_EVENT_CARD_INSERTION: /* first, remove the card */
atomic_set(&skt->present, 1); pcmcia_bus_remove(skt);
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;
default: mutex_lock(&skt->ops_mutex);
break; 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 * NOTE: This is racy. There's no guarantee the card will still be
...@@ -1306,10 +1287,12 @@ EXPORT_SYMBOL(pcmcia_dev_present); ...@@ -1306,10 +1287,12 @@ EXPORT_SYMBOL(pcmcia_dev_present);
static struct pcmcia_callback pcmcia_bus_callback = { static struct pcmcia_callback pcmcia_bus_callback = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.event = ds_event, .add = pcmcia_bus_add,
.remove = pcmcia_bus_remove,
.requery = pcmcia_requery, .requery = pcmcia_requery,
.validate = pccard_validate_cis, .validate = pccard_validate_cis,
.suspend = pcmcia_bus_suspend, .suspend = pcmcia_bus_suspend,
.early_resume = pcmcia_bus_early_resume,
.resume = pcmcia_bus_resume, .resume = pcmcia_bus_resume,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment