📄 os_4bri.c
字号:
serNo |= a->resources.pci.bus << 8; serNo |= a->resources.pci.func; } a->xdi_adapter.serialNo = serNo; DBG_REG(("Serial No. : %ld", a->xdi_adapter.serialNo)) return (serNo);}/*** Release resources of slave adapters*/static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a){ diva_os_xdi_adapter_t *adapter_list[4]; diva_os_xdi_adapter_t *diva_current; int i; adapter_list[0] = a; adapter_list[1] = a->slave_adapters[0]; adapter_list[2] = a->slave_adapters[1]; adapter_list[3] = a->slave_adapters[2]; for (i = 0; i < a->xdi_adapter.tasks; i++) { diva_current = adapter_list[i]; if (diva_current) { diva_os_destroy_spin_lock(&diva_current-> xdi_adapter. isr_spin_lock, "unload"); diva_os_destroy_spin_lock(&diva_current-> xdi_adapter. data_spin_lock, "unload"); diva_os_cancel_soft_isr(&diva_current->xdi_adapter. req_soft_isr); diva_os_cancel_soft_isr(&diva_current->xdi_adapter. isr_soft_isr); diva_os_remove_soft_isr(&diva_current->xdi_adapter. req_soft_isr); diva_current->xdi_adapter.isr_soft_isr.object = NULL; if (diva_current->xdi_adapter.e_tbl) { diva_os_free(0, diva_current->xdi_adapter. e_tbl); } diva_current->xdi_adapter.e_tbl = NULL; diva_current->xdi_adapter.e_max = 0; diva_current->xdi_adapter.e_count = 0; } } return (0);}static intdiva_4bri_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: 4bri_cmd, invalid controller=%d != %d", cmd->adapter, a->controller)) return (-1); } switch (cmd->command) { case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = (dword) a->CardOrdinal; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } break; case DIVA_XDI_UM_CMD_GET_SERIAL_NR: a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { *(dword *) a->xdi_mbox.data = (dword) a->xdi_adapter.serialNo; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } break; case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG: if (!a->xdi_adapter.ControllerNumber) { /* Only master adapter can access hardware config */ a->xdi_mbox.data_length = sizeof(dword) * 9; a->xdi_mbox.data = diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { int i; dword *data = (dword *) a->xdi_mbox.data; for (i = 0; i < 8; i++) { *data++ = a->resources.pci.bar[i]; } *data++ = (dword) a->resources.pci.irq; a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } } break; case DIVA_XDI_UM_CMD_GET_CARD_STATE: if (!a->xdi_adapter.ControllerNumber) { a->xdi_mbox.data_length = sizeof(dword); a->xdi_mbox.data = diva_os_malloc(0, a->xdi_mbox.data_length); if (a->xdi_mbox.data) { dword *data = (dword *) a->xdi_mbox.data; if (!a->xdi_adapter.ram || !a->xdi_adapter.reset || !a->xdi_adapter.cfg) { *data = 3; } else if (a->xdi_adapter.trapped) { *data = 2; } else if (a->xdi_adapter.Initialized) { *data = 1; } else { *data = 0; } a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } } break; case DIVA_XDI_UM_CMD_WRITE_FPGA: if (!a->xdi_adapter.ControllerNumber) { ret = diva_4bri_write_fpga_image(a, (byte *) & cmd[1], cmd->command_data. write_fpga. image_length); } break; case DIVA_XDI_UM_CMD_RESET_ADAPTER: if (!a->xdi_adapter.ControllerNumber) { ret = diva_4bri_reset_adapter(&a->xdi_adapter); } break; case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK: if (!a->xdi_adapter.ControllerNumber) { ret = diva_4bri_write_sdram_block(&a->xdi_adapter, cmd-> command_data. write_sdram. offset, (byte *) & cmd[1], cmd-> command_data. write_sdram. length, a->xdi_adapter. MemorySize); } break; case DIVA_XDI_UM_CMD_START_ADAPTER: if (!a->xdi_adapter.ControllerNumber) { ret = diva_4bri_start_adapter(&a->xdi_adapter, cmd->command_data. start.offset, cmd->command_data. start.features); } break; case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES: if (!a->xdi_adapter.ControllerNumber) { a->xdi_adapter.features = cmd->command_data.features.features; a->xdi_adapter.a.protocol_capabilities = a->xdi_adapter.features; DBG_TRC(("Set raw protocol features (%08x)", a->xdi_adapter.features)) ret = 0; } break; case DIVA_XDI_UM_CMD_STOP_ADAPTER: if (!a->xdi_adapter.ControllerNumber) { ret = diva_4bri_stop_adapter(a); } break; case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY: ret = diva_card_read_xlog(a); break; case DIVA_XDI_UM_CMD_READ_SDRAM: if (!a->xdi_adapter.ControllerNumber && a->xdi_adapter.Address) { if ( (a->xdi_mbox.data_length = cmd->command_data.read_sdram.length)) { if ( (a->xdi_mbox.data_length + cmd->command_data.read_sdram.offset) < a->xdi_adapter.MemorySize) { a->xdi_mbox.data = diva_os_malloc(0, a->xdi_mbox. data_length); if (a->xdi_mbox.data) { byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter); byte __iomem *src = p; byte *dst = a->xdi_mbox.data; dword len = a->xdi_mbox.data_length; src += cmd->command_data.read_sdram.offset; while (len--) { *dst++ = READ_BYTE(src++); } DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p); a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY; ret = 0; } } } } break; default: DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller, cmd->command)) } return (ret);}void *xdiLoadFile(char *FileName, unsigned long *FileLength, unsigned long lim){ void *ret = diva_xdiLoadFileFile; if (FileLength) { *FileLength = diva_xdiLoadFileLength; } diva_xdiLoadFileFile = NULL; diva_xdiLoadFileLength = 0; return (ret);}void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter){}void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter){}static intdiva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data, dword length){ int ret; diva_xdiLoadFileFile = data; diva_xdiLoadFileLength = length; ret = qBri_FPGA_download(&a->xdi_adapter); diva_xdiLoadFileFile = NULL; diva_xdiLoadFileLength = 0; return (ret ? 0 : -1);}static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter){ PISDN_ADAPTER Slave; int i; if (!IoAdapter->Address || !IoAdapter->reset) { return (-1); } if (IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first", IoAdapter->ANum)) return (-1); } /* Forget all entities on all adapters */ for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) { Slave = IoAdapter->QuadroList->QuadroAdapter[i]; Slave->e_count = 0; if (Slave->e_tbl) { memset(Slave->e_tbl, 0x00, Slave->e_max * sizeof(E_INFO)); } Slave->head = 0; Slave->tail = 0; Slave->assign = 0; Slave->trapped = 0; memset(&Slave->a.IdTable[0], 0x00, sizeof(Slave->a.IdTable)); memset(&Slave->a.IdTypeTable[0], 0x00, sizeof(Slave->a.IdTypeTable)); memset(&Slave->a.FlowControlIdTable[0], 0x00, sizeof(Slave->a.FlowControlIdTable)); memset(&Slave->a.FlowControlSkipTable[0], 0x00, sizeof(Slave->a.FlowControlSkipTable)); memset(&Slave->a.misc_flags_table[0], 0x00, sizeof(Slave->a.misc_flags_table)); memset(&Slave->a.rx_stream[0], 0x00, sizeof(Slave->a.rx_stream)); memset(&Slave->a.tx_stream[0], 0x00, sizeof(Slave->a.tx_stream)); memset(&Slave->a.tx_pos[0], 0x00, sizeof(Slave->a.tx_pos)); memset(&Slave->a.rx_pos[0], 0x00, sizeof(Slave->a.rx_pos)); } return (0);}static intdiva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter, dword address, const byte * data, dword length, dword limit){ byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); byte __iomem *mem = p; if (((address + length) >= limit) || !mem) { DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p); DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx", IoAdapter->ANum, address + length)) return (-1); } mem += address; while (length--) { WRITE_BYTE(mem++, *data++); } DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p); return (0);}static intdiva_4bri_start_adapter(PISDN_ADAPTER IoAdapter, dword start_address, dword features){ volatile word __iomem *signature; int started = 0; int i; byte __iomem *p; /* start adapter */ start_qBri_hardware(IoAdapter); p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter); /* wait for signature in shared memory (max. 3 seconds) */ signature = (volatile word __iomem *) (&p[0x1E]); for (i = 0; i < 300; ++i) { diva_os_wait(10); if (READ_WORD(&signature[0]) == 0x4447) { DBG_TRC(("Protocol startup time %d.%02d seconds", (i / 100), (i % 100))) started = 1; break; } } for (i = 1; i < IoAdapter->tasks; i++) { IoAdapter->QuadroList->QuadroAdapter[i]->features = IoAdapter->features; IoAdapter->QuadroList->QuadroAdapter[i]->a. protocol_capabilities = IoAdapter->features; } if (!started) { DBG_FTL(("%s: Adapter selftest failed, signature=%04x", IoAdapter->Properties.Name, READ_WORD(&signature[0]))) DIVA_OS_MEM_DETACH_RAM(IoAdapter, p); (*(IoAdapter->trapFnc)) (IoAdapter); IoAdapter->stop(IoAdapter); return (-1); } DIVA_OS_MEM_DETACH_RAM(IoAdapter, p); for (i = 0; i < IoAdapter->tasks; i++) { IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1; IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0; } if (check_qBri_interrupt(IoAdapter)) { DBG_ERR(("A: A(%d) interrupt test failed", IoAdapter->ANum)) for (i = 0; i < IoAdapter->tasks; i++) { IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0; } IoAdapter->stop(IoAdapter); return (-1); } IoAdapter->Properties.Features = (word) features; diva_xdi_display_adapter_features(IoAdapter->ANum); for (i = 0; i < IoAdapter->tasks; i++) { DBG_LOG(("A(%d) %s adapter successfull started", IoAdapter->QuadroList->QuadroAdapter[i]->ANum, (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI")) diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum); IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features; } return (0);}static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter){#ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI int i; ADAPTER *a = &IoAdapter->a; byte __iomem *p; IoAdapter->IrqCount = 0; if (IoAdapter->ControllerNumber > 0) return (-1); p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE); DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); /* interrupt test */ a->ReadyInt = 1; a->ram_out(a, &PR_RAM->ReadyInt, 1); for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10)); return ((IoAdapter->IrqCount > 0) ? 0 : -1);#else dword volatile __iomem *qBriIrq; byte __iomem *p; /* Reset on-board interrupt register */ IoAdapter->IrqCount = 0; p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter); qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card (IoAdapter-> cardType) ? (MQ2_BREG_IRQ_TEST) : (MQ_BREG_IRQ_TEST)]); WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF); DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p); p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE); DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); diva_os_wait(100); return (0);#endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */}static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a){ PISDN_ADAPTER IoAdapter = &a->xdi_adapter; /* clear any pending interrupt */ IoAdapter->disIrq(IoAdapter); IoAdapter->tst_irq(&IoAdapter->a); IoAdapter->clr_irq(&IoAdapter->a); IoAdapter->tst_irq(&IoAdapter->a); /* kill pending dpcs */ diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr); diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);}static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a){ PISDN_ADAPTER IoAdapter = &a->xdi_adapter; int i; if (!IoAdapter->ram) { return (-1); } if (!IoAdapter->Initialized) { DBG_ERR(("A: A(%d) can't stop PRI adapter - not running", IoAdapter->ANum)) return (-1); /* nothing to stop */ } for (i = 0; i < IoAdapter->tasks; i++) { IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0; } /* Disconnect Adapters from DIDD */ for (i = 0; i < IoAdapter->tasks; i++) { diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum); } i = 100; /* Stop interrupts */ a->clear_interrupts_proc = diva_4bri_clear_interrupts; IoAdapter->a.ReadyInt = 1; IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt); do { diva_os_sleep(10); } while (i-- && a->clear_interrupts_proc); if (a->clear_interrupts_proc) { diva_4bri_clear_interrupts(a); a->clear_interrupts_proc = NULL; DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter", IoAdapter->ANum)) } IoAdapter->a.ReadyInt = 0; /* Stop and reset adapter */ IoAdapter->stop(IoAdapter); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -