⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i82365.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    pci_writeb(s, TOPIC_CARD_CONTROL, p->ccr);    pci_writeb(s, TOPIC_CARD_DETECT, p->cdr);    pci_writel(s, TOPIC_REGISTER_CONTROL, p->rcr);    i365_set(s, TOPIC_FUNCTION_CONTROL, p->fcr);    state = cb_readl(s, CB_SOCKET_STATE);    if (!(state & CB_SS_32BIT))	cb_writel(s, CB_SOCKET_CONTROL, 0);    if (!(state & CB_SS_VSENSE))	cb_writel(s, CB_SOCKET_FORCE, CB_SF_CVSTEST);}static u_int __init topic_set_opts(socket_info_t *s, char *buf){    topic_state_t *p = &s->state.topic;    p->slot |= TOPIC_SLOT_SLOTON|TOPIC_SLOT_SLOTEN;    p->slot &= ~TOPIC_SLOT_ID_LOCK;    p->cdr |= TOPIC_CDR_MODE_PC32;    p->cdr &= ~(TOPIC_CDR_SW_DETECT);    p->ccr |= TOPIC97_ICR_IRQSEL;    p->fcr |= TOPIC_FCR_3V_ENA;    sprintf(buf, " [slot 0x%02x] [ccr 0x%02x] [cdr 0x%02x] [rcr 0x%02x]",	    p->slot, p->ccr, p->cdr, p->rcr);    return 0xffff;}#endif/*======================================================================    Routines to handle common CardBus options    ======================================================================*//* Default settings for PCI command configuration register */#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \		  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)#ifdef CONFIG_PCIstatic void __init cb_get_state(socket_info_t *s){    pci_readb(s, PCI_CACHE_LINE_SIZE, &s->cache);    pci_readb(s, PCI_LATENCY_TIMER, &s->pci_lat);    pci_readb(s, CB_LATENCY_TIMER, &s->cb_lat);    pci_readb(s, CB_CARDBUS_BUS, &s->cap.cardbus);    pci_readb(s, CB_SUBORD_BUS, &s->sub_bus);    pci_readw(s, CB_BRIDGE_CONTROL, &s->bcr);    get_pci_irq(s);}static void cb_set_state(socket_info_t *s){    pci_set_power_state(pci_find_slot(s->bus, s->devfn), 0);    pci_writel(s, CB_LEGACY_MODE_BASE, 0);    pci_writel(s, PCI_BASE_ADDRESS_0, s->cb_phys);    pci_writew(s, PCI_COMMAND, CMD_DFLT);    pci_writeb(s, PCI_CACHE_LINE_SIZE, s->cache);    pci_writeb(s, PCI_LATENCY_TIMER, s->pci_lat);    pci_writeb(s, CB_LATENCY_TIMER, s->cb_lat);    pci_writeb(s, CB_CARDBUS_BUS, s->cap.cardbus);    pci_writeb(s, CB_SUBORD_BUS, s->sub_bus);    pci_writew(s, CB_BRIDGE_CONTROL, s->bcr);}static int cb_get_irq_mode(socket_info_t *s){    return (!(s->bcr & CB_BCR_ISA_IRQ));}static int cb_set_irq_mode(socket_info_t *s, int pcsc, int pint){    flip(s->bcr, CB_BCR_ISA_IRQ, !(pint));    if (s->flags & IS_CIRRUS)	return cirrus_set_irq_mode(s, pcsc, pint);    else if (s->flags & IS_TI)	return ti113x_set_irq_mode(s, pcsc, pint);    /* By default, assume that we can't do ISA status irqs */    return (!pcsc);}static void __init cb_set_opts(socket_info_t *s, char *buf){    s->bcr |= CB_BCR_WRITE_POST;    /* some TI1130's seem to exhibit problems with write posting */    if (((s->type == IS_TI1130) && (s->revision == 4) &&	 (cb_write_post < 0)) || (cb_write_post == 0))	s->bcr &= ~CB_BCR_WRITE_POST;    if (s->cache == 0) s->cache = 8;    if (s->pci_lat == 0) s->pci_lat = 0xa8;    if (s->cb_lat == 0) s->cb_lat = 0xb0;    if (s->cap.pci_irq == 0)	strcat(buf, " [no pci irq]");    else	sprintf(buf, " [pci irq %d]", s->cap.pci_irq);    buf += strlen(buf);    if (!(s->flags & IS_TOPIC))	s->cap.features |= SS_CAP_PAGE_REGS;    sprintf(buf, " [lat %d/%d] [bus %d/%d]",	    s->pci_lat, s->cb_lat, s->cap.cardbus, s->sub_bus);}#endif/*======================================================================    Power control for Cardbus controllers: used both for 16-bit and    Cardbus cards.    ======================================================================*/#ifdef CONFIG_PCIstatic void cb_get_power(socket_info_t *s, socket_state_t *state){    u_int reg = cb_readl(s, CB_SOCKET_CONTROL);    state->Vcc = state->Vpp = 0;    switch (reg & CB_SC_VCC_MASK) {    case CB_SC_VCC_3V:		state->Vcc = 33; break;    case CB_SC_VCC_5V:		state->Vcc = 50; break;    }    switch (reg & CB_SC_VPP_MASK) {    case CB_SC_VPP_3V:		state->Vpp = 33; break;    case CB_SC_VPP_5V:		state->Vpp = 50; break;    case CB_SC_VPP_12V:		state->Vpp = 120; break;    }}static int cb_set_power(socket_info_t *s, socket_state_t *state){    u_int reg = 0;    /* restart card voltage detection if it seems appropriate */    if ((state->Vcc == 0) && (state->Vpp == 0) &&	!(cb_readl(s, CB_SOCKET_STATE) & CB_SS_VSENSE))	cb_writel(s, CB_SOCKET_FORCE, CB_SF_CVSTEST);    switch (state->Vcc) {    case 0:		reg = 0; break;    case 33:		reg = CB_SC_VCC_3V; break;    case 50:		reg = CB_SC_VCC_5V; break;    default:		return -EINVAL;    }    switch (state->Vpp) {    case 0:		break;    case 33:		reg |= CB_SC_VPP_3V; break;    case 50:		reg |= CB_SC_VPP_5V; break;    case 120:		reg |= CB_SC_VPP_12V; break;    default:		return -EINVAL;    }    if (reg != cb_readl(s, CB_SOCKET_CONTROL))	cb_writel(s, CB_SOCKET_CONTROL, reg);    return 0;}#endif/*======================================================================    Generic routines to get and set controller options    ======================================================================*/static void __init get_bridge_state(socket_info_t *s){    if (s->flags & IS_CIRRUS)	cirrus_get_state(s);#ifdef CONFIG_ISA    else if (s->flags & IS_VADEM)	vg46x_get_state(s);#endif#ifdef CONFIG_PCI    else if (s->flags & IS_O2MICRO)	o2micro_get_state(s);    else if (s->flags & IS_TI)	ti113x_get_state(s);    else if (s->flags & IS_RICOH)	ricoh_get_state(s);    else if (s->flags & IS_TOPIC)	topic_get_state(s);    if (s->flags & IS_CARDBUS)	cb_get_state(s);#endif}static void set_bridge_state(socket_info_t *s){#ifdef CONFIG_PCI    if (s->flags & IS_CARDBUS)	cb_set_state(s);#endif    if (s->flags & IS_CIRRUS) {	cirrus_set_state(s);    } else {	i365_set(s, I365_GBLCTL, 0x00);	i365_set(s, I365_GENCTL, 0x00);	/* Trouble: changes timing of memory operations */	/* i365_bset(s, I365_ADDRWIN, I365_ADDR_MEMCS16); */    }    i365_bflip(s, I365_INTCTL, I365_INTR_ENA, s->intr);#ifdef CONFIG_ISA    if (s->flags & IS_VADEM)	vg46x_set_state(s);#endif#ifdef CONFIG_PCI    if (s->flags & IS_O2MICRO)	o2micro_set_state(s);    else if (s->flags & IS_TI)	ti113x_set_state(s);    else if (s->flags & IS_RICOH)	ricoh_set_state(s);    else if (s->flags & IS_TOPIC)	topic_set_state(s);#endif}static u_int __init set_bridge_opts(socket_info_t *s, u_short ns){    u_short i;    u_int m = 0xffff;    char buf[128];    for (i = 0; i < ns; i++) {	if (s[i].flags & IS_ALIVE) {	    printk(KERN_INFO "    host opts [%d]: already alive!\n", i);	    continue;	}	buf[0] = '\0';	get_bridge_state(s+i);	if (s[i].flags & IS_CIRRUS)	    m = cirrus_set_opts(s+i, buf);#ifdef CONFIG_ISA	else if (s[i].flags & IS_VADEM)	    m = vg46x_set_opts(s+i, buf);#endif#ifdef CONFIG_PCI	else if (s[i].flags & IS_O2MICRO)	    m = o2micro_set_opts(s+i, buf);	else if (s[i].flags & IS_TI)	    m = ti113x_set_opts(s+i, buf);	else if (s[i].flags & IS_RICOH)	    m = ricoh_set_opts(s+i, buf);	else if (s[i].flags & IS_TOPIC)	    m = topic_set_opts(s+i, buf);	if (s[i].flags & IS_CARDBUS)	    cb_set_opts(s+i, buf+strlen(buf));#endif	set_bridge_state(s+i);	printk(KERN_INFO "    host opts [%d]:%s\n", i,	       (*buf) ? buf : " none");    }#ifdef CONFIG_PCI    m &= ~pci_irq_mask;#endif    return m;}/*======================================================================    Interrupt testing code, for ISA and PCI interrupts    ======================================================================*/static volatile u_int irq_hits, irq_shared;static volatile socket_info_t *irq_sock;static void irq_count(int irq, void *dev, struct pt_regs *regs){    irq_hits++;    DEBUG(2, "-> hit on irq %d\n", irq);    if (!irq_shared && (irq_hits > 100)) {	printk(KERN_INFO "    PCI irq %d seems to be wedged!\n", irq);	disable_irq(irq);	return;    }#ifdef CONFIG_PCI    if (irq_sock->flags & IS_CARDBUS) {	cb_writel(irq_sock, CB_SOCKET_EVENT, -1);    } else#endif    i365_get((socket_info_t *)irq_sock, I365_CSC);    return;}static u_int __init test_irq(socket_info_t *s, int irq, int pci){    u_char csc = (pci) ? 0 : irq;#ifdef CONFIG_PNP_BIOS    extern int check_pnp_irq(int);    if (!pci && check_pnp_irq(irq)) return 1;#endif    DEBUG(2, "  testing %s irq %d\n", pci ? "PCI" : "ISA", irq);    irq_sock = s; irq_shared = irq_hits = 0;    if (request_irq(irq, irq_count, 0, "scan", socket)) {	irq_shared++;	if (!pci || request_irq(irq, irq_count, SA_SHIRQ, "scan", socket))	    return 1;    }    irq_hits = 0;    __set_current_state(TASK_UNINTERRUPTIBLE);    schedule_timeout(HZ/100);    if (irq_hits && !irq_shared) {	free_irq(irq, socket);	DEBUG(2, "    spurious hit!\n");	return 1;    }    /* Generate one interrupt */#ifdef CONFIG_PCI    if (s->flags & IS_CARDBUS) {	cb_writel(s, CB_SOCKET_EVENT, -1);	i365_set(s, I365_CSCINT, I365_CSC_STSCHG | (csc << 4));	cb_writel(s, CB_SOCKET_EVENT, -1);	cb_writel(s, CB_SOCKET_MASK, CB_SM_CSTSCHG);	cb_writel(s, CB_SOCKET_FORCE, CB_SE_CSTSCHG);	mdelay(1);	cb_writel(s, CB_SOCKET_EVENT, -1);	cb_writel(s, CB_SOCKET_MASK, 0);    } else#endif    {	i365_set(s, I365_CSCINT, I365_CSC_DETECT | (csc << 4));	i365_bset(s, I365_GENCTL, I365_CTL_SW_IRQ);	mdelay(1);    }    free_irq(irq, socket);    /* mask all interrupts */    i365_set(s, I365_CSCINT, 0);    DEBUG(2, "    hits = %d\n", irq_hits);        return pci ? (irq_hits == 0) : (irq_hits != 1);}#ifdef CONFIG_ISAstatic int _check_irq(int irq, int flags){#ifdef CONFIG_PNP_BIOS    extern int check_pnp_irq(int);    if ((flags != SA_SHIRQ) && check_pnp_irq(irq))	return -1;#endif    if (request_irq(irq, irq_count, flags, "x", irq_count) != 0)	return -1;    free_irq(irq, irq_count);    return 0;}static u_int __init isa_scan(socket_info_t *s, u_int mask0){    u_int mask1 = 0;    int i;#ifdef CONFIG_PCI    /* Only scan if we can select ISA csc irq's */    if (!(s->flags & IS_CARDBUS) || (cb_set_irq_mode(s, 0, 0) == 0))#endif    if (do_scan) {	set_bridge_state(s);	i365_set(s, I365_CSCINT, 0);	for (i = 0; i < 16; i++)	    if ((mask0 & (1 << i)) && (test_irq(s, i, 0) == 0))		mask1 |= (1 << i);	for (i = 0; i < 16; i++)	    if ((mask1 & (1 << i)) && (test_irq(s, i, 0) != 0))		mask1 ^= (1 << i);    }        printk(KERN_INFO "    ISA irqs (");    /* we trust TI bridges to do this right */    if (mask1 || (s->flags & IS_TI)) {	printk("scanned");    } else {	/* Fallback: just find interrupts that aren't in use */	for (i = 0; i < 16; i++)	    if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0))		mask1 |= (1 << i);	printk("default");	/* If scan failed, default to polled status */	if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;    }    printk(") = ");        for (i = 0; i < 16; i++)	if (mask1 & (1<<i))	    printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);    if (mask1 == 0) printk("none!");        return mask1;}#endif /* CONFIG_ISA */#ifdef CONFIG_PCIstatic int __init pci_scan(socket_info_t *s){    int ret;    if ((s->flags & IS_RICOH) || !(s->flags & IS_CARDBUS) || !do_scan) {	/* for PCI-to-PCMCIA bridges, just check for wedged irq */	irq_sock = s; irq_hits = 0;	if (request_irq(s->cap.pci_irq, irq_count, 0, "scan", socket))	    return 1;	udelay(50);	free_irq(s->cap.pci_irq, socket);	return (!irq_hits);    }    cb_set_irq_mode(s, 1, 0);    set_bridge_state(s);    i365_set(s, I365_CSCINT, 0);    ret = ((test_irq(s, s->cap.pci_irq, 1) == 0) &&	   (test_irq(s, s->cap.pci_irq, 1) == 0));    if (!ret)	printk(KERN_INFO "    PCI irq %d test failed\n",	       s->cap.pci_irq);    return ret;}#endif /* CONFIG_PCI *//*====================================================================*/#ifdef CONFIG_ISAstatic int __init isa_identify(u_short port, u_short sock){    socket_info_t *s = socket+sockets;    u_char val;    int type = -1;    /* Use the next free entry in the socket table */    s->ioaddr = port;    s->psock = sock;        /* Wake up a sleepy Cirrus controller */    if (wakeup) {	i365_bclr(s, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);

⌨️ 快捷键说明

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