mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-02 20:44:00 +00:00
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:
parent
216d7cdd3b
commit
7b24e79882
3 changed files with 58 additions and 96 deletions
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
* 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);
|
||||||
|
|
||||||
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 @@
|
||||||
* 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)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pcmcia_bus_remove(struct pcmcia_socket *skt)
|
||||||
/*======================================================================
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
struct pcmcia_socket *s = pcmcia_get_socket(skt);
|
atomic_set(&skt->present, 0);
|
||||||
|
pcmcia_card_remove(skt, NULL);
|
||||||
|
|
||||||
if (!s) {
|
mutex_lock(&skt->ops_mutex);
|
||||||
dev_printk(KERN_ERR, &skt->dev,
|
destroy_cis_cache(skt);
|
||||||
"PCMCIA obtaining reference to socket " \
|
pcmcia_cleanup_irq(skt);
|
||||||
"failed, event 0x%x lost!\n", event);
|
mutex_unlock(&skt->ops_mutex);
|
||||||
return -ENODEV;
|
|
||||||
|
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",
|
dev_dbg(&skt->dev, "cis mismatch - different card\n");
|
||||||
event, priority, skt);
|
|
||||||
|
|
||||||
switch (event) {
|
/* first, remove the card */
|
||||||
case CS_EVENT_CARD_REMOVAL:
|
pcmcia_bus_remove(skt);
|
||||||
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:
|
mutex_lock(&skt->ops_mutex);
|
||||||
atomic_set(&skt->present, 1);
|
destroy_cis_cache(skt);
|
||||||
mutex_lock(&s->ops_mutex);
|
kfree(skt->fake_cis);
|
||||||
s->pcmcia_state.has_pfc = 0;
|
skt->fake_cis = NULL;
|
||||||
destroy_cis_cache(s); /* to be on the safe side... */
|
skt->functions = 0;
|
||||||
mutex_unlock(&s->ops_mutex);
|
mutex_unlock(&skt->ops_mutex);
|
||||||
pcmcia_card_add(skt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CS_EVENT_PM_RESUME:
|
/* now, add the new card */
|
||||||
if (verify_cis_cache(skt) != 0) {
|
pcmcia_bus_add(skt);
|
||||||
dev_dbg(&skt->dev, "cis mismatch - different card\n");
|
return 0;
|
||||||
/* 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:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcmcia_put_socket(s);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue