source: rtems/bsps/sparc/shared/tmtc/grtc.c @ d60d303c

5
Last change on this file since d60d303c was d60d303c, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/18 at 11:33:24

bsps/sparc: Move shared files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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