source: rtems/c/src/lib/libbsp/sparc/shared/tmtc/grtc.c @ 3bb4122

4.115
Last change on this file since 3bb4122 was 3bb4122, checked in by Daniel Hellstrom <daniel@…>, on 02/23/15 at 12:02:39

LEON: added new drivers to the LEON2/LEON3 BSPs

Most drivers use the Driver Manager for device probing, they
work on AMBA-over-PCI systems if PCI is big-endian.

New APIs:

  • GPIO Library, interfaced to GRGPIO
  • GENIRQ, Generic interrupt service implementation helper

New GRLIB Drivers:

  • ACTEL 1553 RT, user interface is similar to 1553 BRM driver
  • GR1553 (1553 BC, RT and BM core)
  • AHBSTAT (AHB error status core)
  • GRADCDAC (Core interfacing to ADC/DAC hardware)
  • GRGPIO (GPIO port accessed from GPIO Library)
  • MCTRL (Memory controller settings configuration)
  • GRETH (10/100/1000 Ethernet driver using Driver manager)
  • GRPWM (Pulse Width Modulation core)
  • SPICTRL (SPI master interface)
  • GRSPW_ROUTER (SpaceWire? Router AMBA configuration interface)
  • GRCTM (SpaceCraft? on-board Time Management core)
  • SPWCUC (Time distribution over SpaceWire?)
  • GRTC (SpaceCraft? up-link Tele core)
  • GRTM (SpaceCraft? down-link Tele Metry core)

GR712RC ASIC specific interfaces:

  • GRASCS
  • CANMUX (select between OCCAN and SATCAN)
  • SATCAN
  • SLINK
  • Property mode set to 100644
