source: rtems/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c @ 818f10bc

5
Last change on this file since 818f10bc was 818f10bc, checked in by Daniel Hellstrom <daniel@…>, on 05/11/17 at 10:54:46

leon, grtc: updated overrun condition handling

The following functions now reports to the user that an overrun has
occured by returning errno EIO:

  • grtc_read, on overrun and no more data in the DMA buffer
  • ioctl(GRTC_IOC_RECV), on overrun and no more frames in the DMA buffer
  • ioctl(GRTC_IOC_ISSTARTED), EIO is returned on overrun
  • Property mode set to 100644
File size: 50.7 KB
Line 
1/* GRTC Telecommand decoder driver
2 *
3 *  COPYRIGHT (c) 2007.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.org/license/LICENSE.
9 */
10
11#include <bsp.h>
12#include <rtems/libio.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <assert.h>
17#include <ctype.h>
18#include <malloc.h>
19#include <rtems/bspIo.h>
20
21#include <drvmgr/drvmgr.h>
22#include <drvmgr/ambapp_bus.h>
23#include <ambapp.h>
24#include <bsp/grtc.h>
25
26#ifndef IRQ_GLOBAL_PREPARE
27 #define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
28#endif
29
30#ifndef IRQ_GLOBAL_DISABLE
31 #define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
32#endif
33
34#ifndef IRQ_GLOBAL_ENABLE
35 #define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
36#endif
37
38/*
39#define DEBUG
40#define DEBUGFUNCS
41*/
42
43#include <bsp/debug_defs.h>
44
45#ifdef DEBUG_ERROR
46#define DEBUG_ERR_LOG(device,error) grtc_log_error(device,error)
47#else
48#define DEBUG_ERR_LOG(device,error)
49#endif
50
51/* GRTC register map */
52struct grtc_regs {
53        volatile unsigned int   grst;   /* Global Reset Register (GRR 0x00) */
54        volatile unsigned int   gctrl;  /* Global Control Register (GCR 0x04) */
55        int unused0;
56        volatile unsigned int   sir;    /* Spacecraft Identifier Register (SIR 0x0c) */
57        volatile unsigned int   far;    /* Frame Acceptance Report Register (FAR 0x10) */
58
59        volatile unsigned int   clcw1;  /* CLCW Register 1 (CLCWR1 0x14) */
60        volatile unsigned int   clcw2;  /* CLCW Register 2 (CLCWR2 0x18) */
61        volatile unsigned int   phir;   /* Physical Interface Register (PHIR 0x1c) */
62        volatile unsigned int   cor;    /* Control Register (COR 0x20) */
63
64        volatile unsigned int   str;    /* Status Register (STR 0x24) */
65        volatile unsigned int   asr;    /* Address Space Register (ASR 0x28) */
66        volatile unsigned int   rp;     /* Receive Read Pointer Register (RRP 0x2c) */
67        volatile unsigned int   wp;     /* Receive Write Pointer Register (RWP 0x30) */
68
69        int unused1[(0x60-0x34)/4];
70
71        volatile unsigned int   pimsr;  /* Pending Interrupt Masked Status Register (PIMSR 0x60) */
72        volatile unsigned int   pimr;   /* Pending Interrupt Masked Register (PIMR 0x64) */
73        volatile unsigned int   pisr;   /* Pending Interrupt Status Register (PISR 0x68) */
74        volatile unsigned int   pir;    /* Pending Interrupt Register (PIR 0x6c) */
75        volatile unsigned int   imr;    /* Interrupt Mask Register (IMR 0x70) */
76        volatile unsigned int   picr;   /* Pending Interrupt Clear Register (PICR 0x74) */
77};
78
79/* Security Byte */
80#define GRTC_SEB                0x55000000
81
82/* Global Reset Register (GRR 0x00) */
83#define GRTC_GRR_SRST           0x1
84#define GRTC_GRR_SRST_BIT       0
85
86/* Global Control Register (GCR 0x04) */
87#define GRTC_GCR_PSR_BIT        10
88#define GRTC_GCR_NRZM_BIT       11
89#define GRTC_GCR_PSS_BIT        12
90
91#define GRTC_GCR_PSR            (1<<GRTC_GCR_PSR_BIT)
92#define GRTC_GCR_NRZM           (1<<GRTC_GCR_NRZM_BIT)
93#define GRTC_GCR_PSS            (1<<GRTC_GCR_PSS_BIT)
94
95/* Spacecraft Identifier Register (SIR 0x0c) */
96
97
98/* Frame Acceptance Report Register (FAR 0x10) */
99#define GRTC_FAR_SCI_BIT        10
100#define GRTC_FAR_CSEC_BIT       11
101#define GRTC_FAR_CAC_BIT        12
102#define GRTC_FAR_SSD_BIT        13
103
104#define GRTC_FAR_SCI            (0x7<<GRTC_FAR_SCI_BIT)
105#define GRTC_FAR_CSEC           (0x7<<GRTC_FAR_CSEC_BIT)
106#define GRTC_FAR_CAC            (0x3f<<GRTC_FAR_CAC_BIT)
107#define GRTC_FAR_SSD            (1<<GRTC_FAR_SSD_BIT)
108
109/* CLCW Register 1 (CLCWR1 0x14) */
110/* CLCW Register 2 (CLCWR2 0x18) */
111#define GRTC_CLCW_RVAL_BIT      0
112#define GRTC_CLCW_RTYPE_BIT     8
113#define GRTC_CLCW_FBCO_BIT      9
114#define GRTC_CLCW_RTMI_BIT      11
115#define GRTC_CLCW_WAIT_BIT      12
116#define GRTC_CLCW_LOUT_BIT      13
117#define GRTC_CLCW_NBLO_BIT      14
118#define GRTC_CLCW_NRFA_BIT      15
119#define GRTC_CLCW_VCI_BIT       18
120#define GRTC_CLCW_CIE_BIT       24
121#define GRTC_CLCW_STAF_BIT      26
122#define GRTC_CLCW_VNUM_BIT      29
123#define GRTC_CLCW_CWTY_BIT      31
124
125#define GRTC_CLCW_RVAL          (0xff<<GRTC_CLCW_RVAL_BIT)
126#define GRTC_CLCW_RTYPE         (1<<GRTC_CLCW_RTYPE_BIT)
127#define GRTC_CLCW_FBCO          (0x3<<GRTC_CLCW_FBCO_BIT)
128#define GRTC_CLCW_RTMI          (0x3<<GRTC_CLCW_RTMI_BIT)
129#define GRTC_CLCW_WAIT          (1<<GRTC_CLCW_WAIT_BIT)
130#define GRTC_CLCW_LOUT          (1<<GRTC_CLCW_LOUT_BIT)
131#define GRTC_CLCW_NBLO          (1<<GRTC_CLCW_NBLO_BIT)
132#define GRTC_CLCW_NRFA          (1<<GRTC_CLCW_NRFA_BIT)
133#define GRTC_CLCW_VCI           (0x3f<<GRTC_CLCW_VCI_BIT)
134#define GRTC_CLCW_CIE           (0x3<<GRTC_CLCW_CIE_BIT)
135#define GRTC_CLCW_STAF          (0x3<<GRTC_CLCW_STAF_BIT)
136#define GRTC_CLCW_VNUM          (0x3<<GRTC_CLCW_VNUM_BIT)
137#define GRTC_CLCW_CWTY          (1<<GRTC_CLCW_CWTY_BIT)
138
139/* Physical Interface Register (PIR 0x1c) */
140#define GRTC_PIR_BLO_BIT        0
141#define GRTC_PIR_RFA_BIT        8
142
143#define GRTC_PIR_BLO            (0xff<<GRTC_PIR_BLO_BIT)
144#define GRTC_PIR_RFA            (0xff<<GRTC_PIR_RFA_BIT)
145
146/* Control Register (COR 0x20) */
147#define GRTC_COR_RE_BIT         0
148#define GRTC_COR_CRST_BIT       9
149
150#define GRTC_COR_RE             (1<<GRTC_COR_RE_BIT)
151#define GRTC_COR_CRST           (1<<GRTC_COR_CRST_BIT)
152
153/* Status Register (STR 0x24) */
154#define GRTC_STR_CR_BIT         0
155#define GRTC_STR_OV_BIT         4
156#define GRTC_STR_RFF_BIT        7
157#define GRTC_STR_RBF_BIT        10
158
159#define GRTC_STR_CR             (1<<GRTC_STR_CR_BIT)
160#define GRTC_STR_OV             (1<<GRTC_STR_OV_BIT)
161#define GRTC_STR_RFF            (1<<GRTC_STR_RFF_BIT)
162#define GRTC_STR_RBF            (1<<GRTC_STR_RBF_BIT)
163
164/* Address Space Register (ASR 0x28) */
165#define GRTC_ASR_RXLEN_BIT      0
166#define GRTC_ASR_BUFST_BIT      10
167
168#define GRTC_ASR_RXLEN          (0xff<<GRTC_ASR_RXLEN_BIT)
169#define GRTC_ASR_BUFST          (0x3fffff<<GRTC_ASR_BUFST_BIT)
170
171/* Receive Read Pointer Register (RRP 0x2c) */
172#define GRTC_RRP_PTR_BIT        0
173
174#define GRTC_RRP_PTR            (0xffffff<<GRTC_RRP_PTR_BIT)
175
176/* Receive Write Pointer Register (RWP 0x30) */
177#define GRTC_RWP_PTR_BIT        0
178
179#define GRTC_RWP_PTR            (0xffffff<<GRTC_RWP_PTR_BIT)
180
181/* Pending Interrupt Masked Status Register (PIMSR 0x60) */
182/* Pending Interrupt Masked Register (PIMR 0x64) */
183/* Pending Interrupt Status Register (PISR 0x68) */
184/* Pending Interrupt Register (PIR 0x6c) */
185/* Interrupt Mask Register (IMR 0x70) */
186/* Pending Interrupt Clear Register (PICR 0x74) */
187#define GRTC_INT_RFA_BIT        0
188#define GRTC_INT_BLO_BIT        1
189#define GRTC_INT_FAR_BIT        2
190#define GRTC_INT_CR_BIT         3
191#define GRTC_INT_RBF_BIT        4
192#define GRTC_INT_OV_BIT         5
193#define GRTC_INT_CS_BIT         6
194
195#define GRTC_INT_RFA            (1<<GRTC_INT_RFA_BIT)
196#define GRTC_INT_BLO            (1<<GRTC_INT_BLO_BIT)
197#define GRTC_INT_FAR            (1<<GRTC_INT_FAR_BIT)
198#define GRTC_INT_CR             (1<<GRTC_INT_CR_BIT)
199#define GRTC_INT_OV             (1<<GRTC_INT_OV_BIT)
200#define GRTC_INT_CS             (1<<GRTC_INT_CS_BIT)
201
202#define GRTC_INT_ALL            (GRTC_INT_RFA|GRTC_INT_BLO|GRTC_INT_FAR|GRTC_INT_CR|GRTC_INT_OV|GRTC_INT_CS)
203
204#define READ_REG(address)       (*(volatile unsigned int *)address)
205
206/* Driver functions */
207static rtems_device_driver grtc_initialize(rtems_device_major_number  major, rtems_device_minor_number  minor, void *arg);
208static rtems_device_driver grtc_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
209static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
210static rtems_device_driver grtc_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
211static rtems_device_driver grtc_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
212static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
213
214#define GRTC_DRIVER_TABLE_ENTRY { grtc_initialize, grtc_open, grtc_close, grtc_read, grtc_write, grtc_ioctl }
215
216static rtems_driver_address_table grtc_driver = GRTC_DRIVER_TABLE_ENTRY;
217
218enum {
219        FRM_STATE_NONE = 0,             /* not started */
220        FRM_STATE_HDR = 1,              /* Reading Header (Frame length isn't known) */
221        FRM_STATE_ALLOC = 2,            /* Allocate Frame to hold data */
222        FRM_STATE_PAYLOAD = 3,          /* Reading Payload (Frame length is known) */
223        FRM_STATE_FILLER = 4,           /* Check filler */
224        FRM_STATE_DROP = 5              /* error, drop data until end marker */
225};
226
227/* Frame pool, all frames in pool have the same buffer length (frame mode only) */
228struct grtc_frame_pool {
229        unsigned int            frame_len;      /* Maximal length of frame (payload+hdr+crc..) */
230        unsigned int            frame_cnt;      /* Current number of frames in pool (in frms) */
231        struct grtc_frame       *frms;          /* Chain of frames in pool (this is the pool) */
232};
233
234struct grtc_priv {
235        struct drvmgr_dev               *dev;           /* Driver manager device */
236        char                    devName[32];    /* Device Name */
237        struct grtc_regs        *regs;          /* TC Hardware Register MAP */
238        int                     irq;            /* IRQ number of TC core */
239
240        int                     major;          /* Driver major */
241        int                     minor;          /* Device Minor */
242
243        int                     open;           /* Device has been opened by user */
244        int                     running;        /* TC receiver running */
245        int                     mode;           /* RAW or FRAME mode */
246        int                     overrun_condition;      /* Overrun condition */
247        int                     blocking;       /* Blocking/polling mode */
248        rtems_interval          timeout;        /* Timeout in blocking mode */
249        int                     wait_for_nbytes;/* Number of bytes to wait for in blocking mode */
250
251        struct grtc_ioc_config  config;
252
253/* RAW MODE ONLY */
254        /* Buffer allocation (user provided or driver allocated using malloc) */
255        void                    *buf;
256        void                    *buf_remote;
257        void                    *_buf;
258        int                     buf_custom;     /* 0=no custom buffer, 1=custom buffer (don't free it...) */
259        unsigned int            len;
260
261/* FRAME MODE ONLY */
262        /* Frame management when user provides buffers. */
263        int                     pool_cnt;       /* Number of Pools */
264        struct grtc_frame_pool  *pools;         /* Array of pools */
265
266        struct grtc_list        ready;          /* Ready queue (received frames) */
267
268        /* Frame read data (Frame mode only) */
269        int                     frame_state;
270        int                     filler;
271        unsigned int            hdr[2];         /* 5 byte header */
272        struct grtc_frame       *frm;           /* Frame currently beeing copied */
273        int                     frmlen;
274
275        struct grtc_ioc_stats   stats;          /* Statistics */
276
277        rtems_id sem_rx;
278
279#ifdef DEBUG_ERROR     
280        /* Buffer read/write state */
281        unsigned int rp;
282        unsigned int    wp;
283
284        /* Debugging */
285        int last_error[128];
286        int last_error_cnt;
287#endif
288};
289
290/* Prototypes */
291static void grtc_hw_reset(struct grtc_priv *priv);
292static void grtc_interrupt(void *arg);
293
294/* Common Global Variables */
295static rtems_id grtc_dev_sem;
296static int grtc_driver_io_registered = 0;
297static rtems_device_major_number grtc_driver_io_major = 0;
298
299/******************* Driver manager interface ***********************/
300
301/* Driver prototypes */
302static int grtc_register_io(rtems_device_major_number *m);
303static int grtc_device_init(struct grtc_priv *pDev);
304
305static int grtc_init2(struct drvmgr_dev *dev);
306static int grtc_init3(struct drvmgr_dev *dev);
307
308static struct drvmgr_drv_ops grtc_ops =
309{
310        {NULL, grtc_init2, grtc_init3, NULL},
311        NULL,
312        NULL,
313};
314
315static struct amba_dev_id grtc_ids[] =
316{
317        {VENDOR_GAISLER, GAISLER_GRTC},
318        {0, 0}          /* Mark end of table */
319};
320
321static struct amba_drv_info grtc_drv_info =
322{
323        {
324                DRVMGR_OBJ_DRV,                 /* Driver */
325                NULL,                           /* Next driver */
326                NULL,                           /* Device list */
327                DRIVER_AMBAPP_GAISLER_GRTC_ID,  /* Driver ID */
328                "GRTC_DRV",                     /* Driver Name */
329                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
330                &grtc_ops,
331                NULL,                           /* Funcs */
332                0,                              /* No devices yet */
333                sizeof(struct grtc_priv),
334        },
335        &grtc_ids[0]
336};
337
338void grtc_register_drv (void)
339{
340        DBG("Registering GRTC driver\n");
341        drvmgr_drv_register(&grtc_drv_info.general);
342}
343
344static int grtc_init2(struct drvmgr_dev *dev)
345{
346        struct grtc_priv *priv;
347
348        DBG("GRTC[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
349        priv = dev->priv;
350        if ( !priv )
351                return DRVMGR_NOMEM;
352        priv->dev = dev;
353
354        /* This core will not find other cores, so we wait for init2() */
355
356        return DRVMGR_OK;
357}
358
359static int grtc_init3(struct drvmgr_dev *dev)
360{
361        struct grtc_priv *priv;
362        char prefix[32];
363        rtems_status_code status;
364
365        priv = dev->priv;
366
367        /* Do initialization */
368
369        if ( grtc_driver_io_registered == 0) {
370                /* Register the I/O driver only once for all cores */
371                if ( grtc_register_io(&grtc_driver_io_major) ) {
372                        /* Failed to register I/O driver */
373                        dev->priv = NULL;
374                        return DRVMGR_FAIL;
375                }
376
377                grtc_driver_io_registered = 1;
378        }
379       
380        /* I/O system registered and initialized
381         * Now we take care of device initialization.
382         */
383        if ( grtc_device_init(priv) ) {
384                return DRVMGR_FAIL;
385        }
386
387        /* Get Filesystem name prefix */
388        prefix[0] = '\0';
389        if ( drvmgr_get_dev_prefix(dev, prefix) ) {
390                /* Failed to get prefix, make sure of a unique FS name
391                 * by using the driver minor.
392                 */
393                sprintf(priv->devName, "/dev/grtc%d", dev->minor_drv);
394        } else {
395                /* Got special prefix, this means we have a bus prefix
396                 * And we should use our "bus minor"
397                 */
398                sprintf(priv->devName, "/dev/%sgrtc%d", prefix, dev->minor_bus);
399        }
400
401        /* Register Device */
402        status = rtems_io_register_name(priv->devName, grtc_driver_io_major, dev->minor_drv);
403        if (status != RTEMS_SUCCESSFUL) {
404                return DRVMGR_FAIL;
405        }
406
407        return DRVMGR_OK;
408}
409
410/******************* Driver Implementation ***********************/
411
412static int grtc_register_io(rtems_device_major_number *m)
413{
414        rtems_status_code r;
415
416        if ((r = rtems_io_register_driver(0, &grtc_driver, m)) == RTEMS_SUCCESSFUL) {
417                DBG("GRTC driver successfully registered, major: %d\n", *m);
418        } else {
419                switch(r) {
420                case RTEMS_TOO_MANY:
421                        printk("GRTC rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
422                        return -1;
423                case RTEMS_INVALID_NUMBER: 
424                        printk("GRTC rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
425                        return -1;
426                case RTEMS_RESOURCE_IN_USE:
427                        printk("GRTC rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
428                        return -1;
429                default:
430                        printk("GRTC rtems_io_register_driver failed\n");
431                        return -1;
432                }
433        }
434        return 0;
435}
436
437static int grtc_device_init(struct grtc_priv *pDev)
438{
439        struct amba_dev_info *ambadev;
440        struct ambapp_core *pnpinfo;
441
442        /* Get device information from AMBA PnP information */
443        ambadev = (struct amba_dev_info *)pDev->dev->businfo;
444        if ( ambadev == NULL ) {
445                return -1;
446        }
447        pnpinfo = &ambadev->info;
448        pDev->irq = pnpinfo->irq;
449        pDev->regs = (struct grtc_regs *)pnpinfo->ahb_slv->start[0];
450        pDev->minor = pDev->dev->minor_drv;
451        pDev->open = 0;
452        pDev->running = 0;
453
454        /* Create Binary RX Semaphore with count = 0 */
455        if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'C', '0' + pDev->minor),
456                0,
457                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
458                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
459                0,
460                &pDev->sem_rx) != RTEMS_SUCCESSFUL ) {
461                return -1;
462        }
463
464        /* Reset Hardware before attaching IRQ handler */
465        grtc_hw_reset(pDev);
466
467        return 0;
468}
469
470static void grtc_hw_reset(struct grtc_priv *priv)
471{
472        /* Reset Core */
473        priv->regs->grst = GRTC_SEB | GRTC_GRR_SRST;
474}
475
476static void grtc_hw_get_defaults(struct grtc_priv *pDev, struct grtc_ioc_config *config)
477{
478        unsigned int gcr = READ_REG(&pDev->regs->gctrl);
479
480        config->psr_enable      = (gcr & GRTC_GCR_PSR)  ? 1:0;
481        config->nrzm_enable     = (gcr & GRTC_GCR_NRZM) ? 1:0;
482        config->pss_enable      = (gcr & GRTC_GCR_PSS)  ? 1:0;
483       
484        config->crc_calc        = 0;
485}
486
487/* bufsize is given in bytes */
488static int __inline__ grtc_hw_data_avail_upper(unsigned int rrp, unsigned rwp, unsigned int bufsize)
489{
490        if ( rrp == rwp )
491                return 0;
492
493        if ( rwp > rrp ) {
494                return rwp-rrp;
495        }
496
497        return (bufsize-rrp);
498}
499
500/* bufsize is given in bytes */
501static int __inline__ grtc_hw_data_avail_lower(unsigned int rrp, unsigned rwp, unsigned int bufsize)
502{
503        if ( rrp == rwp )
504                return 0;
505
506        if ( rwp > rrp ) {
507                return 0;
508        }
509
510        return rwp;
511}
512
513/* bufsize is given in bytes */
514static int __inline__ grtc_hw_data_avail(unsigned int rrp, unsigned rwp, unsigned int bufsize)
515{
516        if ( rrp == rwp )
517                return 0;
518
519        if ( rwp > rrp ) {
520                return rwp-rrp;
521        }
522
523        return rwp+(bufsize-rrp);
524}
525
526/* Reads as much as possible but not more than 'max' bytes from the TC receive buffer.
527 * Number of bytes put into 'buf' is returned.
528 */
529static int grtc_hw_read_try(struct grtc_priv *pDev, char *buf, int max)
530{
531        struct grtc_regs *regs = pDev->regs;
532        unsigned int rp, wp, asr, bufmax, rrp, rwp;
533        unsigned int upper, lower;
534        unsigned int count, cnt, left;
535
536        FUNCDBG();
537
538        if ( max < 1 )
539                return 0;
540       
541        rp = READ_REG(&regs->rp);
542        asr = READ_REG(&regs->asr);
543        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
544        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
545        wp = READ_REG(&regs->wp);
546       
547        /* Relative rp and wp */
548        rrp = rp - (asr & GRTC_ASR_BUFST);
549        rwp = wp - (asr & GRTC_ASR_BUFST);
550       
551        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
552        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
553       
554        DBG("grtc_hw_read_try: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
555        DBG("grtc_hw_read_try: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
556                rp,rrp,wp,rwp,bufmax,pDev->buffer);
557       
558        if ( (upper+lower) == 0 )
559                return 0;
560       
561        /* Count bytes will be read */
562        count = (upper+lower) > max ? max : (upper+lower);
563        left = count;
564       
565        /* Read from upper part of data buffer */
566        if ( upper > 0 ){
567                if ( left < upper ){
568                        cnt = left;
569                }else{
570                        cnt = upper;    /* Read all upper data available */
571                }
572                DBG("grtc_hw_read_try: COPYING %d from upper\n",cnt);
573                /* Convert from Remote address (RP) into CPU Local address */
574                memcpy(buf, (void *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf), cnt);
575                buf += cnt;
576                left -= cnt;
577        }
578
579        /* Read from lower part of data buffer */
580        if ( left > 0 ){
581                if ( left < lower ){
582                        cnt = left;
583                }else{
584                        cnt = lower;    /* Read all lower data available */
585                }
586                DBG("grtc_hw_read_try: COPYING %d from lower\n",cnt);
587                memcpy(buf, (void *)pDev->buf, cnt);
588                buf += cnt;
589                left -= cnt;
590        }
591       
592        /* Update hardware RP pointer to tell hardware about new space available */
593        if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
594                regs->rp = (rp+count-bufmax);
595        } else {
596                regs->rp = rp+count;
597        }
598
599        return count;
600}
601
602/* Reads as much as possible but not more than 'max' bytes from the TC receive buffer.
603 * Number of bytes put into 'buf' is returned.
604 */
605static int grtc_data_avail(struct grtc_priv *pDev)
606{
607        unsigned int rp, wp, asr, bufmax, rrp, rwp;
608        struct grtc_regs *regs = pDev->regs;
609
610        FUNCDBG();
611
612        rp = READ_REG(&regs->rp);
613        asr = READ_REG(&regs->asr);
614        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
615        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
616        wp = READ_REG(&regs->wp);
617
618        /* Relative rp and wp */
619        rrp = rp - (asr & GRTC_ASR_BUFST);
620        rwp = wp - (asr & GRTC_ASR_BUFST);
621
622        return grtc_hw_data_avail(rrp,rwp,bufmax);
623}
624
625static void *grtc_memalign(unsigned int boundary, unsigned int length, void *realbuf)
626{
627        *(int *)realbuf = (int)malloc(length+(~GRTC_ASR_BUFST)+1);
628        DBG("GRTC: Alloced %d (0x%x) bytes, requested: %d\n",length+(~GRTC_ASR_BUFST)+1,length+(~GRTC_ASR_BUFST)+1,length);
629        return (void *)(((*(unsigned int *)realbuf)+(~GRTC_ASR_BUFST)+1) & ~(boundary-1));
630}
631
632static int grtc_start(struct grtc_priv *pDev)
633{
634        struct grtc_regs *regs = pDev->regs;
635        unsigned int tmp;
636
637        if ( !pDev->buf || (((unsigned int)pDev->buf & ~GRTC_ASR_BUFST) != 0) ||
638             (pDev->len>(1024*0x100)) || (pDev->len<1024) || ((pDev->len & (1024-1)) != 0)
639           ) {
640                DBG("GRTC: start: buffer not properly allocated(0x%x,0x%x,0x%x,0x%x)\n",pDev->buf,pDev->len,((unsigned int)pDev->buf & ~GRTC_ASR_BUFST),(pDev->len & ~(1024-1)));
641                return RTEMS_NO_MEMORY;
642        }
643
644        memset(pDev->buf,0,pDev->len);
645
646        /* Software init */
647        pDev->overrun_condition = 0;
648#ifdef DEBUG_ERROR
649        pDev->last_error_cnt = 0;
650        memset(&pDev->last_error[0],0,128*sizeof(int));
651#endif
652        memset(&pDev->stats,0,sizeof(struct grtc_ioc_stats));
653
654        /* Reset the receiver */
655        regs->cor = GRTC_SEB | GRTC_COR_CRST;
656        if ( READ_REG(&regs->cor) & GRTC_COR_CRST ){
657                /* Reset Failed */
658                DBG("GRTC: start: Reseting receiver failed\n");
659                return RTEMS_IO_ERROR;
660        }
661
662        /* make sure the RX semaphore is in the correct state when starting.
663         * In case of a previous overrun condition it could be in incorrect
664         * state (where rtems_semaphore_flush was used).
665         */
666        rtems_semaphore_obtain(pDev->sem_rx, RTEMS_NO_WAIT, 0);
667
668        /* Set operating modes */
669        tmp = 0;
670        if ( pDev->config.psr_enable )
671                tmp |= GRTC_GCR_PSR;
672        if ( pDev->config.nrzm_enable )
673                tmp |= GRTC_GCR_NRZM;
674        if ( pDev->config.pss_enable )
675                tmp |= GRTC_GCR_PSS;
676        regs->gctrl = GRTC_SEB | tmp;
677
678        /* Clear any pending interrupt */
679        tmp = READ_REG(&regs->pir);
680        regs->picr = GRTC_INT_ALL;
681
682        /* Unmask only the Overrun interrupt */
683        regs->imr = GRTC_INT_OV;
684
685        /* Set up DMA registers
686         * 1. Let hardware know about our DMA area (size and location)
687         * 2. Set DMA read/write posistions to zero.
688         */
689        regs->asr = (unsigned int)pDev->buf_remote | ((pDev->len>>10)-1);
690        regs->rp = (unsigned int)pDev->buf_remote;
691
692        /* Mark running before enabling the receiver, we could receive
693         * an interrupt directly after enabling the receiver and it would
694         * then interpret the interrupt as spurious (see interrupt handler)
695         */
696        pDev->running = 1;
697
698        /* Enable receiver */
699        regs->cor = GRTC_SEB | GRTC_COR_RE;
700
701        DBG("GRTC: STARTED\n");
702
703        return 0;
704}
705
706static void grtc_stop(struct grtc_priv *pDev)
707{
708        struct grtc_regs *regs = pDev->regs;
709
710        /* Disable the receiver */
711        regs->cor = GRTC_SEB;
712
713        /* disable all interrupts and clear them */
714        regs->imr = 0;
715        READ_REG(&regs->pir);
716        regs->picr = GRTC_INT_ALL;
717
718        DBG("GRTC: STOPPED\n");
719
720        /* Flush semaphores in case a thread is stuck waiting for CLTUs (RX data) */
721        rtems_semaphore_flush(pDev->sem_rx);
722}
723
724/* Wait until 'count' bytes are available in receive buffer, or until
725 * the timeout expires.
726 */
727static int grtc_wait_data(struct grtc_priv *pDev, int count, rtems_interval timeout)
728{
729        int avail;
730        int ret;
731        IRQ_GLOBAL_PREPARE(oldLevel);
732
733        FUNCDBG();
734
735        if ( count < 1 )
736                return 0;
737
738        IRQ_GLOBAL_DISABLE(oldLevel);
739
740        /* Enable interrupts when receiving CLTUs, Also clear old pending CLTUs store
741         * interrupts.
742         */
743        pDev->regs->picr = GRTC_INT_CS;
744        pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRTC_INT_CS;
745       
746        avail = grtc_data_avail(pDev);
747        if ( avail < count ) {
748                /* Wait for interrupt. */
749
750                IRQ_GLOBAL_ENABLE(oldLevel);
751
752                if ( timeout == 0 ){
753                        timeout = RTEMS_NO_TIMEOUT;
754                }
755                ret = rtems_semaphore_obtain(pDev->sem_rx,RTEMS_WAIT,timeout);
756                /* RTEMS_SUCCESSFUL  = interrupt signaled data is available
757                 * RTEMS_TIMEOUT     = timeout expired, probably not enough data available
758                 * RTEMS_UNSATISFIED = driver has been closed or an error (overrun) occured
759                 *                     which should cancel this operation.
760                 * RTEMS_OBJECT_WAS_DELETED, RTEMS_INVALID_ID = driver error.
761                 */
762                IRQ_GLOBAL_DISABLE(oldLevel);
763        }else{
764                ret = RTEMS_SUCCESSFUL;
765        }
766
767        /* Disable interrupts when receiving CLTUs */
768        pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRTC_INT_CS;
769
770        IRQ_GLOBAL_ENABLE(oldLevel);
771
772        return ret;
773}
774
775static rtems_device_driver grtc_open(
776        rtems_device_major_number major,
777        rtems_device_minor_number minor,
778        void *arg)
779{
780        struct grtc_priv *pDev;
781        struct drvmgr_dev *dev;
782
783        FUNCDBG();
784
785        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
786                DBG("Wrong minor %d\n", minor);
787                return RTEMS_INVALID_NUMBER;
788        }
789        pDev = (struct grtc_priv *)dev->priv;
790
791        /* Wait until we get semaphore */
792        if ( rtems_semaphore_obtain(grtc_dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL ){
793                return RTEMS_INTERNAL_ERROR;
794        }
795
796        /* Is device in use? */
797        if ( pDev->open ){
798                rtems_semaphore_release(grtc_dev_sem);
799                return RTEMS_RESOURCE_IN_USE;
800        }
801
802        /* Mark device taken */
803        pDev->open = 1;
804       
805        rtems_semaphore_release(grtc_dev_sem);
806
807        DBG("grtc_open: OPENED minor %d (pDev: 0x%x)\n",pDev->minor,(unsigned int)pDev);
808
809        /* Set defaults */
810        pDev->buf = NULL;
811        pDev->_buf = NULL;
812        pDev->buf_custom = 0;
813        pDev->buf_remote = 0;
814        pDev->len = 0;
815        pDev->timeout = 0; /* no timeout */
816        pDev->blocking = 0; /* polling mode */
817        pDev->mode = GRTC_MODE_RAW; /* Always default to Raw mode */
818        pDev->ready.head = NULL;
819        pDev->ready.tail = NULL;
820        pDev->ready.cnt = 0;
821
822        pDev->running = 0;
823        pDev->overrun_condition = 0;
824
825        memset(&pDev->config,0,sizeof(pDev->config));
826
827        /* The core has been reset when we execute here, so it is possible
828         * to read out defualts from core.
829         */
830        grtc_hw_get_defaults(pDev,&pDev->config);
831
832        return RTEMS_SUCCESSFUL;
833}
834
835static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
836{
837        struct grtc_priv *pDev;
838        struct drvmgr_dev *dev;
839
840        FUNCDBG();
841
842        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
843                return RTEMS_INVALID_NUMBER;
844        }
845        pDev = (struct grtc_priv *)dev->priv;
846
847        if ( pDev->running ){
848                grtc_stop(pDev);
849                pDev->running = 0;
850        }
851
852        /* Reset core */
853        grtc_hw_reset(pDev);
854       
855        /* Mark not open */
856        pDev->open = 0;
857       
858        return RTEMS_SUCCESSFUL;
859}
860
861static rtems_device_driver grtc_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
862{
863        struct grtc_priv *pDev;
864        struct drvmgr_dev *dev;
865        int count;
866        int left;
867        int timedout;
868        int err;
869        rtems_interval timeout;
870        rtems_libio_rw_args_t *rw_args;
871
872        FUNCDBG();
873
874        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
875                return RTEMS_INVALID_NUMBER;
876        }
877        pDev = (struct grtc_priv *)dev->priv;
878
879        if ( !pDev->running && !pDev->overrun_condition ) {
880                return RTEMS_RESOURCE_IN_USE;
881        }
882
883        if ( pDev->mode != GRTC_MODE_RAW ) {
884                return RTEMS_NOT_DEFINED;
885        }
886
887        rw_args = (rtems_libio_rw_args_t *) arg;
888        left = rw_args->count;
889        timedout = 0;
890        timeout = pDev->timeout;
891
892read_from_buffer:
893        /* Read maximally rw_args->count bytes from receive buffer */
894        count = grtc_hw_read_try(pDev,rw_args->buffer,left);
895       
896        left -= count;
897
898        DBG("READ %d bytes from DMA, left: %d\n",count,left);
899
900        if ( !timedout && !pDev->overrun_condition && ((count < 1) || ((count < rw_args->count) && (pDev->blocking == GRTC_BLKMODE_COMPLETE))) ){
901                /* didn't read anything (no data available) or we want to wait for all bytes requested.
902                 *
903                 * Wait for data to arrive only in blocking mode
904                 */
905                if ( pDev->blocking ) {
906                        if ( (err=grtc_wait_data(pDev,left,timeout)) != RTEMS_SUCCESSFUL ){
907                                /* Some kind of error, closed, overrun etc. */
908                                if ( err == RTEMS_TIMEOUT ){
909                                        /* Got a timeout, we try to read as much as possible */
910                                        timedout = 1;
911                                        goto read_from_buffer;
912                                }
913                                return err;
914                        }
915                        goto read_from_buffer;
916                }
917                /* Non-blocking mode and no data read. */
918                return RTEMS_TIMEOUT;
919        }
920
921        /* Tell caller how much was read. */
922
923        DBG("READ returning %d bytes, left: %d\n",rw_args->count-left,left);
924
925        rw_args->bytes_moved = rw_args->count - left;
926        if ( rw_args->bytes_moved == 0 ) {
927                if ( pDev->overrun_condition ) {
928                        /* signal to the user that overrun has happend when
929                         * no more data can be read out.
930                         */
931                        return RTEMS_IO_ERROR;
932                }
933                return RTEMS_TIMEOUT;
934        }
935
936        return RTEMS_SUCCESSFUL;
937}
938
939static rtems_device_driver grtc_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
940{
941        FUNCDBG();
942        return RTEMS_NOT_IMPLEMENTED;
943}
944
945static int grtc_pool_add_frms(struct grtc_frame *frms)
946{
947        struct grtc_frame *frm, *next;
948       
949        /* Add frames to pools */
950        frm = frms;
951        while(frm){
952
953                if ( !frm->pool ) {
954                        /* */
955                        DBG("GRTC: Frame not assigned to a pool\n");
956                        return -1;
957                }
958                next = frm->next; /* Remember next frame to process */
959               
960                DBG("GRTC: adding frame 0x%x to pool %d (%d)\n",frm,frm->pool->frame_len,frm->pool->frame_cnt);
961               
962                /* Insert Frame into pool */
963                frm->next = frm->pool->frms;
964                frm->pool->frms = frm;
965                frm->pool->frame_cnt++;
966
967                frm = next;
968        }
969       
970        return 0;
971}
972
973static struct grtc_frame *grtc_pool_get_frm(struct grtc_priv *pDev, int frame_len, int *error)
974{
975        struct grtc_frame *frm;
976        struct grtc_frame_pool *pool;
977        int i;
978       
979        /* Loop through all pools until a pool is found
980         * with a matching (or larger) frame length
981         */
982        pool = pDev->pools;
983        for (i=0; i<pDev->pool_cnt; i++,pool++) {
984                if ( pool->frame_len >= frame_len ) {
985                        /* Found a good pool ==> get frame */
986                        frm = pool->frms;
987                        if ( !frm ) {
988                                /* not enough frames available for this
989                                 * frame length, we try next
990                                 *
991                                 * If this is a severe error add your handling
992                                 * code here.
993                                 */
994#if 0
995                                if ( error )
996                                        *error = 0;
997                                return 0;
998#endif
999                                continue;
1000                        }
1001                       
1002                        /* Got a frame, the frame is taken out of the
1003                         * pool for usage.
1004                         */
1005                        pool->frms = frm->next;
1006                        pool->frame_cnt--;
1007                        return frm;
1008                }
1009        }
1010       
1011        if ( error )
1012                *error = 1;
1013
1014        /* Didn't find any frames */
1015        return NULL;
1016}
1017
1018/* Return number of bytes processed, Stops at the first occurance
1019 * of the pattern given in 'pattern'
1020 */
1021static int grtc_scan(unsigned short *src, int max, unsigned char pattern, int *found)
1022{
1023        unsigned short tmp = 0;
1024        unsigned int left = max;
1025
1026        while ( (left>1) && (((tmp=*src) & 0x00ff) != pattern) ) {
1027                src++;
1028                left-=2;
1029        }
1030        if ( (tmp & 0xff) == pattern ) {
1031                *found = 1;
1032        } else {
1033                *found = 0;
1034        }
1035        return max-left;
1036}
1037
1038static int grtc_copy(unsigned short *src, unsigned char *buf, int cnt)
1039{
1040        unsigned short tmp;
1041        int left = cnt;
1042       
1043        while ( (left>0) && ((((tmp=*src) & 0x00ff) == 0x00) || ((tmp & 0x00ff) == 0x01)) ) {
1044                *buf++ = tmp>>8;
1045                src++;
1046                left--;
1047        }
1048       
1049        return cnt-left;
1050}
1051
1052
1053static int grtc_hw_find_frm(struct grtc_priv *pDev)
1054{
1055        struct grtc_regs *regs = pDev->regs;
1056        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1057        unsigned int upper, lower;
1058        unsigned int count, cnt;
1059        int found;
1060
1061        FUNCDBG();
1062       
1063        rp = READ_REG(&regs->rp);
1064        asr = READ_REG(&regs->asr);
1065        wp = READ_REG(&regs->wp);
1066
1067        /* Quick Check for most common case where Start of frame is at next
1068         * data byte.
1069         */     
1070        if ( rp != wp ) {
1071                /* At least 1 byte in buffer */
1072                if ( ((*(unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf)) & 0x00ff) == 0x01 ) {
1073                        return 0;
1074                }
1075        }
1076       
1077        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1078        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1079       
1080        /* Relative rp and wp */
1081        rrp = rp - (asr & GRTC_ASR_BUFST);
1082        rwp = wp - (asr & GRTC_ASR_BUFST);
1083       
1084        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1085        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1086       
1087        DBG("grtc_hw_find_frm: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1088        DBG("grtc_hw_find_frm: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1089                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1090       
1091        if ( (upper+lower) == 0 )
1092                return 1;
1093
1094        /* Count bytes will be read */
1095        count = 0;
1096        found = 0;
1097       
1098        /* Read from upper part of data buffer */
1099        if ( upper > 0 ){
1100                cnt = grtc_scan((unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf), upper, 0x01, &found);
1101                count = cnt;
1102                if ( found ) {
1103                        DBG("grtc_hw_find_frm: SCANNED upper %d bytes until found\n",cnt);
1104                        goto out;
1105                }
1106               
1107                DBG("grtc_hw_find_frm: SCANNED all upper %d bytes, not found\n",cnt);
1108        }
1109       
1110        /* Read from lower part of data buffer */
1111        if ( lower > 0 ){
1112                cnt = grtc_scan((unsigned short *)pDev->buf, lower, 0x01, &found);
1113                count += cnt;
1114
1115                if ( found ) {
1116                        DBG("grtc_hw_find_frm: SCANNED lower %d bytes until found\n",cnt);
1117                        goto out;
1118                }
1119               
1120                DBG("grtc_hw_find_frm: SCANNED all lower %d bytes, not found\n",cnt);
1121        }
1122
1123out:
1124        /* Update hardware RP pointer to tell hardware about new space available */
1125        if ( count > 0 ) {
1126                if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1127                        regs->rp = (rp+count-bufmax);
1128                } else {
1129                        regs->rp = rp+count;
1130                }
1131        }
1132        if ( found )
1133                return 0;
1134        return 1;
1135
1136}
1137
1138static int grtc_check_ending(unsigned short *src, int max, int end)
1139{
1140        while ( max > 0 ) {
1141                /* Check Filler */
1142                if ( *src != 0x5500 ) {
1143                        /* Filler is wrong */
1144                        return -1;
1145                }
1146                src++;
1147                max-=2;
1148        }
1149       
1150        /* Check ending (at least */
1151        if ( end ) {
1152                if ( (*src & 0x00ff) != 0x02 ) {
1153                        return -1;
1154                }
1155        }
1156
1157        return 0;
1158}
1159
1160static int grtc_hw_check_ending(struct grtc_priv *pDev, int max)
1161{
1162        struct grtc_regs *regs = pDev->regs;
1163        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1164        unsigned int upper, lower;
1165        unsigned int count, cnt, left;
1166
1167        FUNCDBG();
1168
1169        if ( max < 1 )
1170                return 0;
1171        max = max*2;
1172        max += 2; /* Check ending also (2 byte extra) */
1173
1174        rp = READ_REG(&regs->rp);
1175        asr = READ_REG(&regs->asr);
1176        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1177        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1178        wp = READ_REG(&regs->wp);
1179
1180        /* Relative rp and wp */
1181        rrp = rp - (asr & GRTC_ASR_BUFST);
1182        rwp = wp - (asr & GRTC_ASR_BUFST);
1183
1184        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1185        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1186       
1187        DBG("grtc_hw_check_ending: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1188        DBG("grtc_hw_check_ending: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1189                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1190       
1191        if ( (upper+lower) < max )
1192                return 0;
1193       
1194        /* Count bytes will be read */
1195        count = max;
1196        left = count;
1197       
1198        /* Read from upper part of data buffer */
1199        if ( upper > 0 ){
1200                if ( left <= upper ){
1201                        cnt = left;
1202                        if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt-2, 1) ) {
1203                                return -1;
1204                        }
1205                }else{
1206                        cnt = upper;    /* Read all upper data available */
1207                        if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt, 0) ) {
1208                                return -1;
1209                        }
1210                }
1211                left -= cnt;
1212        }
1213       
1214        /* Read from lower part of data buffer */
1215        if ( left > 0 ){
1216                cnt = left;
1217                if ( grtc_check_ending((unsigned short *)pDev->buf, cnt-2, 1) ) {
1218                        return -1;
1219                }
1220                left -= cnt;
1221        }
1222
1223        /* Update hardware RP pointer to tell hardware about new space available */
1224        if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1225                regs->rp = (rp+count-bufmax);
1226        } else {
1227                regs->rp = rp+count;
1228        }
1229
1230        return 0;       
1231}
1232
1233/* Copies Data from DMA area to buf, the control bytes are stripped. For
1234 * every data byte, in the DMA area, one control byte is stripped.
1235 */
1236static int grtc_hw_copy(struct grtc_priv *pDev, unsigned char *buf, int max, int partial)
1237{
1238        struct grtc_regs *regs = pDev->regs;
1239        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1240        unsigned int upper, lower;
1241        unsigned int count, cnt, left;
1242        int ret, tot, tmp;
1243
1244        FUNCDBG();
1245
1246        if ( max < 1 )
1247                return 0;
1248
1249        rp = READ_REG(&regs->rp);
1250        asr = READ_REG(&regs->asr);
1251        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1252        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1253        wp = READ_REG(&regs->wp);
1254
1255        /* Relative rp and wp */
1256        rrp = rp - (asr & GRTC_ASR_BUFST);
1257        rwp = wp - (asr & GRTC_ASR_BUFST);
1258
1259        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax) >> 1;
1260        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax) >> 1;
1261
1262        DBG("grtc_hw_copy: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1263        DBG("grtc_hw_copy: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1264                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1265
1266        if ( (upper+lower) == 0 || (!partial && ((upper+lower)<max) ) )
1267                return 0;
1268
1269        /* Count bytes will be read */
1270        count = (upper+lower) > max ? max : (upper+lower);
1271        left = count;
1272        tot = 0;
1273
1274        /* Read from upper part of data buffer */
1275        if ( upper > 0 ){
1276                if ( left < upper ){
1277                        cnt = left;
1278                }else{
1279                        cnt = upper;    /* Read all upper data available */
1280                }
1281                DBG("grtc_hw_copy: COPYING %d from upper\n",cnt);
1282                if ( (tot=grtc_copy((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), buf, cnt)) != cnt ) {
1283                        /* Failed to copy due to an receive error */
1284                        DBG("grtc_hw_copy(upper): not all in DMA buffer (%d)\n",tot);
1285                        count = tot;
1286                        ret = -1;
1287                        goto out;
1288                }
1289                buf += cnt;
1290                left -= cnt;
1291        }
1292       
1293        /* Read from lower part of data buffer */
1294        if ( left > 0 ){
1295                if ( left < lower ){
1296                        cnt = left;
1297                }else{
1298                        cnt = lower;    /* Read all lower data available */
1299                }
1300                DBG("grtc_hw_copy: COPYING %d from lower\n",cnt);
1301                if ( (tmp=grtc_copy((unsigned short *)pDev->buf, buf, cnt)) != cnt ) {
1302                        /* Failed to copy due to an receive error */
1303                        DBG("grtc_hw_copy(lower): not all in DMA buffer (%d)\n",tot);
1304                        count = tot+tmp;
1305                        ret = -1;
1306                        goto out;
1307                }
1308                buf += cnt;
1309                left -= cnt;
1310        }
1311        ret = count;
1312
1313out:
1314        count = count*2;
1315        /* Update hardware RP pointer to tell hardware about new space available */
1316        if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1317                regs->rp = (rp+count-bufmax);
1318        } else {
1319                regs->rp = rp+count;
1320        }
1321
1322        return ret;
1323}
1324
1325#ifdef DEBUG_ERROR
1326void grtc_log_error(struct grtc_priv *pDev, int err)
1327{
1328        /* Stop Receiver */
1329        *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1330        *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1331        pDev->last_error[pDev->last_error_cnt] = err;
1332        if ( ++pDev->last_error_cnt > 128 )
1333                pDev->last_error_cnt = 0;
1334}
1335#endif
1336
1337/* Read one frame from DMA buffer
1338 *
1339 * Return Values
1340 *  Zero - nothing more to process
1341 *  1 - more to process, no free frames
1342 *  2 - more to process, frame received
1343 *  negative - more to process, frame dropped
1344 */
1345static int process_dma(struct grtc_priv *pDev)
1346{
1347        int ret, err;
1348        int left, total_len;
1349        unsigned char *dst;
1350        struct grtc_frame *frm;
1351
1352        switch( pDev->frame_state ) {
1353                case FRM_STATE_NONE:
1354                DBG2("FRAME_STATE_NONE\n");
1355       
1356                /* Find Start of next frame by searching for 0x01 */
1357                ret = grtc_hw_find_frm(pDev);
1358                if ( ret != 0 ) {
1359                        /* Frame start not found */
1360                        return 0;
1361                }
1362               
1363                /* Start of frame found, Try to copy header */
1364                pDev->frm = NULL;
1365                pDev->frame_state = FRM_STATE_HDR;
1366
1367                case FRM_STATE_HDR:
1368                DBG2("FRAME_STATE_HDR\n");
1369               
1370                /* Wait for all of header to be in place by setting partial to 0 */
1371                ret = grtc_hw_copy(pDev, (unsigned char *)pDev->hdr, 5, 0);
1372                if ( ret < 0 ) {
1373                        /* Error copying header, restart scanning for new frame */
1374                        DEBUG_ERR_LOG(pDev,1);
1375                        pDev->stats.err++;
1376                        pDev->stats.err_hdr++;
1377                        DBG("FRAME_STATE_HDR: copying failed %d\n",ret);
1378                        pDev->frame_state = FRM_STATE_NONE;
1379                        return -1;
1380                } else if ( ret != 5 ) {
1381                        DBG("FRAME_STATE_HDR: no header (%d)\n",ret);
1382                        /* Not all bytes available, come back later */
1383                        return 0;
1384                }
1385
1386                /* The complete header has been copied, parse it */
1387                pDev->frmlen = (((unsigned short *)pDev->hdr)[1] & 0x3ff)+1;
1388                if ( pDev->frmlen < 5 ) {
1389                        /* Error: frame length is not correct */
1390                        pDev->stats.err++;
1391                        pDev->stats.err_hdr++;
1392                        DBG("FRAME_STATE_HDR: frame length error: %d\n", pDev->frmlen);
1393                        pDev->frame_state = FRM_STATE_NONE;
1394                        return -1;
1395                }
1396                pDev->frame_state = FRM_STATE_ALLOC;
1397
1398                case FRM_STATE_ALLOC:
1399                DBG2("FRAME_STATE_ALLOC\n");
1400                /* Header has been read, allocate a frame to put payload and header into */
1401               
1402                /* Allocate Frame matching Frame length */
1403                err = 0;
1404                frm = grtc_pool_get_frm(pDev,pDev->frmlen,&err);
1405                if ( !frm ) {
1406                        /* Couldn't find frame  */
1407                        DEBUG_ERR_LOG(pDev,2);
1408                        pDev->stats.dropped++;
1409                        DBG2("No free frames\n");
1410                        if ( err == 0 ){
1411                                /* Frame length exist in pool configuration, but no
1412                                 * frames are available for that frame length.
1413                                 */
1414                                DEBUG_ERR_LOG(pDev,3);
1415                                pDev->stats.dropped_no_buf++;
1416                                return 1;
1417                        } else {
1418                                /* Frame length of incoming frame is larger than the
1419                                 * frame length in any of the configured frame pools.
1420                                 *
1421                                 * This may be because of an corrupt header. We simply
1422                                 * scan for the end of frame marker in the DMA buffer
1423                                 * so we can drop the frame.
1424                                 */
1425                                DEBUG_ERR_LOG(pDev,4);
1426                                pDev->stats.dropped_too_long++;
1427                                pDev->frame_state = FRM_STATE_NONE;
1428                                return -2;
1429                        }
1430                }
1431                frm->len = 5; /* Only header currenlty in frame */
1432
1433                /* Copy Frame Header into frame structure */
1434                ((unsigned char*)&frm->hdr)[0] = ((unsigned char*)pDev->hdr)[0];
1435                ((unsigned char*)&frm->hdr)[1] = ((unsigned char*)pDev->hdr)[1];
1436                ((unsigned char*)&frm->hdr)[2] = ((unsigned char*)pDev->hdr)[2];
1437                ((unsigned char*)&frm->hdr)[3] = ((unsigned char*)pDev->hdr)[3];
1438                ((unsigned char*)&frm->hdr)[4] = ((unsigned char*)pDev->hdr)[4];
1439
1440                /* Calc Total and Filler byte count in frame */
1441                total_len = pDev->frmlen / 7;
1442                total_len = total_len * 7;
1443                if ( pDev->frmlen != total_len )
1444                        total_len += 7;
1445
1446                pDev->filler = total_len - pDev->frmlen;
1447
1448                pDev->frame_state = FRM_STATE_PAYLOAD;
1449                pDev->frm = frm;
1450
1451                case FRM_STATE_PAYLOAD:
1452                DBG2("FRAME_STATE_PAYLOAD\n");
1453                /* Parts of payload and the complete header has been read */
1454                frm = pDev->frm;
1455
1456                dst = (unsigned char *)&frm->data[frm->len-5];
1457                left = pDev->frmlen-frm->len;
1458
1459                ret = grtc_hw_copy(pDev,dst,left,1);
1460                if ( ret < 0 ) {
1461                        DEBUG_ERR_LOG(pDev,5);
1462                        /* Error copying header, restart scanning for new frame */
1463                        pDev->frame_state = FRM_STATE_NONE;
1464                        frm->next = NULL;
1465                        grtc_pool_add_frms(frm);
1466                        pDev->frm = NULL;
1467                        pDev->stats.err++;
1468                        pDev->stats.err_payload++;
1469                        return -1;
1470                } else if ( ret != left ) {
1471                        /* Not all bytes available, come back later */
1472                        frm->len += ret;
1473                        return 0;
1474                }
1475                frm->len += ret;
1476                pDev->frame_state = FRM_STATE_FILLER;
1477
1478                case FRM_STATE_FILLER:
1479                DBG2("FRAME_STATE_FILLER\n");
1480                /* check filler data */
1481                frm = pDev->frm;
1482
1483                ret = grtc_hw_check_ending(pDev,pDev->filler);
1484                if ( ret != 0 ) {
1485                        /* Error in frame, drop frame */
1486                        DEBUG_ERR_LOG(pDev,6);
1487                        pDev->frame_state = FRM_STATE_NONE;
1488                        frm->next = NULL;
1489                        grtc_pool_add_frms(frm);
1490                        pDev->frm = NULL;
1491                        pDev->stats.err++;
1492                        pDev->stats.err_ending++;
1493                        return -1;
1494                }
1495
1496                /* A complete frame received, put it into received frame queue */
1497                if ( pDev->ready.head ) {
1498                        /* Queue not empty */
1499                        pDev->ready.tail->next = frm;
1500                } else {
1501                        /* Queue empty */
1502                        pDev->ready.head = frm;
1503                }
1504                pDev->ready.tail = frm;
1505                frm->next = NULL;
1506                pDev->ready.cnt++;
1507                pDev->stats.frames_recv++;
1508
1509                pDev->frame_state = FRM_STATE_NONE;
1510                frm->next = NULL;
1511                return 2;
1512
1513#if 0
1514                case FRM_STATE_DROP:
1515                DBG2("FRAME_STATE_DROP\n");
1516                break;
1517#endif
1518
1519                default:
1520                printk("GRTC: internal error\n");
1521                pDev->frame_state = FRM_STATE_NONE;
1522                break;
1523        }
1524       
1525        return 0;
1526}
1527
1528static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1529{
1530        struct grtc_priv *pDev;
1531        struct drvmgr_dev *dev;
1532        rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
1533        unsigned int *data = ioarg->buffer;
1534        int status,frm_len,i,ret;
1535        struct grtc_ioc_buf_params *buf_arg;
1536        struct grtc_ioc_config *cfg;
1537        struct grtc_ioc_hw_status *hwregs;
1538        struct grtc_ioc_pools_setup *pocfg;
1539        struct grtc_ioc_assign_frm_pool *poassign;
1540        struct grtc_frame *frm, *frms;
1541        struct grtc_frame_pool *pool;
1542        struct grtc_list *frmlist;
1543        struct grtc_ioc_stats *stats;
1544        unsigned int mem;
1545       
1546        IRQ_GLOBAL_PREPARE(oldLevel);
1547
1548        FUNCDBG();
1549
1550        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
1551                return RTEMS_INVALID_NUMBER;
1552        }
1553        pDev = (struct grtc_priv *)dev->priv;
1554
1555        if (!ioarg)
1556                return RTEMS_INVALID_NAME;
1557
1558        ioarg->ioctl_return = 0;
1559        switch(ioarg->command) {
1560                case GRTC_IOC_START:
1561                if ( pDev->running ) {
1562                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1563                }
1564                if ( (status=grtc_start(pDev)) != RTEMS_SUCCESSFUL ){
1565                        return status;
1566                }
1567                /* Register ISR and Unmask interrupt */
1568                drvmgr_interrupt_register(pDev->dev, 0, "grtc", grtc_interrupt, pDev);
1569
1570                /* Read and write are now open... */
1571                break;
1572
1573                case GRTC_IOC_STOP:
1574                if ( !pDev->running ) {
1575                        return RTEMS_RESOURCE_IN_USE;
1576                }
1577                drvmgr_interrupt_unregister(pDev->dev, 0, grtc_interrupt, pDev);
1578                grtc_stop(pDev);
1579                pDev->running = 0;
1580                break;
1581
1582                case GRTC_IOC_ISSTARTED:
1583                if ( !pDev->running ) {
1584                        return RTEMS_RESOURCE_IN_USE;
1585                } else if ( pDev->overrun_condition ) {
1586                        return RTEMS_IO_ERROR;
1587                }
1588                break;
1589
1590                case GRTC_IOC_SET_BLOCKING_MODE:
1591                if ( (unsigned int)data > GRTC_BLKMODE_COMPLETE ) {
1592                        return RTEMS_INVALID_NAME;
1593                }
1594                DBG("GRTC: Set blocking mode: %d\n",(unsigned int)data);
1595                pDev->blocking = (unsigned int)data;
1596                break;
1597
1598                case GRTC_IOC_SET_TIMEOUT:
1599                DBG("GRTC: Timeout: %d\n",(unsigned int)data);
1600                pDev->timeout = (rtems_interval)data;
1601                break;
1602
1603                case GRTC_IOC_SET_BUF_PARAM:
1604                if ( pDev->running ) {
1605                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1606                }
1607
1608                buf_arg = (struct grtc_ioc_buf_params *)data;
1609                if ( !buf_arg ) {
1610                        return RTEMS_INVALID_NAME;
1611                }
1612
1613                DBG("GRTC: IOC_SET_BUF_PARAM: Len: 0x%x, Custom Buffer: 0x%x\n",buf_arg->length,buf_arg->custom_buffer);
1614
1615                /* Check alignment need, skip bit 0 since that bit only indicates remote address or not */
1616                if ( (unsigned int)buf_arg->custom_buffer & (~GRTC_BUF_MASK) & (~0x1) ) {
1617                        return RTEMS_INVALID_NAME;
1618                }
1619
1620                if ( buf_arg->length > 0x100 ){
1621                        DBG("GRTC: Too big buffer requested\n");
1622                        return RTEMS_INVALID_NAME;
1623                }
1624
1625                /* If current buffer allocated by driver we must free it */
1626                if ( !pDev->buf_custom && pDev->buf ){
1627                        free(pDev->_buf);
1628                        pDev->_buf = NULL;
1629                }
1630                pDev->buf = NULL;
1631                pDev->len = buf_arg->length*1024;
1632
1633                if (pDev->len <= 0)
1634                        break;
1635                mem = (unsigned int)buf_arg->custom_buffer;
1636                pDev->buf_custom = mem;
1637
1638                if (mem & 1) {
1639                        /* Remote address given, the address is as the GRTC
1640                         * core looks at it. Translate the base address into
1641                         * an address that the CPU can understand.
1642                         */
1643                        pDev->buf_remote = (void *)(mem & ~0x1);
1644                        drvmgr_translate_check(pDev->dev, DMAMEM_TO_CPU,
1645                                                (void *)pDev->buf_remote,
1646                                                (void **)&pDev->buf,
1647                                                pDev->len);
1648                } else {
1649                        if (mem == 0) {
1650                                pDev->buf = grtc_memalign((~GRTC_ASR_BUFST)+1,pDev->len,&pDev->_buf);
1651                                DBG("grtc_ioctl: SETBUF: new buf: 0x%x(0x%x), Len: %d\n",pDev->buf,pDev->_buf,pDev->len);
1652                                if (!pDev->buf){
1653                                        pDev->len = 0;
1654                                        pDev->buf_custom = 0;
1655                                        pDev->_buf = NULL;
1656                                        pDev->buf_remote = 0;
1657                                        DBG("GRTC: Failed to allocate memory\n");
1658                                        return RTEMS_NO_MEMORY;
1659                                }
1660                        } else{
1661                                pDev->buf = buf_arg->custom_buffer;
1662                        }
1663
1664                        /* Translate into a remote address so that GRTC core
1665                         * on a remote AMBA bus (for example over the PCI bus)
1666                         * gets a valid address
1667                         */
1668                        drvmgr_translate_check(pDev->dev, CPUMEM_TO_DMA,
1669                                                (void *)pDev->buf,
1670                                                (void **)&pDev->buf_remote,
1671                                                pDev->len);
1672                }
1673                break;
1674
1675                case GRTC_IOC_GET_BUF_PARAM:
1676                if ( pDev->running ) {
1677                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1678                }
1679
1680                buf_arg = (struct grtc_ioc_buf_params *)data;
1681                if ( !buf_arg ) {
1682                        return RTEMS_INVALID_NAME;
1683                }
1684
1685                buf_arg->length = pDev->len >> 10; /* Length in 1kByte blocks */
1686                if ( pDev->buf_custom )
1687                        buf_arg->custom_buffer =(void *)pDev->buf;
1688                else
1689                        buf_arg->custom_buffer = 0; /* Don't reveal internal driver buffer */
1690                break;
1691
1692                case GRTC_IOC_SET_CONFIG:
1693                cfg = (struct grtc_ioc_config *)data;
1694                if ( !cfg ) {
1695                        return RTEMS_INVALID_NAME;
1696                }
1697               
1698                if ( pDev->running ) {
1699                        return RTEMS_RESOURCE_IN_USE;
1700                }
1701
1702                pDev->config = *cfg;
1703                break;
1704
1705                case GRTC_IOC_GET_CONFIG:
1706                cfg = (struct grtc_ioc_config *)data;
1707                if ( !cfg ) {
1708                        return RTEMS_INVALID_NAME;
1709                }
1710
1711                *cfg = pDev->config;
1712                break;
1713
1714                case GRTC_IOC_GET_HW_STATUS:
1715                hwregs = (struct grtc_ioc_hw_status *)data;
1716                if ( !hwregs ) {
1717                        return RTEMS_INVALID_NAME;
1718                }
1719                /* We disable interrupt in order to get a snapshot of the registers */
1720                IRQ_GLOBAL_DISABLE(oldLevel);
1721                hwregs->sir     = READ_REG(&pDev->regs->sir);
1722                hwregs->far     = READ_REG(&pDev->regs->far);
1723                hwregs->clcw1   = READ_REG(&pDev->regs->clcw1);
1724                hwregs->clcw2   = READ_REG(&pDev->regs->clcw2);
1725                hwregs->phir    = READ_REG(&pDev->regs->phir);
1726                hwregs->str     = READ_REG(&pDev->regs->str);
1727                IRQ_GLOBAL_ENABLE(oldLevel);
1728                break;
1729
1730                case GRTC_IOC_GET_STATS:
1731                stats = (struct grtc_ioc_stats *)data;
1732                if ( !stats ) {
1733                        return RTEMS_INVALID_NAME;
1734                }
1735                memcpy(stats,&pDev->stats,sizeof(struct grtc_ioc_stats));
1736                break;
1737
1738                case GRTC_IOC_CLR_STATS:
1739                memset(&pDev->stats,0,sizeof(struct grtc_ioc_stats));
1740                break;
1741               
1742                case GRTC_IOC_SET_MODE:
1743                if ( pDev->running ) {
1744                        return RTEMS_RESOURCE_IN_USE;
1745                }
1746                if ( (int)data == GRTC_MODE_FRAME ) {
1747                        pDev->mode = GRTC_MODE_FRAME;
1748                } else if ( (int)data == GRTC_MODE_RAW ) {
1749                        pDev->mode = GRTC_MODE_RAW;
1750                } else {
1751                        return RTEMS_INVALID_NAME;
1752                }
1753                break;
1754               
1755                case GRTC_IOC_POOLS_SETUP:
1756                if ( pDev->running ) {
1757                        return RTEMS_RESOURCE_IN_USE;
1758                }
1759                pocfg = (struct grtc_ioc_pools_setup *)data;
1760                if ( (pDev->mode != GRTC_MODE_FRAME) || !pocfg ) {
1761                        return RTEMS_INVALID_NAME;
1762                }
1763               
1764                /* Check that list is sorted */
1765                frm_len = 0;
1766                for(i=0;i<pocfg->pool_cnt;i++){
1767                        if ( pocfg->pool_frame_len[i] <= frm_len ) {
1768                                return RTEMS_INVALID_NAME;
1769                        }
1770                        frm_len = pocfg->pool_frame_len[i];
1771                }
1772               
1773                /* Ok, we trust user. The pool descriptions are allocated
1774                 * but not frames, that the user must do self.
1775                 */
1776                if ( pDev->pools ) {
1777                        free(pDev->pools);
1778                }
1779                pDev->pools = malloc(pocfg->pool_cnt * sizeof(struct grtc_frame_pool));
1780                if ( !pDev->pools ) {
1781                        pDev->pool_cnt = 0;
1782                        return RTEMS_NO_MEMORY;
1783                }
1784                pDev->pool_cnt = pocfg->pool_cnt;
1785                for (i=0;i<pocfg->pool_cnt;i++) {
1786                        pDev->pools[i].frame_len = pocfg->pool_frame_len[i];
1787                        pDev->pools[i].frame_cnt = 0;
1788                        pDev->pools[i].frms = NULL;
1789                }
1790                break;
1791
1792                case GRTC_IOC_ASSIGN_FRM_POOL:
1793                if ( pDev->running ) {
1794                        return RTEMS_RESOURCE_IN_USE;
1795                }
1796
1797                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1798                        return RTEMS_INVALID_NAME;
1799                }
1800
1801                poassign = (struct grtc_ioc_assign_frm_pool *)data;
1802                if ( !poassign ) {
1803                        return RTEMS_INVALID_NAME;
1804                }
1805               
1806                /* Find pool to assign the frames to */
1807                pool = NULL;
1808                for(i=0; i<pDev->pool_cnt; i++) {
1809                        if ( pDev->pools[i].frame_len == poassign->frame_len ) {
1810                                pool = &pDev->pools[i];
1811                                break;
1812                        }
1813                }
1814                if ( !pool ) {
1815                        /* No Pool matching frame length */
1816                        return RTEMS_INVALID_NAME;
1817                }
1818               
1819                /* Assign frames to pool */
1820                frm = poassign->frames;
1821                while(frm){
1822                        frm->pool = pool;       /* Assign Frame to pool */
1823                        frm = frm->next;
1824                }
1825                break;
1826
1827                case GRTC_IOC_ADD_BUFF:
1828                frms = (struct grtc_frame *)data;
1829
1830                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1831                        return RTEMS_NOT_DEFINED;
1832                }
1833                if ( !frms ) {
1834                        return RTEMS_INVALID_NAME;
1835                }
1836
1837                /* Add frames to respicative pools */
1838                if ( grtc_pool_add_frms(frms) ) {
1839                        return RTEMS_INVALID_NAME;
1840                }
1841                break;
1842
1843                /* Try to read as much data as possible from DMA area and
1844                 * put it into free frames.
1845                 *
1846                 * If receiver is in stopped mode, let user only read previously
1847                 * received frames.
1848                 */
1849                case GRTC_IOC_RECV:
1850
1851                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1852                        return RTEMS_NOT_DEFINED;
1853                }
1854
1855                while ( pDev->running && ((ret=process_dma(pDev) == 2) || (ret == -1)) ) {
1856                        /* Frame received or dropped, process next frame */
1857                }
1858
1859                /* Take frames out from ready queue and put them to user */
1860                frmlist = (struct grtc_list *)data;
1861                if ( !frmlist ) {
1862                        return RTEMS_INVALID_NAME;
1863                }
1864
1865                frmlist->head = pDev->ready.head;
1866                frmlist->tail = pDev->ready.tail;
1867                frmlist->cnt = pDev->ready.cnt;
1868
1869                /* Empty list */
1870                pDev->ready.head = NULL;
1871                pDev->ready.tail = NULL;
1872                pDev->ready.cnt = 0;
1873
1874                if ((frmlist->cnt == 0) && pDev->overrun_condition) {
1875                        /* signal to the user that overrun has happend when
1876                         * no more data can be read out.
1877                         */
1878                        return RTEMS_IO_ERROR;
1879                }
1880                break;
1881
1882                case GRTC_IOC_GET_CLCW_ADR:
1883                if ( !data ) {
1884                        return RTEMS_INVALID_NAME;
1885                }
1886                *data = (unsigned int)&pDev->regs->clcw1;
1887                break;
1888
1889                default:
1890                return RTEMS_NOT_DEFINED;
1891        }
1892        return RTEMS_SUCCESSFUL;
1893}
1894
1895static void grtc_interrupt(void *arg)
1896{
1897        struct grtc_priv *pDev = arg;
1898        struct grtc_regs *regs = pDev->regs;
1899        unsigned int status;
1900
1901        /* Clear interrupt by reading it */
1902        status = READ_REG(&regs->pisr);
1903
1904        /* Spurious Interrupt? */
1905        if ( !pDev->running )
1906                return;
1907
1908        if ( status & GRTC_INT_OV ){
1909               
1910                /* Stop core (Disable receiver, interrupts), set overrun condition,
1911                 * Flush semaphore if thread waiting for data in grtc_wait_data().
1912                 */
1913                pDev->overrun_condition = 1;
1914
1915                grtc_stop(pDev);
1916
1917                /* No need to handle the reset of interrupts, we are still */
1918                goto out;
1919        }
1920
1921        if ( status & GRTC_INT_CS ){
1922                if ( (pDev->blocking==GRTC_BLKMODE_COMPLETE) && pDev->timeout ){
1923                        /* Signal to thread only if enough data is available */
1924                        if ( pDev->wait_for_nbytes > grtc_data_avail(pDev) ){
1925                                /* Not enough data available */
1926                                goto procceed_processing_interrupts;
1927                        }
1928                       
1929                        /* Enough data is available which means that we should wake
1930                         * up thread sleeping.
1931                         */
1932                }
1933               
1934                /* Disable further CLTUs Stored interrupts, no point until thread waiting for them
1935                 * say it want to wait for more.
1936                 */
1937                regs->imr = READ_REG(&regs->imr) & ~GRTC_INT_CS;
1938               
1939                /* Signal Semaphore to wake waiting thread in read() */
1940                rtems_semaphore_release(pDev->sem_rx);
1941        }
1942       
1943procceed_processing_interrupts:
1944
1945        if ( status & GRTC_INT_CR ){
1946       
1947        }
1948
1949        if ( status & GRTC_INT_FAR ){
1950       
1951        }
1952
1953        if ( status & GRTC_INT_BLO ){
1954       
1955        }
1956
1957        if ( status & GRTC_INT_RFA ){
1958       
1959        }
1960out:
1961        if ( status )
1962                regs->picr = status;
1963}
1964
1965static rtems_device_driver grtc_initialize(
1966  rtems_device_major_number major,
1967  rtems_device_minor_number unused,
1968  void *arg
1969  )
1970{
1971        /* Device Semaphore created with count = 1 */
1972        if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'T', 'C'),
1973                1,
1974                RTEMS_FIFO|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1975                0,
1976                &grtc_dev_sem) != RTEMS_SUCCESSFUL ) {
1977                return RTEMS_INTERNAL_ERROR;
1978        }
1979
1980        return RTEMS_SUCCESSFUL;
1981}
Note: See TracBrowser for help on using the repository browser.