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

📄 i82365.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!active) break;    }    if (j == 20)	printk(KERN_NOTICE "i82365: infinite loop in interrupt "	       "handler: active = 0x%04x\n", active);    DEBUG(2, "i82365: interrupt done\n");} /* pcic_interrupt */static void pcic_interrupt_wrapper(u_long data){    pcic_interrupt(0, NULL, NULL);    poll_timer.expires = jiffies + poll_interval;    add_timer(&poll_timer);}/*====================================================================*/static int pcic_register_callback(socket_info_t *s, ss_callback_t *call){    if (call == NULL) {	s->handler = NULL;	MOD_DEC_USE_COUNT;    } else {	MOD_INC_USE_COUNT;	s->handler = call->handler;	s->info = call->info;    }    return 0;} /* pcic_register_callback *//*====================================================================*/static int pcic_inquire_socket(socket_info_t *s, socket_cap_t *cap){    *cap = s->cap;    return 0;}/*====================================================================*/static int i365_get_status(socket_info_t *s, u_int *value){    u_int status;        status = i365_get(s, I365_STATUS);    *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)	? SS_DETECT : 0;    if (i365_get(s, I365_INTCTL) & I365_PC_IOCARD) {	*value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;    } else {	*value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;	*value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;    }    *value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;    *value |= (status & I365_CS_READY) ? SS_READY : 0;    *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;#ifdef CONFIG_PCI    if (s->flags & IS_CARDBUS) {	status = cb_readl(s, CB_SOCKET_STATE);	*value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;	*value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;	*value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;	*value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;    } else if (s->flags & IS_O2MICRO) {	status = i365_get(s, O2_MODE_B);	*value |= (status & O2_MODE_B_VS1) ? 0 : SS_3VCARD;	*value |= (status & O2_MODE_B_VS2) ? 0 : SS_XVCARD;    } else if (s->type == IS_PD6729) {	socket_info_t *t = (s->psock) ? s : s+1;	status = pd67_ext_get(t, PD67_EXTERN_DATA);	*value |= (status & PD67_EXD_VS1(s->psock)) ? 0 : SS_3VCARD;	*value |= (status & PD67_EXD_VS2(s->psock)) ? 0 : SS_XVCARD;    }    /* For now, ignore cards with unsupported voltage keys */    if (*value & SS_XVCARD)	*value &= ~(SS_DETECT|SS_3VCARD|SS_XVCARD);#endif#ifdef CONFIG_ISA    if (s->type == IS_VG469) {	status = i365_get(s, VG469_VSENSE);	if (s->psock & 1) {	    *value |= (status & VG469_VSENSE_B_VS1) ? 0 : SS_3VCARD;	    *value |= (status & VG469_VSENSE_B_VS2) ? 0 : SS_XVCARD;	} else {	    *value |= (status & VG469_VSENSE_A_VS1) ? 0 : SS_3VCARD;	    *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;	}    }#endif    DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", s-socket, *value);    return 0;} /* i365_get_status *//*====================================================================*/static int i365_get_socket(socket_info_t *s, socket_state_t *state){    u_char reg, vcc, vpp;        reg = i365_get(s, I365_POWER);    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;    state->Vcc = state->Vpp = 0;#ifdef CONFIG_PCI    if ((s->flags & IS_CARDBUS) && !(s->flags & IS_TOPIC)) {	cb_get_power(s, state);    } else#endif    {	if ((s->flags & IS_CIRRUS) && (reg & I365_VCC_5V)) {	    state->Vcc = (i365_get(s, PD67_MISC_CTL_1) &			  PD67_MC1_VCC_3V) ? 33 : 50;	} else if ((s->flags & IS_VG_PWR) && (reg & I365_VCC_5V)) {	    state->Vcc = (i365_get(s, VG469_VSELECT) &			  VG469_VSEL_VCC) ? 33 : 50;	} else if ((s->flags & IS_DF_PWR) || (s->flags & IS_TOPIC)) {	    if (vcc == I365_VCC_3V) state->Vcc = 33;	    if (vcc == I365_VCC_5V) state->Vcc = 50;	} else {	    if (reg & I365_VCC_5V) state->Vcc = 50;	}	if (vpp == I365_VPP1_5V)	    state->Vpp = (s->flags & IS_DF_PWR) ? 50 : state->Vcc;	if (vpp == I365_VPP1_12V) state->Vpp = 120;    }    /* IO card, RESET flags, IO interrupt */    reg = i365_get(s, I365_INTCTL);    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;    state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;#ifdef CONFIG_PCI    if (cb_get_irq_mode(s) != 0)	state->io_irq = s->cap.pci_irq;    else#endif	state->io_irq = reg & I365_IRQ_MASK;        /* Card status change mask */    reg = i365_get(s, I365_CSCINT);    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;    if (state->flags & SS_IOCARD) {	state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;    } else {	state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;	state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;	state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;    }        DEBUG(2, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "	  "io_irq %d, csc_mask %#2.2x\n", s-socket, state->flags,	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);    return 0;} /* i365_get_socket *//*====================================================================*/static int i365_set_socket(socket_info_t *s, socket_state_t *state){    u_char reg;        DEBUG(2, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "	  "io_irq %d, csc_mask %#2.2x)\n", s-socket, state->flags,	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);        /* First set global controller options */#ifdef CONFIG_PCI    if (s->cap.pci_irq)	cb_set_irq_mode(s, pci_csc, (s->cap.pci_irq == state->io_irq));    s->bcr &= ~CB_BCR_CB_RESET;#endif    set_bridge_state(s);        /* IO card, RESET flag, IO interrupt */    reg = s->intr | ((state->io_irq == s->cap.pci_irq) ?		     s->pci_irq_code : state->io_irq);    reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;    reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;    i365_set(s, I365_INTCTL, reg);        reg = I365_PWR_NORESET;    if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;    if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;#ifdef CONFIG_PCI    if ((s->flags & IS_CARDBUS) && !(s->flags & IS_TOPIC)) {	cb_set_power(s, state);	reg |= i365_get(s, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);    } else#endif    {	int new = s->flags & (IS_TOPIC|IS_CIRRUS|IS_VG_PWR|IS_DF_PWR);	int vcc3 = (state->Vcc == 33), df = (s->flags & IS_DF_PWR);	if (state->Vcc == 50) {	    reg |= I365_VCC_5V;	} else if (new && vcc3) {	    reg |= ((s->flags & (IS_TOPIC|IS_DF_PWR)) ?		    I365_VCC_3V : I365_VCC_5V);	} else if (state->Vcc)	    return -EINVAL;	if (s->flags & IS_CIRRUS)	    i365_bflip(s, PD67_MISC_CTL_1, PD67_MC1_VCC_3V, vcc3);	if (s->flags & IS_VG_PWR)	    i365_bflip(s, VG469_VSELECT, VG469_VSEL_VCC, vcc3);	if (state->Vpp == 120) {	    reg |= I365_VPP1_12V | (new ? 0 : I365_VPP2_12V);	} else if (state->Vpp == (df ? 50 : state->Vcc)) {	    reg |= I365_VPP1_5V | (new ? 0 : I365_VPP2_5V);	} else if (state->Vpp)	    return -EINVAL;    }        if (reg != i365_get(s, I365_POWER))	i365_set(s, I365_POWER, reg);    /* Card status change interrupt mask */    reg = (s->cap.pci_irq ? s->pci_irq_code : s->cs_irq) << 4;    if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;    if (state->flags & SS_IOCARD) {	if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;    } else {	if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;	if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;	if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;    }    i365_set(s, I365_CSCINT, reg);    i365_get(s, I365_CSC);#ifdef CONFIG_PCI    if (s->flags & IS_CARDBUS) {	if (s->cs_irq || (pci_csc && s->cap.pci_irq))	    cb_writel(s, CB_SOCKET_MASK, CB_SM_CCD);	cb_writel(s, CB_SOCKET_EVENT, -1);    }#endif    return 0;} /* i365_set_socket *//*====================================================================*/static int i365_get_io_map(socket_info_t *s, struct pccard_io_map *io){    u_char map, ioctl, addr;        map = io->map;    if (map > 1) return -EINVAL;    io->start = i365_get_pair(s, I365_IO(map)+I365_W_START);    io->stop = i365_get_pair(s, I365_IO(map)+I365_W_STOP);    ioctl = i365_get(s, I365_IOCTL);    addr = i365_get(s, I365_ADDRWIN);    io->speed = (ioctl & I365_IOCTL_WAIT(map)) ? cycle_time : 0;    io->flags  = (addr & I365_ENA_IO(map)) ? MAP_ACTIVE : 0;    io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;    io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;    io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;    DEBUG(3, "i82365: GetIOMap(%d, %d) = %#2.2x, %d ns, %#4.4x-%#4.4x\n",	  s-socket, map, io->flags, io->speed, io->start, io->stop);    return 0;} /* i365_get_io_map *//*====================================================================*/static int i365_set_io_map(socket_info_t *s, struct pccard_io_map *io){    u_char map, ioctl;        DEBUG(3, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, %#4.4x-%#4.4x)\n",	  s-socket, io->map, io->flags, io->speed, io->start, io->stop);    map = io->map;    if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||	(io->stop < io->start)) return -EINVAL;    /* Turn off the window before changing anything */    if (i365_get(s, I365_ADDRWIN) & I365_ENA_IO(map))	i365_bclr(s, I365_ADDRWIN, I365_ENA_IO(map));    i365_set_pair(s, I365_IO(map)+I365_W_START, io->start);    i365_set_pair(s, I365_IO(map)+I365_W_STOP, io->stop);    ioctl = i365_get(s, I365_IOCTL) & ~I365_IOCTL_MASK(map);    if (io->speed) ioctl |= I365_IOCTL_WAIT(map);    if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);    if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);    if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);    i365_set(s, I365_IOCTL, ioctl);    /* Turn on the window if necessary */    if (io->flags & MAP_ACTIVE)	i365_bset(s, I365_ADDRWIN, I365_ENA_IO(map));    return 0;} /* i365_set_io_map *//*====================================================================*/static int i365_get_mem_map(socket_info_t *s, struct pccard_mem_map *mem){    u_short base, i;    u_char map, addr;        map = mem->map;    if (map > 4) return -EINVAL;    addr = i365_get(s, I365_ADDRWIN);    mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;    base = I365_MEM(map);        i = i365_get_pair(s, base+I365_W_START);    mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;    mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;    mem->sys_start = ((u_long)(i & 0x0fff) << 12);        i = i365_get_pair(s, base+I365_W_STOP);    mem->speed  = (i & I365_MEM_WS0) ? 1 : 0;    mem->speed += (i & I365_MEM_WS1) ? 2 : 0;    mem->speed *= cycle_time;    mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;        i = i365_get_pair(s, base+I365_W_OFF);    mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;    mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;    mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;    mem->card_start &= 0x3ffffff;#ifdef CONFIG_PCI    /* Take care of high byte, for PCI controllers */    if (s->type == IS_PD6729) {	i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));	addr = i365_get(s, PD67_EXT_DATA) << 24;    } else if (s->flags & IS_CARDBUS) {	addr = i365_get(s, CB_MEM_PAGE(map)) << 24;	mem->sys_stop += addr; mem->sys_start += addr;    }#endif        DEBUG(3, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."	  "5lx, %#5.5x\n", s-socket, mem->map, mem->flags, mem->speed,	  mem->sys_start, mem->sys_stop, mem->card_start);    return 0;} /* i365_get_mem_map *//*====================================================================*/  static int i365_set_mem_map(socket_info_t *s, struct pccard_mem_map *mem){    u_short base, i;    u_char map;        DEBUG(3, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"	  "lx, %#5.5x)\n", s-socket, mem->map, mem->flags, mem->speed,	  mem->sys_start, mem->sys_stop, mem->card_start);    map = mem->map;    if ((map > 4) || (mem->card_start > 0x3ffffff) ||	(mem->sys_start > mem->sys_stop) || (mem->speed > 1000))	return -EINVAL;    if (!(s->flags & (IS_PCI|IS_CARDBUS)) &&	((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)))	return -EINVAL;	    /* Turn off the window before changing anything */    if (i365_get(s, I365_ADDRWIN) & I365_ENA_MEM(map))	i365_bclr(s, I365_ADDRWIN, I365_ENA_MEM(map));#ifdef CONFIG_PCI    /* Take care of high byte, for PCI controllers */    if (s->type == IS_PD6729) {	i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));	i365_set(s, PD67_EXT_DATA, (mem->sys_start >> 24));    } else if (s->flags & IS_CARDBUS)	i365_set(s, CB_MEM_PAGE(map), mem->sys_start >> 24);#endif        base = I365_MEM(map);    i = (mem->sys_start >> 12) & 0x0fff;    if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;    if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;    i365_set_pair(s, base+I365_W_START, i);        i = (mem->sys_stop >> 12) & 0x0fff;    switch (mem->speed / cycle_time) {    case 0:	break;    case 1:	i |= I365_MEM_WS0; break;    case 2:	i |= I365_MEM_WS1; break;    default:	i |= I365_MEM_WS1 | I365_MEM_WS0; break;    }    i365_set_pair(s, base+I365_W_STOP, i);        i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;    if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;    if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;    i365_set_pair(s, base+I365_W_OFF, i);        /* Turn on the window if necessary */    if (mem->flags & MAP_ACTIVE)	i365_bset(s, I365_ADDRWIN, I365_ENA_MEM(map));    return 0;} /* i365_set_mem_map *//*======================================================================    The few things that are strictly for Cardbus cards goes here.======================================================================*/#ifdef CONFIG_CARDBUSstatic int cb_get_status(socket_info_t *s, u_int *value){    u_int state = cb_readl(s, CB_SOCKET_STATE);    *value = (state & CB_SS_32BIT) ? SS_CARDBUS : 0;    *value |= (state & CB_SS_CCD) ? 0 : SS_DETECT;    *value |= (state & CB_SS_CSTSCHG) ? SS_STSCHG : 0;    *value |= (state & CB_SS_PWRCYCLE) ? (SS_POWERON|SS_READY) : 0;    *value |= (state & CB_SS_3VCARD) ? SS_3VCARD : 0;    *value |= (state & CB_SS_XVCARD) ? SS_XVCARD : 0;    *value |= (state & CB_SS_VSENSE) ? 0 : SS_PENDING;    DEBUG(1, "yenta: GetStatus(%d) = %#4.4x\n", s-socket, *value);    return 0;} /* cb_get_status */static int cb_get_socket(socket_info_t *s, socket_state_t *state){    u_short bcr;    cb_get_power(s, state);    pci_readw(s, CB_BRIDGE_CONTROL, &bcr);    state->flags |= (bcr & CB_BCR_CB_RESET) ? SS_RESET : 0;    if (cb_get_irq_mode(s) != 0)	state->io_irq = s->cap.pci_irq;    else	state->io_irq = i365_get(s, I365_INTCTL) & I365_IRQ_MASK;    DEBUG(2, "yenta: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d"	  ", io_irq %d, csc_mask %#2.2x\n", s-socket, state->flags,

⌨️ 快捷键说明

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