File indexing completed on 2025-05-11 08:24:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <bsp.h>
0031 #include <rtems/libio.h>
0032 #include <stdlib.h>
0033 #include <stdio.h>
0034 #include <string.h>
0035 #include <assert.h>
0036 #include <ctype.h>
0037 #include <rtems/bspIo.h>
0038
0039 #include <drvmgr/drvmgr.h>
0040 #include <grlib/ambapp_bus.h>
0041 #include <grlib/ambapp.h>
0042 #include <grlib/grtc.h>
0043
0044 #include <grlib/grlib_impl.h>
0045
0046
0047
0048
0049
0050
0051 #include <grlib/debug_defs.h>
0052
0053 #ifdef DEBUG_ERROR
0054 #define DEBUG_ERR_LOG(device,error) grtc_log_error(device,error)
0055 #else
0056 #define DEBUG_ERR_LOG(device,error)
0057 #endif
0058
0059
0060 struct grtc_regs {
0061 volatile unsigned int grst;
0062 volatile unsigned int gctrl;
0063 int unused0;
0064 volatile unsigned int sir;
0065 volatile unsigned int far;
0066
0067 volatile unsigned int clcw1;
0068 volatile unsigned int clcw2;
0069 volatile unsigned int phir;
0070 volatile unsigned int cor;
0071
0072 volatile unsigned int str;
0073 volatile unsigned int asr;
0074 volatile unsigned int rp;
0075 volatile unsigned int wp;
0076
0077 int unused1[(0x60-0x34)/4];
0078
0079 volatile unsigned int pimsr;
0080 volatile unsigned int pimr;
0081 volatile unsigned int pisr;
0082 volatile unsigned int pir;
0083 volatile unsigned int imr;
0084 volatile unsigned int picr;
0085 };
0086
0087
0088 #define GRTC_SEB 0x55000000
0089
0090
0091 #define GRTC_GRR_SRST 0x1
0092 #define GRTC_GRR_SRST_BIT 0
0093
0094
0095 #define GRTC_GCR_PSR_BIT 10
0096 #define GRTC_GCR_NRZM_BIT 11
0097 #define GRTC_GCR_PSS_BIT 12
0098
0099 #define GRTC_GCR_PSR (1<<GRTC_GCR_PSR_BIT)
0100 #define GRTC_GCR_NRZM (1<<GRTC_GCR_NRZM_BIT)
0101 #define GRTC_GCR_PSS (1<<GRTC_GCR_PSS_BIT)
0102
0103
0104
0105
0106
0107 #define GRTC_FAR_SCI_BIT 10
0108 #define GRTC_FAR_CSEC_BIT 11
0109 #define GRTC_FAR_CAC_BIT 12
0110 #define GRTC_FAR_SSD_BIT 13
0111
0112 #define GRTC_FAR_SCI (0x7<<GRTC_FAR_SCI_BIT)
0113 #define GRTC_FAR_CSEC (0x7<<GRTC_FAR_CSEC_BIT)
0114 #define GRTC_FAR_CAC (0x3f<<GRTC_FAR_CAC_BIT)
0115 #define GRTC_FAR_SSD (1<<GRTC_FAR_SSD_BIT)
0116
0117
0118
0119 #define GRTC_CLCW_RVAL_BIT 0
0120 #define GRTC_CLCW_RTYPE_BIT 8
0121 #define GRTC_CLCW_FBCO_BIT 9
0122 #define GRTC_CLCW_RTMI_BIT 11
0123 #define GRTC_CLCW_WAIT_BIT 12
0124 #define GRTC_CLCW_LOUT_BIT 13
0125 #define GRTC_CLCW_NBLO_BIT 14
0126 #define GRTC_CLCW_NRFA_BIT 15
0127 #define GRTC_CLCW_VCI_BIT 18
0128 #define GRTC_CLCW_CIE_BIT 24
0129 #define GRTC_CLCW_STAF_BIT 26
0130 #define GRTC_CLCW_VNUM_BIT 29
0131 #define GRTC_CLCW_CWTY_BIT 31
0132
0133 #define GRTC_CLCW_RVAL (0xff<<GRTC_CLCW_RVAL_BIT)
0134 #define GRTC_CLCW_RTYPE (1<<GRTC_CLCW_RTYPE_BIT)
0135 #define GRTC_CLCW_FBCO (0x3<<GRTC_CLCW_FBCO_BIT)
0136 #define GRTC_CLCW_RTMI (0x3<<GRTC_CLCW_RTMI_BIT)
0137 #define GRTC_CLCW_WAIT (1<<GRTC_CLCW_WAIT_BIT)
0138 #define GRTC_CLCW_LOUT (1<<GRTC_CLCW_LOUT_BIT)
0139 #define GRTC_CLCW_NBLO (1<<GRTC_CLCW_NBLO_BIT)
0140 #define GRTC_CLCW_NRFA (1<<GRTC_CLCW_NRFA_BIT)
0141 #define GRTC_CLCW_VCI (0x3f<<GRTC_CLCW_VCI_BIT)
0142 #define GRTC_CLCW_CIE (0x3<<GRTC_CLCW_CIE_BIT)
0143 #define GRTC_CLCW_STAF (0x3<<GRTC_CLCW_STAF_BIT)
0144 #define GRTC_CLCW_VNUM (0x3<<GRTC_CLCW_VNUM_BIT)
0145 #define GRTC_CLCW_CWTY (1<<GRTC_CLCW_CWTY_BIT)
0146
0147
0148 #define GRTC_PIR_BLO_BIT 0
0149 #define GRTC_PIR_RFA_BIT 8
0150
0151 #define GRTC_PIR_BLO (0xff<<GRTC_PIR_BLO_BIT)
0152 #define GRTC_PIR_RFA (0xff<<GRTC_PIR_RFA_BIT)
0153
0154
0155 #define GRTC_COR_RE_BIT 0
0156 #define GRTC_COR_CRST_BIT 9
0157
0158 #define GRTC_COR_RE (1<<GRTC_COR_RE_BIT)
0159 #define GRTC_COR_CRST (1<<GRTC_COR_CRST_BIT)
0160
0161
0162 #define GRTC_STR_CR_BIT 0
0163 #define GRTC_STR_OV_BIT 4
0164 #define GRTC_STR_RFF_BIT 7
0165 #define GRTC_STR_RBF_BIT 10
0166
0167 #define GRTC_STR_CR (1<<GRTC_STR_CR_BIT)
0168 #define GRTC_STR_OV (1<<GRTC_STR_OV_BIT)
0169 #define GRTC_STR_RFF (1<<GRTC_STR_RFF_BIT)
0170 #define GRTC_STR_RBF (1<<GRTC_STR_RBF_BIT)
0171
0172
0173 #define GRTC_ASR_RXLEN_BIT 0
0174 #define GRTC_ASR_BUFST_BIT 10
0175
0176 #define GRTC_ASR_RXLEN (0xff<<GRTC_ASR_RXLEN_BIT)
0177 #define GRTC_ASR_BUFST (0x3fffff<<GRTC_ASR_BUFST_BIT)
0178
0179
0180 #define GRTC_RRP_PTR_BIT 0
0181
0182 #define GRTC_RRP_PTR (0xffffff<<GRTC_RRP_PTR_BIT)
0183
0184
0185 #define GRTC_RWP_PTR_BIT 0
0186
0187 #define GRTC_RWP_PTR (0xffffff<<GRTC_RWP_PTR_BIT)
0188
0189
0190
0191
0192
0193
0194
0195 #define GRTC_INT_RFA_BIT 0
0196 #define GRTC_INT_BLO_BIT 1
0197 #define GRTC_INT_FAR_BIT 2
0198 #define GRTC_INT_CR_BIT 3
0199 #define GRTC_INT_RBF_BIT 4
0200 #define GRTC_INT_OV_BIT 5
0201 #define GRTC_INT_CS_BIT 6
0202
0203 #define GRTC_INT_RFA (1<<GRTC_INT_RFA_BIT)
0204 #define GRTC_INT_BLO (1<<GRTC_INT_BLO_BIT)
0205 #define GRTC_INT_FAR (1<<GRTC_INT_FAR_BIT)
0206 #define GRTC_INT_CR (1<<GRTC_INT_CR_BIT)
0207 #define GRTC_INT_OV (1<<GRTC_INT_OV_BIT)
0208 #define GRTC_INT_CS (1<<GRTC_INT_CS_BIT)
0209
0210 #define GRTC_INT_ALL (GRTC_INT_RFA|GRTC_INT_BLO|GRTC_INT_FAR|GRTC_INT_CR|GRTC_INT_OV|GRTC_INT_CS)
0211
0212 #define READ_REG(address) (*(volatile unsigned int *)address)
0213
0214
0215 static rtems_device_driver grtc_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0216 static rtems_device_driver grtc_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0217 static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0218 static rtems_device_driver grtc_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0219 static rtems_device_driver grtc_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0220 static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0221
0222 #define GRTC_DRIVER_TABLE_ENTRY { grtc_initialize, grtc_open, grtc_close, grtc_read, grtc_write, grtc_ioctl }
0223
0224 static rtems_driver_address_table grtc_driver = GRTC_DRIVER_TABLE_ENTRY;
0225
0226 enum {
0227 FRM_STATE_NONE = 0,
0228 FRM_STATE_HDR = 1,
0229 FRM_STATE_ALLOC = 2,
0230 FRM_STATE_PAYLOAD = 3,
0231 FRM_STATE_FILLER = 4,
0232 FRM_STATE_DROP = 5
0233 };
0234
0235
0236 struct grtc_frame_pool {
0237 unsigned int frame_len;
0238 unsigned int frame_cnt;
0239 struct grtc_frame *frms;
0240 };
0241
0242 struct grtc_priv {
0243 struct drvmgr_dev *dev;
0244 char devName[52];
0245 struct grtc_regs *regs;
0246 int irq;
0247 SPIN_DECLARE(devlock);
0248
0249 int major;
0250 int minor;
0251
0252 int open;
0253 int running;
0254 int mode;
0255 int overrun_condition;
0256 int blocking;
0257 rtems_interval timeout;
0258 int wait_for_nbytes;
0259
0260 struct grtc_ioc_config config;
0261
0262
0263
0264 void *buf;
0265 void *buf_remote;
0266 void *_buf;
0267 int buf_custom;
0268 unsigned int len;
0269
0270
0271
0272 int pool_cnt;
0273 struct grtc_frame_pool *pools;
0274
0275 struct grtc_list ready;
0276
0277
0278 int frame_state;
0279 int filler;
0280 unsigned int hdr[2];
0281 struct grtc_frame *frm;
0282 int frmlen;
0283
0284 struct grtc_ioc_stats stats;
0285
0286 rtems_id sem_rx;
0287
0288 #ifdef DEBUG_ERROR
0289
0290 unsigned int rp;
0291 unsigned int wp;
0292
0293
0294 int last_error[128];
0295 int last_error_cnt;
0296 #endif
0297 };
0298
0299
0300 static void grtc_hw_reset(struct grtc_priv *priv);
0301 static void grtc_interrupt(void *arg);
0302
0303
0304 static rtems_id grtc_dev_sem;
0305 static int grtc_driver_io_registered = 0;
0306 static rtems_device_major_number grtc_driver_io_major = 0;
0307
0308
0309
0310
0311 static int grtc_register_io(rtems_device_major_number *m);
0312 static int grtc_device_init(struct grtc_priv *pDev);
0313
0314 static int grtc_init2(struct drvmgr_dev *dev);
0315 static int grtc_init3(struct drvmgr_dev *dev);
0316
0317 static struct drvmgr_drv_ops grtc_ops =
0318 {
0319 {NULL, grtc_init2, grtc_init3, NULL},
0320 NULL,
0321 NULL,
0322 };
0323
0324 static struct amba_dev_id grtc_ids[] =
0325 {
0326 {VENDOR_GAISLER, GAISLER_GRTC},
0327 {0, 0}
0328 };
0329
0330 static struct amba_drv_info grtc_drv_info =
0331 {
0332 {
0333 DRVMGR_OBJ_DRV,
0334 NULL,
0335 NULL,
0336 DRIVER_AMBAPP_GAISLER_GRTC_ID,
0337 "GRTC_DRV",
0338 DRVMGR_BUS_TYPE_AMBAPP,
0339 &grtc_ops,
0340 NULL,
0341 0,
0342 sizeof(struct grtc_priv),
0343 },
0344 &grtc_ids[0]
0345 };
0346
0347 void grtc_register_drv (void)
0348 {
0349 DBG("Registering GRTC driver\n");
0350 drvmgr_drv_register(&grtc_drv_info.general);
0351 }
0352
0353 static int grtc_init2(struct drvmgr_dev *dev)
0354 {
0355 struct grtc_priv *priv;
0356
0357 DBG("GRTC[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0358 priv = dev->priv;
0359 if ( !priv )
0360 return DRVMGR_NOMEM;
0361 priv->dev = dev;
0362
0363
0364
0365 return DRVMGR_OK;
0366 }
0367
0368 static int grtc_init3(struct drvmgr_dev *dev)
0369 {
0370 struct grtc_priv *priv;
0371 char prefix[32];
0372 rtems_status_code status;
0373
0374 priv = dev->priv;
0375
0376
0377
0378 if ( grtc_driver_io_registered == 0) {
0379
0380 if ( grtc_register_io(&grtc_driver_io_major) ) {
0381
0382 dev->priv = NULL;
0383 return DRVMGR_FAIL;
0384 }
0385
0386 grtc_driver_io_registered = 1;
0387 }
0388
0389
0390
0391
0392 if ( grtc_device_init(priv) ) {
0393 return DRVMGR_FAIL;
0394 }
0395
0396
0397 prefix[0] = '\0';
0398 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0399
0400
0401
0402 sprintf(priv->devName, "/dev/grtc%d", dev->minor_drv);
0403 } else {
0404
0405
0406
0407 sprintf(priv->devName, "/dev/%sgrtc%d", prefix, dev->minor_bus);
0408 }
0409
0410 SPIN_INIT(&priv->devlock, priv->devName);
0411
0412
0413 status = rtems_io_register_name(priv->devName, grtc_driver_io_major, dev->minor_drv);
0414 if (status != RTEMS_SUCCESSFUL) {
0415 return DRVMGR_FAIL;
0416 }
0417
0418 return DRVMGR_OK;
0419 }
0420
0421
0422
0423 static int grtc_register_io(rtems_device_major_number *m)
0424 {
0425 rtems_status_code r;
0426
0427 if ((r = rtems_io_register_driver(0, &grtc_driver, m)) == RTEMS_SUCCESSFUL) {
0428 DBG("GRTC driver successfully registered, major: %d\n", *m);
0429 } else {
0430 switch(r) {
0431 case RTEMS_TOO_MANY:
0432 printk("GRTC rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
0433 return -1;
0434 case RTEMS_INVALID_NUMBER:
0435 printk("GRTC rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
0436 return -1;
0437 case RTEMS_RESOURCE_IN_USE:
0438 printk("GRTC rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
0439 return -1;
0440 default:
0441 printk("GRTC rtems_io_register_driver failed\n");
0442 return -1;
0443 }
0444 }
0445 return 0;
0446 }
0447
0448 static int grtc_device_init(struct grtc_priv *pDev)
0449 {
0450 struct amba_dev_info *ambadev;
0451 struct ambapp_core *pnpinfo;
0452
0453
0454 ambadev = (struct amba_dev_info *)pDev->dev->businfo;
0455 if ( ambadev == NULL ) {
0456 return -1;
0457 }
0458 pnpinfo = &ambadev->info;
0459 pDev->irq = pnpinfo->irq;
0460 pDev->regs = (struct grtc_regs *)pnpinfo->ahb_slv->start[0];
0461 pDev->minor = pDev->dev->minor_drv;
0462 pDev->open = 0;
0463 pDev->running = 0;
0464
0465
0466 if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'C', '0' + pDev->minor),
0467 0,
0468 RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
0469 RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
0470 0,
0471 &pDev->sem_rx) != RTEMS_SUCCESSFUL ) {
0472 return -1;
0473 }
0474
0475
0476 grtc_hw_reset(pDev);
0477
0478 return 0;
0479 }
0480
0481 static void grtc_hw_reset(struct grtc_priv *priv)
0482 {
0483
0484 priv->regs->grst = GRTC_SEB | GRTC_GRR_SRST;
0485 }
0486
0487 static void grtc_hw_get_defaults(struct grtc_priv *pDev, struct grtc_ioc_config *config)
0488 {
0489 unsigned int gcr = READ_REG(&pDev->regs->gctrl);
0490
0491 config->psr_enable = (gcr & GRTC_GCR_PSR) ? 1:0;
0492 config->nrzm_enable = (gcr & GRTC_GCR_NRZM) ? 1:0;
0493 config->pss_enable = (gcr & GRTC_GCR_PSS) ? 1:0;
0494
0495 config->crc_calc = 0;
0496 }
0497
0498
0499 static int __inline__ grtc_hw_data_avail_upper(unsigned int rrp, unsigned rwp, unsigned int bufsize)
0500 {
0501 if ( rrp == rwp )
0502 return 0;
0503
0504 if ( rwp > rrp ) {
0505 return rwp-rrp;
0506 }
0507
0508 return (bufsize-rrp);
0509 }
0510
0511
0512 static int __inline__ grtc_hw_data_avail_lower(unsigned int rrp, unsigned rwp, unsigned int bufsize)
0513 {
0514 if ( rrp == rwp )
0515 return 0;
0516
0517 if ( rwp > rrp ) {
0518 return 0;
0519 }
0520
0521 return rwp;
0522 }
0523
0524
0525 static int __inline__ grtc_hw_data_avail(unsigned int rrp, unsigned rwp, unsigned int bufsize)
0526 {
0527 if ( rrp == rwp )
0528 return 0;
0529
0530 if ( rwp > rrp ) {
0531 return rwp-rrp;
0532 }
0533
0534 return rwp+(bufsize-rrp);
0535 }
0536
0537
0538
0539
0540 static int grtc_hw_read_try(struct grtc_priv *pDev, char *buf, int max)
0541 {
0542 struct grtc_regs *regs = pDev->regs;
0543 unsigned int rp, wp, asr, bufmax, rrp, rwp;
0544 unsigned int upper, lower;
0545 unsigned int count, cnt, left;
0546
0547 FUNCDBG();
0548
0549 if ( max < 1 )
0550 return 0;
0551
0552 rp = READ_REG(®s->rp);
0553 asr = READ_REG(®s->asr);
0554 bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
0555 bufmax = (bufmax+1) << 10;
0556 wp = READ_REG(®s->wp);
0557
0558
0559 rrp = rp - (asr & GRTC_ASR_BUFST);
0560 rwp = wp - (asr & GRTC_ASR_BUFST);
0561
0562 lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
0563 upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
0564
0565 DBG("grtc_hw_read_try: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
0566 DBG("grtc_hw_read_try: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
0567 rp,rrp,wp,rwp,bufmax,pDev->buffer);
0568
0569 if ( (upper+lower) == 0 )
0570 return 0;
0571
0572
0573 count = (upper+lower) > max ? max : (upper+lower);
0574 left = count;
0575
0576
0577 if ( upper > 0 ){
0578 if ( left < upper ){
0579 cnt = left;
0580 }else{
0581 cnt = upper;
0582 }
0583 DBG("grtc_hw_read_try: COPYING %d from upper\n",cnt);
0584
0585 memcpy(buf, (void *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf), cnt);
0586 buf += cnt;
0587 left -= cnt;
0588 }
0589
0590
0591 if ( left > 0 ){
0592 if ( left < lower ){
0593 cnt = left;
0594 }else{
0595 cnt = lower;
0596 }
0597 DBG("grtc_hw_read_try: COPYING %d from lower\n",cnt);
0598 memcpy(buf, (void *)pDev->buf, cnt);
0599 buf += cnt;
0600 left -= cnt;
0601 }
0602
0603
0604 if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
0605 regs->rp = (rp+count-bufmax);
0606 } else {
0607 regs->rp = rp+count;
0608 }
0609
0610 return count;
0611 }
0612
0613
0614
0615
0616 static int grtc_data_avail(struct grtc_priv *pDev)
0617 {
0618 unsigned int rp, wp, asr, bufmax, rrp, rwp;
0619 struct grtc_regs *regs = pDev->regs;
0620
0621 FUNCDBG();
0622
0623 rp = READ_REG(®s->rp);
0624 asr = READ_REG(®s->asr);
0625 bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
0626 bufmax = (bufmax+1) << 10;
0627 wp = READ_REG(®s->wp);
0628
0629
0630 rrp = rp - (asr & GRTC_ASR_BUFST);
0631 rwp = wp - (asr & GRTC_ASR_BUFST);
0632
0633 return grtc_hw_data_avail(rrp,rwp,bufmax);
0634 }
0635
0636 static void *grtc_memalign(unsigned int boundary, unsigned int length, void *realbuf)
0637 {
0638 *(int *)realbuf = (int)grlib_malloc(length+(~GRTC_ASR_BUFST)+1);
0639 DBG("GRTC: Alloced %d (0x%x) bytes, requested: %d\n",length+(~GRTC_ASR_BUFST)+1,length+(~GRTC_ASR_BUFST)+1,length);
0640 return (void *)(((*(unsigned int *)realbuf)+(~GRTC_ASR_BUFST)+1) & ~(boundary-1));
0641 }
0642
0643 static int grtc_start(struct grtc_priv *pDev)
0644 {
0645 struct grtc_regs *regs = pDev->regs;
0646 unsigned int tmp;
0647
0648 if ( !pDev->buf || (((unsigned int)pDev->buf & ~GRTC_ASR_BUFST) != 0) ||
0649 (pDev->len>(1024*0x100)) || (pDev->len<1024) || ((pDev->len & (1024-1)) != 0)
0650 ) {
0651 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)));
0652 return RTEMS_NO_MEMORY;
0653 }
0654
0655 memset(pDev->buf,0,pDev->len);
0656
0657
0658 pDev->overrun_condition = 0;
0659 #ifdef DEBUG_ERROR
0660 pDev->last_error_cnt = 0;
0661 memset(&pDev->last_error[0],0,128*sizeof(int));
0662 #endif
0663 memset(&pDev->stats,0,sizeof(struct grtc_ioc_stats));
0664
0665
0666 regs->cor = GRTC_SEB | GRTC_COR_CRST;
0667 if ( READ_REG(®s->cor) & GRTC_COR_CRST ){
0668
0669 DBG("GRTC: start: Reseting receiver failed\n");
0670 return RTEMS_IO_ERROR;
0671 }
0672
0673
0674
0675
0676
0677 rtems_semaphore_obtain(pDev->sem_rx, RTEMS_NO_WAIT, 0);
0678
0679
0680 tmp = 0;
0681 if ( pDev->config.psr_enable )
0682 tmp |= GRTC_GCR_PSR;
0683 if ( pDev->config.nrzm_enable )
0684 tmp |= GRTC_GCR_NRZM;
0685 if ( pDev->config.pss_enable )
0686 tmp |= GRTC_GCR_PSS;
0687 regs->gctrl = GRTC_SEB | tmp;
0688
0689
0690 tmp = READ_REG(®s->pir);
0691 regs->picr = GRTC_INT_ALL;
0692
0693
0694 regs->imr = GRTC_INT_OV;
0695
0696
0697
0698
0699
0700 regs->asr = (unsigned int)pDev->buf_remote | ((pDev->len>>10)-1);
0701 regs->rp = (unsigned int)pDev->buf_remote;
0702
0703
0704
0705
0706
0707 pDev->running = 1;
0708
0709
0710 regs->cor = GRTC_SEB | GRTC_COR_RE;
0711
0712 DBG("GRTC: STARTED\n");
0713
0714 return 0;
0715 }
0716
0717 static void grtc_stop(struct grtc_priv *pDev, int overrun)
0718 {
0719 struct grtc_regs *regs = pDev->regs;
0720 SPIN_IRQFLAGS(irqflags);
0721
0722 SPIN_LOCK_IRQ(&pDev->devlock, irqflags);
0723
0724
0725 regs->cor = GRTC_SEB;
0726
0727
0728 regs->imr = 0;
0729 READ_REG(®s->pir);
0730 regs->picr = GRTC_INT_ALL;
0731
0732 DBG("GRTC: STOPPED\n");
0733
0734 if (overrun) {
0735 pDev->overrun_condition = 1;
0736 } else {
0737 pDev->running = 0;
0738 }
0739
0740 SPIN_UNLOCK_IRQ(&pDev->devlock, irqflags);
0741
0742
0743 rtems_semaphore_flush(pDev->sem_rx);
0744 }
0745
0746
0747
0748
0749 static int grtc_wait_data(struct grtc_priv *pDev, int count, rtems_interval timeout)
0750 {
0751 int avail;
0752 int ret;
0753 SPIN_IRQFLAGS(irqflags);
0754
0755 FUNCDBG();
0756
0757 if ( count < 1 )
0758 return 0;
0759
0760 SPIN_LOCK_IRQ(&pDev->devlock, irqflags);
0761
0762
0763
0764
0765 pDev->regs->picr = GRTC_INT_CS;
0766 pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRTC_INT_CS;
0767
0768 avail = grtc_data_avail(pDev);
0769 if ( avail < count ) {
0770
0771
0772 SPIN_UNLOCK_IRQ(&pDev->devlock, irqflags);
0773
0774 if ( timeout == 0 ){
0775 timeout = RTEMS_NO_TIMEOUT;
0776 }
0777 ret = rtems_semaphore_obtain(pDev->sem_rx,RTEMS_WAIT,timeout);
0778
0779
0780
0781
0782
0783
0784 SPIN_LOCK_IRQ(&pDev->devlock, irqflags);
0785 }else{
0786 ret = RTEMS_SUCCESSFUL;
0787 }
0788
0789
0790 pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRTC_INT_CS;
0791
0792 SPIN_UNLOCK_IRQ(&pDev->devlock, irqflags);
0793
0794 return ret;
0795 }
0796
0797 static rtems_device_driver grtc_open(
0798 rtems_device_major_number major,
0799 rtems_device_minor_number minor,
0800 void *arg)
0801 {
0802 struct grtc_priv *pDev;
0803 struct drvmgr_dev *dev;
0804
0805 FUNCDBG();
0806
0807 if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
0808 DBG("Wrong minor %d\n", minor);
0809 return RTEMS_INVALID_NUMBER;
0810 }
0811 pDev = (struct grtc_priv *)dev->priv;
0812
0813
0814 if ( rtems_semaphore_obtain(grtc_dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) != RTEMS_SUCCESSFUL ){
0815 return RTEMS_INTERNAL_ERROR;
0816 }
0817
0818
0819 if ( pDev->open ){
0820 rtems_semaphore_release(grtc_dev_sem);
0821 return RTEMS_RESOURCE_IN_USE;
0822 }
0823
0824
0825 pDev->open = 1;
0826
0827 rtems_semaphore_release(grtc_dev_sem);
0828
0829 DBG("grtc_open: OPENED minor %d (pDev: 0x%x)\n",pDev->minor,(unsigned int)pDev);
0830
0831
0832 pDev->buf = NULL;
0833 pDev->_buf = NULL;
0834 pDev->buf_custom = 0;
0835 pDev->buf_remote = 0;
0836 pDev->len = 0;
0837 pDev->timeout = 0;
0838 pDev->blocking = 0;
0839 pDev->mode = GRTC_MODE_RAW;
0840 pDev->ready.head = NULL;
0841 pDev->ready.tail = NULL;
0842 pDev->ready.cnt = 0;
0843
0844 pDev->running = 0;
0845 pDev->overrun_condition = 0;
0846
0847 memset(&pDev->config,0,sizeof(pDev->config));
0848
0849
0850
0851
0852 grtc_hw_get_defaults(pDev,&pDev->config);
0853
0854 return RTEMS_SUCCESSFUL;
0855 }
0856
0857 static rtems_device_driver grtc_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0858 {
0859 struct grtc_priv *pDev;
0860 struct drvmgr_dev *dev;
0861
0862 FUNCDBG();
0863
0864 if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
0865 return RTEMS_INVALID_NUMBER;
0866 }
0867 pDev = (struct grtc_priv *)dev->priv;
0868
0869 if ( pDev->running ){
0870 grtc_stop(pDev, 0);
0871 }
0872
0873
0874 grtc_hw_reset(pDev);
0875
0876
0877 pDev->open = 0;
0878
0879 return RTEMS_SUCCESSFUL;
0880 }
0881
0882 static rtems_device_driver grtc_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0883 {
0884 struct grtc_priv *pDev;
0885 struct drvmgr_dev *dev;
0886 int count;
0887 int left;
0888 int timedout;
0889 int err;
0890 rtems_interval timeout;
0891 rtems_libio_rw_args_t *rw_args;
0892
0893 FUNCDBG();
0894
0895 if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
0896 return RTEMS_INVALID_NUMBER;
0897 }
0898 pDev = (struct grtc_priv *)dev->priv;
0899
0900 if ( !pDev->running && !pDev->overrun_condition ) {
0901 return RTEMS_RESOURCE_IN_USE;
0902 }
0903
0904 if ( pDev->mode != GRTC_MODE_RAW ) {
0905 return RTEMS_NOT_DEFINED;
0906 }
0907
0908 rw_args = (rtems_libio_rw_args_t *) arg;
0909 left = rw_args->count;
0910 timedout = 0;
0911 timeout = pDev->timeout;
0912
0913 read_from_buffer:
0914
0915 count = grtc_hw_read_try(pDev,rw_args->buffer,left);
0916
0917 left -= count;
0918
0919 DBG("READ %d bytes from DMA, left: %d\n",count,left);
0920
0921 if ( !timedout && !pDev->overrun_condition && ((count < 1) || ((count < rw_args->count) && (pDev->blocking == GRTC_BLKMODE_COMPLETE))) ){
0922
0923
0924
0925
0926 if ( pDev->blocking ) {
0927 if ( (err=grtc_wait_data(pDev,left,timeout)) != RTEMS_SUCCESSFUL ){
0928
0929 if ( err == RTEMS_TIMEOUT ){
0930
0931 timedout = 1;
0932 goto read_from_buffer;
0933 }
0934 return err;
0935 }
0936 goto read_from_buffer;
0937 }
0938
0939 return RTEMS_TIMEOUT;
0940 }
0941
0942
0943
0944 DBG("READ returning %d bytes, left: %d\n",rw_args->count-left,left);
0945
0946 rw_args->bytes_moved = rw_args->count - left;
0947 if ( rw_args->bytes_moved == 0 ) {
0948 if ( pDev->overrun_condition ) {
0949
0950
0951
0952 return RTEMS_IO_ERROR;
0953 }
0954 return RTEMS_TIMEOUT;
0955 }
0956
0957 return RTEMS_SUCCESSFUL;
0958 }
0959
0960 static rtems_device_driver grtc_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0961 {
0962 FUNCDBG();
0963 return RTEMS_NOT_IMPLEMENTED;
0964 }
0965
0966 static int grtc_pool_add_frms(struct grtc_frame *frms)
0967 {
0968 struct grtc_frame *frm, *next;
0969
0970
0971 frm = frms;
0972 while(frm){
0973
0974 if ( !frm->pool ) {
0975
0976 DBG("GRTC: Frame not assigned to a pool\n");
0977 return -1;
0978 }
0979 next = frm->next;
0980
0981 DBG("GRTC: adding frame 0x%x to pool %d (%d)\n",frm,frm->pool->frame_len,frm->pool->frame_cnt);
0982
0983
0984 frm->next = frm->pool->frms;
0985 frm->pool->frms = frm;
0986 frm->pool->frame_cnt++;
0987
0988 frm = next;
0989 }
0990
0991 return 0;
0992 }
0993
0994 static struct grtc_frame *grtc_pool_get_frm(struct grtc_priv *pDev, int frame_len, int *error)
0995 {
0996 struct grtc_frame *frm;
0997 struct grtc_frame_pool *pool;
0998 int i;
0999
1000
1001
1002
1003 pool = pDev->pools;
1004 for (i=0; i<pDev->pool_cnt; i++,pool++) {
1005 if ( pool->frame_len >= frame_len ) {
1006
1007 frm = pool->frms;
1008 if ( !frm ) {
1009
1010
1011
1012
1013
1014
1015 #if 0
1016 if ( error )
1017 *error = 0;
1018 return 0;
1019 #endif
1020 continue;
1021 }
1022
1023
1024
1025
1026 pool->frms = frm->next;
1027 pool->frame_cnt--;
1028 return frm;
1029 }
1030 }
1031
1032 if ( error )
1033 *error = 1;
1034
1035
1036 return NULL;
1037 }
1038
1039
1040
1041
1042 static int grtc_scan(unsigned short *src, int max, unsigned char pattern, int *found)
1043 {
1044 unsigned short tmp = 0;
1045 unsigned int left = max;
1046
1047 while ( (left>1) && (((tmp=*src) & 0x00ff) != pattern) ) {
1048 src++;
1049 left-=2;
1050 }
1051 if ( (tmp & 0xff) == pattern ) {
1052 *found = 1;
1053 } else {
1054 *found = 0;
1055 }
1056 return max-left;
1057 }
1058
1059 static int grtc_copy(unsigned short *src, unsigned char *buf, int cnt)
1060 {
1061 unsigned short tmp;
1062 int left = cnt;
1063
1064 while ( (left>0) && ((((tmp=*src) & 0x00ff) == 0x00) || ((tmp & 0x00ff) == 0x01)) ) {
1065 *buf++ = tmp>>8;
1066 src++;
1067 left--;
1068 }
1069
1070 return cnt-left;
1071 }
1072
1073
1074 static int grtc_hw_find_frm(struct grtc_priv *pDev)
1075 {
1076 struct grtc_regs *regs = pDev->regs;
1077 unsigned int rp, wp, asr, bufmax, rrp, rwp;
1078 unsigned int upper, lower;
1079 unsigned int count, cnt;
1080 int found;
1081
1082 FUNCDBG();
1083
1084 rp = READ_REG(®s->rp);
1085 asr = READ_REG(®s->asr);
1086 wp = READ_REG(®s->wp);
1087
1088
1089
1090
1091 if ( rp != wp ) {
1092
1093 if ( ((*(unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf)) & 0x00ff) == 0x01 ) {
1094 return 0;
1095 }
1096 }
1097
1098 bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1099 bufmax = (bufmax+1) << 10;
1100
1101
1102 rrp = rp - (asr & GRTC_ASR_BUFST);
1103 rwp = wp - (asr & GRTC_ASR_BUFST);
1104
1105 lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1106 upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1107
1108 DBG("grtc_hw_find_frm: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1109 DBG("grtc_hw_find_frm: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1110 rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1111
1112 if ( (upper+lower) == 0 )
1113 return 1;
1114
1115
1116 count = 0;
1117 found = 0;
1118
1119
1120 if ( upper > 0 ){
1121 cnt = grtc_scan((unsigned short *)((rp - (unsigned int)pDev->buf_remote) + (unsigned int)pDev->buf), upper, 0x01, &found);
1122 count = cnt;
1123 if ( found ) {
1124 DBG("grtc_hw_find_frm: SCANNED upper %d bytes until found\n",cnt);
1125 goto out;
1126 }
1127
1128 DBG("grtc_hw_find_frm: SCANNED all upper %d bytes, not found\n",cnt);
1129 }
1130
1131
1132 if ( lower > 0 ){
1133 cnt = grtc_scan((unsigned short *)pDev->buf, lower, 0x01, &found);
1134 count += cnt;
1135
1136 if ( found ) {
1137 DBG("grtc_hw_find_frm: SCANNED lower %d bytes until found\n",cnt);
1138 goto out;
1139 }
1140
1141 DBG("grtc_hw_find_frm: SCANNED all lower %d bytes, not found\n",cnt);
1142 }
1143
1144 out:
1145
1146 if ( count > 0 ) {
1147 if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1148 regs->rp = (rp+count-bufmax);
1149 } else {
1150 regs->rp = rp+count;
1151 }
1152 }
1153 if ( found )
1154 return 0;
1155 return 1;
1156
1157 }
1158
1159 static int grtc_check_ending(unsigned short *src, int max, int end)
1160 {
1161 while ( max > 0 ) {
1162
1163 if ( *src != 0x5500 ) {
1164
1165 return -1;
1166 }
1167 src++;
1168 max-=2;
1169 }
1170
1171
1172 if ( end ) {
1173 if ( (*src & 0x00ff) != 0x02 ) {
1174 return -1;
1175 }
1176 }
1177
1178 return 0;
1179 }
1180
1181 static int grtc_hw_check_ending(struct grtc_priv *pDev, int max)
1182 {
1183 struct grtc_regs *regs = pDev->regs;
1184 unsigned int rp, wp, asr, bufmax, rrp, rwp;
1185 unsigned int upper, lower;
1186 unsigned int count, cnt, left;
1187
1188 FUNCDBG();
1189
1190 if ( max < 1 )
1191 return 0;
1192 max = max*2;
1193 max += 2;
1194
1195 rp = READ_REG(®s->rp);
1196 asr = READ_REG(®s->asr);
1197 bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1198 bufmax = (bufmax+1) << 10;
1199 wp = READ_REG(®s->wp);
1200
1201
1202 rrp = rp - (asr & GRTC_ASR_BUFST);
1203 rwp = wp - (asr & GRTC_ASR_BUFST);
1204
1205 lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax);
1206 upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax);
1207
1208 DBG("grtc_hw_check_ending: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1209 DBG("grtc_hw_check_ending: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1210 rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1211
1212 if ( (upper+lower) < max )
1213 return 0;
1214
1215
1216 count = max;
1217 left = count;
1218
1219
1220 if ( upper > 0 ){
1221 if ( left <= upper ){
1222 cnt = left;
1223 if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt-2, 1) ) {
1224 return -1;
1225 }
1226 }else{
1227 cnt = upper;
1228 if ( grtc_check_ending((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), cnt, 0) ) {
1229 return -1;
1230 }
1231 }
1232 left -= cnt;
1233 }
1234
1235
1236 if ( left > 0 ){
1237 cnt = left;
1238 if ( grtc_check_ending((unsigned short *)pDev->buf, cnt-2, 1) ) {
1239 return -1;
1240 }
1241 left -= cnt;
1242 }
1243
1244
1245 if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1246 regs->rp = (rp+count-bufmax);
1247 } else {
1248 regs->rp = rp+count;
1249 }
1250
1251 return 0;
1252 }
1253
1254
1255
1256
1257 static int grtc_hw_copy(struct grtc_priv *pDev, unsigned char *buf, int max, int partial)
1258 {
1259 struct grtc_regs *regs = pDev->regs;
1260 unsigned int rp, wp, asr, bufmax, rrp, rwp;
1261 unsigned int upper, lower;
1262 unsigned int count, cnt, left;
1263 int ret, tot, tmp;
1264
1265 FUNCDBG();
1266
1267 if ( max < 1 )
1268 return 0;
1269
1270 rp = READ_REG(®s->rp);
1271 asr = READ_REG(®s->asr);
1272 bufmax = (asr & GRTC_ASR_RXLEN) >> GRTC_ASR_RXLEN_BIT;
1273 bufmax = (bufmax+1) << 10;
1274 wp = READ_REG(®s->wp);
1275
1276
1277 rrp = rp - (asr & GRTC_ASR_BUFST);
1278 rwp = wp - (asr & GRTC_ASR_BUFST);
1279
1280 lower = grtc_hw_data_avail_lower(rrp,rwp,bufmax) >> 1;
1281 upper = grtc_hw_data_avail_upper(rrp,rwp,bufmax) >> 1;
1282
1283 DBG("grtc_hw_copy: AVAIL: Lower: %d, Upper: %d\n",lower,upper);
1284 DBG("grtc_hw_copy: rp: 0x%x, rrp: 0x%x, wp: 0x%x, rwp: 0x%x, bufmax: %d\n, start: 0x%x\n",
1285 rp,rrp,wp,rwp,bufmax,pDev->buf_remote);
1286
1287 if ( (upper+lower) == 0 || (!partial && ((upper+lower)<max) ) )
1288 return 0;
1289
1290
1291 count = (upper+lower) > max ? max : (upper+lower);
1292 left = count;
1293 tot = 0;
1294
1295
1296 if ( upper > 0 ){
1297 if ( left < upper ){
1298 cnt = left;
1299 }else{
1300 cnt = upper;
1301 }
1302 DBG("grtc_hw_copy: COPYING %d from upper\n",cnt);
1303 if ( (tot=grtc_copy((unsigned short *)((rp-(unsigned int)pDev->buf_remote)+(unsigned int)pDev->buf), buf, cnt)) != cnt ) {
1304
1305 DBG("grtc_hw_copy(upper): not all in DMA buffer (%d)\n",tot);
1306 count = tot;
1307 ret = -1;
1308 goto out;
1309 }
1310 buf += cnt;
1311 left -= cnt;
1312 }
1313
1314
1315 if ( left > 0 ){
1316 if ( left < lower ){
1317 cnt = left;
1318 }else{
1319 cnt = lower;
1320 }
1321 DBG("grtc_hw_copy: COPYING %d from lower\n",cnt);
1322 if ( (tmp=grtc_copy((unsigned short *)pDev->buf, buf, cnt)) != cnt ) {
1323
1324 DBG("grtc_hw_copy(lower): not all in DMA buffer (%d)\n",tot);
1325 count = tot+tmp;
1326 ret = -1;
1327 goto out;
1328 }
1329 buf += cnt;
1330 left -= cnt;
1331 }
1332 ret = count;
1333
1334 out:
1335 count = count*2;
1336
1337 if ( (rp+count) >= ((asr&GRTC_ASR_BUFST)+bufmax) ){
1338 regs->rp = (rp+count-bufmax);
1339 } else {
1340 regs->rp = rp+count;
1341 }
1342
1343 return ret;
1344 }
1345
1346 #ifdef DEBUG_ERROR
1347 void grtc_log_error(struct grtc_priv *pDev, int err)
1348 {
1349
1350 *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1351 *(volatile unsigned int *)&pDev->regs->cor = 0x55000000;
1352 pDev->last_error[pDev->last_error_cnt] = err;
1353 if ( ++pDev->last_error_cnt > 128 )
1354 pDev->last_error_cnt = 0;
1355 }
1356 #endif
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366 static int process_dma(struct grtc_priv *pDev)
1367 {
1368 int ret, err;
1369 int left, total_len;
1370 unsigned char *dst;
1371 struct grtc_frame *frm;
1372
1373 switch( pDev->frame_state ) {
1374 case FRM_STATE_NONE:
1375 DBG2("FRAME_STATE_NONE\n");
1376
1377
1378 ret = grtc_hw_find_frm(pDev);
1379 if ( ret != 0 ) {
1380
1381 return 0;
1382 }
1383
1384
1385 pDev->frm = NULL;
1386 pDev->frame_state = FRM_STATE_HDR;
1387
1388
1389 case FRM_STATE_HDR:
1390 DBG2("FRAME_STATE_HDR\n");
1391
1392
1393 ret = grtc_hw_copy(pDev, (unsigned char *)pDev->hdr, 5, 0);
1394 if ( ret < 0 ) {
1395
1396 DEBUG_ERR_LOG(pDev,1);
1397 pDev->stats.err++;
1398 pDev->stats.err_hdr++;
1399 DBG("FRAME_STATE_HDR: copying failed %d\n",ret);
1400 pDev->frame_state = FRM_STATE_NONE;
1401 return -1;
1402 } else if ( ret != 5 ) {
1403 DBG("FRAME_STATE_HDR: no header (%d)\n",ret);
1404
1405 return 0;
1406 }
1407
1408
1409 pDev->frmlen = (((unsigned short *)pDev->hdr)[1] & 0x3ff)+1;
1410 if ( pDev->frmlen < 5 ) {
1411
1412 pDev->stats.err++;
1413 pDev->stats.err_hdr++;
1414 DBG("FRAME_STATE_HDR: frame length error: %d\n", pDev->frmlen);
1415 pDev->frame_state = FRM_STATE_NONE;
1416 return -1;
1417 }
1418 pDev->frame_state = FRM_STATE_ALLOC;
1419
1420
1421 case FRM_STATE_ALLOC:
1422 DBG2("FRAME_STATE_ALLOC\n");
1423
1424
1425
1426 err = 0;
1427 frm = grtc_pool_get_frm(pDev,pDev->frmlen,&err);
1428 if ( !frm ) {
1429
1430 DEBUG_ERR_LOG(pDev,2);
1431 pDev->stats.dropped++;
1432 DBG2("No free frames\n");
1433 if ( err == 0 ){
1434
1435
1436
1437 DEBUG_ERR_LOG(pDev,3);
1438 pDev->stats.dropped_no_buf++;
1439 return 1;
1440 } else {
1441
1442
1443
1444
1445
1446
1447
1448 DEBUG_ERR_LOG(pDev,4);
1449 pDev->stats.dropped_too_long++;
1450 pDev->frame_state = FRM_STATE_NONE;
1451 return -2;
1452 }
1453 }
1454 frm->len = 5;
1455
1456
1457 ((unsigned char*)&frm->hdr)[0] = ((unsigned char*)pDev->hdr)[0];
1458 ((unsigned char*)&frm->hdr)[1] = ((unsigned char*)pDev->hdr)[1];
1459 ((unsigned char*)&frm->hdr)[2] = ((unsigned char*)pDev->hdr)[2];
1460 ((unsigned char*)&frm->hdr)[3] = ((unsigned char*)pDev->hdr)[3];
1461 ((unsigned char*)&frm->hdr)[4] = ((unsigned char*)pDev->hdr)[4];
1462
1463
1464 total_len = pDev->frmlen / 7;
1465 total_len = total_len * 7;
1466 if ( pDev->frmlen != total_len )
1467 total_len += 7;
1468
1469 pDev->filler = total_len - pDev->frmlen;
1470
1471 pDev->frame_state = FRM_STATE_PAYLOAD;
1472 pDev->frm = frm;
1473
1474
1475 case FRM_STATE_PAYLOAD:
1476 DBG2("FRAME_STATE_PAYLOAD\n");
1477
1478 frm = pDev->frm;
1479
1480 dst = (unsigned char *)&frm->data[frm->len-5];
1481 left = pDev->frmlen-frm->len;
1482
1483 ret = grtc_hw_copy(pDev,dst,left,1);
1484 if ( ret < 0 ) {
1485 DEBUG_ERR_LOG(pDev,5);
1486
1487 pDev->frame_state = FRM_STATE_NONE;
1488 frm->next = NULL;
1489 grtc_pool_add_frms(frm);
1490 pDev->frm = NULL;
1491 pDev->stats.err++;
1492 pDev->stats.err_payload++;
1493 return -1;
1494 } else if ( ret != left ) {
1495
1496 frm->len += ret;
1497 return 0;
1498 }
1499 frm->len += ret;
1500 pDev->frame_state = FRM_STATE_FILLER;
1501
1502
1503 case FRM_STATE_FILLER:
1504 DBG2("FRAME_STATE_FILLER\n");
1505
1506 frm = pDev->frm;
1507
1508 ret = grtc_hw_check_ending(pDev,pDev->filler);
1509 if ( ret != 0 ) {
1510
1511 DEBUG_ERR_LOG(pDev,6);
1512 pDev->frame_state = FRM_STATE_NONE;
1513 frm->next = NULL;
1514 grtc_pool_add_frms(frm);
1515 pDev->frm = NULL;
1516 pDev->stats.err++;
1517 pDev->stats.err_ending++;
1518 return -1;
1519 }
1520
1521
1522 if ( pDev->ready.head ) {
1523
1524 pDev->ready.tail->next = frm;
1525 } else {
1526
1527 pDev->ready.head = frm;
1528 }
1529 pDev->ready.tail = frm;
1530 frm->next = NULL;
1531 pDev->ready.cnt++;
1532 pDev->stats.frames_recv++;
1533
1534 pDev->frame_state = FRM_STATE_NONE;
1535 frm->next = NULL;
1536 return 2;
1537
1538 #if 0
1539 case FRM_STATE_DROP:
1540 DBG2("FRAME_STATE_DROP\n");
1541 break;
1542 #endif
1543
1544 default:
1545 printk("GRTC: internal error\n");
1546 pDev->frame_state = FRM_STATE_NONE;
1547 break;
1548 }
1549
1550 return 0;
1551 }
1552
1553 static rtems_device_driver grtc_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1554 {
1555 struct grtc_priv *pDev;
1556 struct drvmgr_dev *dev;
1557 rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
1558 unsigned int *data;
1559 int status,frm_len,i,ret;
1560 struct grtc_ioc_buf_params *buf_arg;
1561 struct grtc_ioc_config *cfg;
1562 struct grtc_ioc_hw_status *hwregs;
1563 struct grtc_ioc_pools_setup *pocfg;
1564 struct grtc_ioc_assign_frm_pool *poassign;
1565 struct grtc_frame *frm, *frms;
1566 struct grtc_frame_pool *pool;
1567 struct grtc_list *frmlist;
1568 struct grtc_ioc_stats *stats;
1569 unsigned int mem;
1570 IRQ_LOCAL_DECLARE(oldLevel);
1571
1572 FUNCDBG();
1573
1574 if ( drvmgr_get_dev(&grtc_drv_info.general, minor, &dev) ) {
1575 return RTEMS_INVALID_NUMBER;
1576 }
1577 pDev = (struct grtc_priv *)dev->priv;
1578
1579 if (!ioarg)
1580 return RTEMS_INVALID_NAME;
1581
1582 data = ioarg->buffer;
1583
1584 ioarg->ioctl_return = 0;
1585 switch(ioarg->command) {
1586 case GRTC_IOC_START:
1587 if ( pDev->running ) {
1588 return RTEMS_RESOURCE_IN_USE;
1589 }
1590 if ( (status=grtc_start(pDev)) != RTEMS_SUCCESSFUL ){
1591 return status;
1592 }
1593
1594 drvmgr_interrupt_register(pDev->dev, 0, "grtc", grtc_interrupt, pDev);
1595
1596
1597 break;
1598
1599 case GRTC_IOC_STOP:
1600 if ( !pDev->running ) {
1601 return RTEMS_RESOURCE_IN_USE;
1602 }
1603 drvmgr_interrupt_unregister(pDev->dev, 0, grtc_interrupt, pDev);
1604 grtc_stop(pDev, 0);
1605 break;
1606
1607 case GRTC_IOC_ISSTARTED:
1608 if ( !pDev->running ) {
1609 return RTEMS_RESOURCE_IN_USE;
1610 } else if ( pDev->overrun_condition ) {
1611 return RTEMS_IO_ERROR;
1612 }
1613 break;
1614
1615 case GRTC_IOC_SET_BLOCKING_MODE:
1616 if ( (unsigned int)data > GRTC_BLKMODE_COMPLETE ) {
1617 return RTEMS_INVALID_NAME;
1618 }
1619 DBG("GRTC: Set blocking mode: %d\n",(unsigned int)data);
1620 pDev->blocking = (unsigned int)data;
1621 break;
1622
1623 case GRTC_IOC_SET_TIMEOUT:
1624 DBG("GRTC: Timeout: %d\n",(unsigned int)data);
1625 pDev->timeout = (rtems_interval)data;
1626 break;
1627
1628 case GRTC_IOC_SET_BUF_PARAM:
1629 if ( pDev->running ) {
1630 return RTEMS_RESOURCE_IN_USE;
1631 }
1632
1633 buf_arg = (struct grtc_ioc_buf_params *)data;
1634 if ( !buf_arg ) {
1635 return RTEMS_INVALID_NAME;
1636 }
1637
1638 DBG("GRTC: IOC_SET_BUF_PARAM: Len: 0x%x, Custom Buffer: 0x%x\n",buf_arg->length,buf_arg->custom_buffer);
1639
1640
1641 if ( (unsigned int)buf_arg->custom_buffer & (~GRTC_BUF_MASK) & (~0x1) ) {
1642 return RTEMS_INVALID_NAME;
1643 }
1644
1645 if ( buf_arg->length > 0x100 ){
1646 DBG("GRTC: Too big buffer requested\n");
1647 return RTEMS_INVALID_NAME;
1648 }
1649
1650
1651 if ( !pDev->buf_custom && pDev->buf ){
1652 free(pDev->_buf);
1653 pDev->_buf = NULL;
1654 }
1655 pDev->buf = NULL;
1656 pDev->len = buf_arg->length*1024;
1657
1658 if (pDev->len <= 0)
1659 break;
1660 mem = (unsigned int)buf_arg->custom_buffer;
1661 pDev->buf_custom = mem;
1662
1663 if (mem & 1) {
1664
1665
1666
1667
1668 pDev->buf_remote = (void *)(mem & ~0x1);
1669 drvmgr_translate_check(pDev->dev, DMAMEM_TO_CPU,
1670 (void *)pDev->buf_remote,
1671 (void **)&pDev->buf,
1672 pDev->len);
1673 } else {
1674 if (mem == 0) {
1675 pDev->buf = grtc_memalign((~GRTC_ASR_BUFST)+1,pDev->len,&pDev->_buf);
1676 DBG("grtc_ioctl: SETBUF: new buf: 0x%x(0x%x), Len: %d\n",pDev->buf,pDev->_buf,pDev->len);
1677 if (!pDev->buf){
1678 pDev->len = 0;
1679 pDev->buf_custom = 0;
1680 pDev->_buf = NULL;
1681 pDev->buf_remote = 0;
1682 DBG("GRTC: Failed to allocate memory\n");
1683 return RTEMS_NO_MEMORY;
1684 }
1685 } else{
1686 pDev->buf = buf_arg->custom_buffer;
1687 }
1688
1689
1690
1691
1692
1693 drvmgr_translate_check(pDev->dev, CPUMEM_TO_DMA,
1694 (void *)pDev->buf,
1695 (void **)&pDev->buf_remote,
1696 pDev->len);
1697 }
1698 break;
1699
1700 case GRTC_IOC_GET_BUF_PARAM:
1701 if ( pDev->running ) {
1702 return RTEMS_RESOURCE_IN_USE;
1703 }
1704
1705 buf_arg = (struct grtc_ioc_buf_params *)data;
1706 if ( !buf_arg ) {
1707 return RTEMS_INVALID_NAME;
1708 }
1709
1710 buf_arg->length = pDev->len >> 10;
1711 if ( pDev->buf_custom )
1712 buf_arg->custom_buffer =(void *)pDev->buf;
1713 else
1714 buf_arg->custom_buffer = 0;
1715 break;
1716
1717 case GRTC_IOC_SET_CONFIG:
1718 cfg = (struct grtc_ioc_config *)data;
1719 if ( !cfg ) {
1720 return RTEMS_INVALID_NAME;
1721 }
1722
1723 if ( pDev->running ) {
1724 return RTEMS_RESOURCE_IN_USE;
1725 }
1726
1727 pDev->config = *cfg;
1728 break;
1729
1730 case GRTC_IOC_GET_CONFIG:
1731 cfg = (struct grtc_ioc_config *)data;
1732 if ( !cfg ) {
1733 return RTEMS_INVALID_NAME;
1734 }
1735
1736 *cfg = pDev->config;
1737 break;
1738
1739 case GRTC_IOC_GET_HW_STATUS:
1740 hwregs = (struct grtc_ioc_hw_status *)data;
1741 if ( !hwregs ) {
1742 return RTEMS_INVALID_NAME;
1743 }
1744
1745
1746
1747 IRQ_LOCAL_DISABLE(oldLevel);
1748 hwregs->sir = READ_REG(&pDev->regs->sir);
1749 hwregs->far = READ_REG(&pDev->regs->far);
1750 hwregs->clcw1 = READ_REG(&pDev->regs->clcw1);
1751 hwregs->clcw2 = READ_REG(&pDev->regs->clcw2);
1752 hwregs->phir = READ_REG(&pDev->regs->phir);
1753 hwregs->str = READ_REG(&pDev->regs->str);
1754 IRQ_LOCAL_ENABLE(oldLevel);
1755 break;
1756
1757 case GRTC_IOC_GET_STATS:
1758 stats = (struct grtc_ioc_stats *)data;
1759 if ( !stats ) {
1760 return RTEMS_INVALID_NAME;
1761 }
1762 memcpy(stats,&pDev->stats,sizeof(struct grtc_ioc_stats));
1763 break;
1764
1765 case GRTC_IOC_CLR_STATS:
1766 memset(&pDev->stats,0,sizeof(struct grtc_ioc_stats));
1767 break;
1768
1769 case GRTC_IOC_SET_MODE:
1770 if ( pDev->running ) {
1771 return RTEMS_RESOURCE_IN_USE;
1772 }
1773 if ( (int)data == GRTC_MODE_FRAME ) {
1774 pDev->mode = GRTC_MODE_FRAME;
1775 } else if ( (int)data == GRTC_MODE_RAW ) {
1776 pDev->mode = GRTC_MODE_RAW;
1777 } else {
1778 return RTEMS_INVALID_NAME;
1779 }
1780 break;
1781
1782 case GRTC_IOC_POOLS_SETUP:
1783 if ( pDev->running ) {
1784 return RTEMS_RESOURCE_IN_USE;
1785 }
1786 pocfg = (struct grtc_ioc_pools_setup *)data;
1787 if ( (pDev->mode != GRTC_MODE_FRAME) || !pocfg ) {
1788 return RTEMS_INVALID_NAME;
1789 }
1790
1791
1792 frm_len = 0;
1793 for(i=0;i<pocfg->pool_cnt;i++){
1794 if ( pocfg->pool_frame_len[i] <= frm_len ) {
1795 return RTEMS_INVALID_NAME;
1796 }
1797 frm_len = pocfg->pool_frame_len[i];
1798 }
1799
1800
1801
1802
1803 if ( pDev->pools ) {
1804 free(pDev->pools);
1805 }
1806 pDev->pools = grlib_malloc(pocfg->pool_cnt * sizeof(*pDev->pools));
1807 if ( !pDev->pools ) {
1808 pDev->pool_cnt = 0;
1809 return RTEMS_NO_MEMORY;
1810 }
1811 pDev->pool_cnt = pocfg->pool_cnt;
1812 for (i=0;i<pocfg->pool_cnt;i++) {
1813 pDev->pools[i].frame_len = pocfg->pool_frame_len[i];
1814 pDev->pools[i].frame_cnt = 0;
1815 pDev->pools[i].frms = NULL;
1816 }
1817 break;
1818
1819 case GRTC_IOC_ASSIGN_FRM_POOL:
1820 if ( pDev->running ) {
1821 return RTEMS_RESOURCE_IN_USE;
1822 }
1823
1824 if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1825 return RTEMS_INVALID_NAME;
1826 }
1827
1828 poassign = (struct grtc_ioc_assign_frm_pool *)data;
1829 if ( !poassign ) {
1830 return RTEMS_INVALID_NAME;
1831 }
1832
1833
1834 pool = NULL;
1835 for(i=0; i<pDev->pool_cnt; i++) {
1836 if ( pDev->pools[i].frame_len == poassign->frame_len ) {
1837 pool = &pDev->pools[i];
1838 break;
1839 }
1840 }
1841 if ( !pool ) {
1842
1843 return RTEMS_INVALID_NAME;
1844 }
1845
1846
1847 frm = poassign->frames;
1848 while(frm){
1849 frm->pool = pool;
1850 frm = frm->next;
1851 }
1852 break;
1853
1854 case GRTC_IOC_ADD_BUFF:
1855 frms = (struct grtc_frame *)data;
1856
1857 if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1858 return RTEMS_NOT_DEFINED;
1859 }
1860 if ( !frms ) {
1861 return RTEMS_INVALID_NAME;
1862 }
1863
1864
1865 if ( grtc_pool_add_frms(frms) ) {
1866 return RTEMS_INVALID_NAME;
1867 }
1868 break;
1869
1870
1871
1872
1873
1874
1875
1876 case GRTC_IOC_RECV:
1877
1878 if ( (pDev->mode != GRTC_MODE_FRAME) ) {
1879 return RTEMS_NOT_DEFINED;
1880 }
1881
1882 while ( pDev->running && ((ret=process_dma(pDev) == 2) || (ret == -1)) ) {
1883
1884 }
1885
1886
1887 frmlist = (struct grtc_list *)data;
1888 if ( !frmlist ) {
1889 return RTEMS_INVALID_NAME;
1890 }
1891
1892 frmlist->head = pDev->ready.head;
1893 frmlist->tail = pDev->ready.tail;
1894 frmlist->cnt = pDev->ready.cnt;
1895
1896
1897 pDev->ready.head = NULL;
1898 pDev->ready.tail = NULL;
1899 pDev->ready.cnt = 0;
1900
1901 if ((frmlist->cnt == 0) && pDev->overrun_condition) {
1902
1903
1904
1905 return RTEMS_IO_ERROR;
1906 }
1907 break;
1908
1909 case GRTC_IOC_GET_CLCW_ADR:
1910 if ( !data ) {
1911 return RTEMS_INVALID_NAME;
1912 }
1913 *data = (unsigned int)&pDev->regs->clcw1;
1914 break;
1915
1916 default:
1917 return RTEMS_NOT_DEFINED;
1918 }
1919 return RTEMS_SUCCESSFUL;
1920 }
1921
1922 static void grtc_interrupt(void *arg)
1923 {
1924 struct grtc_priv *pDev = arg;
1925 struct grtc_regs *regs = pDev->regs;
1926 unsigned int status;
1927 SPIN_ISR_IRQFLAGS(irqflags);
1928
1929
1930 status = READ_REG(®s->pisr);
1931
1932
1933 if ( !pDev->running )
1934 return;
1935
1936 if ( status & GRTC_INT_OV ){
1937
1938
1939
1940 grtc_stop(pDev, 1);
1941
1942
1943 goto out;
1944 }
1945
1946 if ( status & GRTC_INT_CS ){
1947 SPIN_LOCK(&pDev->devlock, irqflags);
1948
1949 if ( (pDev->blocking==GRTC_BLKMODE_COMPLETE) && pDev->timeout ){
1950
1951 if ( pDev->wait_for_nbytes > grtc_data_avail(pDev) ){
1952
1953 goto procceed_processing_interrupts;
1954 }
1955
1956
1957
1958
1959 }
1960
1961
1962
1963
1964 regs->imr = READ_REG(®s->imr) & ~GRTC_INT_CS;
1965 SPIN_UNLOCK(&pDev->devlock, irqflags);
1966
1967
1968 rtems_semaphore_release(pDev->sem_rx);
1969 }
1970
1971 procceed_processing_interrupts:
1972
1973 if ( status & GRTC_INT_CR ){
1974
1975 }
1976
1977 if ( status & GRTC_INT_FAR ){
1978
1979 }
1980
1981 if ( status & GRTC_INT_BLO ){
1982
1983 }
1984
1985 if ( status & GRTC_INT_RFA ){
1986
1987 }
1988 out:
1989 if ( status )
1990 regs->picr = status;
1991 }
1992
1993 static rtems_device_driver grtc_initialize(
1994 rtems_device_major_number major,
1995 rtems_device_minor_number unused,
1996 void *arg
1997 )
1998 {
1999
2000 if ( rtems_semaphore_create(rtems_build_name('G', 'R', 'T', 'C'),
2001 1,
2002 RTEMS_FIFO|RTEMS_NO_INHERIT_PRIORITY|RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
2003 0,
2004 &grtc_dev_sem) != RTEMS_SUCCESSFUL ) {
2005 return RTEMS_INTERNAL_ERROR;
2006 }
2007
2008 return RTEMS_SUCCESSFUL;
2009 }