diff --git a/tools/atrf-id/atrf-id.c b/tools/atrf-id/atrf-id.c index 035c402..0679b35 100644 --- a/tools/atrf-id/atrf-id.c +++ b/tools/atrf-id/atrf-id.c @@ -158,7 +158,12 @@ static void show_info(struct atrf_dsc *dsc) static void usage(const char *name) { - fprintf(stderr, "usage: %s [-d driver[:arg]]\n", name); + fprintf(stderr, +"usage: %s [-d driver[:arg]] [-s [-s]]\n\n" +" -d driver[:arg] use the specified driver (default: %s)\n" +" -s print only the local driver specification\n" +" -s -s print only the remote driver specification\n" + , name, atrf_default_driver_name()); exit(1); } @@ -167,13 +172,17 @@ int main(int argc, char *const *argv) { const char *driver = NULL; struct atrf_dsc *dsc; + int spec_only = 0; int c; - while ((c = getopt(argc, argv, "d:")) != EOF) + while ((c = getopt(argc, argv, "d:s")) != EOF) switch (c) { case 'd': driver = optarg; break; + case 's': + spec_only++; + break; default: usage(*argv); } @@ -184,7 +193,18 @@ int main(int argc, char *const *argv) if (!dsc) return 1; - show_info(dsc); + if (spec_only) { + const char *spec = atrf_driver_spec(dsc, spec_only > 1); + + if (spec) + printf("%s\n", spec); + else { + fprintf(stderr, "can't obtain specification\n"); + exit(1); + } + } else { + show_info(dsc); + } atrf_close(dsc); diff --git a/tools/atrf-proxy/PROTOCOL b/tools/atrf-proxy/PROTOCOL index ddff124..28d87bf 100644 --- a/tools/atrf-proxy/PROTOCOL +++ b/tools/atrf-proxy/PROTOCOL @@ -8,6 +8,10 @@ Messages +[greeting] -message +SPEC ++driver_spec +-message + RESET +[comment] -message diff --git a/tools/atrf-proxy/atrf-proxy.c b/tools/atrf-proxy/atrf-proxy.c index c9e37f6..1a95150 100644 --- a/tools/atrf-proxy/atrf-proxy.c +++ b/tools/atrf-proxy/atrf-proxy.c @@ -151,6 +151,15 @@ static int cmd_zero(struct atrf_dsc *dsc, struct netio *netio, const char *cmd) { int res; + if (!strcasecmp(cmd, "spec")) { + const char *spec = atrf_driver_spec(dsc, 1); + + if (spec) + return netio_printf(netio, "+%s\n", spec); + else + return netio_printf(netio, + "-can't obtain specification\n"); + } if (!strcasecmp(cmd, "reset")) { atrf_reset(dsc); return netio_printf(netio, "+\n"); diff --git a/tools/include/atrf.h b/tools/include/atrf.h index b0b6f2f..2c768d0 100644 --- a/tools/include/atrf.h +++ b/tools/include/atrf.h @@ -32,6 +32,7 @@ void *atrf_ben_regs(struct atrf_dsc *dsc); /* hack for atrf-xtal */ const char *atrf_default_driver_name(void); struct atrf_dsc *atrf_open(const char *spec); void atrf_close(struct atrf_dsc *dsc); +const char *atrf_driver_spec(struct atrf_dsc *dsc, int last); int atrf_error(struct atrf_dsc *dsc); int atrf_clear_error(struct atrf_dsc *dsc); diff --git a/tools/lib/atnet.c b/tools/lib/atnet.c index 239e853..b17170a 100644 --- a/tools/lib/atnet.c +++ b/tools/lib/atnet.c @@ -31,6 +31,7 @@ struct atnet_dsc { struct netio *netio; int error; + char *spec; char reply[1000]; }; @@ -192,6 +193,7 @@ static void *atnet_open(const char *arg) } dsc->error = 0; + dsc->spec = NULL; *dsc->reply = 0; return dsc; @@ -203,6 +205,28 @@ static void atnet_close(void *handle) struct atnet_dsc *dsc = handle; netio_close(dsc->netio); + free(dsc->spec); +} + + +/* ----- driver specification ---------------------------------------------- */ + + +static const char *atnet_driver_spec(void *handle) +{ + struct atnet_dsc *dsc = handle; + + if (dialog(dsc, "SPEC") < 0) { + dsc->error = 1; + return NULL; + } + free(dsc->spec); + dsc->spec = strdup(dsc->reply+1); + if (!dsc->spec) { + perror("strdup"); + exit(1); + } + return dsc->spec; } @@ -421,6 +445,7 @@ struct atrf_driver atnet_driver = { .name = "net", .open = atnet_open, .close = atnet_close, + .driver_spec = atnet_driver_spec, .error = atnet_error, .clear_error = atnet_clear_error, .reset = atnet_reset, diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index c8cb2c7..682d2f9 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -24,6 +24,7 @@ struct atrf_dsc { const struct atrf_driver *driver; void *handle; + char *spec; enum atrf_chip_id chip_id; }; @@ -164,6 +165,15 @@ struct atrf_dsc *atrf_open(const char *spec) } dsc->driver = driver; dsc->handle = handle; + if (spec) { + dsc->spec = strdup(spec); + if (!dsc->spec) { + perror("strdup"); + exit(1); + } + } else { + dsc->spec= NULL; + } dsc->chip_id = identify(dsc); return dsc; } @@ -173,10 +183,21 @@ void atrf_close(struct atrf_dsc *dsc) { if (dsc->driver->close) dsc->driver->close(dsc->handle); + free(dsc->spec); free(dsc); } +const char *atrf_driver_spec(struct atrf_dsc *dsc, int last) +{ + if (!dsc->spec) + return dsc->driver->name; + if (!last || !dsc->driver->driver_spec) + return dsc->spec; + return dsc->driver->driver_spec(dsc->handle); +} + + void atrf_reset(struct atrf_dsc *dsc) { if (dsc->driver->reset) diff --git a/tools/lib/driver.h b/tools/lib/driver.h index bf61fba..40a1d6a 100644 --- a/tools/lib/driver.h +++ b/tools/lib/driver.h @@ -21,6 +21,7 @@ struct atrf_driver { const char *name; void *(*open)(const char *arg); void (*close)(void *dsc); + const char *(*driver_spec)(void *dsc); int (*error)(void *dsc); int (*clear_error)(void *dsc); void (*reset)(void *dsc);