source: rtems/c/src/lib/libbsp/sparc/shared/can/grcan.c @ 13279f5d

4.104.114.84.95
Last change on this file since 13279f5d was 13279f5d, checked in by Joel Sherrill <joel.sherrill@…>, on 09/07/07 at 14:34:18

2007-09-07 Daniel Hellstrom <daniel@…>

  • shared/1553/b1553brm.c, shared/can/grcan.c, shared/can/grcan_rasta.c, shared/can/occan.c, shared/spw/grspw.c, shared/spw/grspw_pci.c, shared/uart/apbuart.c: Remove warnings.
  • Property mode set to 100644
File size: 45.3 KB
Line 
1/*
2 *  GRCAN driver 
3 *
4 *  COPYRIGHT (c) 2007.
5 *  Gaisler Research.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *
12 *  2007-06-13, Daniel Hellstrom <daniel@gaisler.com>
13 *    New driver in sparc shared directory. Parts taken
14 *    from rasta grhcan driver.
15 *
16 */
17
18#include <bsp.h>
19#include <rtems/libio.h>
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <assert.h>
24#include <sched.h>
25#include <ctype.h>
26#include <rtems/bspIo.h>
27
28#include <grcan.h>
29#include <ambapp.h>
30#include <pci.h>
31
32#define WRAP_AROUND_TX_MSGS 1
33#define WRAP_AROUND_RX_MSGS 2
34#define GRCAN_MSG_SIZE sizeof(struct grcan_msg)
35#define BLOCK_SIZE (16*4)
36
37/* Default Maximium buffer size for statically allocated buffers */
38#ifndef TX_BUF_SIZE
39#define TX_BUF_SIZE (BLOCK_SIZE*16)
40#endif
41
42/* Make receiver buffers bigger than transmitt */
43#ifndef RX_BUF_SIZE
44#define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
45#endif
46
47#ifndef IRQ_GLOBAL_DISABLE
48 #define IRQ_GLOBAL_DISABLE() sparc_disable_interrupts()
49#endif
50
51#ifndef IRQ_GLOBAL_ENABLE
52 #define IRQ_GLOBAL_ENABLE() sparc_enable_interrupts()
53#endif
54
55#ifndef IRQ_CLEAR_PENDING
56 #define IRQ_CLEAR_PENDING(irqno)
57#endif
58
59#ifndef IRQ_UNMASK
60 #define IRQ_UNMASK(irqno)
61#endif
62
63#ifndef IRQ_MASK
64 #define IRQ_MASK(irqno)
65#endif
66
67#ifndef GRCAN_PREFIX
68 #define GRCAN_PREFIX(name) grcan##name
69#endif
70
71#ifndef MEMAREA_TO_HW
72  #define MEMAREA_TO_HW(x) (x)
73#endif
74
75/* default name to /dev/grcan0 */
76#if !defined(GRCAN_DEVNAME) || !defined(GRCAN_DEVNAME_NO)
77 #undef GRCAN_DEVNAME
78 #undef GRCAN_DEVNAME_NO
79 #define GRCAN_DEVNAME "/dev/grcan0"
80 #define GRCAN_DEVNAME_NO(devstr,no) ((devstr)[10]='0'+(no))
81#endif
82
83#ifndef GRCAN_REG_INT
84 #define GRCAN_REG_INT(handler,irqno,arg) set_vector(handler,irqno+0x10,1)
85 #undef  GRCAN_DEFINE_INTHANDLER
86 #define GRCAN_DEFINE_INTHANDLER
87#endif
88
89#ifndef GRCAN_DEFAULT_BAUD
90  /* default to 500kbits/s */
91  #define GRCAN_DEFAULT_BAUD 500000
92#endif
93
94/* Uncomment for debug output */
95/****************** DEBUG Definitions ********************/
96#define DBG_IOCTRL 1
97#define DBG_TX 2
98#define DBG_RX 4
99
100#define DEBUG_FLAGS (DBG_IOCTRL | DBG_RX | DBG_TX )
101/*#define DEBUG
102#define DEBUGFUNCS*/
103
104#include <debug_defs.h>
105
106/*
107#ifdef DEBUG
108#include <debug_defs.h>
109#else
110void silentdbg_init(void);
111void silentdbg_printf(char *fmt, ...);
112void silentdbg_int_printf(char *fmt, ...);
113void silentdbg_get_buf(char *buf, int max);
114int silentdbg_print_buf(int max);
115 extern int DEBUG_printf(const char *fmt, ...);
116 #define DBG(fmt, args...)    do { silentdbg_printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args); } while(0)
117 #define DBG2(fmt)            do { silentdbg_printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__); } while(0)
118 #define DBGC(c,fmt, args...) do { if (DEBUG_FLAGS & c) { silentdbg_printf(" : %03d @ %18s()]:" fmt , __LINE__,__FUNCTION__,## args);  }} while(0)
119 #ifdef DEBUGFUNCS
120  #define FUNCDBG()         do { silentdbg_printf("%s\n\r",__FUNCTION__); } while(0)
121  #define FUNCDBG_INT()
122 #else
123  #define FUNCDBG()
124  #define FUNCDBG_INT()     do { silentdbg_int_printf("%s\n\r",__FUNCTION__); } while(0)
125 #endif
126 
127#endif
128*/
129/*********************************************************/
130
131/* grcan needs to have it buffers aligned to 1k boundaries */
132#define BUFFER_ALIGNMENT_NEEDS 1024
133
134#ifdef STATICALLY_ALLOCATED_TX_BUFFER
135static unsigned int tx_circbuf[GRCAN_MAX_CORES][TX_BUF_SIZE]
136        __attribute__ ((aligned(BUFFER_ALIGNMENT_NEEDS)));
137#define STATIC_TX_BUF_SIZE TX_BUF_SIZE
138#define STATIC_TX_BUF_ADDR(core) (&tx_circbuf[(core)][0])
139#endif
140
141#ifdef STATICALLY_ALLOCATED_RX_BUFFER
142static unsigned int rx_circbuf[GRCAN_MAX_CORES][RX_BUF_SIZE]
143        __attribute__ ((aligned(BUFFER_ALIGNMENT_NEEDS)));
144#define STATIC_RX_BUF_SIZE RX_BUF_SIZE
145#define STATIC_RX_BUF_ADDR(core) (&rx_circbuf[(core)][0])
146#endif
147
148/*
149 * If USE_AT697_RAM is defined the RAM on the AT697 board will be used for DMA buffers (but rx message queue is always in AT697 ram).
150 * USE_AT697_DMA specifies whether the messages will be fetched using DMA or PIO.
151 *
152 * RASTA_PCI_BASE is the base address of the GRPCI AHB slave
153 *
154 * GRCAN_BUF_SIZE must be set to the size (in bytes) of the GRCAN DMA buffers.
155 *
156 * RX_QUEUE_SIZE defines the number of messages that fits in the  RX message queue. On RX interrupts the messages in the DMA buffer
157 * are copied into the message queue (using dma if the rx buf is not in the AT697 ram).
158 */
159
160/*#define USE_AT697_RAM              1      */
161#define USE_AT697_DMA              1     
162#define RASTA_PCI_BASE             0xe0000000   
163#define GRCAN_BUF_SIZE            4096     
164#define RX_QUEUE_SIZE              1024         
165
166#define INDEX(x) ( x&(RX_QUEUE_SIZE-1) )
167
168/* pa(x)
169 *
170 * x: address in AT697 address space
171 *
172 * returns the address in the RASTA address space that can be used to access x with dma.
173 *
174*/
175#ifdef USE_AT697_RAM
176static inline unsigned int pa(unsigned int addr) {
177    return ((addr & 0x0fffffff) | RASTA_PCI_BASE);   
178}
179#else
180static inline unsigned int pa(unsigned int addr) {
181    return ((addr & 0x0fffffff) | 0x40000000);       
182}
183#endif
184
185struct grcan_msg {
186    unsigned int head[2];
187    unsigned char data[8];
188};
189
190struct grcan_config {
191        struct grcan_timing timing;
192        struct grcan_selection selection;
193        int abort;
194        int silent;
195};
196
197struct grcan_priv {
198  unsigned int baseaddr, ram_base;
199  struct grcan_regs *regs;
200  int irq;
201  int minor;
202  int open;
203  int started;
204  unsigned int channel;
205  int flushing;
206  unsigned int corefreq_hz;
207 
208  /* Circular DMA buffers */
209  void *_rx;
210  void *_tx;
211  struct grcan_msg *rx;
212  struct grcan_msg *tx;
213  unsigned int rxbuf_size;    /* requested RX buf size in bytes */
214  unsigned int txbuf_size;    /* requested TX buf size in bytes */
215
216  int txblock, rxblock;
217  int txcomplete, rxcomplete;
218  int txerror, rxerror;
219 
220  struct grcan_filter sfilter;
221  struct grcan_filter afilter;
222  int config_changed; /* 0=no changes, 1=changes ==> a Core reset is needed */
223  struct grcan_config config;
224  struct grcan_stats stats;
225 
226  rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
227};
228
229static int grcan_core_cnt;
230struct grcan_priv *grcans;
231static amba_confarea_type *amba_bus;
232struct grcan_device_info *grcan_cores;
233static int grcan_core_cnt;
234
235static rtems_device_driver grcan_initialize(rtems_device_major_number  major, rtems_device_minor_number  minor, void *arg);
236static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
237static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
238static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
239static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
240static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
241
242#define GRCAN_DRIVER_TABLE_ENTRY { grcan_initialize, grcan_open, grcan_close, grcan_read, grcan_write, grcan_ioctl }
243
244static unsigned int grcan_hw_read_try(
245  struct grcan_priv *pDev,
246  struct grcan_regs *regs,
247  CANMsg *buffer,
248  int max);
249
250static unsigned int grcan_hw_write_try(
251  struct grcan_priv *pDev,
252  struct grcan_regs *regs,
253  CANMsg *buffer,
254  int count);
255
256static void grcan_hw_config(
257  struct grcan_regs *regs,
258  struct grcan_config *conf);
259 
260static void grcan_hw_accept(
261  struct grcan_regs *regs,
262  struct grcan_filter *afilter);
263
264static void grcan_hw_sync(
265  struct grcan_regs *regs,
266  struct grcan_filter *sfilter);
267
268#ifndef GRCAN_DONT_DECLARE_IRQ_HANDLER
269static rtems_isr grcan_interrupt_handler(rtems_vector_number v);
270#endif
271
272static void grcan_interrupt(struct grcan_priv *pDev);
273
274#ifdef GRCAN_REG_BYPASS_CACHE
275#define READ_REG(address) _grcan_read_nocache((unsigned int)(address))
276#else
277#define READ_REG(address) (*(unsigned int *)(address))
278#endif
279
280#ifdef GRCAN_DMA_BYPASS_CACHE
281#define READ_DMA_WORD(address) _grcan_read_nocache((unsigned int)(address))
282#define READ_DMA_BYTE(address) _grcan_read_nocache_byte((unsigned int)(address))
283static unsigned char __inline__ _grcan_read_nocache_byte(unsigned int address)
284{
285  unsigned char tmp;
286  asm(" lduba [%1]1, %0 "
287    : "=r"(tmp)
288    : "r"(address)
289  );
290  return tmp;
291}
292#else
293#define READ_DMA_WORD(address) (*(unsigned int *)(address))
294#define READ_DMA_BYTE(address) (*(unsigned char *)(address))
295#endif
296
297#if defined(GRCAN_REG_BYPASS_CACHE) || defined(GRCAN_DMA_BYPASS_CACHE)
298static unsigned int __inline__ _grcan_read_nocache(unsigned int address)
299{
300  unsigned int tmp;
301  asm(" lda [%1]1, %0 "
302    : "=r"(tmp)
303    : "r"(address)
304  );
305  return tmp;
306}
307#endif
308
309
310static rtems_driver_address_table grcan_driver = GRCAN_DRIVER_TABLE_ENTRY;
311
312static void __inline__ grcan_hw_reset(struct grcan_regs *regs)
313{
314        regs->ctrl = GRCAN_CTRL_RESET;
315}
316
317static rtems_device_driver grcan_start(struct grcan_priv *pDev)
318{
319  unsigned int tmp;
320  FUNCDBG();
321 
322  /* Check that memory has been allocated successfully */
323  if ( !pDev->tx || !pDev->rx )
324    return RTEMS_NO_MEMORY;
325 
326  /* Configure FIFO configuration register
327   * and Setup timing
328   */
329  if ( pDev->config_changed ){
330    grcan_hw_config(pDev->regs,&pDev->config);
331    pDev->config_changed = 0;
332  }
333
334  /* Setup receiver */
335  pDev->regs->rx0addr = MEMAREA_TO_HW((unsigned int)pDev->rx);
336  pDev->regs->rx0size = pDev->rxbuf_size;
337 
338  /* Setup Transmitter */
339  pDev->regs->tx0addr = MEMAREA_TO_HW((unsigned int)pDev->tx);
340  pDev->regs->tx0size = pDev->txbuf_size;
341 
342  /* Setup acceptance filters */
343  grcan_hw_accept(pDev->regs,&pDev->afilter);
344 
345  /* Sync filters */
346  grcan_hw_sync(pDev->regs,&pDev->sfilter);
347 
348  /* Clear status bits */
349  tmp = READ_REG(&pDev->regs->stat);
350  pDev->regs->stat = 0;
351 
352  /* Setup IRQ handling */
353 
354  /* Clear all IRQs */ 
355  tmp = READ_REG(&pDev->regs->pir);
356  pDev->regs->picr = 0x1ffff;
357 
358  /* unmask TxLoss|TxErrCntr|RxErrCntr|TxAHBErr|RxAHBErr|OR|OFF|PASS */
359  pDev->regs->imr = 0x1601f;
360 
361  /* Enable routing of the IRQs */
362  IRQ_GLOBAL_DISABLE();
363  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_TXSYNC);
364  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_RXSYNC);
365  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_IRQ);
366  IRQ_GLOBAL_ENABLE();
367 
368  /* Reset some software data */
369  /*pDev->txerror = 0;
370  pDev->rxerror = 0;*/
371
372  /* Enable receiver/transmitter */
373  pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
374  pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
375 
376  /* Enable HurriCANe core */
377  pDev->regs->ctrl = GRCAN_CTRL_ENABLE;
378 
379  /* Leave transmitter disabled, it is enabled when
380   * trying to send something.
381   */
382  return RTEMS_SUCCESSFUL;
383}
384
385static void grcan_stop(struct grcan_priv *pDev)
386{
387  FUNCDBG();
388     
389  /* Mask all IRQs */
390  pDev->regs->imr = 0;
391  IRQ_MASK(pDev->irq+GRCAN_IRQ_TXSYNC);
392  IRQ_MASK(pDev->irq+GRCAN_IRQ_RXSYNC);
393  IRQ_MASK(pDev->irq+GRCAN_IRQ_IRQ);
394 
395  /* Disable receiver & transmitter */
396  pDev->regs->rx0ctrl = 0;
397  pDev->regs->tx0ctrl = 0;
398 
399  /* Reset semaphores to the initial state and wakeing
400   * all threads waiting for an IRQ. The threads that
401   * get woken up must check for RTEMS_UNSATISFIED in
402   * order to determine that they should return to
403   * user space with error status.
404   */
405  rtems_semaphore_flush(pDev->rx_sem);
406  rtems_semaphore_flush(pDev->tx_sem);
407  rtems_semaphore_flush(pDev->txempty_sem);
408}
409
410static void grcan_hw_config(
411  struct grcan_regs *regs,
412  struct grcan_config *conf
413  )
414{
415  unsigned int config=0;
416 
417  /* Reset HurriCANe Core */
418  regs->ctrl = 0;
419 
420  if ( conf->silent )
421    config |= GRCAN_CFG_SILENT;
422     
423  if ( conf->abort )
424    config |= GRCAN_CFG_ABORT;
425 
426  if ( conf->selection.selection )
427    config |= GRCAN_CFG_SELECTION;
428     
429  if ( conf->selection.enable0 )
430    config |= GRCAN_CFG_ENABLE0;
431     
432  if ( conf->selection.enable1 )
433    config |= GRCAN_CFG_ENABLE1;
434 
435  /* Timing */
436  config |= (conf->timing.bpr<<GRCAN_CFG_BPR_BIT) & GRCAN_CFG_BPR;
437  config |= (conf->timing.rsj<<GRCAN_CFG_RSJ_BIT) & GRCAN_CFG_RSJ;
438  config |= (conf->timing.ps1<<GRCAN_CFG_PS1_BIT) & GRCAN_CFG_PS1;
439  config |= (conf->timing.ps2<<GRCAN_CFG_PS2_BIT) & GRCAN_CFG_PS2;
440  config |= (conf->timing.scaler<<GRCAN_CFG_SCALER_BIT) & GRCAN_CFG_SCALER;
441 
442  /* Write configuration */
443  regs->conf = config;
444 
445  /* Enable HurriCANe Core */
446  regs->ctrl = GRCAN_CTRL_ENABLE;
447}
448
449static void grcan_hw_accept(
450  struct grcan_regs *regs,
451  struct grcan_filter *afilter
452  )
453{
454  /* Disable Sync mask totaly (if we change scode or smask
455   * in an unfortunate way we may trigger a sync match)
456   */
457  regs->rx0mask = 0xffffffff;
458 
459  /* Set Sync Filter in a controlled way */
460  regs->rx0code = afilter->code;
461  regs->rx0mask = afilter->mask;
462}
463
464static void grcan_hw_sync(
465  struct grcan_regs *regs,
466  struct grcan_filter *sfilter
467  )
468{
469  /* Disable Sync mask totaly (if we change scode or smask
470   * in an unfortunate way we may trigger a sync match)
471   */
472  regs->smask = 0xffffffff;
473 
474  /* Set Sync Filter in a controlled way */
475  regs->scode = sfilter->code;
476  regs->smask = sfilter->mask;
477}
478
479static unsigned int grcan_hw_rxavail(
480  unsigned int rp,
481  unsigned int wp,
482  unsigned int size
483  )
484{
485  if ( rp == wp ) {
486    /* read pointer and write pointer is equal only
487     * when RX buffer is empty.
488     */
489    return 0;
490  }
491 
492  if ( wp > rp ) {
493    return (wp-rp)/GRCAN_MSG_SIZE;
494  }else{
495    return (size-(rp-wp))/GRCAN_MSG_SIZE;
496  }
497}
498
499static unsigned int grcan_hw_txspace(
500  unsigned int rp,
501  unsigned int wp,
502  unsigned int size
503  )
504{
505  unsigned int left;
506 
507  if ( rp == wp ) {
508    /* read pointer and write pointer is equal only
509     * when TX buffer is empty.
510     */
511    return size/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
512  }
513 
514  /* size - 4 - abs(read-write) */
515  if ( wp > rp ) {
516    left = size-(wp-rp);
517  }else{
518    left = rp-wp;
519  }
520 
521  return left/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
522}
523
524static int grcan_hw_rx_ongoing(struct grcan_regs *regs)
525{
526  return READ_REG(&regs->rx0ctrl) & GRCAN_RXCTRL_ONGOING;
527};
528
529static int grcan_hw_tx_ongoing(struct grcan_regs *regs)
530{
531  return READ_REG(&regs->tx0ctrl) & GRCAN_TXCTRL_ONGOING;
532};
533
534static int grcan_calc_timing(
535  unsigned int baud,          /* The requested BAUD to calculate timing for */
536  unsigned int core_hz,       /* Frequency in Hz of GRCAN Core */
537  struct grcan_timing *timing /* result is placed here */
538  )
539{
540  return -1; /* not implemented yet */
541}
542
543static unsigned int grcan_hw_read_try(
544  struct grcan_priv *pDev,
545  struct grcan_regs *regs,
546  CANMsg *buffer,
547  int max
548  )
549{
550  int i,j;
551  CANMsg *dest;
552  struct grcan_msg *source,tmp;
553  unsigned int wp,rp,size,rxmax,addr,trunk_msg_cnt;
554 
555  FUNCDBG();
556 
557  wp = READ_REG(&regs->rx0wr);
558  rp = READ_REG(&regs->rx0rd);
559 
560  /*
561   * Due to hardware wrap around simplification write pointer will
562   * never reach the read pointer, at least a gap of 8 bytes.
563   * The only time they are equal is when the read pointer has
564   * reached the write pointer (empty buffer)
565   *
566   */
567  if ( wp != rp ){
568    /* Not empty, we have received chars...
569     * Read as much as possible from DMA buffer
570     */
571    size = READ_REG(&regs->rx0size);
572   
573    /* Get number of bytes available in RX buffer */
574    trunk_msg_cnt = grcan_hw_rxavail(rp,wp,size);
575   
576    /* truncate size if user space buffer hasn't room for
577     * all received chars.
578     */
579    if ( trunk_msg_cnt > max )
580      trunk_msg_cnt = max;
581   
582    /* Read until i is 0 */
583    i=trunk_msg_cnt;
584   
585    addr = (unsigned int)pDev->rx;
586    source = (struct grcan_msg *)(addr + rp);
587    dest = buffer;
588    rxmax = addr + (size-GRCAN_MSG_SIZE);
589   
590    /* Read as many can messages as possible */
591    while(i>0){
592      /* Read CAN message from DMA buffer */
593      tmp.head[0] = READ_DMA_WORD(&source->head[0]);
594      tmp.head[1] = READ_DMA_WORD(&source->head[1]);
595      /* Convert one grcan CAN message to one "software" CAN message */
596      dest->extended = tmp.head[0]>>31;
597      dest->rtr = (tmp.head[0] >>30) & 0x1;
598      if ( dest->extended ){
599        dest->id = tmp.head[0] & 0x3fffffff;
600      }else{
601        dest->id = (tmp.head[0] >>18) & 0xfff;
602      }
603      dest->len = tmp.head[1] >> 28;
604      for(j=0; j<dest->len; j++)
605        dest->data[j] = READ_DMA_BYTE(&source->data[j]);
606     
607      /* wrap around if neccessary */
608      source = ( (unsigned int)source >= rxmax ) ? (struct grcan_msg *)addr : source+1;
609      dest++; /* straight user buffer */
610      i--;
611    }
612    /* Increment Hardware READ pointer (mark read byte as read)
613     * ! wait for registers to be safely re-configurable
614     */
615    regs->rx0ctrl = 0; /* DISABLE RX CHANNEL */
616    i=0;
617    while( grcan_hw_rx_ongoing(regs) && (i<1000) ){
618      i++;
619    }
620    regs->rx0rd = (unsigned int)source-addr;
621    regs->rx0ctrl = GRCAN_RXCTRL_ENABLE; /* ENABLE_RX_CHANNEL */
622    return trunk_msg_cnt;
623  }
624  return 0;
625}
626
627static unsigned int grcan_hw_write_try(
628  struct grcan_priv *pDev,
629  struct grcan_regs *regs,
630  CANMsg *buffer,
631  int count
632  )
633{
634  unsigned int rp, wp, size, txmax, addr, ret;
635  struct grcan_msg *dest;
636  CANMsg *source;
637  int space_left;
638  unsigned int tmp;
639  int i;
640 
641  DBGC(DBG_TX,"\n");
642  /*FUNCDBG();*/
643 
644  rp = READ_REG(&regs->tx0rd);
645  wp = READ_REG(&regs->tx0wr);
646  size = READ_REG(&regs->tx0size);
647 
648  space_left = grcan_hw_txspace(rp,wp,size);
649 
650  /* is circular fifo full? */
651  if ( space_left < 1 )
652    return 0;
653 
654  /* Truncate size */
655  if ( space_left > count )
656    space_left = count;
657  ret = space_left;
658 
659  addr = (unsigned int)pDev->tx;
660 
661  dest = (struct grcan_msg *)(addr + wp);
662  source = (CANMsg *)buffer;
663  txmax = addr + (size-GRCAN_MSG_SIZE);
664 
665  while ( space_left>0 ) {
666    /* Convert and write CAN message to DMA buffer */
667    if ( source->extended ){
668      tmp = (1<<31) | (source->id & 0x3fffffff);
669    }else{
670      tmp = (source->id&0xfff)<<18;
671    }
672    if ( source->rtr )
673      tmp|=(1<<30);
674    dest->head[0] = tmp;
675    dest->head[1] = source->len<<28;
676    for ( i=0; i<source->len; i++)
677      dest->data[i] = source->data[i];
678    source++; /* straight user buffer */
679    dest = ((unsigned int)dest >= txmax) ? (struct grcan_msg *)addr : dest+1;
680    space_left--;
681  }
682 
683  /* Update write pointer
684   * ! wait for registers to be safely re-configurable
685   */
686  regs->tx0ctrl = 0; /* DISABLE TX CHANNEL */
687  i=0;
688  while( (grcan_hw_tx_ongoing(regs)) && i<1000 ){
689    i++;
690    printk("ongoing tx\n");
691  }
692  regs->tx0wr = (unsigned int)dest - addr; /* Update write pointer */
693  regs->tx0ctrl = GRCAN_TXCTRL_ENABLE; /* ENABLE_TX_CHANNEL */
694  return ret;
695}
696
697static int grcan_wait_rxdata(
698  struct grcan_priv *pDev,
699  int min
700  )
701{
702  unsigned int wp, rp, size, irq;
703  unsigned int irq_trunk, dataavail;
704  int wait;
705 
706  FUNCDBG();
707 
708  size = READ_REG(&pDev->regs->rx0size);
709  rp = READ_REG(&pDev->regs->rx0rd);
710  wp = READ_REG(&pDev->regs->rx0wr);
711 
712  /**** Calculate IRQ Pointer ****/
713  irq = wp + min*GRCAN_MSG_SIZE;
714  /* wrap irq around */
715  if ( irq >= size ){
716    irq_trunk = irq-size;
717  }else
718    irq_trunk = irq;
719
720  /*** block until receive IRQ received
721   * Set up a valid IRQ point so that an IRQ is received
722   * when one or more messages are received
723   */
724  IRQ_GLOBAL_DISABLE();
725 
726  /* init IRQ HW */
727  pDev->regs->rx0irq = irq_trunk;
728 
729  /* Clear pending Rx IRQ */
730  pDev->regs->picr = GRCAN_RXIRQ_IRQ;
731 
732  wp = READ_REG(&pDev->regs->rx0wr);
733 
734  /* Calculate messages available */
735  dataavail = grcan_hw_rxavail(rp,wp,size);
736 
737  if ( dataavail < min ){
738    /* Still empty, proceed with sleep - Turn on IRQ (unmask irq) */
739    pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
740    wait=1;
741  }else{
742    /* enough message has been received, abort sleep - don't unmask interrupt */
743    wait=0;
744  }
745  IRQ_GLOBAL_ENABLE();
746   
747    /* Wait for IRQ to fire only if has been triggered */
748  if ( wait ){
749    if ( rtems_semaphore_obtain(pDev->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_UNSATISFIED )
750      return -1; /* Device driver has been closed or stopped, return with error status */
751  }
752 
753  return 0;
754}
755
756/* Wait until min bytes available in TX circular buffer.
757 * The IRQ RxIrq is used to pin point the location of
758 *
759 * min must be at least WRAP_AROUND_TX_BYTES bytes less
760 * than max buffer for this algo to work.
761 *
762 */
763static int grcan_wait_txspace(
764  struct grcan_priv *pDev,
765  int min
766  )
767{
768  int wait;
769  unsigned int irq, rp, wp, size, space_left;
770  unsigned int irq_trunk;
771 
772  DBGC(DBG_TX,"\n");
773  /*FUNCDBG();*/
774 
775  size = READ_REG(&pDev->regs->tx0size);
776  wp = READ_REG(&pDev->regs->tx0wr); 
777
778  IRQ_GLOBAL_DISABLE(); 
779 
780  rp = READ_REG(&pDev->regs->tx0rd);
781 
782  /**** Calculate IRQ Pointer ****/
783  irq = rp + min*GRCAN_MSG_SIZE;
784  /* wrap irq around */
785  if ( irq >= size ){
786    irq_trunk = irq - size;
787  }else
788    irq_trunk = irq;
789 
790  /* trigger HW to do a IRQ when enough room in buffer */
791  pDev->regs->tx0irq = irq_trunk;
792 
793  /* Clear pending Tx IRQ */
794  pDev->regs->picr = GRCAN_TXIRQ_IRQ;
795 
796  /* One problem, if HW already gone past IRQ place the IRQ will
797   * never be received resulting in a thread hang. We check if so
798   * before proceeding.
799   *
800   * has the HW already gone past the IRQ generation place?
801   *  == does min fit info tx buffer?
802   */
803  rp = READ_REG(&pDev->regs->tx0rd);
804 
805  space_left = grcan_hw_txspace(rp,wp,size);
806 
807  if ( space_left < min ){
808    /* Still too full, proceed with sleep - Turn on IRQ (unmask irq) */
809    pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
810    wait=1;
811  }else{
812    /* There are enough room in buffer, abort wait - don't unmask interrupt */
813    wait=0;
814  }
815  IRQ_GLOBAL_ENABLE();
816 
817  /* Wait for IRQ to fire only if it has been triggered */
818  if ( wait ){
819    if ( rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ==
820         RTEMS_UNSATISFIED ){
821      /* Device driver has flushed us, this may be due to another thread has
822       * closed the device, this is to avoid deadlock */
823      return -1;
824    }
825  }
826 
827  /* At this point the TxIRQ has been masked, we ned not to mask it */
828  return 0;
829}
830
831static int grcan_tx_flush(struct grcan_priv *pDev)
832{
833  int wait;
834  unsigned int rp, wp;
835  FUNCDBG();
836 
837  /* loop until all data in circular buffer has been read by hw.
838   * (write pointer != read pointer )
839   *
840   * Hardware doesn't update write pointer - we do
841   */
842  while ( (wp=READ_REG(&pDev->regs->tx0wr)) != (rp=READ_REG(&pDev->regs->tx0rd)) ) {
843    /* Wait for TX empty IRQ */
844    IRQ_GLOBAL_DISABLE();
845    /* Clear pending TXEmpty IRQ */
846    pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
847     
848    if ( wp != READ_REG(&pDev->regs->tx0rd) ) {
849      /* Still not empty, proceed with sleep - Turn on IRQ (unmask irq) */
850      pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
851      wait = 1;
852    }else{
853      /* TX fifo is empty */
854      wait = 0;
855    }
856    IRQ_GLOBAL_ENABLE();
857    if ( !wait )
858      break;
859   
860    /* Wait for IRQ to wake us */
861    if ( rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ==
862         RTEMS_UNSATISFIED ) {
863      return -1;
864    }
865  }
866  return 0;
867}
868
869static int grcan_alloc_buffers(struct grcan_priv *pDev, int rx, int tx)
870{
871  FUNCDBG();
872 
873  if ( tx ) {
874#ifdef STATIC_TX_BUF_ADDR
875    pDev->_tx = STATIC_TX_BUF_ADDR(pDev->minor);
876    if ( pDev->txbuf_size > STATIC_TX_BUF_SIZE ){
877      pDev->txbuf_size = STATIC_TX_BUF_SIZE;
878      return -1;
879    }
880    /* Assume aligned buffer */
881    pDev->tx = (struct grcan_msg *)pDev->_tx;
882#else
883    pDev->_tx = malloc(pDev->txbuf_size + BUFFER_ALIGNMENT_NEEDS);
884    if ( !pDev->_tx )
885      return -1;
886
887    /* Align TX buffer */
888    pDev->tx = (struct grcan_msg *)
889               (((unsigned int)pDev->_tx + (BUFFER_ALIGNMENT_NEEDS-1)) &
890               ~(BUFFER_ALIGNMENT_NEEDS-1));
891#endif
892  }
893 
894  if ( rx ) {
895#ifdef STATIC_RX_BUF_ADDR
896    pDev->_rx = STATIC_RX_BUF_ADDR(pDev->minor);
897    if ( pDev->rxbuf_size > STATIC_RX_BUF_SIZE ){
898      pDev->rxbuf_size = STATIC_RX_BUF_SIZE;
899      return -1;
900    }
901    /* Assume aligned buffer */
902    pDev->rx = (struct grcan_msg *)pDev->_rx;
903#else
904    pDev->_rx = malloc(pDev->rxbuf_size + BUFFER_ALIGNMENT_NEEDS);
905    if ( !pDev->_rx )
906      return -1;
907
908    /* Align TX buffer */
909    pDev->rx = (struct grcan_msg *)
910               (((unsigned int)pDev->_rx + (BUFFER_ALIGNMENT_NEEDS-1)) &
911               ~(BUFFER_ALIGNMENT_NEEDS-1));
912#endif
913  }
914  return 0;
915}
916
917static void grcan_free_buffers(struct grcan_priv *pDev, int rx, int tx)
918{
919  FUNCDBG();
920 
921#ifndef STATIC_TX_BUF_ADDR
922  if ( tx && pDev->_tx ){
923    free(pDev->_tx);
924    pDev->_tx = NULL;
925    pDev->tx = NULL;
926  }
927#endif
928#ifndef STATIC_RX_BUF_ADDR
929  if ( rx && pDev->_rx ){
930    free(pDev->_rx);
931    pDev->_rx = NULL;
932    pDev->rx = NULL;
933  }
934#endif
935}
936
937#if 0
938static char *almalloc(int sz)
939{
940  char *tmp;
941  tmp = calloc(1,2*sz);
942  tmp = (char *) (((int)tmp+sz) & ~(sz -1));
943  return(tmp);
944}
945#endif
946
947static rtems_device_driver grcan_initialize(
948  rtems_device_major_number major,
949  rtems_device_minor_number unused,
950  void *arg
951  )
952{
953  int minor;
954  struct grcan_priv *pDev;
955  amba_apb_device dev;
956  rtems_status_code status;
957  char fs_name[20];
958  unsigned int sys_freq_hz;
959
960  printk("grcan_initialize()\n\r");
961
962  FUNCDBG();
963 
964  /* find GRCAN cores */
965  if ( !grcan_cores ) {   
966    grcan_core_cnt = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,GAISLER_GRHCAN);
967    DBG("GRCAN: Using AMBA Plug&Play, found %d cores\n",grcan_core_cnt);
968    if ( grcan_core_cnt < 1 )
969      return RTEMS_UNSATISFIED;
970  }
971
972#ifdef GRCAN_MAX_CORENR
973  /* limit number of cores */
974  if ( grcan_core_cnt > GRCAN_MAX_CORENR )
975    grcan_core_cnt = GRCAN_MAX_CORENR;
976#endif
977
978  /* Allocate memory for cores */
979  grcans = malloc(grcan_core_cnt * sizeof(struct grcan_priv));
980  if ( !grcans )
981    return RTEMS_NO_MEMORY;
982  memset(grcans,0,grcan_core_cnt * sizeof(struct grcan_priv));
983
984  /* make a local copy of device name */
985  strcpy(fs_name,GRCAN_DEVNAME);
986
987  /* Detect System Frequency from initialized timer */
988#ifndef SYS_FREQ_HZ
989#if defined(LEON3)
990  /* LEON3: find timer address via AMBA Plug&Play info */
991  {
992    amba_apb_device gptimer;
993    LEON3_Timer_Regs_Map *tregs;
994
995    if (amba_find_apbslv (&amba_conf, VENDOR_GAISLER, GAISLER_GPTIMER, &gptimer)
996        == 1) {
997      tregs = (LEON3_Timer_Regs_Map *) gptimer.start;
998      sys_freq_hz = (tregs->scaler_reload + 1) * 1000 * 1000;
999      DBG("GRCAN: detected %dHZ system frequency\n\r", sys_freq_hz);
1000    } else {
1001      sys_freq_hz = 40000000;   /* Default to 40MHz */
1002      printk("GRCAN: Failed to detect system frequency\n\r");
1003    }
1004  }
1005#elif defined(LEON2)
1006  /* LEON2: use hardcoded address to get to timer */
1007  {
1008    LEON_Register_Map *regs = (LEON_Register_Map *) 0x80000000;
1009
1010    sys_freq_hz = (regs->Scaler_Reload + 1) * 1000 * 1000;
1011  }
1012#else
1013#error CPU not supported by driver
1014#endif
1015#else
1016  /* Use hardcoded frequency */
1017  sys_freq_hz = SYS_FREQ_HZ;
1018#endif
1019
1020  for(minor=0; minor<grcan_core_cnt; minor++){
1021
1022    pDev = &grcans[minor];
1023    pDev->minor = minor;
1024    pDev->open = 0;
1025    pDev->corefreq_hz = sys_freq_hz;
1026    GRCAN_DEVNAME_NO(fs_name,minor);
1027   
1028    /* Find core address & IRQ */
1029    if ( !grcan_cores ) {
1030      amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,GAISLER_GRHCAN,&dev,minor);
1031      pDev->irq = dev.irq;
1032      pDev->regs = (struct grcan_regs *)dev.start;
1033    }else{
1034      pDev->irq = grcan_cores[minor].irq;
1035      pDev->regs = (struct grcan_regs *)grcan_cores[minor].base_address;
1036    }
1037   
1038    DBG("Registering GRCAN core at [0x%x] irq %d, minor %d as %s\n",pDev->regs,pDev->irq,minor,fs_name);
1039    printk("Registering GRCAN core at [0x%x] irq %d, minor %d as %s\n\r",pDev->regs,pDev->irq,minor,fs_name);
1040   
1041    status = rtems_io_register_name(fs_name, major, 0);
1042    if (status != RTEMS_SUCCESSFUL)
1043      rtems_fatal_error_occurred(status);
1044   
1045                /* Reset Hardware before attaching IRQ handler */
1046    grcan_hw_reset(pDev->regs);
1047                               
1048    /* Register interrupt handler */
1049    GRCAN_REG_INT(GRCAN_PREFIX(_interrupt_handler), pDev->irq+GRCAN_IRQ_IRQ, pDev);
1050    /*
1051    GRCAN_REG_INT(grcan_interrupt_handler, pDev->irq+GRCAN_IRQ_TXSYNC, pDev);
1052    GRCAN_REG_INT(grcan_interrupt_handler, pDev->irq+GRCAN_IRQ_RXSYNC, pDev);
1053    */
1054   
1055    /* RX Semaphore created with count = 0 */
1056    if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'R', '0'+minor),
1057        0,
1058        RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
1059        RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1060        0,
1061        &pDev->rx_sem) != RTEMS_SUCCESSFUL )
1062      return RTEMS_INTERNAL_ERROR;
1063
1064    /* TX Semaphore created with count = 0 */
1065    if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'T', '0'+minor),
1066        0,
1067        RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
1068        RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1069        0,
1070        &pDev->tx_sem) != RTEMS_SUCCESSFUL )
1071      return RTEMS_INTERNAL_ERROR;
1072
1073    /* TX Empty Semaphore created with count = 0 */
1074    if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'E', '0'+minor),
1075        0,
1076        RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
1077        RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1078        0,
1079        &pDev->txempty_sem) != RTEMS_SUCCESSFUL )
1080      return RTEMS_INTERNAL_ERROR;
1081
1082    /* Device Semaphore created with count = 1 */
1083    if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'A', '0'+minor),
1084        1,
1085        RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
1086        RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
1087        0,
1088        &pDev->dev_sem) != RTEMS_SUCCESSFUL )
1089      return RTEMS_INTERNAL_ERROR;
1090  }
1091
1092  return RTEMS_SUCCESSFUL;
1093}
1094
1095static rtems_device_driver grcan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg) {
1096  struct grcan_priv *pDev;
1097  rtems_device_driver ret;
1098 
1099  FUNCDBG();
1100
1101  if ( (minor < 0) || (minor>=grcan_core_cnt) ) {
1102    DBG("Wrong minor %d\n", minor);
1103    return RTEMS_INVALID_NUMBER;
1104  }
1105 
1106  pDev = &grcans[minor];
1107
1108  /* Wait until we get semaphore */
1109  if ( rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) !=
1110       RTEMS_SUCCESSFUL ){
1111    return RTEMS_INTERNAL_ERROR;
1112  }
1113 
1114  /* is device busy/taken? */
1115  if  ( pDev->open ) {
1116    ret=RTEMS_RESOURCE_IN_USE;
1117    goto out;
1118  }
1119
1120  /* Mark device taken */
1121  pDev->open = 1;
1122
1123  pDev->txblock = pDev->rxblock = 1;
1124  pDev->txcomplete = pDev->rxcomplete = 0;
1125  pDev->started = 0;
1126  pDev->config_changed = 1;
1127  pDev->config.silent = 0;
1128  pDev->config.abort = 0;
1129  pDev->config.selection.selection = 0;
1130  pDev->config.selection.enable0 = 0;
1131  pDev->config.selection.enable1 = 1;
1132  pDev->flushing = 0;
1133  pDev->rx = pDev->_rx = NULL;
1134  pDev->tx = pDev->_tx = NULL;
1135  pDev->txbuf_size = TX_BUF_SIZE;
1136  pDev->rxbuf_size = RX_BUF_SIZE;
1137  printk("Defaulting to rxbufsize: %d, txbufsize: %d\n",RX_BUF_SIZE,TX_BUF_SIZE);
1138 
1139  /* Default to accept all messages */
1140  pDev->afilter.mask = 0x00000000;
1141  pDev->afilter.code = 0x00000000;
1142   
1143  /* Default to disable sync messages (only trigger when id is set to all ones) */
1144  pDev->sfilter.mask = 0xffffffff;
1145  pDev->sfilter.code = 0x00000000;
1146   
1147  /* Calculate default timing register values */
1148  grcan_calc_timing(GRCAN_DEFAULT_BAUD,pDev->corefreq_hz,&pDev->config.timing);
1149 
1150  if ( grcan_alloc_buffers(pDev,1,1) ) {
1151    ret=RTEMS_NO_MEMORY;
1152    goto out;
1153  }
1154 
1155  /* Clear statistics */
1156  memset(&pDev->stats,0,sizeof(struct grcan_stats));
1157 
1158  ret = RTEMS_SUCCESSFUL;
1159out:
1160  rtems_semaphore_release(pDev->dev_sem);
1161  return ret;
1162}
1163
1164static rtems_device_driver grcan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1165{
1166  struct grcan_priv *pDev = &grcans[minor];
1167 
1168  FUNCDBG();
1169 
1170  if ( pDev->started )
1171    grcan_stop(pDev);
1172 
1173  grcan_hw_reset(pDev->regs);
1174 
1175  grcan_free_buffers(pDev,1,1);
1176 
1177  /* Mark Device as closed */
1178  pDev->open = 0;
1179
1180  return RTEMS_SUCCESSFUL;
1181}
1182
1183static rtems_device_driver grcan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1184{
1185  struct grcan_priv *pDev = &grcans[minor];
1186  rtems_libio_rw_args_t *rw_args; 
1187  CANMsg *dest;
1188  unsigned int count, left;
1189  int req_cnt;
1190 
1191  rw_args = (rtems_libio_rw_args_t *) arg;
1192  dest = (CANMsg *) rw_args->buffer;
1193  req_cnt = rw_args->count / sizeof(CANMsg);
1194
1195  FUNCDBG();
1196 
1197  if ( (!dest) || (req_cnt<1) )
1198    return RTEMS_INVALID_NAME;
1199 
1200  if ( !pDev->started )
1201    return RTEMS_RESOURCE_IN_USE;
1202
1203/*  FUNCDBG("grcan_read [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);*/
1204 
1205  count = grcan_hw_read_try(pDev,pDev->regs,dest,req_cnt);
1206  if ( !( pDev->rxblock && pDev->rxcomplete && (count!=req_cnt) ) ){
1207    if ( count > 0 ) {
1208      /* Successfully received messages (at least one) */
1209      rw_args->bytes_moved = count * sizeof(CANMsg);
1210      return RTEMS_SUCCESSFUL;
1211    }
1212 
1213    /* nothing read, shall we block? */
1214    if ( !pDev->rxblock ) {
1215      /* non-blocking mode */
1216      rw_args->bytes_moved = 0;
1217      return RTEMS_TIMEOUT;
1218    }
1219  }
1220
1221  while(count == 0 || (pDev->rxcomplete && (count!=req_cnt)) ){
1222 
1223    if ( !pDev->rxcomplete ){
1224      left = 1; /* return as soon as there is one message available */
1225    }else{
1226      left = req_cnt - count;     /* return as soon as all data are available */
1227
1228      /* never wait for more than the half the maximum size of the receive buffer
1229       * Why? We need some time to copy buffer before to catch up with hw, otherwise
1230       * we would have to copy everything when the data has been received.
1231       */
1232      if ( left > ((pDev->rxbuf_size/GRCAN_MSG_SIZE)/2) ){
1233        left = (pDev->rxbuf_size/GRCAN_MSG_SIZE)/2;
1234      }
1235    }
1236
1237    if ( grcan_wait_rxdata(pDev,left) ) {
1238      /* The wait has been aborted, probably due to
1239       * the device driver has been closed by another
1240       * thread.
1241       */
1242      rw_args->bytes_moved = count * sizeof(CANMsg);
1243      return RTEMS_UNSATISFIED;
1244    }
1245   
1246    /* Try read bytes from circular buffer */
1247    count += grcan_hw_read_try(
1248      pDev,
1249      pDev->regs,
1250      dest+count,
1251      req_cnt-count);
1252  }
1253  /* no need to unmask IRQ as IRQ Handler do that for us. */
1254  rw_args->bytes_moved = count * sizeof(CANMsg);
1255  return RTEMS_SUCCESSFUL;
1256}
1257 
1258static rtems_device_driver grcan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1259{
1260  struct grcan_priv *pDev = &grcans[minor];
1261  rtems_libio_rw_args_t *rw_args;
1262  CANMsg *source;
1263  unsigned int count, left;
1264  int req_cnt;
1265 
1266  DBGC(DBG_TX,"\n");
1267  /*FUNCDBG();*/
1268 
1269  if ( !pDev->started || pDev->config.silent || pDev->flushing )
1270    return RTEMS_RESOURCE_IN_USE;
1271 
1272  rw_args = (rtems_libio_rw_args_t *) arg;
1273  req_cnt = rw_args->count / sizeof(CANMsg);
1274  source = (CANMsg *) rw_args->buffer;
1275 
1276  /* check proper length and buffer pointer */
1277  if (( req_cnt < 1) || (source == NULL) ){
1278    return RTEMS_INVALID_NAME;
1279  }
1280   
1281  count = grcan_hw_write_try(pDev,pDev->regs,source,req_cnt);
1282  if ( !(pDev->txblock && pDev->txcomplete && (count!=req_cnt)) ) {
1283    if ( count > 0 ) {
1284      /* Successfully transmitted chars (at least one char) */
1285      rw_args->bytes_moved = count * sizeof(CANMsg);
1286      return RTEMS_SUCCESSFUL;
1287    }
1288 
1289    /* nothing written, shall we block? */
1290    if ( !pDev->txblock ) {
1291      /* non-blocking mode */
1292      rw_args->bytes_moved = 0;
1293      return RTEMS_TIMEOUT;
1294    }
1295  }
1296 
1297  /* if in txcomplete mode we need to transmit all chars */
1298  while((count == 0) || (pDev->txcomplete && (count!=req_cnt)) ){
1299    /*** block until room to fit all or as much of transmit buffer as possible IRQ comes
1300     * Set up a valid IRQ point so that an IRQ is received
1301     * when we can put a chunk of data into transmit fifo
1302     */
1303    if ( !pDev->txcomplete ){
1304      left = 1; /* wait for anything to fit buffer */
1305    }else{
1306      left = req_cnt - count; /* wait for all data to fit in buffer */
1307   
1308      /* never wait for more than the half the maximum size of the transmitt buffer
1309       * Why? We need some time to fill buffer before hw catches up.
1310       */
1311      if ( left > ((pDev->txbuf_size/GRCAN_MSG_SIZE)/2) ){
1312        left = (pDev->txbuf_size/GRCAN_MSG_SIZE)/2;
1313      }
1314    }
1315   
1316    /* Wait until more room in transmit buffer */
1317    if ( grcan_wait_txspace(pDev,left) ){
1318      /* The wait has been aborted, probably due to
1319       * the device driver has been closed by another
1320       * thread. To avoid deadlock we return directly
1321       * with error status.
1322       */
1323      rw_args->bytes_moved = count * sizeof(CANMsg);
1324      return RTEMS_UNSATISFIED;
1325    }
1326   
1327    if ( pDev->txerror ){
1328      /* Return number of bytes sent, compare write pointers */
1329      pDev->txerror = 0;
1330#if 0
1331#error HANDLE AMBA error
1332#endif
1333    }
1334   
1335    /* Try read bytes from circular buffer */
1336    count += grcan_hw_write_try(
1337      pDev,
1338      pDev->regs,
1339      source+count,
1340      req_cnt-count);
1341  }
1342  /* no need to unmask IRQ as IRQ Handler do that for us. */
1343 
1344  rw_args->bytes_moved = count * sizeof(CANMsg);
1345  return RTEMS_SUCCESSFUL;
1346}
1347
1348static rtems_device_driver grcan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1349{
1350  struct grcan_priv *pDev = &grcans[minor];
1351  rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *)arg;
1352  unsigned int *data = ioarg->buffer;
1353  struct grcan_timing timing;
1354  unsigned int speed;
1355  struct grcan_selection *selection;
1356  int tmp,ret;
1357  rtems_device_driver status;
1358  struct grcan_stats *stats;
1359  struct grcan_filter *filter;
1360 
1361  FUNCDBG();
1362 
1363  if (!ioarg)
1364    return RTEMS_INVALID_NAME;
1365
1366  ioarg->ioctl_return = 0;
1367  switch(ioarg->command) {
1368    case GRCAN_IOC_START:
1369      if ( pDev->started )
1370        return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1371     
1372      if ( (status=grcan_start(pDev)) != RTEMS_SUCCESSFUL ){
1373        return status;
1374      }
1375      /* Read and write are now open... */
1376      pDev->started = 1;
1377      break;
1378   
1379    case GRCAN_IOC_STOP:
1380      if ( !pDev->started )
1381        return RTEMS_RESOURCE_IN_USE;
1382     
1383      grcan_stop(pDev);
1384      pDev->started = 0;
1385      break;
1386   
1387    case GRCAN_IOC_ISSTARTED:
1388      if ( !pDev->started )
1389        return RTEMS_RESOURCE_IN_USE;
1390      break;
1391   
1392    case GRCAN_IOC_FLUSH:
1393      if ( !pDev->started || pDev->flushing || pDev->config.silent )
1394        return RTEMS_RESOURCE_IN_USE;
1395     
1396      pDev->flushing = 1;
1397      tmp = grcan_tx_flush(pDev);
1398      pDev->flushing = 0;
1399      if ( tmp ) {
1400        /* The wait has been aborted, probably due to
1401         * the device driver has been closed by another
1402         * thread.
1403         */
1404         return RTEMS_UNSATISFIED;
1405      }
1406      break;
1407   
1408#if 0   
1409    /* Set physical link */
1410                case GRCAN_IOC_SET_LINK:
1411#ifdef REDUNDANT_CHANNELS
1412                        if ( pDev->started )
1413                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1414                       
1415                        /* switch HW channel */
1416                        pDev->channel = (unsigned int)ioargs->buffer;
1417#else
1418                        return RTEMS_NOT_IMPLEMENTED;
1419#endif
1420                        break;
1421#endif
1422
1423    case GRCAN_IOC_SET_SILENT:
1424      if ( pDev->started )
1425        return RTEMS_RESOURCE_IN_USE;
1426      pDev->config.silent = (int)ioarg->buffer;
1427      pDev->config_changed = 1;
1428      break;   
1429
1430    case GRCAN_IOC_SET_ABORT:
1431      if ( pDev->started )
1432        return RTEMS_RESOURCE_IN_USE;
1433      pDev->config.abort = (int)ioarg->buffer;
1434      /* This Configuration parameter doesn't need HurriCANe reset
1435       * ==> no pDev->config_changed = 1;
1436       */
1437      break;
1438   
1439    case GRCAN_IOC_SET_SELECTION:
1440      if ( pDev->started )
1441        return RTEMS_RESOURCE_IN_USE;
1442
1443      selection = (struct grcan_selection *)ioarg->buffer;
1444      if ( !selection )
1445        return RTEMS_INVALID_NAME;
1446     
1447      pDev->config.selection = *selection;
1448      pDev->config_changed = 1;
1449      break;
1450       
1451    case GRCAN_IOC_SET_RXBLOCK:
1452      pDev->rxblock = (int)ioarg->buffer;
1453      break;
1454     
1455    case GRCAN_IOC_SET_TXBLOCK:
1456      pDev->txblock = (int)ioarg->buffer;
1457      break;
1458   
1459    case GRCAN_IOC_SET_TXCOMPLETE:
1460      pDev->txcomplete = (int)ioarg->buffer;
1461      break;
1462
1463    case GRCAN_IOC_SET_RXCOMPLETE:
1464      pDev->rxcomplete = (int)ioarg->buffer;
1465      break;
1466         
1467    case GRCAN_IOC_GET_STATS:
1468      stats = (struct grcan_stats *)ioarg->buffer;
1469      if ( !stats )
1470        return RTEMS_INVALID_NAME;
1471      *stats = pDev->stats;
1472      break;
1473   
1474    case GRCAN_IOC_CLR_STATS:
1475      IRQ_GLOBAL_DISABLE();
1476      memset(&pDev->stats,0,sizeof(struct grcan_stats));
1477      IRQ_GLOBAL_ENABLE();
1478      break;
1479
1480                case GRCAN_IOC_SET_SPEED:
1481               
1482                        /* cannot change speed during run mode */
1483                        if ( pDev->started )
1484                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1485                       
1486                        /* get speed rate from argument */
1487                        speed = (unsigned int)ioarg->buffer;
1488                        ret = grcan_calc_timing(pDev->corefreq_hz,speed,&timing);
1489                        if ( ret )
1490                                return  RTEMS_INVALID_NAME; /* EINVAL */
1491                       
1492                        /* save timing/speed */
1493                        pDev->config.timing = timing;
1494      pDev->config_changed = 1;
1495                        break;
1496   
1497    case GRCAN_IOC_SET_BTRS:
1498                        /* Set BTR registers manually
1499                         * Read GRCAN/HurriCANe Manual.
1500                         */
1501                        if ( pDev->started )
1502                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1503       
1504                        if ( !ioarg->buffer )
1505        return RTEMS_INVALID_NAME;
1506     
1507                        pDev->config.timing = *(struct grcan_timing *)ioarg->buffer;
1508      pDev->config_changed = 1;
1509                        break;
1510   
1511    case GRCAN_IOC_SET_AFILTER:
1512      filter = (struct grcan_filter *)ioarg->buffer;
1513      if ( !filter ){
1514        /* Disable filtering - let all messages pass */
1515        pDev->afilter.mask = 0x0;
1516        pDev->afilter.code = 0x0;
1517      }else{
1518        /* Save filter */
1519        pDev->afilter = *filter;
1520      }
1521      /* Set hardware acceptance filter */     
1522      grcan_hw_accept(pDev->regs,&pDev->afilter);
1523      break;
1524   
1525    case GRCAN_IOC_SET_SFILTER:
1526      filter = (struct grcan_filter *)ioarg->buffer;
1527      if ( !filter ){
1528        /* disable TX/RX SYNC filtering */
1529        pDev->sfilter.mask = 0xffffffff;
1530        pDev->sfilter.mask = 0;
1531       
1532        /* disable Sync interrupt */
1533        pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1534      }else{
1535        /* Save filter */
1536        pDev->sfilter = *filter;
1537       
1538        /* Enable Sync interrupt */
1539        pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1540      }
1541      /* Set Sync RX/TX filter */
1542      grcan_hw_sync(pDev->regs,&pDev->sfilter);
1543      break;
1544
1545    case GRCAN_IOC_GET_STATUS:
1546      if ( !data )
1547        return RTEMS_INVALID_NAME;
1548      /* Read out the statsu register from the GRCAN core */
1549      data[0] = READ_REG(&pDev->regs->stat);
1550      break;
1551 
1552    default:
1553      return RTEMS_NOT_DEFINED;
1554  }
1555  return RTEMS_SUCCESSFUL;
1556}
1557
1558#ifndef GRCAN_DONT_DECLARE_IRQ_HANDLER
1559/* Find what device caused the IRQ */
1560static rtems_isr grcan_interrupt_handler(rtems_vector_number v)
1561{
1562  int minor=0;
1563  while ( minor < grcan_core_cnt ){
1564    if ( grcans[minor].irq == (v+0x10) ){
1565      grcan_interrupt(&grcans[minor]);
1566      break;
1567    }
1568  }
1569}
1570#endif
1571
1572/* Handle the IRQ */
1573static void grcan_interrupt(struct grcan_priv *pDev)
1574{
1575  unsigned int status = READ_REG(&pDev->regs->pimsr);
1576  unsigned int canstat = READ_REG(&pDev->regs->stat);
1577 
1578  /* Spurious IRQ call? */
1579  if ( !status && !canstat )
1580    return;
1581 
1582  FUNCDBG();
1583 
1584  /* Increment number of interrupts counter */
1585  pDev->stats.ints++;
1586 
1587  if ( (status & GRCAN_ERR_IRQ) || (canstat & GRCAN_STAT_PASS) ){
1588    /* Error-Passive interrupt */
1589    pDev->stats.passive_cnt++;
1590  }
1591
1592  if ( (status & GRCAN_OFF_IRQ) || (canstat & GRCAN_STAT_OFF) ){
1593    /* Bus-off condition interrupt
1594     * The link is brought down by hardware, we wake all threads
1595     * that is blocked in read/write calls and stop futher calls
1596     * to read/write until user has called ioctl(fd,START,0).
1597     */
1598     pDev->started = 0;
1599     grcan_stop(pDev); /* this mask all IRQ sources */
1600     status=0x1ffff; /* clear all interrupts */
1601     goto out;
1602  }
1603 
1604  if ( (status & GRCAN_OR_IRQ) || (canstat & GRCAN_STAT_OR) ){
1605    /* Over-run during reception interrupt */
1606    pDev->stats.overrun_cnt++;
1607  }
1608 
1609  if ( (status & GRCAN_RXAHBERR_IRQ) ||
1610       (status & GRCAN_TXAHBERR_IRQ) ||
1611       (canstat & GRCAN_STAT_AHBERR) ){
1612    /* RX or Tx AHB Error interrupt */
1613    printk("AHBERROR: status: 0x%x, canstat: 0x%x\n",status,canstat);
1614    pDev->stats.ahberr_cnt++;
1615  }
1616 
1617  if ( status & GRCAN_TXLOSS_IRQ ) {
1618    pDev->stats.txloss_cnt++;
1619  }
1620 
1621  if ( status & GRCAN_RXIRQ_IRQ ){
1622    /* RX IRQ pointer interrupt */
1623    /*printk("RxIrq 0x%x\n",status);*/
1624    pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_RXIRQ_IRQ;
1625    rtems_semaphore_release(pDev->rx_sem);
1626  }
1627 
1628  if ( status & GRCAN_TXIRQ_IRQ ){
1629    /* TX IRQ pointer interrupt */
1630    pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXIRQ_IRQ;
1631    rtems_semaphore_release(pDev->tx_sem);
1632  }
1633 
1634  if ( status & GRCAN_TXSYNC_IRQ ){
1635    /* TxSync message transmitted interrupt */
1636    pDev->stats.txsync_cnt++;
1637  }
1638 
1639  if ( status & GRCAN_RXSYNC_IRQ ){
1640    /* RxSync message received interrupt */
1641    pDev->stats.rxsync_cnt++;
1642  }
1643 
1644  if ( status & GRCAN_TXEMPTY_IRQ ){
1645    pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXEMPTY_IRQ;
1646    rtems_semaphore_release(pDev->txempty_sem);
1647  }
1648 
1649out: 
1650  /* Clear IRQs */
1651  pDev->regs->picr = status;
1652}
1653
1654static int grcan_register_internal(void)
1655{
1656  rtems_status_code r;
1657  rtems_device_major_number m;
1658 
1659  if ((r = rtems_io_register_driver(0, &grcan_driver, &m)) !=
1660       RTEMS_SUCCESSFUL) {
1661    switch(r) {
1662      case RTEMS_TOO_MANY:
1663        DBG2("failed RTEMS_TOO_MANY\n");
1664        break;
1665      case RTEMS_INVALID_NUMBER:
1666        DBG2("failed RTEMS_INVALID_NUMBER\n");
1667        break;
1668      case RTEMS_RESOURCE_IN_USE:
1669        DBG2("failed RTEMS_RESOURCE_IN_USE\n");
1670        break;
1671      default:
1672        DBG("failed %i\n",r);
1673        break;
1674    }
1675    return 1;
1676  }
1677  DBG("Registered GRCAN on major %d\n",m);
1678  return 0;
1679}
1680
1681
1682/* Use custom addresses and IRQs to find hardware */
1683int GRCAN_PREFIX(_register_abs)(struct grcan_device_info *devices, int dev_cnt)
1684{
1685  FUNCDBG();
1686 
1687  if ( !devices || (dev_cnt<0) )
1688    return 1;
1689  grcan_cores = devices;
1690  grcan_core_cnt = dev_cnt;
1691
1692  amba_bus = NULL;
1693        return grcan_register_internal();
1694}
1695
1696/* Use prescanned AMBA Plug&Play information to find all GRCAN cores */
1697int GRCAN_PREFIX(_register)(amba_confarea_type *abus)
1698{
1699  FUNCDBG();
1700 
1701  if ( !abus )
1702    return 1;
1703  amba_bus = abus;
1704  grcan_cores = NULL;
1705  grcan_core_cnt = 0;
1706  return grcan_register_internal();
1707}
Note: See TracBrowser for help on using the repository browser.