📄 gdth.c
字号:
outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-PCI: Initialization error\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } gdth_writeb(0, &dp6c_ptr->u.ic.S_Status); } else { /* MPR */ TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); ha->brd = gdth_mmap(pcistr->dpmem, sizeof(gdt6m_dpram_str)); if (ha->brd == NULL) { printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } /* manipulate config. space to enable DPMEM, start RP controller */#if LINUX_VERSION_CODE >= 0x20363 pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); command |= 6; pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); if (pci_resource_start(pcistr->pdev, 8) == 1UL) pci_resource_start(pcistr->pdev, 8) = 0UL; i = 0xFEFF0001UL; pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); gdth_delay(1); pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, pci_resource_start(pcistr->pdev, 8));#elif LINUX_VERSION_CODE >= 0x2015C pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); command |= 6; pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); if (pcistr->pdev->rom_address == 1UL) pcistr->pdev->rom_address = 0UL; i = 0xFEFF0001UL; pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); gdth_delay(1); pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, pcistr->pdev->rom_address);#else pcibios_read_config_word(pcistr->bus, pcistr->device_fn, PCI_COMMAND, &command); command |= 6; pcibios_write_config_word(pcistr->bus, pcistr->device_fn, PCI_COMMAND, command); pcibios_read_config_dword(pcistr->bus, pcistr->device_fn, PCI_ROM_ADDRESS, &rom_addr); if (rom_addr == 1UL) rom_addr = 0UL; i = 0xFEFF0001UL; pcibios_write_config_dword(pcistr->bus, pcistr->device_fn, PCI_ROM_ADDRESS, i); gdth_delay(1); pcibios_write_config_dword(pcistr->bus, pcistr->device_fn, PCI_ROM_ADDRESS, rom_addr);#endif /* check and reset interface area */ dp6m_ptr = (gdt6m_dpram_str *)ha->brd; gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); if (gdth_readl(&dp6m_ptr->u) != DPMEM_MAGIC) { printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", pcistr->dpmem); found = FALSE; for (i = 0xC8000; i < 0xE8000; i += 0x4000) { gdth_munmap(ha->brd); ha->brd = gdth_mmap(i, sizeof(ushort)); if (ha->brd == NULL) { printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } if (gdth_readw(ha->brd) != 0xffff) { TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); continue; } gdth_munmap(ha->brd);#if LINUX_VERSION_CODE >= 0x2015C pci_write_config_dword(pcistr->pdev, PCI_BASE_ADDRESS_0, i);#else pcibios_write_config_dword(pcistr->bus, pcistr->device_fn, PCI_BASE_ADDRESS_0, i);#endif ha->brd = gdth_mmap(i, sizeof(gdt6m_dpram_str)); if (ha->brd == NULL) { printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); return 0; } dp6m_ptr = (gdt6m_dpram_str *)ha->brd; gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); if (gdth_readl(&dp6m_ptr->u) == DPMEM_MAGIC) { printk("GDT-PCI: Use free address at 0x%x\n", i); found = TRUE; break; } } if (!found) { printk("GDT-PCI: No free address found!\n"); gdth_munmap(ha->brd); return 0; } } memset_io((char *)&dp6m_ptr->u,0,sizeof(dp6m_ptr->u)); /* disable board interrupts, deinit services */ gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, &dp6m_ptr->i960r.edoor_en_reg); gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); gdth_writeb(0x00, &dp6m_ptr->u.ic.S_Status); gdth_writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); gdth_writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); gdth_writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { if (--retries == 0) { printk("GDT-PCI: Initialization error (DEINIT failed)\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } prot_ver = (unchar)gdth_readl(&dp6m_ptr->u.ic.S_Info[0]); gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-PCI: Illegal protocol version\n"); gdth_munmap(ha->brd); return 0; } ha->type = GDT_PCIMPR; ha->ic_all_size = sizeof(dp6m_ptr->u); /* special command to controller BIOS */ gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); gdth_writel(0x01, &dp6m_ptr->u.ic.S_Info[2]); gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); gdth_writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); retries = INIT_RETRIES; gdth_delay(20); while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { if (--retries == 0) { printk("GDT-PCI: Initialization error\n"); gdth_munmap(ha->brd); return 0; } gdth_delay(1); } gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); } return 1;}/* controller protocol functions */GDTH_INITFUNC(static void, gdth_enable_int(int hanum)){ gdth_ha_str *ha; ulong flags; gdt2_dpram_str *dp2_ptr; gdt6_dpram_str *dp6_ptr; gdt6m_dpram_str *dp6m_ptr; TRACE(("gdth_enable_int() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); GDTH_LOCK_HA(ha, flags); if (ha->type == GDT_EISA) { outb(0xff, ha->bmic + EDOORREG); outb(0xff, ha->bmic + EDENABREG); outb(0x01, ha->bmic + EINTENABREG); } else if (ha->type == GDT_ISA) { dp2_ptr = (gdt2_dpram_str *)ha->brd; gdth_writeb(1, &dp2_ptr->io.irqdel); gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index); gdth_writeb(1, &dp2_ptr->io.irqen); } else if (ha->type == GDT_PCI) { dp6_ptr = (gdt6_dpram_str *)ha->brd; gdth_writeb(1, &dp6_ptr->io.irqdel); gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index); gdth_writeb(1, &dp6_ptr->io.irqen); } else if (ha->type == GDT_PCINEW) { outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); outb(0x03, PTR2USHORT(&ha->plx->control1)); } else if (ha->type == GDT_PCIMPR) { dp6m_ptr = (gdt6m_dpram_str *)ha->brd; gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, &dp6m_ptr->i960r.edoor_en_reg); } GDTH_UNLOCK_HA(ha, flags);}static int gdth_get_status(unchar *pIStatus,int irq){ register gdth_ha_str *ha; int i; TRACE(("gdth_get_status() irq %d ctr_count %d\n", irq,gdth_ctr_count)); *pIStatus = 0; for (i=0; i<gdth_ctr_count; ++i) { ha = HADATA(gdth_ctr_tab[i]); if (ha->irq != (unchar)irq) /* check IRQ */ continue; if (ha->type == GDT_EISA) *pIStatus = inb((ushort)ha->bmic + EDOORREG); else if (ha->type == GDT_ISA) *pIStatus = gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCI) *pIStatus = gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Cmd_Index); else if (ha->type == GDT_PCINEW) *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); else if (ha->type == GDT_PCIMPR) *pIStatus = gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.edoor_reg); if (*pIStatus) return i; /* board found */ } return -1;} static int gdth_test_busy(int hanum){ register gdth_ha_str *ha; register int gdtsema0 = 0; TRACE(("gdth_test_busy() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); if (ha->type == GDT_EISA) gdtsema0 = (int)inb(ha->bmic + SEMA0REG); else if (ha->type == GDT_ISA) gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Sema0); else if (ha->type == GDT_PCI) gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Sema0); else if (ha->type == GDT_PCINEW) gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); else if (ha->type == GDT_PCIMPR) gdtsema0 = (int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg); return (gdtsema0 & 1);}static int gdth_get_cmd_index(int hanum){ register gdth_ha_str *ha; int i; TRACE(("gdth_get_cmd_index() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); for (i=0; i<GDTH_MAXCMDS; ++i) { if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; ha->cmd_tab[i].service = ha->pccb->Service; ha->pccb->CommandIndex = (ulong32)i+2; return (i+2); } } return 0;}static void gdth_set_sema0(int hanum){ register gdth_ha_str *ha; TRACE(("gdth_set_sema0() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); if (ha->type == GDT_EISA) { outb(1, ha->bmic + SEMA0REG); } else if (ha->type == GDT_ISA) { gdth_writeb(1, &((gdt2_dpram_str *)ha->brd)->u.ic.Sema0); } else if (ha->type == GDT_PCI) { gdth_writeb(1, &((gdt6_dpram_str *)ha->brd)->u.ic.Sema0); } else if (ha->type == GDT_PCINEW) { outb(1, PTR2USHORT(&ha->plx->sema0_reg)); } else if (ha->type == GDT_PCIMPR) { gdth_writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg); }}static void gdth_copy_command(int hanum){ register gdth_ha_str *ha; register gdth_cmd_str *cmd_ptr; register gdt6m_dpram_str *dp6m_ptr; register gdt6c_dpram_str *dp6c_ptr; gdt6_dpram_str *dp6_ptr; gdt2_dpram_str *dp2_ptr; ushort cp_count,dp_offset,cmd_no; TRACE(("gdth_copy_command() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); cp_count = ha->cmd_len; dp_offset= ha->cmd_offs_dpmem; cmd_no = ha->cmd_cnt; cmd_ptr = ha->pccb; ++ha->cmd_cnt; if (ha->type == GDT_EISA) return; /* no DPMEM, no copy */ /* set cpcount dword aligned */ if (cp_count & 3) cp_count += (4 - (cp_count & 3)); ha->cmd_offs_dpmem += cp_count; /* set offset and service, copy command to DPMEM */ if (ha->type == GDT_ISA) { dp2_ptr = (gdt2_dpram_str *)ha->brd; gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp2_ptr->u.ic.comm_queue[cmd_no].offset); gdth_writew((ushort)cmd_ptr->Service, &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } else if (ha->type == GDT_PCI) { dp6_ptr = (gdt6_dpram_str *)ha->brd; gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp6_ptr->u.ic.comm_queue[cmd_no].offset); gdth_writew((ushort)cmd_ptr->Service, &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); } else if (ha->type == GDT_PCINEW) { dp6c_ptr = (gdt6c_dpram_str *)ha->brd; gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); gdth_writew((ushort)cmd_ptr->Service, &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); memcpy_t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -