Initialize return value.
[openocd.git] / src / jtag / drivers / remote_bitbang.c
blobd3ab1b11d3cd83282ea21b3362b4916b0e20b50c
1 /***************************************************************************
2 * Copyright (C) 2011 by Richard Uhler *
3 * ruhler@mit.edu *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <netdb.h>
27 #include <jtag/interface.h>
28 #include "bitbang.h"
30 // from unix man page and sys/un.h:
31 #define UNIX_PATH_MAX 108
33 // arbitrary limit on host name length:
34 #define REMOTE_BITBANG_HOST_MAX 255
36 #define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
37 LOG_ERROR(expr); LOG_ERROR("Terminating openocd."); exit(-1);
39 static char remote_bitbang_host[REMOTE_BITBANG_HOST_MAX] = "openocd";
40 static uint16_t remote_bitbang_port = 0;
42 FILE* remote_bitbang_in;
43 FILE* remote_bitbang_out;
45 static void remote_bitbang_putc(int c)
47 if (EOF == fputc(c, remote_bitbang_out)) {
48 REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno));
52 static int remote_bitbang_quit(void)
54 if (EOF == fputc('Q', remote_bitbang_out)) {
55 LOG_ERROR("fputs: %s", strerror(errno));
56 return ERROR_FAIL;
59 if (EOF == fflush(remote_bitbang_out)) {
60 LOG_ERROR("fflush: %s", strerror(errno));
61 return ERROR_FAIL;
64 // We only need to close one of the FILE*s, because they both use the same
65 // underlying file descriptor.
66 if (EOF == fclose(remote_bitbang_out)) {
67 LOG_ERROR("fclose: %s", strerror(errno));
68 return ERROR_FAIL;
71 LOG_INFO("remote_bitbang interface quit");
72 return ERROR_OK;
75 // Get the next read response.
76 static int remote_bitbang_rread(void)
78 if (EOF == fflush(remote_bitbang_out)) {
79 remote_bitbang_quit();
80 REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno));
83 int c = fgetc(remote_bitbang_in);
84 switch (c) {
85 case '0': return 0;
86 case '1': return 1;
87 default:
88 remote_bitbang_quit();
89 REMOTE_BITBANG_RAISE_ERROR(
90 "remote_bitbang: invalid read response: %c(%i)", c, c);
94 static int remote_bitbang_read(void)
96 remote_bitbang_putc('R');
97 return remote_bitbang_rread();
100 static void remote_bitbang_write(int tck, int tms, int tdi)
102 char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
103 remote_bitbang_putc(c);
106 static void remote_bitbang_reset(int trst, int srst)
108 char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
109 remote_bitbang_putc(c);
112 static void remote_bitbang_blink(int on)
114 char c = on ? 'B' : 'b';
115 remote_bitbang_putc(c);
118 static struct bitbang_interface remote_bitbang_bitbang = {
119 .read = &remote_bitbang_read,
120 .write = &remote_bitbang_write,
121 .reset = &remote_bitbang_reset,
122 .blink = &remote_bitbang_blink,
125 static int remote_bitbang_speed(int speed)
127 return ERROR_OK;
130 static int remote_bitbang_init_tcp(void)
132 LOG_INFO("Connecting to %s:%i", remote_bitbang_host, remote_bitbang_port);
133 int fd = socket(PF_INET, SOCK_STREAM, 0);
134 if (fd < 0) {
135 LOG_ERROR("socket: %s", strerror(errno));
136 return ERROR_FAIL;
139 struct hostent* hent = gethostbyname(remote_bitbang_host);
140 if (hent == NULL) {
141 char* errorstr = "???";
142 switch (h_errno) {
143 case HOST_NOT_FOUND: errorstr = "host not found"; break;
144 case NO_ADDRESS: errorstr = "no address"; break;
145 case NO_RECOVERY: errorstr = "no recovery"; break;
146 case TRY_AGAIN: errorstr = "try again"; break;
148 LOG_ERROR("gethostbyname: %s", errorstr);
149 return ERROR_FAIL;
152 struct sockaddr_in addr;
153 addr.sin_family = AF_INET;
154 addr.sin_port = htons(remote_bitbang_port);
155 addr.sin_addr = *(struct in_addr*)hent->h_addr;
156 if (connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
157 LOG_ERROR("connect: %s", strerror(errno));
158 return ERROR_FAIL;
161 remote_bitbang_in = fdopen(fd, "r");
162 if (remote_bitbang_in == NULL) {
163 LOG_ERROR("fdopen: failed to open read stream");
164 return ERROR_FAIL;
167 remote_bitbang_out = fdopen(fd, "w");
168 if (remote_bitbang_out == NULL) {
169 LOG_ERROR("fdopen: failed to open write stream");
170 return ERROR_FAIL;
173 LOG_INFO("remote_bitbang driver initialized");
174 return ERROR_OK;
177 static int remote_bitbang_init_unix(void)
179 LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
180 int fd = socket(PF_UNIX, SOCK_STREAM, 0);
181 if (fd < 0) {
182 LOG_ERROR("socket: %s", strerror(errno));
183 return ERROR_FAIL;
186 struct sockaddr_un addr;
187 addr.sun_family = AF_UNIX;
188 strncpy(addr.sun_path, remote_bitbang_host, UNIX_PATH_MAX);
189 addr.sun_path[UNIX_PATH_MAX-1] = '\0';
191 if (connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0) {
192 LOG_ERROR("connect: %s", strerror(errno));
193 return ERROR_FAIL;
196 remote_bitbang_in = fdopen(fd, "r");
197 if (remote_bitbang_in == NULL) {
198 LOG_ERROR("fdopen: failed to open read stream");
199 return ERROR_FAIL;
202 remote_bitbang_out = fdopen(fd, "w");
203 if (remote_bitbang_out == NULL) {
204 LOG_ERROR("fdopen: failed to open write stream");
205 return ERROR_FAIL;
208 LOG_INFO("remote_bitbang driver initialized");
209 return ERROR_OK;
212 static int remote_bitbang_init(void)
214 bitbang_interface = &remote_bitbang_bitbang;
216 LOG_INFO("Initializing remote_bitbang driver");
217 if (remote_bitbang_port == 0) {
218 return remote_bitbang_init_unix();
220 return remote_bitbang_init_tcp();
223 static int remote_bitbang_khz(int khz, int* jtag_speed)
225 *jtag_speed = 0;
226 return ERROR_OK;
229 static int remote_bitbang_speed_div(int speed, int* khz)
231 // I don't think this really matters any.
232 *khz = 1;
233 return ERROR_OK;
237 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
239 if (CMD_ARGC == 1) {
240 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], remote_bitbang_port);
241 return ERROR_OK;
243 return ERROR_COMMAND_SYNTAX_ERROR;
246 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
248 if (CMD_ARGC == 1) {
249 strncpy(remote_bitbang_host, CMD_ARGV[0], REMOTE_BITBANG_HOST_MAX);
250 remote_bitbang_host[REMOTE_BITBANG_HOST_MAX-1] = '\0';
251 return ERROR_OK;
253 return ERROR_COMMAND_SYNTAX_ERROR;
257 static const struct command_registration remote_bitbang_command_handlers[] = {
259 .name = "remote_bitbang_port",
260 .handler = remote_bitbang_handle_remote_bitbang_port_command,
261 .mode = COMMAND_CONFIG,
262 .help = "Set the port to use to connect to the remote jtag.\n"
263 " if 0, use unix sockets to connect to the remote jtag.",
264 .usage = "port_number",
267 .name = "remote_bitbang_host",
268 .handler = remote_bitbang_handle_remote_bitbang_host_command,
269 .mode = COMMAND_CONFIG,
270 .help = "Set the host to use to connect to the remote jtag.\n"
271 " if port is 0, this is the name of the unix socket to use.",
272 .usage = "host_name",
274 COMMAND_REGISTRATION_DONE,
277 struct jtag_interface remote_bitbang_interface = {
278 .name = "remote_bitbang",
279 .execute_queue = &bitbang_execute_queue,
280 .speed = &remote_bitbang_speed,
281 .commands = remote_bitbang_command_handlers,
282 .init = &remote_bitbang_init,
283 .quit = &remote_bitbang_quit,
284 .khz = &remote_bitbang_khz,
285 .speed_div = &remote_bitbang_speed_div,