From 4ad0383020b999845663c368751c4a50d462f41d Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 15:27:03 -0300 Subject: [PATCH 1/6] tools/atrf-proxy/: network proxy (untested) --- tools/atrf-proxy/Makefile | 16 ++ tools/atrf-proxy/PROTOCOL | 68 +++++++ tools/atrf-proxy/atrf-proxy.c | 331 ++++++++++++++++++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 tools/atrf-proxy/Makefile create mode 100644 tools/atrf-proxy/PROTOCOL create mode 100644 tools/atrf-proxy/atrf-proxy.c diff --git a/tools/atrf-proxy/Makefile b/tools/atrf-proxy/Makefile new file mode 100644 index 0000000..4ba765d --- /dev/null +++ b/tools/atrf-proxy/Makefile @@ -0,0 +1,16 @@ +# +# atrf-proxy/Makefile - ATRF network proxy +# +# Written 2011 by Werner Almesberger +# Copyright 2011 Werner Almesberger +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# + + +MAIN = atrf-proxy + +include ../Makefile.common diff --git a/tools/atrf-proxy/PROTOCOL b/tools/atrf-proxy/PROTOCOL new file mode 100644 index 0000000..8cdf53b --- /dev/null +++ b/tools/atrf-proxy/PROTOCOL @@ -0,0 +1,68 @@ +Protocol specification +====================== + +Messages +-------- + + ++[greeting] +-message + +RESET ++[comment] +-message + +RESET_RF ++[comment] +-message + +TEST ++[comment] +-message + +SLP_TR 0|1 ++[comment] +-message + +CLKM freq_mhz ++[comment] +-message + +SET register value ++[comment] +-message + +GET register ++value +-message + +WRITE length raw-data ++[comment] +-message + +READ ++length raw-data +-message + +POLL ++0|1 +-message + + +Message format +-------------- + +Commands are not case-sensitive. Messages and comments consist of printable +ASCII characters and spaces. + +Whitespace separating words is always exactly one space character. +Lines end with a * single newline, without trailing whitespace. +Numeric values are in C notation, i.e., 64, 0100, and 0x40 would all +represent the same value. + +"raw-data" is a string of binary data of the indicated length. The other +formatting conventions remain valid after this string, i.e., it must be +followed by a single newline. + +The device is implicitly opened when establishing a TCP session. The +device is implicitly closed when closing the TCP session. diff --git a/tools/atrf-proxy/atrf-proxy.c b/tools/atrf-proxy/atrf-proxy.c new file mode 100644 index 0000000..be06382 --- /dev/null +++ b/tools/atrf-proxy/atrf-proxy.c @@ -0,0 +1,331 @@ +/* + * atrf-proxy/atrf-proxy.c - ATRF network proxy + * + * Written 2011 by Werner Almesberger + * Copyright 2011 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include +#include +#include +#include /* for strcasecmp */ +#include +#include +#include +#include + +#include "atrf.h" +#include "netio.h" + + +#define DEFAULT_PORT 0x1540 /* 5440 */ + + +static int verbose = 0; + + +static int get_num(struct netio *netio, int last, int *ret) +{ + char buf[10]; + ssize_t got; + unsigned long n; + char *end; + + got = netio_read_until(netio, + last ? "\n" : " ", buf, sizeof(buf), NULL); + if (got < 0) { + *ret = -1; + return -1; + } + buf[got] = 0; + n = strtoul(buf, &end, 0); + if (*end) { + *ret = netio_printf(netio, "-bad number\n"); + return -1; + } + /* @@@ check against INT_MAX */ + return n; +} + + +static int cmd_two(struct atrf_dsc *dsc, struct netio *netio, const char *cmd) +{ + int n, ret; + + n = get_num(netio, 0, &ret); + if (n < 0) + return ret; + if (n > 255) + return netio_printf(netio, "-bad argument\n"); + + if (!strcasecmp(cmd, "set")) { + int val; + + val = get_num(netio, 1, &ret); + if (val < 0) + return ret; + if (val > 255) + return netio_printf(netio, "-bad argument\n"); + atrf_reg_write(dsc, n, ret); + if (atrf_error(dsc)) + return netio_printf(netio, "-I/O error\n"); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "write")) { + uint8_t *tmp; + ssize_t got; + + if (n > 128) + return netio_printf(netio, "-bad argument\n"); + tmp = malloc(n+1); + if (!tmp) + return netio_printf(netio, "-out of memory\n"); + got = netio_read(netio, tmp, n+1); + if (got != n+1) { + free(tmp); + return -1; + } + if (tmp[n] != '\n') { + free(tmp); + return netio_printf(netio, "-unterminated command\n"); + } + atrf_buf_write(dsc, tmp, n); + free(tmp); + if (atrf_error(dsc)) + return netio_printf(netio, "-I/O error\n"); + return netio_printf(netio, "+\n"); + } + abort(); +} + + +static int cmd_more(struct atrf_dsc *dsc, struct netio *netio, const char *cmd) +{ + int n, ret; + + if (!strcasecmp(cmd, "set")) + return cmd_two(dsc, netio, cmd); + if (!strcasecmp(cmd, "write")) + return cmd_two(dsc, netio, cmd); + + n = get_num(netio, 1, &ret); + if (n < 0) + return ret; + + if (!strcasecmp(cmd, "slp_tr")) { + if (n > 1) + return netio_printf(netio, "-bad argument\n"); + if (atrf_slp_tr(dsc, n) < 0) + return netio_printf(netio, "-I/O error\n"); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "clkm")) { + if (n > 16) + return netio_printf(netio, "-bad argument\n"); + if (atrf_set_clkm(dsc, n) < 0) + return netio_printf(netio, "-error\n"); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "get")) { + uint8_t res; + + if (n > 255) + return netio_printf(netio, "-bad argument\n"); + res = atrf_reg_read(dsc, n); + if (atrf_error(dsc)) + return netio_printf(netio, "-I/O error\n"); + return netio_printf(netio, "+0x%02x\n", res); + } + return netio_printf(netio, "-unrecognized command\n"); +} + + +static int cmd_zero(struct atrf_dsc *dsc, struct netio *netio, const char *cmd) +{ + int res; + + if (!strcasecmp(cmd, "reset")) { + atrf_reset(dsc); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "reset_rf")) { + atrf_reset_rf(dsc); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "test")) { + atrf_test_mode(dsc); + return netio_printf(netio, "+\n"); + } + if (!strcasecmp(cmd, "read")) { + uint8_t buf[128+1]; /* one more for the trailing \n */ + int got; + + got = atrf_buf_read(dsc, buf, sizeof(buf)); + if (got < 0) + return netio_printf(netio, "-I/O error\n"); + if (netio_printf(netio, "+%d ", got) < 0) + return -1; + buf[got] = '\n'; + return netio_write(netio, buf, got+1); + } + if (!strcasecmp(cmd, "poll")) { + res = atrf_interrupt(dsc); + if (res < 0) + return netio_printf(netio, "-I/O error\n"); + if (!res) + usleep(100*1000); + return netio_printf(netio, "+%d\n", res); + } + return netio_printf(netio, "-unrecognized command\n"); +} + + +static void session(const char *driver, struct netio *netio) +{ + struct atrf_dsc *dsc; + + dsc = atrf_open(driver); + if (!dsc) { + netio_printf(netio, "-unable to open driver\n"); + return; + } + + if (netio_printf(netio, + "+connected to %s\n", driver ? driver : "default") < 0) + goto done; + + while (1) { + char buf[100]; + ssize_t got; + char last; + + got = netio_read_until(netio, " \n", buf, sizeof(buf), &last); + if (got < 0) + break; + if (!got && last) { + netio_printf(netio, "-empty input\n"); + continue; + } + buf[got] = 0; + switch (last) { + case ' ': + if (cmd_more(dsc, netio, buf) < 0) + goto done; + break; + case '\n': + if (cmd_zero(dsc, netio, buf) < 0) + goto done; + break; + case 0: + goto done; + default: + abort(); + } + } + +done: + atrf_close(dsc); +} + + +static void loop(const char *driver, int port) +{ + struct sockaddr_in addr; + int s; + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + perror("socket"); + exit(1); + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("bind"); + exit(1); + } + + if (listen(s, 0) < 0) { + perror("listen"); + exit(1); + } + + while (1) { + socklen_t len = sizeof(addr); + int s2; + struct netio *netio; + + s2 = accept(s, (struct sockaddr *) &addr, &len); + if (s2 < 0) { + perror("accept"); + continue; + } + + if (verbose) + fprintf(stderr, "%s:%u\n", inet_ntoa(addr.sin_addr), + ntohs(addr.sin_port)); + + netio = netio_open(s2); + if (netio) { + session(driver, netio); + netio_close(netio); + } else { + if (close(s2) < 0) + perror("close"); + } + } +} + + +static void usage(const char *name) +{ + fprintf(stderr, "usage: %s [-d driver[:arg]] [-v ...] [port]\n", name); + exit(1); +} + + +int main(int argc, char **argv) +{ + unsigned long port = DEFAULT_PORT; + const char *driver = NULL; + char *end; + int c; + + while ((c = getopt(argc, argv, "d:v")) != EOF) + switch (c) { + case 'd': + driver = optarg; + break; + case 'v': + verbose++; + netio_verbose++; + break; + default: + usage(*argv); + } + + switch (argc-optind) { + case 0: + break; + case 1: + port = strtoul(argv[optind], &end, 0); + if (*end || !port || port > 0xffff) + usage(*argv); + break; + default: + usage(*argv); + } + + loop(driver, port); + + return 0; +} From 0b0b5712e86d25e71b0ea4901b349da17fe53222 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 17:19:25 -0300 Subject: [PATCH 2/6] atrf-trim.c (main): passing the trim value is not a usage error --- tools/atrf-trim/atrf-trim.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/atrf-trim/atrf-trim.c b/tools/atrf-trim/atrf-trim.c index 8d8bf5b..d4805f5 100644 --- a/tools/atrf-trim/atrf-trim.c +++ b/tools/atrf-trim/atrf-trim.c @@ -43,8 +43,6 @@ int main(int argc, char *const *argv) default: usage(*argv); } - if (argc != optind) - usage(*argv); switch (argc-optind) { case 0: From 641567e393ea1da761d348bdb44e7f49bf249396 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 17:29:07 -0300 Subject: [PATCH 3/6] tools/lib/atrf.c: moved declaration of driver operations to driver.h --- tools/lib/atrf.c | 4 ---- tools/lib/driver.h | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index a9b8f33..5a9ebca 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -21,10 +21,6 @@ #include "atrf.h" -extern struct atrf_driver atusb_driver; -extern struct atrf_driver atben_driver; - - struct atrf_dsc { const struct atrf_driver *driver; void *handle; diff --git a/tools/lib/driver.h b/tools/lib/driver.h index bc88f3c..f562f0d 100644 --- a/tools/lib/driver.h +++ b/tools/lib/driver.h @@ -36,6 +36,10 @@ struct atrf_driver { }; +extern struct atrf_driver atusb_driver; +extern struct atrf_driver atben_driver; + + int atrf_set_clkm_generic( void (*reg_write)(void *dsc, uint8_t reg, uint8_t value), void *handle, int mhz); From 7be700df117fd33c76d96eca9a801502a88329cc Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 17:34:46 -0300 Subject: [PATCH 4/6] tools/lib/atrf.c: perform driver-specific operations only if using that driver - atrf.c (atrf_usb_handle): only return the handle if using the atusb driver - atrf.c (atrf_ben_regs): only call atben_regs if using the atben driver --- tools/lib/atrf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index 5a9ebca..4c83db4 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -31,20 +31,20 @@ struct atrf_dsc { void *atrf_usb_handle(struct atrf_dsc *dsc) { #ifdef HAVE_USB - return dsc->handle; -#else - return NULL; + if (dsc->driver == &atusb_driver) + return dsc->handle; #endif + return NULL; } void *atrf_ben_regs(struct atrf_dsc *dsc) { #ifdef HAVE_BEN - return atben_regs(dsc->handle); -#else - return NULL; + if (dsc->driver == &atben_driver) + return atben_regs(dsc->handle); #endif + return NULL; } From 39319e145a658a8eb149de7b43ac36af06a4da5e Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 17:45:19 -0300 Subject: [PATCH 5/6] tools/lib/: added network proxy-based driver (in progress) - atnet.c: driver "net", which accessed hardware via atrf-proxy - Makefile (OBJS): added atnet.o - driver.h (atnet_driver), atrf.c (drivers): added the atnet driver - atrf.c (drivers): moved the driver list closer to the top --- tools/lib/Makefile | 2 +- tools/lib/atnet.c | 411 +++++++++++++++++++++++++++++++++++++++++++++ tools/lib/atrf.c | 23 +-- tools/lib/driver.h | 1 + 4 files changed, 425 insertions(+), 12 deletions(-) create mode 100644 tools/lib/atnet.c diff --git a/tools/lib/Makefile b/tools/lib/Makefile index 3b1fd7d..1c03d90 100644 --- a/tools/lib/Makefile +++ b/tools/lib/Makefile @@ -19,7 +19,7 @@ OBJS_host = atusb.o usbopen.o OBJS_ben_jlime = atben.o OBJS_ben_openwrt = atben.o -OBJS = atrf.o misctxrx.o cwtest.o netio.o $(OBJS_$(TARGET)) +OBJS = atrf.o atnet.o misctxrx.o cwtest.o netio.o $(OBJS_$(TARGET)) .PHONY: all clean spotless diff --git a/tools/lib/atnet.c b/tools/lib/atnet.c new file mode 100644 index 0000000..b857598 --- /dev/null +++ b/tools/lib/atnet.c @@ -0,0 +1,411 @@ +/* + * lib/atnet.c - Access functions library for network proxy + * + * Written 2011 by Werner Almesberger + * Copyright 2011 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netio.h" + +#include "driver.h" + + +#define DEFAULT_PORT "5440" + + +static char reply[1000]; + + +static int dialog_vsend(struct netio *netio, const char *fmt, va_list ap) +{ + va_list ap2; + char *buf; + int n; + + va_copy(ap2, ap); + n = vsnprintf(NULL, 0, fmt, ap2); + + buf = malloc(n+1); + if (!buf) { + perror("malloc"); + return -1; + } + + vsprintf(buf, fmt, ap); + + buf[n] = '\n'; + if (netio_write(netio, buf, n+1) < 0) + return -1; + return 0; +} + + +static int dialog_send(struct netio *netio, const char *fmt, ...) +{ + va_list ap; + int res; + + va_start(ap, fmt); + res = dialog_vsend(netio, fmt, ap); + va_end(ap); + return res; +} + + +static int dialog_recv(struct netio *netio) +{ + int n; + + n = netio_read_until(netio, "\n", reply, sizeof(reply)-1, NULL); + if (n < 0) + return -1; + reply[n] = 0; + + return reply[0] == '+' ? 0 : -1; +} + + +static int dialog(struct netio *netio, const char *fmt, ...) +{ + va_list ap; + int res; + + va_start(ap, fmt); + res = dialog_vsend(netio, fmt, ap); + va_end(ap); + if (res < 0) + return res; + + return dialog_recv(netio); +} + + +/* ----- error handling ---------------------------------------------------- */ + + +static int error; + + +static int atnet_error(void *dsc) +{ + return error; +} + + +static int atnet_clear_error(void *dsc) +{ + int ret; + + ret = error; + error = 0; + return ret; +} + + +/* ----- open/close -------------------------------------------------------- */ + + +static void *atnet_open(const char *arg) +{ + char *host = NULL, *comma; + const char *port = DEFAULT_PORT; + struct addrinfo *addrs; + const struct addrinfo *addr; + static struct addrinfo hint = { .ai_socktype = SOCK_STREAM }; + int res, s; + struct netio *netio; + + if (arg) { + host = strdup(arg); + if (!host) { + perror("strdup"); + return NULL; + } + comma = strchr(host, ','); + if (comma) { + *comma = 0; + port = comma+1; + } + } + res = getaddrinfo(arg && *host ? host : NULL, port, &hint, &addrs); + if (res < 0) { + fprintf(stderr, "%s: %s\n", arg, gai_strerror(res)); + free(host); + return NULL; + } + free(host); + + for (addr = addrs; addr; addr = addr->ai_next) { + s = socket(addr->ai_family, addr->ai_socktype, + addr->ai_protocol); + if (s < 0) + continue; + if (connect(s, addr->ai_addr, addr->ai_addrlen) >= 0) + break; + close(s); + } + if (!addr) { + perror(arg); + freeaddrinfo(addrs); + return NULL; + } + + freeaddrinfo(addrs); + + netio = netio_open(s); + if (!netio) + return NULL; + + if (dialog_recv(netio) < 0) { + netio_close(netio); + return NULL; + } + + error = 0; + return netio; +} + + +static void atnet_close(void *dsc) +{ + struct netio *netio = dsc; + + netio_close(netio); +} + + +/* ----- device mode ------------------------------------------------------- */ + + +static void atnet_reset(void *dsc) +{ + struct netio *netio = dsc; + + if (error) + return; + if (dialog(netio, "RESET") < 0) + error = 1; +} + + +static void atnet_reset_rf(void *dsc) +{ + struct netio *netio = dsc; + + if (error) + return; + if (dialog(netio, "RESET_RF") < 0) + error = 1; +} + + +static void atnet_test_mode(void *dsc) +{ + struct netio *netio = dsc; + + if (error) + return; + if (dialog(netio, "TEST") < 0) + error = 1; +} + + +static void atnet_slp_tr(void *dsc, int on) +{ + struct netio *netio = dsc; + + if (error) + return; + if (dialog(netio, "SLP_TR %d", on) < 0) + error = 1; +} + + +/* ----- register access --------------------------------------------------- */ + + +static void atnet_reg_write(void *dsc, uint8_t reg, uint8_t value) +{ + struct netio *netio = dsc; + + if (error) + return; + if (dialog(netio, "SET 0x%02x 0x%02x", reg, value) < 0) + error = 1; +} + + +static uint8_t atnet_reg_read(void *dsc, uint8_t reg) +{ + struct netio *netio = dsc; + unsigned long value; + char *end; + + if (error) + return; + if (dialog(netio, "GET 0x%02x", reg) < 0) { + error = 1; + return 0; + } + value = strtoul(reply+1, &end, 0); + if (*end || value > 255) { + fprintf(stderr, "invalid response \"%s\"\n", reply); + error = 1; + return 0; + } + return value; +} + + +/* ----- frame buffer access ----------------------------------------------- */ + + +static void atnet_buf_write(void *dsc, const void *buf, int size) +{ + struct netio *netio = dsc; + char tmp[20]; + int n; + + if (error) + return; + + n = snprintf(tmp, sizeof(tmp), "WRITE %d ", size); + assert(n < sizeof(tmp)); + if (netio_write(netio, tmp, n) < 0) { + error = 1; + return; + } + + if (netio_write(netio, buf, size) < 0) { + error = 1; + return; + } + + if (netio_write(netio, "\n", 1) < 0) { + error = 1; + return; + } + + if (dialog_recv(netio) < 0) + error = 1; +} + + +static int atnet_buf_read(void *dsc, void *buf, int size) +{ + struct netio *netio = dsc; + uint8_t tmp[200]; + int n, got = 0; + unsigned long len = 0; + char *end; + + if (error) + return -1; + + if (dialog_send(netio, "READ") < 0) + goto fail; + + n = netio_read_until(netio, " ", tmp, sizeof(tmp)-1, NULL); + if (*tmp == '-') { + tmp[n] = 0; + fprintf(stderr, "%s\n", tmp+1); + goto fail; + } + if (*tmp != '+' || n < 3) /* +0 */ + goto invalid; + len = strtoul(tmp+1, &end, 0); + if (*end != ' ') + goto invalid; + if (len > size) { + fprintf(stderr, "buffer overflow\n"); + goto fail; + } + + got = netio_read(netio, buf, len); + if (got < 0) + goto fail; + + if (netio_getc(netio, tmp) < 0) + goto fail; + if (*tmp == '\n') + return len; + +invalid: + fprintf(stderr, "invalid reponse\n"); +fail: + error = 1; + return -1; +} + + +/* ----- RF interrupt ------------------------------------------------------ */ + + +static int atnet_interrupt(void *dsc) +{ + struct netio *netio = dsc; + unsigned long value; + char *end; + + if (error) + return -1; + if (dialog(netio, "POLL") < 0) { + error = 1; + return -1; + } + value = strtoul(reply+1, &end, 0); + if (*end || value > 1) { + fprintf(stderr, "invalid response \"%s\"\n", reply); + error = 1; + return -1; + } + return value; +} + + +/* ----- CLKM handling ----------------------------------------------------- */ + + +static int atnet_set_clkm(void *dsc, int mhz) +{ + struct netio *netio = dsc; + + return dialog(netio, "CLKM %d", mhz); +} + + +/* ----- driver interface -------------------------------------------------- */ + + +struct atrf_driver atnet_driver = { + .name = "net", + .open = atnet_open, + .close = atnet_close, + .error = atnet_error, + .clear_error = atnet_clear_error, + .reset = atnet_reset, + .reset_rf = atnet_reset_rf, + .test_mode = atnet_test_mode, + .slp_tr = atnet_slp_tr, + .set_clkm = atnet_set_clkm, + .reg_write = atnet_reg_write, + .reg_read = atnet_reg_read, + .buf_write = atnet_buf_write, + .buf_read = atnet_buf_read, + .interrupt = atnet_interrupt, +}; diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index 4c83db4..1cf4160 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -28,6 +28,18 @@ struct atrf_dsc { }; +static const struct atrf_driver *drivers[] = { +#ifdef HAVE_BEN + &atben_driver, +#endif +#ifdef HAVE_USB + &atusb_driver, +#endif + &atnet_driver, + NULL +}; + + void *atrf_usb_handle(struct atrf_dsc *dsc) { #ifdef HAVE_USB @@ -92,17 +104,6 @@ static enum atrf_chip_id identify(struct atrf_dsc *dsc) } -const static struct atrf_driver *drivers[] = { -#ifdef HAVE_BEN - &atben_driver, -#endif -#ifdef HAVE_USB - &atusb_driver, -#endif - NULL -}; - - const char *atrf_default_driver_name(void) { return drivers[0] ? drivers[0]->name : "none"; diff --git a/tools/lib/driver.h b/tools/lib/driver.h index f562f0d..95879c0 100644 --- a/tools/lib/driver.h +++ b/tools/lib/driver.h @@ -38,6 +38,7 @@ struct atrf_driver { extern struct atrf_driver atusb_driver; extern struct atrf_driver atben_driver; +extern struct atrf_driver atnet_driver; int atrf_set_clkm_generic( From 5dd2b4ae58277dadcce4a9d00db6cec8e76e1750 Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Sun, 10 Apr 2011 19:54:42 -0300 Subject: [PATCH 6/6] tools/lib/atusb.c (atusb_interrupt): if we have an error, report it immediately --- tools/lib/atusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/atusb.c b/tools/lib/atusb.c index 510c848..e64316d 100644 --- a/tools/lib/atusb.c +++ b/tools/lib/atusb.c @@ -224,6 +224,7 @@ static int atusb_interrupt(void *dsc) if (res < 0) { fprintf(stderr, "ATUSB_POLL_INT: %d\n", res); error = 1; + return -1; } return buf;