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
		Add a link
		
	
		Reference in a new issue
	
	 Dominik Brodowski
				Dominik Brodowski