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); | ||||
| 
 | ||||
| /*
 | ||||
|  * 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: | ||||
|  |  | |||
|  | @ -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); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
| 	if (!s) { | ||||
| 		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", | ||||
| 		   event, priority, skt); | ||||
| 
 | ||||
| 	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; | ||||
| 
 | ||||
| 	case CS_EVENT_CARD_INSERTION: | ||||
| 	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(&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) { | ||||
| 	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, "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); | ||||
| 	pcmcia_bus_remove(skt); | ||||
| 
 | ||||
| 	mutex_lock(&skt->ops_mutex); | ||||
| 	destroy_cis_cache(skt); | ||||
| 	kfree(skt->fake_cis); | ||||
| 	skt->fake_cis = NULL; | ||||
| 			s->functions = 0; | ||||
| 			mutex_unlock(&s->ops_mutex); | ||||
| 	skt->functions = 0; | ||||
| 	mutex_unlock(&skt->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); | ||||
| 
 | ||||
| 	pcmcia_bus_add(skt); | ||||
| 	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, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dominik Brodowski
				Dominik Brodowski