au1000_generic.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 697 行 · 第 1/2 页

C
697
字号
 * From the sa1100 socket driver :  * * Implements the inquire_socket() operation for the in-kernel PCMCIA * service (formerly SS_InquireSocket in Card Services).  We set  * SS_CAP_STATIC_MAP, which disables the memory resource database check.  * (Mapped memory is set up within the socket driver itself.) * * In conjunction with the STATIC_MAP capability is a new field, * `io_offset', recommended by David Hinds. Rather than go through * the SetIOMap interface (which is not quite suited for communicating * window locations up from the socket driver), we just pass up  * an offset which is applied to client-requested base I/O addresses * in alloc_io_space(). * * Returns: 0 on success, -1 if no pin has been configured for `sock' */static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap){	struct pcmcia_irq_info irq_info;	if(sock > socket_count){		printk(KERN_ERR "au1000: socket %u not configured\n", sock);		return -1;	}	/* from the sa1100_generic driver: */	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the	*   force_low argument to validate_mem() in rsrc_mgr.c -- since in	*   general, the mapped * addresses of the PCMCIA memory regions	*   will not be within 0xffff, setting force_low would be	*   undesirable.	*	* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory	*   resource database; we instead pass up physical address ranges	*   and allow other parts of Card Services to deal with remapping.	*	* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but	*   not 32-bit CardBus devices.	*/	cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);	irq_info.sock=sock;	irq_info.irq=-1;	if(pcmcia_low_level->get_irq_info(&irq_info)<0){		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);		return -1;	}	cap->irq_mask=0;	cap->map_size=MAP_SIZE;	cap->pci_irq=irq_info.irq;	cap->io_offset=pcmcia_socket[sock].virt_io;	return 0;}  /* au1000_pcmcia_inquire_socket() */static int au1000_pcmcia_get_status(unsigned int sock, unsigned int *status){	struct pcmcia_state state;	if((pcmcia_low_level->socket_state(sock, &state))<0){		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");		return -1;	}	pcmcia_socket[sock].k_state = state;	*status = state.detect?SS_DETECT:0;	*status |= state.ready?SS_READY:0;	*status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;	if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)		*status |= state.bvd1?SS_STSCHG:0;	else {		if(state.bvd1==0)			*status |= SS_BATDEAD;		else if(state.bvd2 == 0)			*status |= SS_BATWARN;	}	*status|=state.vs_3v?SS_3VCARD:0;	*status|=state.vs_Xv?SS_XVCARD:0;	debug(2, "\tstatus: %s%s%s%s%s%s%s%s\n",	(*status&SS_DETECT)?"DETECT ":"",	(*status&SS_READY)?"READY ":"", 	(*status&SS_BATDEAD)?"BATDEAD ":"",	(*status&SS_BATWARN)?"BATWARN ":"",	(*status&SS_POWERON)?"POWERON ":"",	(*status&SS_STSCHG)?"STSCHG ":"",	(*status&SS_3VCARD)?"3VCARD ":"",	(*status&SS_XVCARD)?"XVCARD ":"");	return 0;}  /* au1000_pcmcia_get_status() */static int au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state){	*state = pcmcia_socket[sock].cs_state;	return 0;}static int au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state){	struct pcmcia_configure configure;	debug(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"	"\tVcc %d  Vpp %d  irq %d\n",	(state->csc_mask==0)?"<NONE>":"",	(state->csc_mask&SS_DETECT)?"DETECT ":"",	(state->csc_mask&SS_READY)?"READY ":"",	(state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",	(state->csc_mask&SS_BATWARN)?"BATWARN ":"",	(state->csc_mask&SS_STSCHG)?"STSCHG ":"",	(state->flags==0)?"<NONE>":"",	(state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",	(state->flags&SS_IOCARD)?"IOCARD ":"",	(state->flags&SS_RESET)?"RESET ":"",	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",	state->Vcc, state->Vpp, state->io_irq);	configure.sock=sock;	configure.vcc=state->Vcc;	configure.vpp=state->Vpp;	configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;	configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;	configure.reset=(state->flags&SS_RESET)?1:0;	if(pcmcia_low_level->configure_socket(&configure)<0){		printk(KERN_ERR "Unable to configure socket %u\n", sock);		return -1;	}	pcmcia_socket[sock].cs_state = *state;	return 0;}  /* au1000_pcmcia_set_socket() */static int au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map){	debug(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);	if(map->map>=MAX_IO_WIN){		printk(KERN_ERR "%s(): map (%d) out of range\n", 				__FUNCTION__, map->map);		return -1;	}	*map=pcmcia_socket[sock].io_map[map->map];	return 0;}int au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map){	unsigned int speed;	unsigned long start;	if(map->map>=MAX_IO_WIN){		printk(KERN_ERR "%s(): map (%d) out of range\n", 				__FUNCTION__, map->map);		return -1;	}	if(map->flags&MAP_ACTIVE){		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;		pcmcia_socket[sock].speed_io=speed;	}	start=map->start;	if(map->stop==1) {		map->stop=PAGE_SIZE-1;	}	map->start=pcmcia_socket[sock].virt_io;	map->stop=map->start+(map->stop-start);	pcmcia_socket[sock].io_map[map->map]=*map;	debug(3, "set_io_map %d start %x stop %x\n", 			map->map, map->start, map->stop);	return 0;}  /* au1000_pcmcia_set_io_map() */static int au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map){	if(map->map>=MAX_WIN) {		printk(KERN_ERR "%s(): map (%d) out of range\n", 				__FUNCTION__, map->map);		return -1;	}	*map=pcmcia_socket[sock].mem_map[map->map];	return 0;}static int au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map){	unsigned int speed;	u_long flags;	if(map->map>=MAX_WIN){		printk(KERN_ERR "%s(): map (%d) out of range\n", 				__FUNCTION__, map->map);		return -1;	}	if(map->flags&MAP_ACTIVE){		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;		/* TBD */		if(map->flags&MAP_ATTRIB){			pcmcia_socket[sock].speed_attr=speed;		} 		else {			pcmcia_socket[sock].speed_mem=speed;		}	}	spin_lock_irqsave(&pcmcia_lock, flags);	if (map->flags & MAP_ATTRIB) {		map->static_start = pcmcia_socket[sock].phys_attr + 			map->card_start;	}	else {		map->static_start = pcmcia_socket[sock].phys_mem + 			map->card_start;	}	pcmcia_socket[sock].mem_map[map->map]=*map;	spin_unlock_irqrestore(&pcmcia_lock, flags);	debug(3, "set_mem_map %d start %x card_start %x\n", 			map->map, map->static_start,			map->card_start);	return 0;}  /* au1000_pcmcia_set_mem_map() */#if defined(CONFIG_PROC_FS)static void au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base){	struct proc_dir_entry *entry;	if((entry=create_proc_entry("status", 0, base))==NULL){		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");		return;	}	entry->read_proc=au1000_pcmcia_proc_status;	entry->data=(void *)sock;}/* au1000_pcmcia_proc_status() * Implements the /proc/bus/pccard/??/status file. * * Returns: the number of characters added to the buffer */static int au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, 		int count, int *eof, void *data){	char *p=buf;	unsigned int sock=(unsigned int)data;	p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 	     pcmcia_socket[sock].k_state.detect?"detect ":"",	     pcmcia_socket[sock].k_state.ready?"ready ":"",	     pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",	     pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",	     pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",	     pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",	     pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");	p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",	     pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",	     pcmcia_socket[sock].k_state.ready?"SS_READY ":"",	     pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\	     "SS_IOCARD ":"",	     (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&	      pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&	      (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&	      (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",	     pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",	     pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");	p+=sprintf(p, "mask     : %s%s%s%s%s\n",	     pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\	     "SS_DETECT ":"",	     pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\	     "SS_READY ":"",	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\	     "SS_BATDEAD ":"",	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\	     "SS_BATWARN ":"",	     pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\	     "SS_STSCHG ":"");	p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",	     pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\	     "SS_PWR_AUTO ":"",	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\	     "SS_IOCARD ":"",	     pcmcia_socket[sock].cs_state.flags&SS_RESET?\	     "SS_RESET ":"",	     pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\	     "SS_SPKR_ENA ":"",	     pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\	     "SS_OUTPUT_ENA ":"");	p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);	p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);	p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);	p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);	p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);	p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);	return p-buf;}#endif  /* defined(CONFIG_PROC_FS) */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?