File size: 49.9 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.com/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 <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 <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 char           hdr[5] __attribute__((aligned(2)));
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 possiböe 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 possiböe 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        /* Set operating modes */
663        tmp = 0;
664        if ( pDev->config.psr_enable )
665                tmp |= GRTC_GCR_PSR;
666        if ( pDev->config.nrzm_enable )
667                tmp |= GRTC_GCR_NRZM;
668        if ( pDev->config.pss_enable )
669                tmp |= GRTC_GCR_PSS;
670        regs->gctrl = GRTC_SEB | tmp;
671
672        /* Clear any pending interrupt */
673        tmp = READ_REG(&regs->pir);
674        regs->picr = GRTC_INT_ALL;
675
676        /* Unmask only the Overrun interrupt */
677        regs->imr = GRTC_INT_OV;
678
679        /* Set up DMA registers
680         * 1. Let hardware know about our DMA area (size and location)
681         * 2. Set DMA read/write posistions to zero.
682         */
683        regs->asr = (unsigned int)pDev->buf_remote | ((pDev->len>>10)-1);
684        regs->rp = (unsigned int)pDev->buf_remote;
685
686        /* Mark running before enabling the receiver, we could receive
687         * an interrupt directly after enabling the receiver and it would
688         * then interpret the interrupt as spurious (see interrupt handler)
689         */
690        pDev->running = 1;
691
692        /* Enable receiver */
693        regs->cor = GRTC_SEB | GRTC_COR_RE;
694
695        DBG("GRTC: STARTED\n");
696
697        return 0;
698}
699
700static void grtc_stop(struct grtc_priv *pDev)
701{
702        struct grtc_regs *regs = pDev->regs;
703        unsigned int tmp;
704       
705        /* Disable the receiver */
706        regs->cor = GRTC_SEB;
707       
708        /* disable all interrupts and clear them */
709        regs->imr = 0;
710        tmp = READ_REG(&regs->pir);
711        regs->picr = GRTC_INT_ALL;
712       
713        DBG("GRTC: STOPPED\n");
714       
715        /* Flush semaphores in case a thread is stuck waiting for CLTUs (RX data) */
716        rtems_semaphore_flush(pDev->sem_rx);
717}
718
719/* Wait until 'count' bytes are available in receive buffer, or until
720 * the timeout expires.
721 */
722static int grtc_wait_data(struct grtc_priv *pDev, int count, rtems_interval timeout)
723{
724        int avail;
725        int ret;
726        IRQ_GLOBAL_PREPARE(oldLevel);
727
728        FUNCDBG();
729
730        if ( count < 1 )
731                return 0;
732
733        IRQ_GLOBAL_DISABLE(oldLevel);
734
735        /* Enable interrupts when receiving CLTUs, Also clear old pending CLTUs store
736         * interrupts.
737         */
738        pDev->regs->picr = GRTC_INT_CS;
739        pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRTC_INT_CS;
740       
741        avail = grtc_data_avail(pDev);
742        if ( avail < count ) {
743                /* Wait for interrupt. */
744
745                IRQ_GLOBAL_ENABLE(oldLevel);
746
747                if ( timeout == 0 ){
748                        timeout = RTEMS_NO_TIMEOUT;
749                }
750                ret = rtems_semaphore_obtain(pDev->sem_rx,RTEMS_WAIT,timeout);
751                /* RTEMS_SUCCESSFUL  = interrupt signaled data is available
752                 * RTEMS_TIMEOUT     = timeout expired, probably not enough data available
753                 * RTEMS_UNSATISFIED = driver has been closed or an error (overrun) occured
754                 *                     which should cancel this operation.
755                 * RTEMS_OBJECT_WAS_DELETED, RTEMS_INVALID_ID = driver error.
756                 */
757                IRQ_GLOBAL_DISABLE(oldLevel);
758        }else{
759                ret = RTEMS_SUCCESSFUL;
760        }
761
762        /* Disable interrupts when receiving CLTUs */
763        pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRTC_INT_CS;
764
765        IRQ_GLOBAL_ENABLE(oldLevel);
766
767        return ret;
768}
769
770static rtems_device_driver grtc_open(
771        rtems_device_major_number major,
772        rtems_device_minor_number minor,
773        void *arg)
774{
775        struct grtc_priv *pDev;
776        struct drvmgr_dev *dev;
777
778        FUNCDBG();
779
780        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
781                DBG("Wrong minor %d\n", minor);
782                return RTEMS_INVALID_NUMBER;
783        }
784        pDev = (struct grtc_priv *)dev->priv;
785
786        /* Wait until we get semaphore */
787        if ( rtems_semaphore_obtain(grtc_dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL ){
788                return RTEMS_INTERNAL_ERROR;
789        }
790
791        /* Is device in use? */
792        if ( pDev->open ){
793                rtems_semaphore_release(grtc_dev_sem);
794                return RTEMS_RESOURCE_IN_USE;
795        }
796
797        /* Mark device taken */
798        pDev->open = 1;
799       
800        rtems_semaphore_release(grtc_dev_sem);
801
802        DBG("grtc_open: OPENED minor %d (pDev: 0x%x)\n",pDev->minor,(unsigned int)pDev);
803
804        /* Set defaults */
805        pDev->buf = NULL;
806        pDev->_buf = NULL;
807        pDev->buf_custom = 0;
808        pDev->buf_remote = 0;
809        pDev->len = 0;
810        pDev->timeout = 0; /* no timeout */
811        pDev->blocking = 0; /* polling mode */
812        pDev->mode = GRTC_MODE_RAW; /* Always default to Raw mode */
813        pDev->ready.head = NULL;
814        pDev->ready.tail = NULL;
815        pDev->ready.cnt = 0;
816
817        pDev->running = 0;
818
819        memset(&pDev->config,0,sizeof(pDev->config));
820
821        /* The core has been reset when we execute here, so it is possible
822         * to read out defualts from core.
823         */
824        grtc_hw_get_defaults(pDev,&pDev->config);
825
826        return RTEMS_SUCCESSFUL;
827}
828
829static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
830{
831        struct grtc_priv *pDev;
832        struct drvmgr_dev *dev;
833
834        FUNCDBG();
835
836        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
837                return RTEMS_INVALID_NUMBER;
838        }
839        pDev = (struct grtc_priv *)dev->priv;
840
841        if ( pDev->running ){
842                grtc_stop(pDev);
843                pDev->running = 0;
844        }
845       
846        /* Reset core */
847        grtc_hw_reset(pDev);
848       
849        /* Mark not open */
850        pDev->open = 0;
851       
852        return RTEMS_SUCCESSFUL;
853}
854
855static rtems_device_driver grtc_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
856{
857        struct grtc_priv *pDev;
858        struct drvmgr_dev *dev;
859        int count;
860        int left;
861        int timedout;
862        int err;
863        rtems_interval timeout;
864        rtems_libio_rw_args_t *rw_args;
865
866        FUNCDBG();
867
868        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
869                return RTEMS_INVALID_NUMBER;
870        }
871        pDev = (struct grtc_priv *)dev->priv;
872
873        if ( !pDev->running && !pDev->overrun_condition ) {
874                return RTEMS_RESOURCE_IN_USE;
875        }
876
877        if ( pDev->mode != GRTC_MODE_RAW ) {
878                return RTEMS_NOT_DEFINED;
879        }
880
881        rw_args = (rtems_libio_rw_args_t *) arg;
882        left = rw_args->count;
883        timedout = 0;
884        timeout = pDev->timeout;
885
886read_from_buffer:
887        /* Read maximally rw_args->count bytes from receive buffer */
888        count = grtc_hw_read_try(pDev,rw_args->buffer,left);
889       
890        left -= count;
891
892        DBG("READ %d bytes from DMA, left: %d\n",count,left);
893
894        if ( !timedout && !pDev->overrun_condition && ((count < 1) || ((count < rw_args->count) && (pDev->blocking == GRTC_BLKMODE_COMPLETE))) ){
895                /* didn't read anything (no data available) or we want to wait for all bytes requested.
896                 *
897                 * Wait for data to arrive only in blocking mode
898                 */
899                if ( pDev->blocking ) {
900                        if ( (err=grtc_wait_data(pDev,left,timeout)) != RTEMS_SUCCESSFUL ){
901                                /* Some kind of error, closed, overrun etc. */
902                                if ( err == RTEMS_TIMEOUT ){
903                                        /* Got a timeout, we try to read as much as possible */
904                                        timedout = 1;
905                                        goto read_from_buffer;
906                                }
907                                return err;
908                        }
909                        goto read_from_buffer;
910                }
911                /* Non-blocking mode and no data read. */
912                return RTEMS_TIMEOUT;
913        }
914       
915        /* Tell caller how much was read. */
916       
917        DBG("READ returning %d bytes, left: %d\n",rw_args->count-left,left);
918       
919        rw_args->bytes_moved = rw_args->count - left;
920        if ( rw_args->bytes_moved == 0 ){
921                return RTEMS_TIMEOUT;
922        }
923       
924        return RTEMS_SUCCESSFUL;
925}
926
927static rtems_device_driver grtc_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
928{
929        FUNCDBG();
930        return RTEMS_NOT_IMPLEMENTED;
931}
932
933static int grtc_pool_add_frms(struct grtc_frame *frms)
934{
935        struct grtc_frame *frm, *next;
936       
937        /* Add frames to pools */
938        frm = frms;
939        while(frm){
940
941                if ( !frm->pool ) {
942                        /* */
943                        DBG("GRTC: Frame not assigned to a pool\n");
944                        return -1;
945                }
946                next = frm->next; /* Remember next frame to process */
947               
948                DBG("GRTC: adding frame 0x%x to pool %d (%d)\n",frm,frm->pool->frame_len,frm->pool->frame_cnt);
949               
950                /* Insert Frame into pool */
951                frm->next = frm->pool->frms;
952                frm->pool->frms = frm;
953                frm->pool->frame_cnt++;
954
955                frm = next;
956        }
957       
958        return 0;
959}
960
961static struct grtc_frame *grtc_pool_get_frm(struct grtc_priv *pDev, int frame_len, int *error)
962{
963        struct grtc_frame *frm;
964        struct grtc_frame_pool *pool;
965        int i;
966       
967        /* Loop through all pools until a pool is found
968         * with a matching (or larger) frame length
969         */
970        pool = pDev->pools;
971        for (i=0; i<pDev->pool_cnt; i++,pool++) {
972                if ( pool->frame_len >= frame_len ) {
973                        /* Found a good pool ==> get frame */
974                        frm = pool->frms;
975                        if ( !frm ) {
976                                /* not enough frames available for this
977                                 * frame length, we try next
978                                 *
979                                 * If this is a severe error add your handling
980                                 * code here.
981                                 */
982#if 0
983                                if ( error )
984                                        *error = 0;
985                                return 0;
986#endif
987                                continue;
988                        }
989                       
990                        /* Got a frame, the frame is taken out of the
991                         * pool for usage.
992                         */
993                        pool->frms = frm->next;
994                        pool->frame_cnt--;
995                        return frm;
996                }
997        }
998       
999        if ( error )
1000                *error = 1;
1001
1002        /* Didn't find any frames */
1003        return NULL;
1004}
1005
1006/* Return number of bytes processed, Stops at the first occurance
1007 * of the pattern given in 'pattern'
1008 */
1009static int grtc_scan(unsigned short *src, int max, unsigned char pattern, int *found)
1010{
1011        unsigned short tmp = 0;
1012        unsigned int left = max;
1013
1014        while ( (left>1) && (((tmp=*src) & 0x00ff) != pattern) ) {
1015                src++;
1016                left-=2;
1017        }
1018        if ( (tmp & 0xff) == pattern ) {
1019                *found = 1;
1020        } else {
1021                *found = 0;
1022        }
1023        return max-left;
1024}
1025
1026static int grtc_copy(unsigned short *src, unsigned char *buf, int cnt)
1027{
1028        unsigned short tmp;
1029        int left = cnt;
1030       
1031        while ( (left>0) && ((((tmp=*src) & 0x00ff) == 0x00) || ((tmp & 0x00ff) == 0x01)) ) {
1032                *buf++ = tmp>>8;
1033                src++;
1034                left--;
1035        }
1036       
1037        return cnt-left;
1038}
1039
1040
1041static int grtc_hw_find_frm(struct grtc_priv *pDev)
1042{
1043        struct grtc_regs *regs = pDev->regs;
1044        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1045        unsigned int upper, lower;
1046        unsigned int count, cnt;
1047        int found;
1048
1049        FUNCDBG();
1050       
1051        rp = READ_REG(&regs->rp);
1052        asr = READ_REG(&regs->asr);
1053        wp = READ_REG(&regs->wp);
1054
1055        /* Quick Check for most common case where Start of frame is at next
1056         * data byte.
1057         */     
1058        if ( rp != wp ) {
1059                /* At least 1 byte in buffer */
1060                if ( ((*(unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf)) & 0x00ff) == 0x01 ) {
1061                        return 0;
1062                }
1063        }
1064       
1065        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1066        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1067       
1068        /* Relative rp and wp */
1069        rrp = rp - (asr & GRTC_ASR_BUFST);
1070        rwp = wp - (asr & GRTC_ASR_BUFST);
1071       
1072        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1073        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1074       
1075        DBG("grtc_hw_find_frm: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1076        DBG("grtc_hw_find_frm: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1077                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1078       
1079        if ( (upper+lower) == 0 )
1080                return 1;
1081
1082        /* Count bytes will be read */
1083        count = 0;
1084        found = 0;
1085       
1086        /* Read from upper part of data buffer */
1087        if ( upper > 0 ){
1088                cnt = grtc_scan((unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf), upper, 0x01, &found);
1089                count = cnt;
1090                if ( found ) {
1091                        DBG("grtc_hw_find_frm: SCANNED upper %d bytes until found\n",cnt);
1092                        goto out;
1093                }
1094               
1095                DBG("grtc_hw_find_frm: SCANNED all upper %d bytes, not found\n",cnt);
1096        }
1097       
1098        /* Read from lower part of data buffer */
1099        if ( lower > 0 ){
1100                cnt = grtc_scan((unsigned short *)pDev->buf, lower, 0x01, &found);
1101                count += cnt;
1102
1103                if ( found ) {
1104                        DBG("grtc_hw_find_frm: SCANNED lower %d bytes until found\n",cnt);
1105                        goto out;
1106                }
1107               
1108                DBG("grtc_hw_find_frm: SCANNED all lower %d bytes, not found\n",cnt);
1109        }
1110
1111out:
1112        /* Update hardware RP pointer to tell hardware about new space available */
1113        if ( count > 0 ) {
1114                if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1115                        regs->rp = (rp+count-bufmax);
1116                } else {
1117                        regs->rp = rp+count;
1118                }
1119        }
1120        if ( found )
1121                return 0;
1122        return 1;
1123
1124}
1125
1126static int grtc_check_ending(unsigned short *src, int max, int end)
1127{
1128        while ( max > 0 ) {
1129                /* Check Filler */
1130                if ( *src != 0x5500 ) {
1131                        /* Filler is wrong */
1132                        return -1;
1133                }
1134                src++;
1135                max-=2;
1136        }
1137       
1138        /* Check ending (at least */
1139        if ( end ) {
1140                if ( (*src & 0x00ff) != 0x02 ) {
1141                        return -1;
1142                }
1143        }
1144
1145        return 0;
1146}
1147
1148static int grtc_hw_check_ending(struct grtc_priv *pDev, int max)
1149{
1150        struct grtc_regs *regs = pDev->regs;
1151        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1152        unsigned int upper, lower;
1153        unsigned int count, cnt, left;
1154        int tot;
1155
1156        FUNCDBG();
1157
1158        if ( max < 1 )
1159                return 0;
1160        max = max*2;
1161        max += 2; /* Check ending also (2 byte extra) */
1162
1163        rp = READ_REG(&regs->rp);
1164        asr = READ_REG(&regs->asr);
1165        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1166        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1167        wp = READ_REG(&regs->wp);
1168
1169        /* Relative rp and wp */
1170        rrp = rp - (asr & GRTC_ASR_BUFST);
1171        rwp = wp - (asr & GRTC_ASR_BUFST);
1172
1173        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1174        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1175       
1176        DBG("grtc_hw_check_ending: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1177        DBG("grtc_hw_check_ending: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1178                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1179       
1180        if ( (upper+lower) < max )
1181                return 0;
1182       
1183        /* Count bytes will be read */
1184        count = max;
1185        left = count;
1186        tot = 0;
1187       
1188        /* Read from upper part of data buffer */
1189        if ( upper > 0 ){
1190                if ( left <= upper ){
1191                        cnt = left;
1192                        if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt-2, 1) ) {
1193                                return -1;
1194                        }
1195                }else{
1196                        cnt = upper;    /* Read all upper data available */
1197                        if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt, 0) ) {
1198                                return -1;
1199                        }
1200                }
1201                left -= cnt;
1202        }
1203       
1204        /* Read from lower part of data buffer */
1205        if ( left > 0 ){
1206                cnt = left;
1207                if ( grtc_check_ending((unsigned short *)pDev->buf, cnt-2, 1) ) {
1208                        return -1;
1209                }
1210                left -= cnt;
1211        }
1212
1213        /* Update hardware RP pointer to tell hardware about new space available */
1214        if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1215                regs->rp = (rp+count-bufmax);
1216        } else {
1217                regs->rp = rp+count;
1218        }
1219
1220        return 0;       
1221}
1222
1223/* Copies Data from DMA area to buf, the control bytes are stripped. For
1224 * every data byte, in the DMA area, one control byte is stripped.
1225 */
1226static int grtc_hw_copy(struct grtc_priv *pDev, unsigned char *buf, int max, int partial)
1227{
1228        struct grtc_regs *regs = pDev->regs;
1229        unsigned int rp, wp, asr, bufmax, rrp, rwp;
1230        unsigned int upper, lower;
1231        unsigned int count, cnt, left;
1232        int ret, tot, tmp;
1233
1234        FUNCDBG();
1235
1236        if ( max < 1 )
1237                return 0;
1238
1239        rp = READ_REG(&regs->rp);
1240        asr = READ_REG(&regs->asr);
1241        bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1242        bufmax = (bufmax+1) << 10; /* Convert from 1kbyte blocks into bytes */
1243        wp = READ_REG(&regs->wp);
1244
1245        /* Relative rp and wp */
1246        rrp = rp - (asr & GRTC_ASR_BUFST);
1247        rwp = wp - (asr & GRTC_ASR_BUFST);
1248
1249        lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax) >> 1;
1250        upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax) >> 1;
1251
1252        DBG("grtc_hw_copy: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1253        DBG("grtc_hw_copy: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1254                rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1255
1256        if ( (upper+lower) == 0 || (!partial && ((upper+lower)<max) ) )
1257                return 0;
1258
1259        /* Count bytes will be read */
1260        count = (upper+lower) > max ? max : (upper+lower);
1261        left = count;
1262        tot = 0;
1263
1264        /* Read from upper part of data buffer */
1265        if ( upper > 0 ){
1266                if ( left < upper ){
1267                        cnt = left;
1268                }else{
1269                        cnt = upper;    /* Read all upper data available */
1270                }
1271                DBG("grtc_hw_copy: COPYING %d from upper\n",cnt);
1272                if ( (tot=grtc_copy((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), buf, cnt)) != cnt ) {
1273                        /* Failed to copy due to an receive error */
1274                        DBG("grtc_hw_copy(upper): not all in DMA buffer (%d)\n",tot);
1275                        count = tot;
1276                        ret = -1;
1277                        goto out;
1278                }
1279                buf += cnt;
1280                left -= cnt;
1281        }
1282       
1283        /* Read from lower part of data buffer */
1284        if ( left > 0 ){
1285                if ( left < lower ){
1286                        cnt = left;
1287                }else{
1288                        cnt = lower;    /* Read all lower data available */
1289                }
1290                DBG("grtc_hw_copy: COPYING %d from lower\n",cnt);
1291                if ( (tmp=grtc_copy((unsigned short *)pDev->buf, buf, cnt)) != cnt ) {
1292                        /* Failed to copy due to an receive error */
1293                        DBG("grtc_hw_copy(lower): not all in DMA buffer (%d)\n",tot);
1294                        count = tot+tmp;
1295                        ret = -1;
1296                        goto out;
1297                }
1298                buf += cnt;
1299                left -= cnt;
1300        }
1301        ret = count;
1302
1303out:
1304        count = count*2;
1305        /* Update hardware RP pointer to tell hardware about new space available */
1306        if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1307                regs->rp = (rp+count-bufmax);
1308        } else {
1309                regs->rp = rp+count;
1310        }
1311
1312        return ret;
1313}
1314
1315#ifdef DEBUG_ERROR
1316void grtc_log_error(struct grtc_priv *pDev, int err)
1317{
1318        /* Stop Receiver */
1319        *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1320        *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1321        pDev->last_error[pDev->last_error_cnt] = err;
1322        if ( ++pDev->last_error_cnt > 128 )
1323                pDev->last_error_cnt = 0;
1324}
1325#endif
1326
1327/* Read one frame from DMA buffer
1328 *
1329 * Return Values
1330 *  Zero - nothing more to process
1331 *  1 - more to process, no free frames
1332 *  2 - more to process, frame received
1333 *  negative - more to process, frame dropped
1334 */
1335static int process_dma(struct grtc_priv *pDev)
1336{
1337        int ret, err;
1338        int left, total_len;
1339        unsigned char *dst;
1340        struct grtc_frame *frm;
1341
1342        switch( pDev->frame_state ) {
1343                case FRM_STATE_NONE:
1344                DBG2("FRAME_STATE_NONE\n");
1345       
1346                /* Find Start of next frame by searching for 0x01 */
1347                ret = grtc_hw_find_frm(pDev);
1348                if ( ret != 0 ) {
1349                        /* Frame start not found */
1350                        return 0;
1351                }
1352               
1353                /* Start of frame found, Try to copy header */
1354                pDev->frm = NULL;
1355                pDev->frame_state = FRM_STATE_HDR;
1356
1357                case FRM_STATE_HDR:
1358                DBG2("FRAME_STATE_HDR\n");
1359               
1360                /* Wait for all of header to be in place by setting partial to 0 */
1361                ret = grtc_hw_copy(pDev,pDev->hdr,5,0);
1362                if ( ret < 0 ) {
1363                        /* Error copying header, restart scanning for new frame */
1364                        DEBUG_ERR_LOG(pDev,1);
1365                        pDev->stats.err++;
1366                        pDev->stats.err_hdr++;
1367                        DBG("FRAME_STATE_HDR: copying failed %d\n",ret);
1368                        pDev->frame_state = FRM_STATE_NONE;
1369                        return -1;
1370                } else if ( ret != 5 ) {
1371                        DBG("FRAME_STATE_HDR: no header (%d)\n",ret);
1372                        /* Not all bytes available, come back later */
1373                        return 0;
1374                }
1375
1376                /* The complete header has been copied, parse it */
1377                pDev->frmlen = ((*(unsigned short *)&pDev->hdr[2]) & 0x3ff)+1;
1378                if ( pDev->frmlen < 5 ) {
1379                        /* Error: frame length is not correct */
1380                        pDev->stats.err++;
1381                        pDev->stats.err_hdr++;
1382                        DBG("FRAME_STATE_HDR: frame length error: %d\n", pDev->frmlen);
1383                        pDev->frame_state = FRM_STATE_NONE;
1384                        return -1;
1385                }
1386                pDev->frame_state = FRM_STATE_ALLOC;
1387
1388                case FRM_STATE_ALLOC:
1389                DBG2("FRAME_STATE_ALLOC\n");
1390                /* Header has been read, allocate a frame to put payload and header into */
1391               
1392                /* Allocate Frame matching Frame length */
1393                err = 0;
1394                frm = grtc_pool_get_frm(pDev,pDev->frmlen,&err);
1395                if ( !frm ) {
1396                        /* Couldn't find frame  */
1397                        DEBUG_ERR_LOG(pDev,2);
1398                        pDev->stats.dropped++;
1399                        DBG2("No free frames\n");
1400                        if ( err == 0 ){
1401                                /* Frame length exist in pool configuration, but no
1402                                 * frames are available for that frame length.
1403                                 */
1404                                DEBUG_ERR_LOG(pDev,3);
1405                                pDev->stats.dropped_no_buf++;
1406                                return 1;
1407                        } else {
1408                                /* Frame length of incoming frame is larger than the
1409                                 * frame length in any of the configured frame pools.
1410                                 *
1411                                 * This may be because of an corrupt header. We simply
1412                                 * scan for the end of frame marker in the DMA buffer
1413                                 * so we can drop the frame.
1414                                 */
1415                                DEBUG_ERR_LOG(pDev,4);
1416                                pDev->stats.dropped_too_long++;
1417                                pDev->frame_state = FRM_STATE_NONE;
1418                                return -2;
1419                        }
1420                }
1421                frm->len = 5; /* Only header currenlty in frame */
1422
1423                /* Copy Frame Header into frame structure */
1424                *((unsigned char *)&frm->hdr + 0) = pDev->hdr[0];
1425                *((unsigned char *)&frm->hdr + 1) = pDev->hdr[1];
1426                *((unsigned char *)&frm->hdr + 2) = pDev->hdr[2];
1427                *((unsigned char *)&frm->hdr + 3) = pDev->hdr[3];
1428                *((unsigned char *)&frm->hdr + 4) = pDev->hdr[4];
1429
1430                /* Calc Total and Filler byte count in frame */
1431                total_len = pDev->frmlen / 7;
1432                total_len = total_len * 7;
1433                if ( pDev->frmlen != total_len )
1434                        total_len += 7;
1435
1436                pDev->filler = total_len - pDev->frmlen;
1437
1438                pDev->frame_state = FRM_STATE_PAYLOAD;
1439                pDev->frm = frm;
1440
1441                case FRM_STATE_PAYLOAD:
1442                DBG2("FRAME_STATE_PAYLOAD\n");
1443                /* Parts of payload and the complete header has been read */
1444                frm = pDev->frm;
1445
1446                dst = (unsigned char *)&frm->data[frm->len-5];
1447                left = pDev->frmlen-frm->len;
1448
1449                ret = grtc_hw_copy(pDev,dst,left,1);
1450                if ( ret < 0 ) {
1451                        DEBUG_ERR_LOG(pDev,5);
1452                        /* Error copying header, restart scanning for new frame */
1453                        pDev->frame_state = FRM_STATE_NONE;
1454                        frm->next = NULL;
1455                        grtc_pool_add_frms(frm);
1456                        pDev->frm = NULL;
1457                        pDev->stats.err++;
1458                        pDev->stats.err_payload++;
1459                        return -1;
1460                } else if ( ret != left ) {
1461                        /* Not all bytes available, come back later */
1462                        frm->len += ret;
1463                        return 0;
1464                }
1465                frm->len += ret;
1466                pDev->frame_state = FRM_STATE_FILLER;
1467
1468                case FRM_STATE_FILLER:
1469                DBG2("FRAME_STATE_FILLER\n");
1470                /* check filler data */
1471                frm = pDev->frm;
1472
1473                ret = grtc_hw_check_ending(pDev,pDev->filler);
1474                if ( ret != 0 ) {
1475                        /* Error in frame, drop frame */
1476                        DEBUG_ERR_LOG(pDev,6);
1477                        pDev->frame_state = FRM_STATE_NONE;
1478                        frm->next = NULL;
1479                        grtc_pool_add_frms(frm);
1480                        pDev->frm = NULL;
1481                        pDev->stats.err++;
1482                        pDev->stats.err_ending++;
1483                        return -1;
1484                }
1485
1486                /* A complete frame received, put it into received frame queue */
1487                if ( pDev->ready.head ) {
1488                        /* Queue not empty */
1489                        pDev->ready.tail->next = frm;
1490                } else {
1491                        /* Queue empty */
1492                        pDev->ready.head = frm;
1493                }
1494                pDev->ready.tail = frm;
1495                frm->next = NULL;
1496                pDev->ready.cnt++;
1497                pDev->stats.frames_recv++;
1498
1499                pDev->frame_state = FRM_STATE_NONE;
1500                frm->next = NULL;
1501                return 2;
1502
1503#if 0
1504                case FRM_STATE_DROP:
1505                DBG2("FRAME_STATE_DROP\n");
1506                break;
1507#endif
1508
1509                default:
1510                printk("GRTC: internal error\n");
1511                pDev->frame_state = FRM_STATE_NONE;
1512                break;
1513        }
1514       
1515        return 0;
1516}
1517
1518static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1519{
1520        struct grtc_priv *pDev;
1521        struct drvmgr_dev *dev;
1522        rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
1523        unsigned int *data = ioarg->buffer;
1524        int status,frm_len,i,ret;
1525        struct grtc_ioc_buf_params *buf_arg;
1526        struct grtc_ioc_config *cfg;
1527        struct grtc_ioc_hw_status *hwregs;
1528        struct grtc_ioc_pools_setup *pocfg;
1529        struct grtc_ioc_assign_frm_pool *poassign;
1530        struct grtc_frame *frm, *frms;
1531        struct grtc_frame_pool *pool;
1532        struct grtc_list *frmlist;
1533        struct grtc_ioc_stats *stats;
1534        unsigned int mem;
1535       
1536        IRQ_GLOBAL_PREPARE(oldLevel);
1537
1538        FUNCDBG();
1539
1540        if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
1541                return RTEMS_INVALID_NUMBER;
1542        }
1543        pDev = (struct grtc_priv *)dev->priv;
1544
1545        if (!ioarg)
1546                return RTEMS_INVALID_NAME;
1547
1548        ioarg->ioctl_return = 0;
1549        switch(ioarg->command) {
1550                case GRTC_IOC_START:
1551                if ( pDev->running ) {
1552                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1553                }
1554                if ( (status=grtc_start(pDev)) != RTEMS_SUCCESSFUL ){
1555                        return status;
1556                }
1557                /* Register ISR and Unmask interrupt */
1558                drvmgr_interrupt_register(pDev->dev, 0, "grtc", grtc_interrupt, pDev);
1559
1560                /* Read and write are now open... */
1561                break;
1562
1563                case GRTC_IOC_STOP:
1564                if ( !pDev->running ) {
1565                        return RTEMS_RESOURCE_IN_USE;
1566                }
1567                drvmgr_interrupt_unregister(pDev->dev, 0, grtc_interrupt, pDev);
1568                grtc_stop(pDev);
1569                pDev->running = 0;
1570                break;
1571
1572                case GRTC_IOC_ISSTARTED:
1573                if ( !pDev->running ) {
1574                        return RTEMS_RESOURCE_IN_USE;
1575                }
1576                break;
1577
1578                case GRTC_IOC_SET_BLOCKING_MODE:
1579                if ( (unsigned int)data > GRTC_BLKMODE_COMPLETE ) {
1580                        return RTEMS_INVALID_NAME;
1581                }
1582                DBG("GRTC: Set blocking mode: %d\n",(unsigned int)data);
1583                pDev->blocking = (unsigned int)data;
1584                break;
1585
1586                case GRTC_IOC_SET_TIMEOUT:
1587                DBG("GRTC: Timeout: %d\n",(unsigned int)data);
1588                pDev->timeout = (rtems_interval)data;
1589                break;
1590
1591                case GRTC_IOC_SET_BUF_PARAM:
1592                if ( pDev->running ) {
1593                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1594                }
1595
1596                buf_arg = (struct grtc_ioc_buf_params *)data;
1597                if ( !buf_arg ) {
1598                        return RTEMS_INVALID_NAME;
1599                }
1600
1601                DBG("GRTC: IOC_SET_BUF_PARAM: Len: 0x%x, Custom Buffer: 0x%x\n",buf_arg->length,buf_arg->custom_buffer);
1602
1603                /* Check alignment need, skip bit 0 since that bit only indicates remote address or not */
1604                if ( (unsigned int)buf_arg->custom_buffer & (~GRTC_BUF_MASK) & (~0x1) ) {
1605                        return RTEMS_INVALID_NAME;
1606                }
1607
1608                if ( buf_arg->length > 0x100 ){
1609                        DBG("GRTC: Too big buffer requested\n");
1610                        return RTEMS_INVALID_NAME;
1611                }
1612
1613                /* If current buffer allocated by driver we must free it */
1614                if ( !pDev->buf_custom && pDev->buf ){
1615                        free(pDev->_buf);
1616                        pDev->_buf = NULL;
1617                }
1618                pDev->buf = NULL;
1619                pDev->len = buf_arg->length*1024;
1620
1621                if (pDev->len <= 0)
1622                        break;
1623                mem = (unsigned int)buf_arg->custom_buffer;
1624                pDev->buf_custom = mem;
1625
1626                if (mem & 1) {
1627                        /* Remote address given, the address is as the GRTC
1628                         * core looks at it. Translate the base address into
1629                         * an address that the CPU can understand.
1630                         */
1631                        pDev->buf_remote = (void *)(mem & ~0x1);
1632                        drvmgr_translate_check(pDev->dev, DMAMEM_TO_CPU,
1633                                                (void *)pDev->buf_remote,
1634                                                (void **)&pDev->buf,
1635                                                pDev->len);
1636                } else {
1637                        if (mem == 0) {
1638                                pDev->buf = grtc_memalign((~GRTC_ASR_BUFST)+1,pDev->len,&pDev->_buf);
1639                                DBG("grtc_ioctl: SETBUF: new buf: 0x%x(0x%x), Len: %d\n",pDev->buf,pDev->_buf,pDev->len);
1640                                if (!pDev->buf){
1641                                        pDev->len = 0;
1642                                        pDev->buf_custom = 0;
1643                                        pDev->_buf = NULL;
1644                                        pDev->buf_remote = 0;
1645                                        DBG("GRTC: Failed to allocate memory\n");
1646                                        return RTEMS_NO_MEMORY;
1647                                }
1648                        } else{
1649                                pDev->buf = buf_arg->custom_buffer;
1650                        }
1651
1652                        /* Translate into a remote address so that GRTC core
1653                         * on a remote AMBA bus (for example over the PCI bus)
1654                         * gets a valid address
1655                         */
1656                        drvmgr_translate_check(pDev->dev, CPUMEM_TO_DMA,
1657                                                (void *)pDev->buf,
1658                                                (void **)&pDev->buf_remote,
1659                                                pDev->len);
1660                }
1661                break;
1662
1663                case GRTC_IOC_GET_BUF_PARAM:
1664                if ( pDev->running ) {
1665                        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1666                }
1667
1668                buf_arg = (struct grtc_ioc_buf_params *)data;
1669                if ( !buf_arg ) {
1670                        return RTEMS_INVALID_NAME;
1671                }
1672
1673                buf_arg->length = pDev->len >> 10; /* Length in 1kByte blocks */
1674                if ( pDev->buf_custom )
1675                        buf_arg->custom_buffer =(void *)pDev->buf;
1676                else
1677                        buf_arg->custom_buffer = 0; /* Don't reveal internal driver buffer */
1678                break;
1679
1680                case GRTC_IOC_SET_CONFIG:
1681                cfg = (struct grtc_ioc_config *)data;
1682                if ( !cfg ) {
1683                        return RTEMS_INVALID_NAME;
1684                }
1685               
1686                if ( pDev->running ) {
1687                        return RTEMS_RESOURCE_IN_USE;
1688                }
1689
1690                pDev->config = *cfg;
1691                break;
1692
1693                case GRTC_IOC_GET_CONFIG:
1694                cfg = (struct grtc_ioc_config *)data;
1695                if ( !cfg ) {
1696                        return RTEMS_INVALID_NAME;
1697                }
1698
1699                *cfg = pDev->config;
1700                break;
1701
1702                case GRTC_IOC_GET_HW_STATUS:
1703                hwregs = (struct grtc_ioc_hw_status *)data;
1704                if ( !hwregs ) {
1705                        return RTEMS_INVALID_NAME;
1706                }
1707                /* We disable interrupt in order to get a snapshot of the registers */
1708                IRQ_GLOBAL_DISABLE(oldLevel);
1709                hwregs->sir     = READ_REG(&pDev->regs->sir);
1710                hwregs->far     = READ_REG(&pDev->regs->far);
1711                hwregs->clcw1   = READ_REG(&pDev->regs->clcw1);
1712                hwregs->clcw2   = READ_REG(&pDev->regs->clcw2);
1713                hwregs->phir    = READ_REG(&pDev->regs->phir);
1714                hwregs->str     = READ_REG(&pDev->regs->str);
1715                IRQ_GLOBAL_ENABLE(oldLevel);
1716                break;
1717
1718                case GRTC_IOC_GET_STATS:
1719                stats = (struct grtc_ioc_stats *)data;
1720                if ( !stats ) {
1721                        return RTEMS_INVALID_NAME;
1722                }
1723                memcpy(stats,&pDev->stats,sizeof(struct grtc_ioc_stats));
1724                break;
1725
1726                case GRTC_IOC_CLR_STATS:
1727                memset(&pDev->stats,0,sizeof(struct grtc_ioc_stats));
1728                break;
1729               
1730                case GRTC_IOC_SET_MODE:
1731                if ( pDev->running ) {
1732                        return RTEMS_RESOURCE_IN_USE;
1733                }
1734                if ( (int)data == GRTC_MODE_FRAME ) {
1735                        pDev->mode = GRTC_MODE_FRAME;
1736                } else if ( (int)data == GRTC_MODE_RAW ) {
1737                        pDev->mode = GRTC_MODE_RAW;
1738                } else {
1739                        return RTEMS_INVALID_NAME;
1740                }
1741                break;
1742               
1743                case GRTC_IOC_POOLS_SETUP:
1744                if ( pDev->running ) {
1745                        return RTEMS_RESOURCE_IN_USE;
1746                }
1747                pocfg = (struct grtc_ioc_pools_setup *)data;
1748                if ( (pDev->mode != GRTC_MODE_FRAME) || !pocfg ) {
1749                        return RTEMS_INVALID_NAME;
1750                }
1751               
1752                /* Check that list is sorted */
1753                frm_len = 0;
1754                for(i=0;i<pocfg->pool_cnt;i++){
1755                        if ( pocfg->pool_frame_len[i] <= frm_len ) {
1756                                return RTEMS_INVALID_NAME;
1757                        }
1758                        frm_len = pocfg->pool_frame_len[i];
1759                }
1760               
1761                /* Ok, we trust user. The pool descriptions are allocated
1762                 * but not frames, that the user must do self.
1763                 */
1764                if ( pDev->pools ) {
1765                        free(pDev->pools);
1766                }
1767                pDev->pools = malloc(pocfg->pool_cnt * sizeof(struct grtc_frame_pool));
1768                if ( !pDev->pools ) {
1769                        pDev->pool_cnt = 0;
1770                        return RTEMS_NO_MEMORY;
1771                }
1772                pDev->pool_cnt = pocfg->pool_cnt;
1773                for (i=0;i<pocfg->pool_cnt;i++) {
1774                        pDev->pools[i].frame_len = pocfg->pool_frame_len[i];
1775                        pDev->pools[i].frame_cnt = 0;
1776                        pDev->pools[i].frms = NULL;
1777                }
1778                break;
1779
1780                case GRTC_IOC_ASSIGN_FRM_POOL:
1781                if ( pDev->running ) {
1782                        return RTEMS_RESOURCE_IN_USE;
1783                }
1784
1785                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1786                        return RTEMS_INVALID_NAME;
1787                }
1788
1789                poassign = (struct grtc_ioc_assign_frm_pool *)data;
1790                if ( !poassign ) {
1791                        return RTEMS_INVALID_NAME;
1792                }
1793               
1794                /* Find pool to assign the frames to */
1795                pool = NULL;
1796                for(i=0; i<pDev->pool_cnt; i++) {
1797                        if ( pDev->pools[i].frame_len == poassign->frame_len ) {
1798                                pool = &pDev->pools[i];
1799                                break;
1800                        }
1801                }
1802                if ( !pool ) {
1803                        /* No Pool matching frame length */
1804                        return RTEMS_INVALID_NAME;
1805                }
1806               
1807                /* Assign frames to pool */
1808                frm = poassign->frames;
1809                while(frm){
1810                        frm->pool = pool;       /* Assign Frame to pool */
1811                        frm = frm->next;
1812                }
1813                break;
1814
1815                case GRTC_IOC_ADD_BUFF:
1816                frms = (struct grtc_frame *)data;
1817
1818                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1819                        return RTEMS_NOT_DEFINED;
1820                }
1821                if ( !frms ) {
1822                        return RTEMS_INVALID_NAME;
1823                }
1824
1825                /* Add frames to respicative pools */
1826                if ( grtc_pool_add_frms(frms) ) {
1827                        return RTEMS_INVALID_NAME;
1828                }
1829                break;
1830
1831                /* Try to read as much data as possible from DMA area and
1832                 * put it into free frames.
1833                 *
1834                 * If receiver is in stopped mode, let user only read previously
1835                 * received frames.
1836                 */
1837                case GRTC_IOC_RECV:
1838
1839                if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1840                        return RTEMS_NOT_DEFINED;
1841                }
1842
1843                while ( pDev->running && ((ret=process_dma(pDev) == 2) || (ret == -1)) ) {
1844                        /* Frame received or dropped, process next frame */
1845                }
1846
1847                /* Take frames out from ready queue and put them to user */
1848                frmlist = (struct grtc_list *)data;
1849                if ( !frmlist ) {
1850                        return RTEMS_INVALID_NAME;
1851                }
1852
1853                frmlist->head = pDev->ready.head;
1854                frmlist->tail = pDev->ready.tail;
1855                frmlist->cnt = pDev->ready.cnt;
1856               
1857                /* Empty list */
1858                pDev->ready.head = NULL;
1859                pDev->ready.tail = NULL;
1860                pDev->ready.cnt = 0;
1861                break;
1862               
1863                case GRTC_IOC_GET_CLCW_ADR:
1864                if ( !data ) {
1865                        return RTEMS_INVALID_NAME;
1866                }
1867                *data = (unsigned int)&pDev->regs->clcw1;
1868                break;
1869
1870                default:
1871                return RTEMS_NOT_DEFINED;
1872        }
1873        return RTEMS_SUCCESSFUL;
1874}
1875
1876static void grtc_interrupt(void *arg)
1877{
1878        struct grtc_priv *pDev = arg;
1879        struct grtc_regs *regs = pDev->regs;
1880        unsigned int status;
1881
1882        /* Clear interrupt by reading it */
1883        status = READ_REG(&regs->pisr);
1884       
1885        /* Spurious Interrupt? */
1886        if ( !pDev->running )
1887                return;
1888
1889        if ( status & GRTC_INT_OV ){
1890               
1891                /* Stop core (Disable receiver, interrupts), set overrun condition,
1892                 * Flush semaphore if thread waiting for data in grtc_wait_data().
1893                 */
1894                pDev->overrun_condition = 1;
1895
1896                grtc_stop(pDev);
1897
1898                /* No need to handle the reset of interrupts, we are still */
1899                goto out;
1900        }
1901
1902        if ( status & GRTC_INT_CS ){
1903                if ( (pDev->blocking==GRTC_BLKMODE_COMPLETE) && pDev->timeout ){
1904                        /* Signal to thread only if enough data is available */
1905                        if ( pDev->wait_for_nbytes > grtc_data_avail(pDev) ){
1906                                /* Not enough data available */
1907                                goto procceed_processing_interrupts;
1908                        }
1909                       
1910                        /* Enough data is available which means that we should wake
1911                         * up thread sleeping.
1912                         */
1913                }
1914               
1915                /* Disable further CLTUs Stored interrupts, no point until thread waiting for them
1916                 * say it want to wait for more.
1917                 */
1918                regs->imr = READ_REG(&regs->imr) & ~GRTC_INT_CS;
1919               
1920                /* Signal Semaphore to wake waiting thread in read() */
1921                rtems_semaphore_release(pDev->sem_rx);
1922        }
1923       
1924procceed_processing_interrupts:
1925
1926        if ( status & GRTC_INT_CR ){
1927       
1928        }
1929
1930        if ( status & GRTC_INT_FAR ){
1931       
1932        }
1933
1934        if ( status & GRTC_INT_BLO ){
1935       
1936        }
1937
1938        if ( status & GRTC_INT_RFA ){
1939       
1940        }
1941out:
1942        if ( status )
1943                regs->picr = status;
1944}
1945
1946static rtems_device_driver grtc_initialize(
1947  rtems_device_major_number major,
1948  rtems_device_minor_number unused,
1949  void *arg
1950  )
1951{
1952        /* Device Semaphore created with count = 1 */
1953        if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'T', 'C'),
1954                1,
1955                RTEMS_FIFO|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1956                0,
1957                &grtc_dev_sem) != RTEMS_SUCCESSFUL ) {
1958                return RTEMS_INTERNAL_ERROR;
1959        }
1960
1961        return RTEMS_SUCCESSFUL;
1962}
Note: See TracBrowser for help on using the repository browser.