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

📄 fourbri.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* * * Copyright (C) Eicon Technology Corporation, 2000. * * This source file is supplied for the exclusive use with Eicon * Technology Corporation's range of DIVA Server Adapters. * * Eicon File Revision :    1.7   * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *//* Diva Server 4BRI specific part of initialisation */#include "sys.h"#include "idi.h"#include "divas.h"#include "pc.h"#include "pr_pc.h"#include "dsp_defs.h"#include "constant.h"#include "adapter.h"#include "uxio.h"#define TEST_INT_DIVAS_Q	0x13#define	DIVAS_MAINT_OFFSET	0xff00	/* value for 4BRI card */#define MQ_BOARD_DSP_OFFSET 0x00a00000#define MQ_DSP1_ADDR_OFFSET 0x00000008#define MQ_DSP_JUNK_OFFSET  0x00000400#define MQ_DSP1_DATA_OFFSET 0x00000000#define MQ_BOARD_ISAC_DSP_RESET  0x00800028#define MQ_BREG_RISC  0x1200      /* RISC Reset */#define MQ_ISAC_DSP_RESET 0x0028 /* ISAC and DSP reset address offset */#define MQ_RISC_COLD_RESET_MASK         0x0001      /* RISC Cold reset                        */#define MQ_RISC_WARM_RESET_MASK         0x0002      /* RISC Warm reset                        */#define MQ_IRQ_REQ_ON                   0x1#define MQ_IRQ_REQ_OFF                  0x0#define MQ_BREG_IRQ_TEST                0x0608#define PLX9054_INTCSR      0x69 #define PLX9054_INT_ENA     0x09#define DIVAS_IOBASE	0x01#define M_PCI_RESET	0x10byte mem_in(ADAPTER *a, void *adr);word mem_inw(ADAPTER *a, void *adr);void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);void mem_out(ADAPTER *a, void *adr, byte data);void mem_outw(ADAPTER *a, void *adr, word data);void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);void mem_inc(ADAPTER *a, void *adr);int Divas4BRIInitPCI(card_t *card, dia_card_t *cfg);int fourbri_ISR (card_t* card);int FPGA_Download(word, dword, byte *, byte *, int);extern byte FPGA_Bytes[];extern void *get_card(int);byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);word GetProtFeatureValue(char *sw_id);void memcp(byte *dst, byte *src, dword dwLen);int memcm(byte *dst, byte *src, dword dwLen);static int diva_server_4bri_reset(card_t *card){	byte *ctl;	DPRINTF(("divas: reset Diva Server 4BRI"));	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);	/* stop RISC, DSP's and ISAC  */   UxCardMemOut(card->hw, &ctl[MQ_BREG_RISC], 0);   UxCardMemOut(card->hw, &ctl[MQ_ISAC_DSP_RESET], 0);	UxCardMemDetach(card->hw, ctl);	return 0;}static int diva_server_4bri_config(card_t *card, dia_config_t *config){	byte *shared;	int i, j;	DPRINTF(("divas: configure Diva Server 4BRI"));	shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);		for (i=0; i<256; i++)	{		UxCardMemOut(card->hw, &shared[i], 0);	}	UxCardMemOut(card->hw, &shared[ 8], config->tei);	UxCardMemOut(card->hw, &shared[ 9], config->nt2);	UxCardMemOut(card->hw, &shared[10], 0);	UxCardMemOut(card->hw, &shared[11], config->watchdog);	UxCardMemOut(card->hw, &shared[12], config->permanent);	UxCardMemOut(card->hw, &shared[13], config->x_interface);	UxCardMemOut(card->hw, &shared[14], config->stable_l2);	UxCardMemOut(card->hw, &shared[15], config->no_order_check);	UxCardMemOut(card->hw, &shared[16], config->handset_type);	UxCardMemOut(card->hw, &shared[17], 0);	UxCardMemOut(card->hw, &shared[18], config->low_channel);	UxCardMemOut(card->hw, &shared[19], config->prot_version);	UxCardMemOut(card->hw, &shared[20], config->crc4);	if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))	{		DPRINTF(("divas: Signifying V.90"));		UxCardMemOut(card->hw, &shared[22], 4);	}	else	{		UxCardMemOut(card->hw, &shared[22], 0);	}	for (i=0; i<2; i++)	{		for (j=0; j<32; j++)		{			UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);		}		for (j=0; j<32; j++)		{			UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);		}		for (j=0; j<32; j++)		{			UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);		}	}	UxCardMemDetach(card->hw, shared);	return 0;}staticvoid diva_server_4bri_reset_int(card_t *card){	byte *ctl;	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);	UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);	UxCardMemDetach(card->hw, ctl);	return;} static int diva_server_4bri_test_int(card_t *card){	byte *ctl, i;	byte *reg;	DPRINTF(("divas: test interrupt for Diva Server 4BRI"));	/* We get the last (dummy) adapter in so we need to go back to the first */	card = get_card(card->cfg.card_id - 3);	/* Enable interrupts on PLX chip */	reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);	UxCardPortIoOut(card->hw, reg, PLX9054_INTCSR, PLX9054_INT_ENA);	UxCardMemDetach(card->hw, reg);	/* Set the test interrupt flag */	card->test_int_pend = TEST_INT_DIVAS_Q;	/* Now to trigger the interrupt */	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);	UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_ON);	UxCardMemDetach(card->hw, ctl);	for (i = 0; i < 50; i++)	{		if (!card->test_int_pend)		{			break;		}		UxPause(10);	}	if (card->test_int_pend)	{		DPRINTF(("active: timeout waiting for card to interrupt"));		return (-1);	}		return 0;}static void print_hdr(unsigned char *code, int offset){	unsigned char hdr[80];	int i;	i = 0;	while ((i < (DIM(hdr) -1)) && 		(code[offset + i] != '\0') &&		(code[offset + i] != '\r') &&		(code[offset + i] != '\n'))	{		hdr[i] = code[offset + i];		i++;	}	hdr[i] = '\0';	DPRINTF(("divas: loading %s", hdr));}static int diva_server_4bri_load(card_t *card, dia_load_t *load){	byte *pRAM=NULL;	int download_offset=0;	card_t *FirstCard;	byte sw_id[80];	DPRINTF(("divas: loading Diva Server 4BRI[%d]", load->card_id));	switch(load->code_type)	{		case DIA_CPU_CODE:			DPRINTF(("divas: RISC code"));			print_hdr(load->code, 0x80);			card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);			download_offset = 0; // Protocol code written to offset 0			pRAM = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);			break;		case DIA_DSP_CODE:			DPRINTF(("divas: DSP code"));			print_hdr(load->code, 0x0); 			FirstCard = get_card(load->card_id - 3);			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))			{				download_offset = MQ_V90D_DSP_CODE_BASE;			}			else			{				download_offset = MQ_ORG_DSP_CODE_BASE;			}			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);			download_offset += (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC);			break;		case DIA_TABLE_CODE:			DPRINTF(("divas: TABLE code"));			FirstCard = get_card(load->card_id - 3);			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))			{				download_offset = MQ_V90D_DSP_CODE_BASE + sizeof(dword);			}			else			{				download_offset = MQ_ORG_DSP_CODE_BASE + sizeof(dword);			}			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);			break;		case DIA_CONT_CODE:			DPRINTF(("divas: continuation code"));			break;        case DIA_DLOAD_CNT:			DPRINTF(("divas: COUNT code"));			FirstCard = get_card(load->card_id - 3);			if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))			{				download_offset = MQ_V90D_DSP_CODE_BASE;			}			else			{				download_offset = MQ_ORG_DSP_CODE_BASE;			}			pRAM = UxCardMemAttach(FirstCard->hw, DIVAS_RAM_MEMORY);			break;		case DIA_FPGA_CODE:			DPRINTF(("divas: 4BRI FPGA download - %d bytes", load->length));			if (FPGA_Download(IDI_ADAPTER_MAESTRAQ, 			card->hw->io_base,			 sw_id,			 load->code,			 load->length			) == -1)			{				DPRINTF(("divas: FPGA download failed"));				return -1;			}			/* NOW reset the 4BRI */			diva_server_4bri_reset(card);			return 0; // No need for anything further loading		default:			DPRINTF(("divas: unknown code type"));			return -1;	}   memcp(pRAM + (download_offset & 0x3FFFFF), load->code, load->length);	{		int mism_off;	if ((mism_off = memcm(pRAM + (download_offset & 0x3FFFFF), load->code, load->length)))	{		DPRINTF(("divas: memory mismatch at offset %d", mism_off));		UxCardMemDetach(card->hw, pRAM);		return -1;	}	}	UxCardMemDetach(card->hw, pRAM);	return 0;}static int diva_server_4bri_start(card_t *card, byte *channels){	byte *ctl;	byte *shared, i;	int adapter_num;	DPRINTF(("divas: start Diva Server 4BRI"));	*channels = 0;	card->is_live = FALSE;	ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);	UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_COLD_RESET_MASK);	UxPause(2);	UxCardMemOutW(card->hw, &ctl[MQ_BREG_RISC], MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);	UxPause(10);		UxCardMemDetach(card->hw, ctl);	shared = (byte *) UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);	for ( i = 0 ; i < 300 ; ++i )	{		UxPause (10) ;		if ( UxCardMemInW(card->hw, &shared[0x1E]) == 0x4447 )		{			DPRINTF(("divas: Protocol startup time %d.%02d seconds",			         (i / 100), (i % 100) ));			break;		}	}	if (i==300)	{		DPRINTF(("divas: Timeout starting card"));		DPRINTF(("divas: Signature == 0x%04X", UxCardMemInW(card->hw, &shared[0x1E])));		UxCardMemDetach(card->hw, shared);		return -1;	}	UxCardMemDetach(card->hw, shared);	for (adapter_num=3; adapter_num >= 0; adapter_num--)	{		card_t *qbri_card;		qbri_card = get_card(card->cfg.card_id - adapter_num);		if (qbri_card)		{			qbri_card->is_live = TRUE;			shared = UxCardMemAttach(qbri_card->hw, DIVAS_SHARED_MEMORY);			*channels += UxCardMemIn(qbri_card->hw, &shared[0x3F6]);			UxCardMemDetach(qbri_card->hw, shared);		}		else		{			DPRINTF(("divas: Couldn't get card info %d", card->cfg.card_id));		}	}	diva_server_4bri_test_int(card);	return 0;}staticint 	diva_server_4bri_mem_get(card_t *card, mem_block_t *mem_block){	byte	*a;	byte	*card_addr;	word	length = 0;	int		i;	a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);	card_addr = a;	card_addr += mem_block->addr;	for (i=0; i < sizeof(mem_block->data); i++)	{		mem_block->data[i] = UxCardMemIn(card->hw, card_addr);		card_addr++;		length++;	}	UxCardMemDetach(card->hw, a);	return length;}/* * Initialise 4BRI specific entry points */int Divas4BriInit(card_t *card, dia_card_t *cfg){//	byte sw_id[80];//	extern int FPGA_Done;	DPRINTF(("divas: initialise Diva Server 4BRI"));	if (Divas4BRIInitPCI(card, cfg) == -1)	{		return -1;	}	/* Need to download the FPGA *//*	if (!FPGA_Done)	{		int retVal;		retVal=FPGA_Download(IDI_ADAPTER_MAESTRAQ, 			cfg->io_base,			 sw_id,			 FPGA_Bytes			);		if(retVal==-1)		{					DPRINTF(("divas: FPGA Download Failed"));			return -1;		}		FPGA_Done = 1;	} */	card->card_reset = diva_server_4bri_reset;	card->card_load = diva_server_4bri_load;	card->card_config = diva_server_4bri_config;	card->card_start = diva_server_4bri_start;	card->reset_int = diva_server_4bri_reset_int;	card->card_mem_get = diva_server_4bri_mem_get;	card->xlog_offset = DIVAS_MAINT_OFFSET;	card->out = DivasOut;	card->test_int = DivasTestInt;	card->dpc = DivasDpc;	card->clear_int = DivasClearInt;	card->card_isr = fourbri_ISR;	card->a.ram_out = mem_out;	card->a.ram_outw = mem_outw;	card->a.ram_out_buffer = mem_out_buffer;	card->a.ram_inc = mem_inc;	card->a.ram_in = mem_in;	card->a.ram_inw = mem_inw;	card->a.ram_in_buffer = mem_in_buffer;	card->a.ram_look_ahead = mem_look_ahead;	return 0;}void memcp(byte *dst, byte *src, dword dwLen){	while (dwLen)	{		*dst = *src;		dst++; src++;		dwLen--;	}}int memcm(byte *dst, byte *src, dword dwLen){	int offset = 0;	while (offset < dwLen)	{		if(*dst != *src)			return (offset+1);		offset++;		src++;		dst++;	}	return 0;}/*int fourbri_ISR (card_t* card) {	int served = 0;	byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);		if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01) 	{		served = 1;		card->int_pend  += 1;		DivasDpcSchedule(); 		UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);	}	UxCardMemDetach(card->hw, DivasIOBase);	return (served != 0);}*/int fourbri_ISR (card_t* card) {	int served = 0;	byte *ctl;	byte *reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);	if (UxCardPortIoIn(card->hw, reg, PLX9054_INTCSR) & 0x80) 	{		served = 1;		card->int_pend  += 1;		DivasDpcSchedule(); /* ISR DPC */		ctl = UxCardMemAttach(card->hw, DIVAS_CTL_MEMORY);		UxCardMemOut(card->hw, &ctl[MQ_BREG_IRQ_TEST], MQ_IRQ_REQ_OFF);		UxCardMemDetach(card->hw, ctl);	}	UxCardMemDetach(card->hw, reg);	return (served != 0);}

⌨️ 快捷键说明

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