📄 os_bri.c
字号:
/* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */#include "platform.h"#include "debuglib.h"#include "cardtype.h"#include "pc.h"#include "pr_pc.h"#include "di_defs.h"#include "dsp_defs.h"#include "di.h"#include "io.h"#include "xdi_msg.h"#include "xdi_adapter.h"#include "os_bri.h"#include "diva_pci.h"#include "mi_pc.h"#include "pc_maint.h"/*** IMPORTS*/extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);extern void diva_xdi_display_adapter_features(int card);extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);/*** LOCALS*/static int bri_bar_length[3] = { 0x80, 0x80, 0x20};static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a);static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a);static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, diva_xdi_um_cfg_cmd_t * cmd, int length);static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a);static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, const byte * data, dword length);static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter, dword start_address, dword features);static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a){ a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0; a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1; a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2; a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1; a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2; a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2; a->xdi_adapter.ram = a->resources.pci.addr[0]; a->xdi_adapter.cfg = a->resources.pci.addr[1]; a->xdi_adapter.Address = a->resources.pci.addr[2]; a->xdi_adapter.reset = a->xdi_adapter.cfg; a->xdi_adapter.port = a->xdi_adapter.Address; a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET; a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */}/*** BAR0 - MEM Addr - 0x80 - NOT USED** BAR1 - I/O Addr - 0x80** BAR2 - I/O Addr - 0x20*/int diva_bri_init_card(diva_os_xdi_adapter_t * a){ int bar; dword bar2 = 0, bar2_length = 0xffffffff; word cmd = 0, cmd_org; byte Bus, Slot; void *hdev; byte __iomem *p; /* Set properties */ a->xdi_adapter.Properties = CardProperties[a->CardOrdinal]; DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name)) /* Get resources */ for (bar = 0; bar < 3; bar++) { a->resources.pci.bar[bar] = divasa_get_pci_bar(a->resources.pci.bus, a->resources.pci.func, bar, a->resources.pci.hdev); if (!a->resources.pci.bar[bar]) { DBG_ERR(("A: can't get BAR[%d]", bar)) return (-1); } } a->resources.pci.irq = (byte) divasa_get_pci_irq(a->resources.pci.bus, a->resources.pci.func, a->resources.pci.hdev); if (!a->resources.pci.irq) { DBG_ERR(("A: invalid irq")); return (-1); } /* Get length of I/O bar 2 - it is different by older EEPROM version */ Bus = a->resources.pci.bus; Slot = a->resources.pci.func; hdev = a->resources.pci.hdev; /* Get plain original values of the BAR2 CDM registers */ PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev); PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev); /* Disable device and get BAR2 length */ PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev); PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev); PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev); /* Restore BAR2 and CMD registers */ PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev); PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev); /* Calculate BAR2 length */ bar2_length = (~(bar2_length & ~7)) + 1; DBG_LOG(("BAR[2] length=%lx", bar2_length)) /* Map and register resources */ if (!(a->resources.pci.addr[0] = divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0], bri_bar_length[0]))) { DBG_ERR(("A: BRI, can't map BAR[0]")) diva_bri_cleanup_adapter(a); return (-1); } sprintf(&a->port_name[0], "BRI %02x:%02x", a->resources.pci.bus, a->resources.pci.func); if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1], bri_bar_length[1], &a->port_name[0], 1)) { DBG_ERR(("A: BRI, can't register BAR[1]")) diva_bri_cleanup_adapter(a); return (-1); } a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1]; a->resources.pci.length[1] = bri_bar_length[1]; if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2], bar2_length, &a->port_name[0], 2)) { DBG_ERR(("A: BRI, can't register BAR[2]")) diva_bri_cleanup_adapter(a); return (-1); } a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2]; a->resources.pci.length[2] = bar2_length; /* Set all memory areas */ diva_bri_set_addresses(a); /* Get Serial Number */ a->xdi_adapter.serialNo = diva_bri_get_serial_number(a); /* Register I/O ports with correct name now */ if (diva_bri_reregister_io(a)) { diva_bri_cleanup_adapter(a); return (-1); } /* Initialize OS dependent objects */ if (diva_os_initialize_spin_lock (&a->xdi_adapter.isr_spin_lock, "isr")) { diva_bri_cleanup_adapter(a); return (-1); } if (diva_os_initialize_spin_lock (&a->xdi_adapter.data_spin_lock, "data")) { diva_bri_cleanup_adapter(a); return (-1); } strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasbrid"); if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr, DIDpcRoutine, &a->xdi_adapter)) { diva_bri_cleanup_adapter(a); return (-1); } /* Do not initialize second DPC - only one thread will be created */ a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object; /* Create entity table */ a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels; a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info; a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO)); if (!a->xdi_adapter.e_tbl) { diva_bri_cleanup_adapter(a); return (-1); } memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO)); /* Set up interface */ a->xdi_adapter.a.io = &a->xdi_adapter; a->xdi_adapter.DIRequest = request; a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter; a->interface.cmd_proc = diva_bri_cmd_card_proc; p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter); outpp(p, 0x41); DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p); prepare_maestra_functions(&a->xdi_adapter); a->dsp_mask = 0x00000003; /* Set IRQ handler */ a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq; sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld", (long) a->xdi_adapter.serialNo); if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr, a->xdi_adapter.irq_info.irq_name)) { diva_bri_cleanup_adapter(a); return (-1); } a->xdi_adapter.irq_info.registered = 1; diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name, a->resources.pci.irq, a->xdi_adapter.serialNo); return (0);}static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a){ int i; if (a->xdi_adapter.Initialized) { diva_bri_stop_adapter(a); } /* Remove ISR Handler */ if (a->xdi_adapter.irq_info.registered) { diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr); } a->xdi_adapter.irq_info.registered = 0; if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) { divasa_unmap_pci_bar(a->resources.pci.addr[0]); a->resources.pci.addr[0] = NULL; a->resources.pci.bar[0] = 0; } for (i = 1; i < 3; i++) { if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) { diva_os_register_io_port(a, 0, a->resources.pci.bar[i], a->resources.pci. length[i], &a->port_name[0], i); a->resources.pci.addr[i] = NULL; a->resources.pci.bar[i] = 0; } } /* Free OS objects */ diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr); diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr); diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr); a->xdi_adapter.isr_soft_isr.object = NULL; diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm"); diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm"); /* Free memory */ if (a->xdi_adapter.e_tbl) { diva_os_free(0, a->xdi_adapter.e_tbl); a->xdi_adapter.e_tbl = NULL; } return (0);}void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter){}/*** Get serial number*/static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a){ dword serNo = 0; byte __iomem *confIO; word serHi, serLo; word __iomem *confMem; confIO = DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter); serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF); serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF); serNo = ((dword) serHi << 16) | (dword) serLo; DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO); if ((serNo == 0) || (serNo == 0xFFFFFFFF)) { DBG_FTL(("W: BRI use BAR[0] to get card serial number")) confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter); serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF); serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF); serNo = (((dword) serHi) << 16) | ((dword) serLo); DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem); } DBG_LOG(("Serial Number=%ld", serNo)) return (serNo);}/*** Unregister I/O and register it with new name,** based on Serial Number*/static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a){ int i; for (i = 1; i < 3; i++) { diva_os_register_io_port(a, 0, a->resources.pci.bar[i], a->resources.pci.length[i], &a->port_name[0], i); a->resources.pci.addr[i] = NULL; } sprintf(a->port_name, "DIVA BRI %ld", (long) a->xdi_adapter.serialNo); for (i = 1; i < 3; i++) { if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i], a->resources.pci.length[i], &a->port_name[0], i)) { DBG_ERR(("A: failed to reregister BAR[%d]", i)) return (-1); } a->resources.pci.addr[i] = (void *) (unsigned long) a->resources.pci.bar[i]; } return (0);}/*** Process command from user mode*/static intdiva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, diva_xdi_um_cfg_cmd_t * cmd, int length){ int ret = -1; if (cmd->adapter != a->controller) { DBG_ERR(("A: pri_cmd, invalid controller=%d != %d", cmd->adapter, a->controller)) return (-1); } switch (cmd->command) { case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -