📄 i82365.c
字号:
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 + -