diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-02-24 16:01:13 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-03-01 09:30:57 +0100 |
commit | ff612b866f301686fc490d076a138eaa65d79d4e (patch) | |
tree | 691f2fcbfabec8f9c11e66ec8f38bad0832fc333 /common | |
parent | 1eddb0d3821d7bb368fa6b092b980b89fc47db28 (diff) | |
download | barebox-ff612b866f301686fc490d076a138eaa65d79d4e.tar.gz barebox-ff612b866f301686fc490d076a138eaa65d79d4e.tar.xz |
ratp: implement generic command support
The RATP implementation now allows executing generic commands with a
binary interface: binary requests are received and binary responses
are returned.
Each command can define its own RATP request contents (e.g. to specify
command-specific options) as well as its own RATP response contents
(if any data is to be returned).
Each command is associated with a pair of numeric unique request and
response IDs, and for easy reference these IDs are maintained in the
common ratp_bb header. Modules may override generic implemented
commands or include their own new ones (as long as the numeric IDs
introduced are unique).
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r-- | common/module.lds.S | 2 | ||||
-rw-r--r-- | common/ratp.c | 82 |
2 files changed, 68 insertions, 16 deletions
diff --git a/common/module.lds.S b/common/module.lds.S index a03d04f401..f3dbb12f4a 100644 --- a/common/module.lds.S +++ b/common/module.lds.S @@ -35,6 +35,8 @@ SECTIONS .got : { *(.got) } .barebox_cmd : { BAREBOX_CMDS } + .barebox_ratp_cmd : { BAREBOX_RATP_CMDS } + . = ALIGN(4); .bss : { *(.bss) } } diff --git a/common/ratp.c b/common/ratp.c index 80863f81fb..b051fdee42 100644 --- a/common/ratp.c +++ b/common/ratp.c @@ -31,21 +31,10 @@ #include <ratp_bb.h> #include <fs.h> -#define BB_RATP_TYPE_COMMAND 1 -#define BB_RATP_TYPE_COMMAND_RETURN 2 -#define BB_RATP_TYPE_CONSOLEMSG 3 -#define BB_RATP_TYPE_PING 4 -#define BB_RATP_TYPE_PONG 5 -#define BB_RATP_TYPE_GETENV 6 -#define BB_RATP_TYPE_GETENV_RETURN 7 -#define BB_RATP_TYPE_FS 8 -#define BB_RATP_TYPE_FS_RETURN 9 - -struct ratp_bb { - uint16_t type; - uint16_t flags; - uint8_t data[]; -}; +LIST_HEAD(ratp_command_list); +EXPORT_SYMBOL(ratp_command_list); + +#define for_each_ratp_command(cmd) list_for_each_entry(cmd, &ratp_command_list, list) struct ratp_bb_command_return { uint32_t errno; @@ -66,6 +55,51 @@ struct ratp_ctx { struct poller_struct poller; }; +static int compare_ratp_command(struct list_head *a, struct list_head *b) +{ + int id_a = list_entry(a, struct ratp_command, list)->request_id; + int id_b = list_entry(b, struct ratp_command, list)->request_id; + + return (id_a - id_b); +} + +int register_ratp_command(struct ratp_command *cmd) +{ + debug("register ratp command: request %hu, response %hu\n", + cmd->request_id, cmd->response_id); + list_add_sort(&cmd->list, &ratp_command_list, compare_ratp_command); + return 0; +} +EXPORT_SYMBOL(register_ratp_command); + +struct ratp_command *find_ratp_request(uint16_t request_id) +{ + struct ratp_command *cmdtp; + + for_each_ratp_command(cmdtp) + if (request_id == cmdtp->request_id) + return cmdtp; + + return NULL; /* not found */ +} + +extern struct ratp_command __barebox_ratp_cmd_start; +extern struct ratp_command __barebox_ratp_cmd_end; + +static int init_ratp_command_list(void) +{ + struct ratp_command *cmdtp; + + for (cmdtp = &__barebox_ratp_cmd_start; + cmdtp != &__barebox_ratp_cmd_end; + cmdtp++) + register_ratp_command(cmdtp); + + return 0; +} + +late_initcall(init_ratp_command_list); + static int console_recv(struct ratp *r, uint8_t *data) { struct ratp_ctx *ctx = container_of(r, struct ratp_ctx, ratp); @@ -207,8 +241,24 @@ static int ratp_bb_dispatch(struct ratp_ctx *ctx, const void *buf, int len) int dlen = len - sizeof(struct ratp_bb); char *varname; int ret = 0; + uint16_t type = be16_to_cpu(rbb->type); + struct ratp_command *cmd; + + /* See if there's a command registered to this type */ + cmd = find_ratp_request(type); + if (cmd) { + struct ratp_bb *rsp = NULL; + int rsp_len = 0; + + ret = cmd->cmd(rbb, len, &rsp, &rsp_len); + if (!ret) + ret = ratp_send(&ctx->ratp, rsp, rsp_len); + + free(rsp); + return ret; + } - switch (be16_to_cpu(rbb->type)) { + switch (type) { case BB_RATP_TYPE_COMMAND: if (ratp_command) return 0; |