GNU Linux-libre 4.4.284-gnu1
[releases.git] / drivers / isdn / hardware / eicon / s_bri.c
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_bri.h"
37 #include "dsp_defs.h"
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE (64 * 1024)
40 /* --------------------------------------------------------------------------
41    Investigate card state, recovery trace buffer
42    -------------------------------------------------------------------------- */
43 static void bri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
44         byte  __iomem *addrHi, *addrLo, *ioaddr;
45         word *Xlog;
46         dword   regs[4], i, size;
47         Xdesc   xlogDesc;
48         byte __iomem *Port;
49 /*
50  * first read pointers and trap frame
51  */
52         if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE)))
53                 return;
54         Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
55         addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
56         addrLo = Port + ADDR;
57         ioaddr = Port + DATA;
58         outpp(addrHi,  0);
59         outppw(addrLo, 0);
60         for (i = 0; i < 0x100; Xlog[i++] = inppw(ioaddr));
61 /*
62  * check for trapped MIPS 3xxx CPU, dump only exception frame
63  */
64         if (GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999)
65         {
66                 dump_trap_frame(IoAdapter, &((byte *)Xlog)[0x90]);
67                 IoAdapter->trapped = 1;
68         }
69         regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]);
70         regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]);
71         regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]);
72         regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]);
73         outpp(addrHi, (regs[1] >> 16) & 0x7F);
74         outppw(addrLo, regs[1] & 0xFFFF);
75         xlogDesc.cnt = inppw(ioaddr);
76         outpp(addrHi, (regs[2] >> 16) & 0x7F);
77         outppw(addrLo, regs[2] & 0xFFFF);
78         xlogDesc.out = inppw(ioaddr);
79         xlogDesc.buf = Xlog;
80         regs[0] &= IoAdapter->MemorySize - 1;
81         if ((regs[0] < IoAdapter->MemorySize - 1))
82         {
83                 size = IoAdapter->MemorySize - regs[0];
84                 if (size > MAX_XLOG_SIZE)
85                         size = MAX_XLOG_SIZE;
86                 for (i = 0; i < (size / sizeof(*Xlog)); regs[0] += 2)
87                 {
88                         outpp(addrHi, (regs[0] >> 16) & 0x7F);
89                         outppw(addrLo, regs[0] & 0xFFFF);
90                         Xlog[i++] = inppw(ioaddr);
91                 }
92                 dump_xlog_buffer(IoAdapter, &xlogDesc);
93                 diva_os_free(0, Xlog);
94                 IoAdapter->trapped = 2;
95         }
96         outpp(addrHi, (byte)((BRI_UNCACHED_ADDR(IoAdapter->MemoryBase + IoAdapter->MemorySize -
97                                                 BRI_SHARED_RAM_SIZE)) >> 16));
98         outppw(addrLo, 0x00);
99         DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
100 }
101 /* ---------------------------------------------------------------------
102    Reset hardware
103    --------------------------------------------------------------------- */
104 static void reset_bri_hardware(PISDN_ADAPTER IoAdapter) {
105         byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
106         outpp(p, 0x00);
107         DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
108 }
109 /* ---------------------------------------------------------------------
110    Halt system
111    --------------------------------------------------------------------- */
112 static void stop_bri_hardware(PISDN_ADAPTER IoAdapter) {
113         byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
114         if (p) {
115                 outpp(p, 0x00); /* disable interrupts ! */
116         }
117         DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
118         p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
119         outpp(p, 0x00);    /* clear int, halt cpu */
120         DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
121 }
122 static int load_bri_hardware(PISDN_ADAPTER IoAdapter) {
123         return (0);
124 }
125 /******************************************************************************/
126 static int bri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
127         byte __iomem *p;
128
129         p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
130         if (!(inpp(p) & 0x01)) {
131                 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
132                 return (0);
133         }
134         /*
135           clear interrupt line
136         */
137         outpp(p, 0x08);
138         DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
139         IoAdapter->IrqCount++;
140         if (IoAdapter->Initialized) {
141                 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
142         }
143         return (1);
144 }
145 /* --------------------------------------------------------------------------
146    Disable IRQ in the card hardware
147    -------------------------------------------------------------------------- */
148 static void disable_bri_interrupt(PISDN_ADAPTER IoAdapter) {
149         byte __iomem *p;
150         p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
151         if (p)
152         {
153                 outpp(p, 0x00); /* disable interrupts ! */
154         }
155         DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
156         p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
157         outpp(p, 0x00); /* clear int, halt cpu */
158         DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
159 }
160 /* -------------------------------------------------------------------------
161    Fill card entry points
162    ------------------------------------------------------------------------- */
163 void prepare_maestra_functions(PISDN_ADAPTER IoAdapter) {
164         ADAPTER *a = &IoAdapter->a;
165         a->ram_in             = io_in;
166         a->ram_inw            = io_inw;
167         a->ram_in_buffer      = io_in_buffer;
168         a->ram_look_ahead     = io_look_ahead;
169         a->ram_out            = io_out;
170         a->ram_outw           = io_outw;
171         a->ram_out_buffer     = io_out_buffer;
172         a->ram_inc            = io_inc;
173         IoAdapter->MemoryBase = BRI_MEMORY_BASE;
174         IoAdapter->MemorySize = BRI_MEMORY_SIZE;
175         IoAdapter->out        = pr_out;
176         IoAdapter->dpc        = pr_dpc;
177         IoAdapter->tst_irq    = scom_test_int;
178         IoAdapter->clr_irq    = scom_clear_int;
179         IoAdapter->pcm        = (struct pc_maint *)MIPS_MAINT_OFFS;
180         IoAdapter->load       = load_bri_hardware;
181         IoAdapter->disIrq     = disable_bri_interrupt;
182         IoAdapter->rstFnc     = reset_bri_hardware;
183         IoAdapter->stop       = stop_bri_hardware;
184         IoAdapter->trapFnc    = bri_cpu_trapped;
185         IoAdapter->diva_isr_handler = bri_ISR;
186         /*
187           Prepare OS dependent functions
188         */
189         diva_os_prepare_maestra_functions(IoAdapter);
190 }
191 /* -------------------------------------------------------------------------- */