source: rtems/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-slave.c @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQUartBridge
5 *
6 * @brief UART bridge slave implementation.
7 */
8
9/*
10 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.com/license/LICENSE.
21 */
22
23#include <assert.h>
24
25#include <libchip/sersupp.h>
26
27#include <bspopts.h>
28#include <bsp/uart-bridge.h>
29
30#define TRANSMIT_EVENT RTEMS_EVENT_13
31
32static rtems_mode disable_preemption(void)
33{
34  rtems_status_code sc = RTEMS_SUCCESSFUL;
35  rtems_mode prev_mode = 0;
36
37  sc = rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode);
38  assert(sc == RTEMS_SUCCESSFUL);
39
40  return prev_mode;
41}
42
43static void restore_preemption(rtems_mode prev_mode)
44{
45  rtems_status_code sc = RTEMS_SUCCESSFUL;
46
47  sc = rtems_task_mode (prev_mode, RTEMS_PREEMPT_MASK, &prev_mode);
48  assert(sc == RTEMS_SUCCESSFUL);
49}
50
51static void uart_bridge_slave_service(intercom_packet *packet, void *arg)
52{
53  uart_bridge_slave_control *control = arg;
54  struct rtems_termios_tty *tty = control->tty;
55
56  /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */
57  rtems_mode prev_mode = disable_preemption();
58
59  rtems_termios_enqueue_raw_characters(tty, packet->data, (int) packet->size);
60  qoriq_intercom_free_packet(packet);
61
62  restore_preemption(prev_mode);
63}
64
65static void transmit_task(rtems_task_argument arg)
66{
67  rtems_status_code sc = RTEMS_SUCCESSFUL;
68  uart_bridge_slave_control *control = (uart_bridge_slave_control *) arg;
69  rtems_chain_control *fifo = &control->transmit_fifo;
70  struct rtems_termios_tty *tty = control->tty;
71
72  while (true) {
73    intercom_packet *packet = NULL;
74    sc = rtems_chain_get_with_wait(
75      fifo,
76      TRANSMIT_EVENT,
77      RTEMS_NO_TIMEOUT,
78      (rtems_chain_node **) &packet
79    );
80    assert(sc == RTEMS_SUCCESSFUL);
81
82    /* Workaround for https://www.rtems.org/bugzilla/show_bug.cgi?id=1736 */
83    rtems_mode prev_mode = disable_preemption();
84
85    size_t size = packet->size;
86    qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_MASTER_CORE, packet);
87    rtems_termios_dequeue_characters(tty, (int) size);
88
89    restore_preemption(prev_mode);
90  }
91}
92
93static void create_transmit_task(
94  uart_bridge_slave_control *control
95)
96{
97  rtems_status_code sc = RTEMS_SUCCESSFUL;
98  rtems_id task = RTEMS_ID_NONE;
99  char index = (char) ('0' + control->type - INTERCOM_TYPE_UART_0);
100
101  sc = rtems_task_create(
102    rtems_build_name('U', 'B', 'T', index),
103    QORIQ_UART_BRIDGE_TASK_PRIORITY,
104    0,
105    RTEMS_DEFAULT_MODES,
106    RTEMS_DEFAULT_ATTRIBUTES,
107    &task
108  );
109  assert(sc == RTEMS_SUCCESSFUL);
110
111  sc = rtems_task_start(
112    task,
113    transmit_task,
114    (rtems_task_argument) control
115  );
116  assert(sc == RTEMS_SUCCESSFUL);
117
118  control->transmit_task = task;
119}
120
121static void initialize(int minor)
122{
123  /* Do nothing */
124}
125
126static int first_open(int major, int minor, void *arg)
127{
128  rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
129  struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
130  console_tbl *ct = Console_Port_Tbl[minor];
131  console_data *cd = &Console_Port_Data [minor];
132  uart_bridge_slave_control *control = ct->pDeviceParams;
133  intercom_type type = control->type;
134
135  control->tty = tty;
136  cd->termios_data = tty;
137  rtems_termios_set_initial_baud(tty, 115200);
138  create_transmit_task(control);
139  qoriq_intercom_service_install(type, uart_bridge_slave_service, control);
140
141  return 0;
142}
143
144static int last_close(int major, int minor, void *arg)
145{
146  console_tbl *ct = Console_Port_Tbl[minor];
147  uart_bridge_slave_control *control = ct->pDeviceParams;
148
149  qoriq_intercom_service_remove(control->type);
150
151  return 0;
152}
153
154static ssize_t write_with_interrupts(int minor, const char *buf, size_t len)
155{
156  rtems_status_code sc = RTEMS_SUCCESSFUL;
157  console_tbl *ct = Console_Port_Tbl[minor];
158  uart_bridge_slave_control *control = ct->pDeviceParams;
159  intercom_packet *packet = qoriq_intercom_allocate_packet(
160    control->type,
161    INTERCOM_SIZE_64
162  );
163
164  packet->size = len;
165  memcpy(packet->data, buf, len);
166
167  /*
168   * Due to the lovely Termios implementation we have to hand this over to
169   * another context.
170   */
171  sc = rtems_chain_append_with_notification(
172    &control->transmit_fifo,
173    &packet->glue.node,
174    control->transmit_task,
175    TRANSMIT_EVENT
176  );
177  assert(sc == RTEMS_SUCCESSFUL);
178
179  return 0;
180}
181
182static void write_polled(int minor, char c)
183{
184  console_tbl *ct = Console_Port_Tbl[minor];
185  uart_bridge_slave_control *control = ct->pDeviceParams;
186  intercom_packet *packet = qoriq_intercom_allocate_packet(
187    control->type,
188    INTERCOM_SIZE_64
189  );
190  char *data = packet->data;
191  data [0] = c;
192  packet->size = 1;
193  qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_MASTER_CORE, packet);
194}
195
196static int set_attribues(int minor, const struct termios *term)
197{
198  return -1;
199}
200
201console_fns qoriq_uart_bridge_slave = {
202  .deviceProbe = libchip_serial_default_probe,
203  .deviceFirstOpen = first_open,
204  .deviceLastClose = last_close,
205  .deviceRead = NULL,
206  .deviceWrite = write_with_interrupts,
207  .deviceInitialize = initialize,
208  .deviceWritePolled = write_polled,
209  .deviceSetAttributes = set_attribues,
210  .deviceOutputUsesInterrupts = true
211};
Note: See TracBrowser for help on using the repository browser.