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 + -
显示快捷键?