diff options
Diffstat (limited to 'drivers/isdn/hardware/eicon/s_pri.c')
-rw-r--r-- | drivers/isdn/hardware/eicon/s_pri.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c new file mode 100644 index 000000000000..18f287888570 --- /dev/null +++ b/drivers/isdn/hardware/eicon/s_pri.c | |||
@@ -0,0 +1,205 @@ | |||
1 | |||
2 | /* | ||
3 | * | ||
4 | Copyright (c) Eicon Networks, 2002. | ||
5 | * | ||
6 | This source file is supplied for the use with | ||
7 | Eicon Networks range of DIVA Server Adapters. | ||
8 | * | ||
9 | Eicon File Revision : 2.1 | ||
10 | * | ||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of the GNU General Public License as published by | ||
13 | the Free Software Foundation; either version 2, or (at your option) | ||
14 | any later version. | ||
15 | * | ||
16 | This program is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY | ||
18 | implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
19 | See the GNU General Public License for more details. | ||
20 | * | ||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "di_defs.h" | ||
28 | #include "pc.h" | ||
29 | #include "pr_pc.h" | ||
30 | #include "di.h" | ||
31 | #include "mi_pc.h" | ||
32 | #include "pc_maint.h" | ||
33 | #include "divasync.h" | ||
34 | #include "io.h" | ||
35 | #include "helpers.h" | ||
36 | #include "dsrv_pri.h" | ||
37 | #include "dsp_defs.h" | ||
38 | /*****************************************************************************/ | ||
39 | #define MAX_XLOG_SIZE (64 * 1024) | ||
40 | /* ------------------------------------------------------------------------- | ||
41 | Does return offset between ADAPTER->ram and real begin of memory | ||
42 | ------------------------------------------------------------------------- */ | ||
43 | static dword pri_ram_offset (ADAPTER* a) { | ||
44 | return ((dword)MP_SHARED_RAM_OFFSET); | ||
45 | } | ||
46 | /* ------------------------------------------------------------------------- | ||
47 | Recovery XLOG buffer from the card | ||
48 | ------------------------------------------------------------------------- */ | ||
49 | static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) { | ||
50 | byte __iomem *base ; | ||
51 | word *Xlog ; | ||
52 | dword regs[4], TrapID, size ; | ||
53 | Xdesc xlogDesc ; | ||
54 | /* | ||
55 | * check for trapped MIPS 46xx CPU, dump exception frame | ||
56 | */ | ||
57 | base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); | ||
58 | TrapID = READ_DWORD(&base[0x80]) ; | ||
59 | if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) ) | ||
60 | { | ||
61 | dump_trap_frame (IoAdapter, &base[0x90]) ; | ||
62 | IoAdapter->trapped = 1 ; | ||
63 | } | ||
64 | regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]); | ||
65 | regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]); | ||
66 | regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]); | ||
67 | regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]); | ||
68 | regs[0] &= IoAdapter->MemorySize - 1 ; | ||
69 | if ( (regs[0] < IoAdapter->MemorySize - 1) ) | ||
70 | { | ||
71 | if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) { | ||
72 | DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); | ||
73 | return ; | ||
74 | } | ||
75 | size = IoAdapter->MemorySize - regs[0] ; | ||
76 | if ( size > MAX_XLOG_SIZE ) | ||
77 | size = MAX_XLOG_SIZE ; | ||
78 | memcpy_fromio(Xlog, &base[regs[0]], size) ; | ||
79 | xlogDesc.buf = Xlog ; | ||
80 | xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ; | ||
81 | xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ; | ||
82 | dump_xlog_buffer (IoAdapter, &xlogDesc) ; | ||
83 | diva_os_free (0, Xlog) ; | ||
84 | IoAdapter->trapped = 2 ; | ||
85 | } | ||
86 | DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); | ||
87 | } | ||
88 | /* ------------------------------------------------------------------------- | ||
89 | Hardware reset of PRI card | ||
90 | ------------------------------------------------------------------------- */ | ||
91 | static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) { | ||
92 | byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); | ||
93 | WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); | ||
94 | diva_os_wait (50) ; | ||
95 | WRITE_BYTE(p, 0x00); | ||
96 | diva_os_wait (50) ; | ||
97 | DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); | ||
98 | } | ||
99 | /* ------------------------------------------------------------------------- | ||
100 | Stop Card Hardware | ||
101 | ------------------------------------------------------------------------- */ | ||
102 | static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) { | ||
103 | dword i; | ||
104 | byte __iomem *p; | ||
105 | dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); | ||
106 | WRITE_DWORD(&cfgReg[3], 0); | ||
107 | WRITE_DWORD(&cfgReg[1], 0); | ||
108 | DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); | ||
109 | IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ; | ||
110 | i = 0 ; | ||
111 | while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) ) | ||
112 | { | ||
113 | diva_os_wait (1) ; | ||
114 | i++ ; | ||
115 | } | ||
116 | DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i)) | ||
117 | cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); | ||
118 | WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000))); | ||
119 | DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); | ||
120 | diva_os_wait (1) ; | ||
121 | p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); | ||
122 | WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); | ||
123 | DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); | ||
124 | } | ||
125 | static int load_pri_hardware (PISDN_ADAPTER IoAdapter) { | ||
126 | return (0); | ||
127 | } | ||
128 | /* -------------------------------------------------------------------------- | ||
129 | PRI Adapter interrupt Service Routine | ||
130 | -------------------------------------------------------------------------- */ | ||
131 | static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) { | ||
132 | byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter); | ||
133 | if ( !(READ_DWORD(cfg) & 0x80000000) ) { | ||
134 | DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); | ||
135 | return (0) ; | ||
136 | } | ||
137 | /* | ||
138 | clear interrupt line | ||
139 | */ | ||
140 | WRITE_DWORD(cfg, (dword)~0x03E00000) ; | ||
141 | DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); | ||
142 | IoAdapter->IrqCount++ ; | ||
143 | if ( IoAdapter->Initialized ) | ||
144 | { | ||
145 | diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr); | ||
146 | } | ||
147 | return (1) ; | ||
148 | } | ||
149 | /* ------------------------------------------------------------------------- | ||
150 | Disable interrupt in the card hardware | ||
151 | ------------------------------------------------------------------------- */ | ||
152 | static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) { | ||
153 | dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ; | ||
154 | WRITE_DWORD(&cfgReg[3], 0); | ||
155 | WRITE_DWORD(&cfgReg[1], 0); | ||
156 | WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ; | ||
157 | DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); | ||
158 | } | ||
159 | /* ------------------------------------------------------------------------- | ||
160 | Install entry points for PRI Adapter | ||
161 | ------------------------------------------------------------------------- */ | ||
162 | static void prepare_common_pri_functions (PISDN_ADAPTER IoAdapter) { | ||
163 | ADAPTER *a = &IoAdapter->a ; | ||
164 | a->ram_in = mem_in ; | ||
165 | a->ram_inw = mem_inw ; | ||
166 | a->ram_in_buffer = mem_in_buffer ; | ||
167 | a->ram_look_ahead = mem_look_ahead ; | ||
168 | a->ram_out = mem_out ; | ||
169 | a->ram_outw = mem_outw ; | ||
170 | a->ram_out_buffer = mem_out_buffer ; | ||
171 | a->ram_inc = mem_inc ; | ||
172 | a->ram_offset = pri_ram_offset ; | ||
173 | a->ram_out_dw = mem_out_dw; | ||
174 | a->ram_in_dw = mem_in_dw; | ||
175 | a->istream_wakeup = pr_stream; | ||
176 | IoAdapter->out = pr_out ; | ||
177 | IoAdapter->dpc = pr_dpc ; | ||
178 | IoAdapter->tst_irq = scom_test_int ; | ||
179 | IoAdapter->clr_irq = scom_clear_int ; | ||
180 | IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS | ||
181 | - MP_SHARED_RAM_OFFSET) ; | ||
182 | IoAdapter->load = load_pri_hardware ; | ||
183 | IoAdapter->disIrq = disable_pri_interrupt ; | ||
184 | IoAdapter->rstFnc = reset_pri_hardware ; | ||
185 | IoAdapter->stop = stop_pri_hardware ; | ||
186 | IoAdapter->trapFnc = pri_cpu_trapped ; | ||
187 | IoAdapter->diva_isr_handler = pri_ISR; | ||
188 | } | ||
189 | /* ------------------------------------------------------------------------- | ||
190 | Install entry points for PRI Adapter | ||
191 | ------------------------------------------------------------------------- */ | ||
192 | void prepare_pri_functions (PISDN_ADAPTER IoAdapter) { | ||
193 | IoAdapter->MemorySize = MP_MEMORY_SIZE ; | ||
194 | prepare_common_pri_functions (IoAdapter) ; | ||
195 | diva_os_prepare_pri_functions (IoAdapter); | ||
196 | } | ||
197 | /* ------------------------------------------------------------------------- | ||
198 | Install entry points for PRI Rev.2 Adapter | ||
199 | ------------------------------------------------------------------------- */ | ||
200 | void prepare_pri2_functions (PISDN_ADAPTER IoAdapter) { | ||
201 | IoAdapter->MemorySize = MP2_MEMORY_SIZE ; | ||
202 | prepare_common_pri_functions (IoAdapter) ; | ||
203 | diva_os_prepare_pri2_functions (IoAdapter); | ||
204 | } | ||
205 | /* ------------------------------------------------------------------------- */ | ||