linux/drivers/isdn/hardware/eicon/s_pri.c
<<
>>
Prefs
   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   ------------------------------------------------------------------------- */
  43static dword pri_ram_offset(ADAPTER *a) {
  44        return ((dword)MP_SHARED_RAM_OFFSET);
  45}
  46/* -------------------------------------------------------------------------
  47   Recovery XLOG buffer from the card
  48   ------------------------------------------------------------------------- */
  49static 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   ------------------------------------------------------------------------- */
  91static 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   ------------------------------------------------------------------------- */
 102static 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}
 125static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
 126        return (0);
 127}
 128/* --------------------------------------------------------------------------
 129   PRI Adapter interrupt Service Routine
 130   -------------------------------------------------------------------------- */
 131static 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   ------------------------------------------------------------------------- */
 152static 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   ------------------------------------------------------------------------- */
 162static 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   ------------------------------------------------------------------------- */
 192void 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   ------------------------------------------------------------------------- */
 200void 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/* ------------------------------------------------------------------------- */
 206