Showing error 1804

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/isdn/hardware/eicon/s_4bri.c
Line in file: 394
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-11 08:47:26 UTC


Source:

  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 "pc_init.h"
 35#include "io.h"
 36#include "helpers.h"
 37#include "dsrv4bri.h"
 38#include "dsp_defs.h"
 39#include "sdp_hdr.h"
 40
 41/*****************************************************************************/
 42#define        MAX_XLOG_SIZE        (64 * 1024)
 43
 44/* --------------------------------------------------------------------------
 45                Recovery XLOG from QBRI Card
 46         -------------------------------------------------------------------------- */
 47static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
 48        byte  __iomem *base ;
 49        word *Xlog ;
 50        dword   regs[4], TrapID, offset, size ;
 51        Xdesc   xlogDesc ;
 52        int factor = (IoAdapter->tasks == 1) ? 1 : 2;
 53
 54/*
 55 *        check for trapped MIPS 46xx CPU, dump exception frame
 56 */
 57
 58        base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
 59        offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
 60
 61        TrapID = READ_DWORD(&base[0x80]) ;
 62
 63        if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
 64        {
 65                dump_trap_frame (IoAdapter, &base[0x90]) ;
 66                IoAdapter->trapped = 1 ;
 67        }
 68
 69        regs[0] = READ_DWORD((base + offset) + 0x70);
 70        regs[1] = READ_DWORD((base + offset) + 0x74);
 71        regs[2] = READ_DWORD((base + offset) + 0x78);
 72        regs[3] = READ_DWORD((base + offset) + 0x7c);
 73        regs[0] &= IoAdapter->MemorySize - 1 ;
 74
 75        if ( (regs[0] >= offset)
 76          && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) )
 77        {
 78                if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
 79                        DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
 80                        return ;
 81                }
 82
 83                size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ;
 84                if ( size > MAX_XLOG_SIZE )
 85                        size = MAX_XLOG_SIZE ;
 86                memcpy_fromio (Xlog, &base[regs[0]], size) ;
 87                xlogDesc.buf = Xlog ;
 88                xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ;
 89                xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ;
 90                dump_xlog_buffer (IoAdapter, &xlogDesc) ;
 91                diva_os_free (0, Xlog) ;
 92                IoAdapter->trapped = 2 ;
 93        }
 94        DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
 95}
 96
 97/* --------------------------------------------------------------------------
 98                Reset QBRI Hardware
 99         -------------------------------------------------------------------------- */
