source: mainline/uspace/app/tester/hw/serial/serial1.c@ dac43be

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dac43be was ffdd2b9, checked in by Martin Decky <martin@…>, 15 years ago

integrate standalone test_serial into the tester framework

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2009 Lenka Trochtova
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup tester
30 * @brief Test the serial port driver - loopback test
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <inttypes.h>
38#include <errno.h>
39#include <stdlib.h>
40#include <stdio.h>
41#include <ipc/ipc.h>
42#include <sys/types.h>
43#include <async.h>
44#include <ipc/services.h>
45#include <ipc/devman.h>
46#include <devman.h>
47#include <device/char.h>
48#include <str.h>
49#include <ipc/serial_ctl.h>
50#include "../../tester.h"
51
52#define DEFAULT_COUNT 1024
53#define DEFAULT_SLEEP 100000
54#define EOT "####> End of transfer <####\n"
55
56const char *test_serial1(void)
57{
58 size_t cnt;
59
60 if (test_argc < 1)
61 cnt = DEFAULT_COUNT;
62 else
63 switch (str_size_t(test_argv[0], NULL, 0, true, &cnt)) {
64 case EOK:
65 break;
66 case EINVAL:
67 return "Invalid argument, unsigned integer expected";
68 case EOVERFLOW:
69 return "Argument size overflow";
70 default:
71 return "Unexpected argument error";
72 }
73
74 int res = devman_get_phone(DEVMAN_CLIENT, IPC_FLAG_BLOCKING);
75
76 devman_handle_t handle;
77 res = devman_device_get_handle("/hw/pci0/00:01.0/com1", &handle,
78 IPC_FLAG_BLOCKING);
79 if (res != EOK)
80 return "Could not get serial device handle";
81
82 int phone = devman_device_connect(handle, IPC_FLAG_BLOCKING);
83 if (phone < 0) {
84 devman_hangup_phone(DEVMAN_CLIENT);
85 return "Unable to connect to serial device";
86 }
87
88 char *buf = (char *) malloc(cnt + 1);
89 if (buf == NULL) {
90 ipc_hangup(phone);
91 devman_hangup_phone(DEVMAN_CLIENT);
92 return "Failed to allocate input buffer";
93 }
94
95 ipcarg_t old_baud;
96 ipcarg_t old_par;
97 ipcarg_t old_stop;
98 ipcarg_t old_word_size;
99
100 res = ipc_call_sync_0_4(phone, SERIAL_GET_COM_PROPS, &old_baud,
101 &old_par, &old_word_size, &old_stop);
102 if (res != EOK) {
103 free(buf);
104 ipc_hangup(phone);
105 devman_hangup_phone(DEVMAN_CLIENT);
106 return "Failed to get old serial communication parameters";
107 }
108
109 res = ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, 1200,
110 SERIAL_NO_PARITY, 8, 1);
111 if (EOK != res) {
112 free(buf);
113 ipc_hangup(phone);
114 devman_hangup_phone(DEVMAN_CLIENT);
115 return "Failed to set serial communication parameters";
116 }
117
118 TPRINTF("Trying to read %zu characters from serial device "
119 "(handle=%" PRIun ")\n", cnt, handle);
120
121 size_t total = 0;
122 while (total < cnt) {
123 ssize_t read = read_dev(phone, buf, cnt - total);
124
125 if (read < 0) {
126 ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
127 old_par, old_word_size, old_stop);
128 free(buf);
129 ipc_hangup(phone);
130 devman_hangup_phone(DEVMAN_CLIENT);
131 return "Failed read from serial device";
132 }
133
134 if ((size_t) read > cnt - total) {
135 ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
136 old_par, old_word_size, old_stop);
137 free(buf);
138 ipc_hangup(phone);
139 devman_hangup_phone(DEVMAN_CLIENT);
140 return "Read more data than expected";
141 }
142
143 TPRINTF("Read %zd bytes\n", read);
144
145 if (read == 0)
146 usleep(DEFAULT_SLEEP);
147 else {
148 buf[read] = 0;
149
150 /*
151 * Write data back to the device to test the opposite
152 * direction of data transfer.
153 */
154 ssize_t written = write_dev(phone, buf, read);
155
156 if (written < 0) {
157 ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
158 old_par, old_word_size, old_stop);
159 free(buf);
160 ipc_hangup(phone);
161 devman_hangup_phone(DEVMAN_CLIENT);
162 return "Failed write to serial device";
163 }
164
165 if (written != read) {
166 ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
167 old_par, old_word_size, old_stop);
168 free(buf);
169 ipc_hangup(phone);
170 devman_hangup_phone(DEVMAN_CLIENT);
171 return "Written less data than read from serial device";
172 }
173
174 TPRINTF("Written %zd bytes\n", written);
175 }
176
177 total += read;
178 }
179
180 TPRINTF("Trying to write EOT banner to the serial device\n");
181
182 size_t eot_size = str_size(EOT);
183 ssize_t written = write_dev(phone, (void *) EOT, eot_size);
184
185 ipc_call_sync_4_0(phone, SERIAL_SET_COM_PROPS, old_baud,
186 old_par, old_word_size, old_stop);
187 free(buf);
188 ipc_hangup(phone);
189 devman_hangup_phone(DEVMAN_CLIENT);
190
191 if (written < 0)
192 return "Failed to write EOT banner to serial device";
193
194 if ((size_t) written != eot_size)
195 return "Written less data than the size of the EOT banner "
196 "to serial device";
197
198 return NULL;
199}
200
201/** @}
202 */
Note: See TracBrowser for help on using the repository browser.