diff --git a/moberg.c b/moberg.c index bc9e52905c7b3a2fea511b2e1772878e53c767c4..ad8de2e688fb073540df72de91f4f25a7d368ab6 100644 --- a/moberg.c +++ b/moberg.c @@ -31,7 +31,6 @@ static struct deferred_action { static void run_deferred_actions() { while (deferred_action) { - fprintf(stderr, "RUNNING deferred\n"); struct deferred_action *deferred = deferred_action; deferred_action = deferred_action->next; deferred->action(deferred->param); @@ -288,6 +287,7 @@ enum moberg_status moberg_start( struct moberg *moberg, FILE *f) { + return moberg_config_start(moberg->config, f); return moberg_OK; } @@ -296,6 +296,7 @@ enum moberg_status moberg_stop( struct moberg *moberg, FILE *f) { + return moberg_config_stop(moberg->config, f); return moberg_OK; } @@ -305,7 +306,6 @@ void moberg_deferred_action( { struct deferred_action *deferred = malloc(sizeof(*deferred)); if (deferred) { - fprintf(stderr, "DEFERRED %p %p\n", action, param); deferred->next = deferred_action; deferred->action = action; deferred->param = param; diff --git a/moberg_config.c b/moberg_config.c index 6f7e6e4497fc3b33167e93b2d6a844a7550cb974..879b6e851347c3306d6ff582e72da69ec0f35196 100644 --- a/moberg_config.c +++ b/moberg_config.c @@ -94,4 +94,21 @@ int moberg_config_install_channels(struct moberg_config *config, return result; } +int moberg_config_start(struct moberg_config *config, + FILE *f) +{ + for (struct device_entry *d = config->device_head ; d ; d = d->next) { + moberg_device_start(d->device, f); + } + return 1; +} + +int moberg_config_stop(struct moberg_config *config, + FILE *f) +{ + for (struct device_entry *d = config->device_head ; d ; d = d->next) { + moberg_device_stop(d->device, f); + } + return 1; +} diff --git a/moberg_config.h b/moberg_config.h index 1aae2e4dbd0489415c2ad192e8a6c4fb3d2ffc1e..a107d8a15bb0b2e879593ec9d27fee8de399c1c4 100644 --- a/moberg_config.h +++ b/moberg_config.h @@ -17,4 +17,10 @@ int moberg_config_add_device(struct moberg_config *config, int moberg_config_install_channels(struct moberg_config *config, struct moberg_channel_install *install); +int moberg_config_start(struct moberg_config *config, + FILE *f); + +int moberg_config_stop(struct moberg_config *config, + FILE *f); + #endif diff --git a/moberg_device.c b/moberg_device.c index b2daf2ff5a48640496f708aa8d2ddbd546742975..638179b26a8203f5122722aa084c3b72098fd0b1 100644 --- a/moberg_device.c +++ b/moberg_device.c @@ -228,13 +228,6 @@ int moberg_device_parse_map(struct moberg_device* device, }; struct moberg_channel_map map_channel = { .device=device, -#if 0 - .analog_in=moberg_device_add_analog_in, - .analog_out=moberg_device_add_analog_out, - .digital_in=moberg_device_add_digital_in, - .digital_out= moberg_device_add_digital_out, - .encoder_in= moberg_device_add_encoder_in, -#endif .map=map }; @@ -259,50 +252,19 @@ int moberg_device_install_channels(struct moberg_device *device, channel->index, device, channel->u.channel); - switch (channel->kind) { - case chan_ANALOGIN: { -/* - install->analog_in(install->context, - channel->index, - device, - channel->u.analog_in); -*/ - } break; - case chan_ANALOGOUT: { -/* - install->analog_out(install->context, - channel->index, - device, - channel->u.analog_out); -*/ - } break; - case chan_DIGITALIN: { -/* - install->digital_in(install->context, - channel->index, - device, - channel->u.digital_in); -*/ - } break; - case chan_DIGITALOUT: { -/* - install->digital_out(install->context, - channel->index, - device, - channel->u.digital_out); -*/ - } break; - case chan_ENCODERIN: { -/* - install->encoder_in(install->context, - channel->index, - device, - channel->u.encoder_in); -*/ - } break; - } channel = next; } return 1; } +int moberg_device_start(struct moberg_device *device, + FILE *f) +{ + return device->driver.start(device->device_context, f); +} + +int moberg_device_stop(struct moberg_device *device, + FILE *f) +{ + return device->driver.stop(device->device_context, f); +} diff --git a/moberg_device.h b/moberg_device.h index de4a90d62f5345ca3eb0f33d9f35429731f98355..0acafb29d9a4ee3270dbadc9c25835252197b5ff 100644 --- a/moberg_device.h +++ b/moberg_device.h @@ -18,6 +18,7 @@ struct moberg_device_driver { /* Use-count of device, when it reaches zero, device will be free'd */ int (*up)(struct moberg_device_context *context); int (*down)(struct moberg_device_context *context); + /* Parse driver dependent parts of config file */ int (*parse_config)( struct moberg_device_context *device, @@ -27,6 +28,15 @@ struct moberg_device_driver { struct moberg_parser_context *parser, enum moberg_channel_kind kind, struct moberg_channel_map *map); + + /* Shell commands for starting and stopping */ + int (*start)( + struct moberg_device_context *device, + FILE *f); + int (*stop)( + struct moberg_device_context *device, + FILE *f); + }; struct moberg_device; @@ -49,5 +59,13 @@ int moberg_device_parse_map(struct moberg_device* device, int moberg_device_install_channels(struct moberg_device *device, struct moberg_channel_install *install); +int moberg_device_start(struct moberg_device *device, + FILE *f); + +int moberg_device_stop(struct moberg_device *device, + FILE *f); + + + #endif diff --git a/moberg_module.h b/moberg_module.h index 6916bbf88d6b85120846bf81b4d0916afa1488b7..434f2c385397ad22339f0c6a99bbd9f8bf235b5d 100644 --- a/moberg_module.h +++ b/moberg_module.h @@ -36,8 +36,7 @@ struct moberg_parser_integer { struct moberg_parser_token { enum moberg_parser_token_kind kind; union { - struct moberg_parser_ident ident; - struct moberg_parser_ident string; + struct moberg_parser_ident idstr; struct moberg_parser_integer integer; } u; }; diff --git a/moberg_parser.c b/moberg_parser.c index 61cd5cce769e879697846b4df74c40702554d6f7..ac7bdbdde46996210e30d1d1e3893ca545df8d16 100644 --- a/moberg_parser.c +++ b/moberg_parser.c @@ -44,8 +44,8 @@ static inline int acceptkeyword(context_t *c, static const void nextsym_ident(context_t *c) { c->token.kind = tok_IDENT; - c->token.u.ident.length = 1; - c->token.u.ident.value = c->p; + c->token.u.idstr.length = 1; + c->token.u.idstr.value = c->p; c->p++; while (*c->p) { switch (*c->p) { @@ -54,7 +54,7 @@ static const void nextsym_ident(context_t *c) case '0'...'9': case '_': c->p++; - c->token.u.ident.length++; + c->token.u.idstr.length++; break; default: return; @@ -77,15 +77,15 @@ static const void nextsym_string(context_t *c) { c->token.kind = tok_STRING; c->p++; - c->token.u.string.value = c->p; - c->token.u.string.length = 0; + c->token.u.idstr.value = c->p; + c->token.u.idstr.length = 0; while (*c->p && *c->p != '"') { if (*c->p == '\\') { - c->token.u.string.length++; + c->token.u.idstr.length++; c->p++; } if (*c->p) { - c->token.u.string.length++; + c->token.u.idstr.length++; c->p++; } } @@ -235,7 +235,7 @@ int moberg_parser_acceptkeyword(context_t *c, { token_t t; if (peeksym(c, tok_IDENT, &t) && - strncmp(keyword, t.u.ident.value, t.u.ident.length) == 0) { + strncmp(keyword, t.u.idstr.value, t.u.idstr.length) == 0) { nextsym(c); c->expected.n = 0; return 1; @@ -277,11 +277,11 @@ void moberg_parser_failed( break; case tok_IDENT: fprintf(f, "%.*s (<IDENT>)", - c->token.u.ident.length, c->token.u.ident.value); + c->token.u.idstr.length, c->token.u.idstr.value); break; case tok_STRING: fprintf(f, "\"%.*s'\" (<STRING>)", - c->token.u.string.length, c->token.u.string.value); + c->token.u.idstr.length, c->token.u.idstr.value); break; } fprintf(f, "\n%s\n", c->p); @@ -375,10 +375,10 @@ static int parse(context_t *c) if (! acceptsym(c, tok_IDENT, &t)) { goto syntax_err; } if (! acceptsym(c, tok_RPAREN, NULL)) { goto syntax_err; } - char *name = strndup(t.u.ident.value, t.u.ident.length); + char *name = strndup(t.u.idstr.value, t.u.idstr.length); if (! name) { fprintf(stderr, "Failed to allocate driver name '%.*s'\n", - t.u.ident.length, t.u.ident.value); + t.u.idstr.length, t.u.idstr.value); goto err; } device = moberg_device_new(name); diff --git a/modules/comedi/comedi.c b/modules/comedi/comedi.c index c53521cda07ec014bc11c0a94befd1fb395f687c..d0ddead90b22b440ee0423391a8543c0a79427bd 100644 --- a/modules/comedi/comedi.c +++ b/modules/comedi/comedi.c @@ -15,7 +15,13 @@ struct moberg_device_context { int (*dlclose)(void *dlhandle); void *dlhandle; int use_count; - char *device; + char *name; + struct idstr { + struct idstr *next; + struct idstr *prev; + kind_t kind; + char *value; + } modprobe_list, config_list; }; struct moberg_channel_context { @@ -58,6 +64,10 @@ static struct moberg_device_context *new_context( memset(result, 0, sizeof(*result)); result->dlclose = dlclose; result->dlhandle = dlhandle; + result->modprobe_list.next = &result->modprobe_list; + result->modprobe_list.prev = &result->modprobe_list; + result->config_list.next = &result->config_list; + result->config_list.prev = &result->config_list; } return result; } @@ -74,7 +84,23 @@ static int device_down(struct moberg_device_context *context) int result = context->use_count; if (context->use_count <= 0) { moberg_deferred_action(context->dlclose, context->dlhandle); - free(context->device); + free(context->name); + struct idstr *e; + + e = context->modprobe_list.next; + while (e != &context->modprobe_list) { + struct idstr *next = e->next; + free(e->value); + free(e); + e = next; + } + e = context->config_list.next; + while (e != &context->config_list) { + struct idstr *next = e->next; + free(e->value); + free(e); + e = next; + } free(context); return 0; } @@ -99,13 +125,12 @@ static int channel_down(struct moberg_channel *channel) return channel->context->use_count; } -static void init_channel( - struct moberg_channel *channel, - void *to_free, - struct moberg_channel_context *context, - struct moberg_device_context *device, - enum moberg_channel_kind kind, - union moberg_channel_action action) +static void init_channel(struct moberg_channel *channel, + void *to_free, + struct moberg_channel_context *context, + struct moberg_device_context *device, + enum moberg_channel_kind kind, + union moberg_channel_action action) { context->to_free = to_free; context->device = device; @@ -132,10 +157,45 @@ static inline int acceptkeyword(context_t *c, { return moberg_parser_acceptkeyword(c, keyword); } + +static int append_modprobe(struct moberg_device_context *device, + token_t token) +{ + struct idstr *modprobe = malloc(sizeof(*modprobe)); + if (! modprobe) { goto err; } + modprobe->value = strndup(token.u.idstr.value, token.u.idstr.length); + if (! modprobe->value) { goto free_modprobe; } + modprobe->prev = device->modprobe_list.prev; + modprobe->next = modprobe->prev->next; + modprobe->prev->next = modprobe; + modprobe->next->prev = modprobe; + return 1; +free_modprobe: + free(modprobe); +err: + return 0; +} + +static int append_config(struct moberg_device_context *device, + token_t token) +{ + struct idstr *config = malloc(sizeof(*config)); + if (! config) { goto err; } + config->value = strndup(token.u.idstr.value, token.u.idstr.length); + if (! config->value) { goto free_config; } + config->prev = device->config_list.prev; + config->next = config->prev->next; + config->prev->next = config; + config->next->prev = config; + return 1; +free_config: + free(config); +err: + return 0; +} -static int parse_config( - struct moberg_device_context *device, - struct moberg_parser_context *c) +static int parse_config(struct moberg_device_context *device, + struct moberg_parser_context *c) { if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; } for (;;) { @@ -146,15 +206,17 @@ static int parse_config( if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; } if (! acceptsym(c, tok_STRING, &name)) { goto syntax_err; } if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; } - device->device = strndup(name.u.string.value, name.u.string.length); + device->name = strndup(name.u.idstr.value, name.u.idstr.length); } else if (acceptkeyword(c, "config")) { if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; } if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; } for (;;) { + token_t config; if (acceptsym(c, tok_RBRACKET, NULL)) { break; - } else if (acceptsym(c, tok_IDENT, NULL) || - acceptsym(c, tok_STRING, NULL)) { + } else if (acceptsym(c, tok_IDENT, &config) || + acceptsym(c, tok_STRING, &config)) { + append_config(device, config); } else { goto syntax_err; } @@ -164,10 +226,12 @@ static int parse_config( if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; } if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; } for (;;) { + token_t modprobe; if (acceptsym(c, tok_RBRACKET, NULL)) { break; - } else if (acceptsym(c, tok_IDENT, NULL) || - acceptsym(c, tok_STRING, NULL)) { + } else if (acceptsym(c, tok_IDENT, &modprobe) || + acceptsym(c, tok_STRING, &modprobe)) { + append_modprobe(device, modprobe); } else { goto syntax_err; } @@ -183,11 +247,10 @@ syntax_err: return 0; } -static int parse_map( - struct moberg_device_context *device, - struct moberg_parser_context *c, - enum moberg_channel_kind kind, - struct moberg_channel_map *map) +static int parse_map(struct moberg_device_context *device, + struct moberg_parser_context *c, + enum moberg_channel_kind kind, + struct moberg_channel_map *map) { token_t min, max; @@ -304,10 +367,49 @@ err: return 0; } +static int start(struct moberg_device_context *device, + FILE *f) +{ + for (struct idstr *e = device->modprobe_list.next ; + e != &device->modprobe_list ; + e = e->next) { + fprintf(f, "modprobe %s\n", e->value); + } + fprintf(f, "comedi_config %s ", device->name); + int i = 0; + for (struct idstr *e = device->config_list.next ; + e != &device->config_list ; + e = e->next) { + switch (i) { + case 0: fprintf(f, "%s", e->value); break; + case 1: fprintf(f, " %s", e->value); break; + default: fprintf(f, ",%s", e->value); break; + } + i++; + } + fprintf(f, "\n"); + + return 1; +} + +static int stop(struct moberg_device_context *device, + FILE *f) +{ + fprintf(f, "comedi_config --remove %s\n", device->name); + for (struct idstr *e = device->modprobe_list.prev ; + e != &device->modprobe_list ; + e = e->prev) { + fprintf(f, "rmmod %s\n", e->value); + } + return 1; +} + struct moberg_device_driver moberg_device_driver = { .new=new_context, .up=device_up, .down=device_down, .parse_config=parse_config, .parse_map=parse_map, + .start=start, + .stop=stop }; diff --git a/modules/serial2002/serial2002.c b/modules/serial2002/serial2002.c index 9ab9e43fb108835ca3a56bb562133b8c875f42bf..8b9404eea7efbed7fdda5ae96b4c0200d452199f 100644 --- a/modules/serial2002/serial2002.c +++ b/modules/serial2002/serial2002.c @@ -145,7 +145,7 @@ static int parse_config( if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; } if (! acceptsym(c, tok_STRING, &name)) { goto syntax_err; } if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; } - device->name = strndup(name.u.string.value, name.u.string.length); + device->name = strndup(name.u.idstr.value, name.u.idstr.length); } else if (acceptkeyword(c, "baud")) { token_t baud; if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; } @@ -275,10 +275,24 @@ syntax_err: return 0; } +static int start(struct moberg_device_context *device, + FILE *f) +{ + return 1; +} + +static int stop(struct moberg_device_context *device, + FILE *f) +{ + return 1; +} + struct moberg_device_driver moberg_device_driver = { .new=new_context, .up=device_up, .down=device_down, .parse_config=parse_config, .parse_map=parse_map, + .start=start, + .stop=stop };