Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+7 −29
Original line number Original line Diff line number Diff line
@@ -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:
+4 −3
Original line number Original line Diff line number Diff line
@@ -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);
};
};


+43 −60
Original line number Original line Diff line number Diff line
@@ -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)
{
	atomic_set(&skt->present, 0);
	pcmcia_card_remove(skt, NULL);


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

	destroy_cis_cache(skt);
    The card status event handler.
	pcmcia_cleanup_irq(skt);

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


/* Normally, the event is passed to individual drivers after
	return 0;
 * 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_add(struct pcmcia_socket *skt)
{
{
	struct pcmcia_socket *s = pcmcia_get_socket(skt);
	atomic_set(&skt->present, 1);


	if (!s) {
	mutex_lock(&skt->ops_mutex);
		dev_printk(KERN_ERR, &skt->dev,
	skt->pcmcia_state.has_pfc = 0;
			   "PCMCIA obtaining reference to socket "	\
	destroy_cis_cache(skt); /* to be on the safe side... */
			   "failed, event 0x%x lost!\n", event);
	mutex_unlock(&skt->ops_mutex);
		return -ENODEV;
	}


	dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
	pcmcia_card_add(skt);
		   event, priority, skt);


	switch (event) {
	return 0;
	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:
static int pcmcia_bus_early_resume(struct pcmcia_socket *skt)
		atomic_set(&skt->present, 1);
{
		mutex_lock(&s->ops_mutex);
	if (!verify_cis_cache(skt)) {
		s->pcmcia_state.has_pfc = 0;
		pcmcia_put_socket(skt);
		destroy_cis_cache(s); /* to be on the safe side... */
		return 0;
		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");
	dev_dbg(&skt->dev, "cis mismatch - different card\n");

	/* first, remove the card */
	/* first, remove the card */
			ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
	pcmcia_bus_remove(skt);
			mutex_lock(&s->ops_mutex);

	mutex_lock(&skt->ops_mutex);
	destroy_cis_cache(skt);
	destroy_cis_cache(skt);
	kfree(skt->fake_cis);
	kfree(skt->fake_cis);
	skt->fake_cis = NULL;
	skt->fake_cis = NULL;
			s->functions = 0;
	skt->functions = 0;
			mutex_unlock(&s->ops_mutex);
	mutex_unlock(&skt->ops_mutex);
			/* now, add the new card */
			ds_event(skt, CS_EVENT_CARD_INSERTION,
				 CS_EVENT_PRI_LOW);
		}
		break;


	default:
	/* now, add the new card */
		break;
	pcmcia_bus_add(skt);
	return 0;
}
}


    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,
};
};