100static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
101        word volatile __iomem *qBriReset ;
102        byte  volatile __iomem *qBriCntrl ;
103        byte  volatile __iomem *p ;
104
105        qBriReset = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
106        WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ;
107        diva_os_wait (1) ;
108        WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ;
109        diva_os_wait (1);
110        WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM) ;
111        diva_os_wait (1) ;
112        WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ;
113        diva_os_wait (1);
114        DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
115
116        qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
117        p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
118        WRITE_DWORD(p, 0) ;
119        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
120
121        DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
122        DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
123}
124
125/* --------------------------------------------------------------------------
126                Start Card CPU
127         -------------------------------------------------------------------------- */
128void start_qBri_hardware (PISDN_ADAPTER IoAdapter) {
129        byte volatile __iomem *qBriReset ;
130        byte volatile __iomem *p ;
131
132        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
133        qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
134        WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ;
135        diva_os_wait (2) ;
136        WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ;
137        diva_os_wait (10) ;
138        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
139
140        DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
141}
142
143/* --------------------------------------------------------------------------
144                Stop Card CPU
145         -------------------------------------------------------------------------- */
146static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
147        byte volatile __iomem *p ;
148        dword volatile __iomem *qBriReset ;
149        dword volatile __iomem *qBriIrq ;
150        dword volatile __iomem *qBriIsacDspReset ;
151        int rev2 = DIVA_4BRI_REVISION(IoAdapter);
152        int reset_offset = rev2 ? (MQ2_BREG_RISC)      : (MQ_BREG_RISC);
153        int irq_offset   = rev2 ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST);
154        int hw_offset    = rev2 ? (MQ2_ISAC_DSP_RESET) : (MQ_ISAC_DSP_RESET);
155
156        if ( IoAdapter->ControllerNumber > 0 )
157                return ;
158        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
159        qBriReset = (dword volatile __iomem *)&p[reset_offset];
160        qBriIsacDspReset = (dword volatile __iomem *)&p[hw_offset];
161/*
162 *        clear interrupt line (reset Local Interrupt Test Register)
163 */
164        WRITE_DWORD(qBriReset, 0) ;
165         WRITE_DWORD(qBriIsacDspReset, 0) ;
166        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
167        
168        p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
169        WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);        /* disable PCI interrupts */
170        DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
171        
172        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
173        qBriIrq   = (dword volatile __iomem *)&p[irq_offset];
174        WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
175        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
176
177        DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
178
179}
180
181/* --------------------------------------------------------------------------
182                FPGA download
183         -------------------------------------------------------------------------- */
184#define FPGA_NAME_OFFSET         0x10
185
186static byte * qBri_check_FPGAsrc (PISDN_ADAPTER IoAdapter, char *FileName,
187                                  dword *Length, dword *code) {
188        byte *File ;
189        char  *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime ;
190        dword  fpgaFlen,  fpgaTlen,  fpgaDlen, cnt, year, i ;
191
192        if (!(File = (byte *)xdiLoadFile (FileName, Length, 0))) {
193                return (NULL) ;
194        }
195/*
196 *         scan file until FF and put id string into buffer
197 */
198        for ( i = 0 ; File[i] != 0xff ; )
199        {
200                if ( ++i >= *Length )
201                {
202                        DBG_FTL(("FPGA download: start of data header not found"))
203                        xdiFreeFile (File) ;
204                        return (NULL) ;
205                }
206        }
207        *code = i++ ;
208
209        if ( (File[i] & 0xF0) != 0x20 )
210        {
211                DBG_FTL(("FPGA download: data header corrupted"))
212                xdiFreeFile (File) ;
213                return (NULL) ;
214        }
215        fpgaFlen = (dword)  File[FPGA_NAME_OFFSET - 1] ;
216        if ( fpgaFlen == 0 )
217                fpgaFlen = 12 ;
218        fpgaFile = (char *)&File[FPGA_NAME_OFFSET] ;
219        fpgaTlen = (dword)  fpgaFile[fpgaFlen + 2] ;
220        if ( fpgaTlen == 0 )
221                fpgaTlen = 10 ;
222        fpgaType = (char *)&fpgaFile[fpgaFlen + 3] ;
223        fpgaDlen = (dword)  fpgaType[fpgaTlen + 2] ;
224        if ( fpgaDlen == 0 )
225                fpgaDlen = 11 ;
226        fpgaDate = (char *)&fpgaType[fpgaTlen + 3] ;
227        fpgaTime = (char *)&fpgaDate[fpgaDlen + 3] ;
228        cnt = (dword)(((File[  i  ] & 0x0F) << 20) + (File[i + 1] << 12)
229                     + (File[i + 2]         <<  4) + (File[i + 3] >>  4)) ;
230
231        if ( (dword)(i + (cnt / 8)) > *Length )
232        {
233                DBG_FTL(("FPGA download: '%s' file too small (%ld < %ld)",
234                         FileName, *Length, code + ((cnt + 7) / 8) ))
235                xdiFreeFile (File) ;
236                return (NULL) ;
237        }
238        i = 0 ;
239        do
240        {
241                while ( (fpgaDate[i] != '\0')
242                     && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9')) )
243                {
244                        i++;
245                }
246                year = 0 ;
247                while ( (fpgaDate[i] >= '0') && (fpgaDate[i] <= '9') )
248                        year = year * 10 + (fpgaDate[i++] - '0') ;
249        } while ( (year < 2000) && (fpgaDate[i] != '\0') );
250
251        switch (IoAdapter->cardType) {
252                case CARDTYPE_DIVASRV_B_2F_PCI:
253                        break;
254
255                default:
256            if ( year >= 2001 ) {
257                                IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED ;
258                        }
259        }
260
261        DBG_LOG(("FPGA[%s] file %s (%s %s) len %d",
262                 fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt))
263        return (File) ;
264}
265
266/******************************************************************************/
267
268#define FPGA_PROG   0x0001                /* PROG enable low */
269#define FPGA_BUSY   0x0002                /* BUSY high, DONE low */
270#define        FPGA_CS     0x000C                /* Enable I/O pins */
271#define FPGA_CCLK   0x0100
272#define FPGA_DOUT   0x0400
273#define FPGA_DIN    FPGA_DOUT   /* bidirectional I/O */
274
275int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
276        int            bit ;
277        byte           *File ;
278        dword          code, FileLength ;
279        word volatile __iomem *addr = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
280        word           val, baseval = FPGA_CS | FPGA_PROG ;
281
282
283
284        if (DIVA_4BRI_REVISION(IoAdapter))
285        {
286                char* name;
287
288                switch (IoAdapter->cardType) {
289                        case CARDTYPE_DIVASRV_B_2F_PCI:
290                                name = "dsbri2f.bit";
291                                break;
292
293                        case CARDTYPE_DIVASRV_B_2M_V2_PCI:
294                        case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
295                                name = "dsbri2m.bit";
296                                break;
297
298                        default:
299                                name = "ds4bri2.bit";
300                }
301
302                File = qBri_check_FPGAsrc (IoAdapter, name,
303                                                   &FileLength, &code);
304        }
305        else
306        {
307                File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit",
308                                           &FileLength, &code) ;
309        }
310        if ( !File ) {
311                DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
312                return (0) ;
313        }
314/*
315 *        prepare download, pulse PROGRAM pin down.
316 */
317        WRITE_WORD(addr, baseval & ~FPGA_PROG) ; /* PROGRAM low pulse */
318        WRITE_WORD(addr, baseval) ;              /* release */
319        diva_os_wait (50) ;  /* wait until FPGA finished internal memory clear */
320/*
321 *        check done pin, must be low
322 */
323        if ( READ_WORD(addr) & FPGA_BUSY )
324        {
325                DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
326                xdiFreeFile (File) ;
327                DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
328                return (0) ;
329        }
330/*
331 *        put data onto the FPGA
332 */
333        while ( code < FileLength )
334        {
335                val = ((word)File[code++]) << 3 ;
336
337                for ( bit = 8 ; bit-- > 0 ; val <<= 1 ) /* put byte onto FPGA */
338                {
339                        baseval &= ~FPGA_DOUT ;             /* clr  data bit */
340                        baseval |= (val & FPGA_DOUT) ;      /* copy data bit */
341                        WRITE_WORD(addr, baseval) ;
342                        WRITE_WORD(addr, baseval | FPGA_CCLK) ;     /* set CCLK hi */
343                        WRITE_WORD(addr, baseval | FPGA_CCLK) ;     /* set CCLK hi */
344                        WRITE_WORD(addr, baseval) ;                 /* set CCLK lo */
345                }
346        }
347        xdiFreeFile (File) ;
348        diva_os_wait (100) ;
349        val = READ_WORD(addr) ;
350
351        DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
352
353        if ( !(val & FPGA_BUSY) )
354        {
355                DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
356                return (0) ;
357        }
358
359        return (1) ;
360}
361
362static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
363        return (0);
364}
365
366/* --------------------------------------------------------------------------
367                Card ISR
368         -------------------------------------------------------------------------- */
369static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
370        dword volatile     __iomem *qBriIrq ;
371
372        PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList ;
373
374        word                      i ;
375        int                     serviced = 0 ;
376        byte __iomem *p;
377
378        p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
379
380        if ( !(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80) ) {
381                DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
382                return (0) ;
383        }
384        DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
385
386/*
387 *        clear interrupt line (reset Local Interrupt Test Register)
388 */
389        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
390        qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
391        WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
392        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
393
394        for ( i = 0 ; i < IoAdapter->tasks; ++i )
395        {
396                IoAdapter = QuadroList->QuadroAdapter[i] ;
397
398                if ( IoAdapter && IoAdapter->Initialized
399                  && IoAdapter->tst_irq (&IoAdapter->a) )
400                {
401                        IoAdapter->IrqCount++ ;
402                        serviced = 1 ;
403                        diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
404                }
405        }
406
407        return (serviced) ;
408}
409
410/* --------------------------------------------------------------------------
411                Does disable the interrupt on the card
412         -------------------------------------------------------------------------- */
413static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
414        dword volatile __iomem *qBriIrq ;
415        byte __iomem *p;
416
417        if ( IoAdapter->ControllerNumber > 0 )
418                return ;
419/*
420 *        clear interrupt line (reset Local Interrupt Test Register)
421 */
422        p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
423        WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);        /* disable PCI interrupts */
424        DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
425
426        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
427        qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
428        WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
429        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
430}
431
432/* --------------------------------------------------------------------------
433                Install Adapter Entry Points
434         -------------------------------------------------------------------------- */
435static void set_common_qBri_functions (PISDN_ADAPTER IoAdapter) {
436        ADAPTER *a;
437
438        a = &IoAdapter->a ;
439
440        a->ram_in           = mem_in ;
441        a->ram_inw          = mem_inw ;
442        a->ram_in_buffer    = mem_in_buffer ;
443        a->ram_look_ahead   = mem_look_ahead ;
444        a->ram_out          = mem_out ;
445        a->ram_outw         = mem_outw ;
446        a->ram_out_buffer   = mem_out_buffer ;
447        a->ram_inc          = mem_inc ;
448
449        IoAdapter->out      = pr_out ;
450        IoAdapter->dpc      = pr_dpc ;
451        IoAdapter->tst_irq  = scom_test_int ;
452        IoAdapter->clr_irq  = scom_clear_int ;
453        IoAdapter->pcm      = (struct pc_maint *)MIPS_MAINT_OFFS ;
454
455        IoAdapter->load     = load_qBri_hardware ;
456
457        IoAdapter->disIrq   = disable_qBri_interrupt ;
458        IoAdapter->rstFnc   = reset_qBri_hardware ;
459        IoAdapter->stop     = stop_qBri_hardware ;
460        IoAdapter->trapFnc  = qBri_cpu_trapped ;
461
462        IoAdapter->diva_isr_handler = qBri_ISR;
463
464        IoAdapter->a.io       = (void*)IoAdapter ;
465}
466
467static void set_qBri_functions (PISDN_ADAPTER IoAdapter) {
468        if (!IoAdapter->tasks) {
469                IoAdapter->tasks = MQ_INSTANCE_COUNT;
470        }
471        IoAdapter->MemorySize = MQ_MEMORY_SIZE ;
472        set_common_qBri_functions (IoAdapter) ;
473        diva_os_set_qBri_functions (IoAdapter) ;
474}
475
476static void set_qBri2_functions (PISDN_ADAPTER IoAdapter) {
477        if (!IoAdapter->tasks) {
478                IoAdapter->tasks = MQ_INSTANCE_COUNT;
479        }
480        IoAdapter->MemorySize = (IoAdapter->tasks == 1) ? BRI2_MEMORY_SIZE : MQ2_MEMORY_SIZE;
481        set_common_qBri_functions (IoAdapter) ;
482        diva_os_set_qBri2_functions (IoAdapter) ;
483}
484
485/******************************************************************************/
486
487void prepare_qBri_functions (PISDN_ADAPTER IoAdapter) {
488
489        set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ;
490        set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ;
491        set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ;
492        set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ;
493
494}
495
496void prepare_qBri2_functions (PISDN_ADAPTER IoAdapter) {
497        if (!IoAdapter->tasks) {
498                IoAdapter->tasks = MQ_INSTANCE_COUNT;
499        }
500
501        set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ;
502        if (IoAdapter->tasks > 1) {
503                set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ;
504                set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ;
505                set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ;
506        }
507
508}
509
510/* -------------------------------------------------------------------------- */