diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2022-05-05 11:37:24 +0900 |
---|---|---|
committer | 坂本 貴史 <o-takashi@sakamocchi.jp> | 2022-05-05 16:09:50 +0900 |
commit | f0362d6820570d68b9b0f271901202ace481108a (patch) | |
tree | af56c666469e20a87d229293c979fffe18bb3572 | |
parent | 76056ca42762fe9509fc30a510fa5d1cdc3ca657 (diff) | |
download | libhinoko-f0362d6820570d68b9b0f271901202ace481108a.tar.gz |
fw_iso_ctx: code refactoring to split chunk registration function
It's planned to make Hinoko.FwIsoCtx as interface. It's convenient
for derived object to use private helper function instead of instance
method.
This commit splits current implementaion of
Hinoko.FwIsoCtx.register_chunk() into internal API part and private
implementation.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r-- | src/fw_iso_ctx.c | 68 | ||||
-rw-r--r-- | src/fw_iso_ctx_private.c | 95 | ||||
-rw-r--r-- | src/fw_iso_ctx_private.h | 6 |
3 files changed, 103 insertions, 66 deletions
diff --git a/src/fw_iso_ctx.c b/src/fw_iso_ctx.c index 8a8a86d..55d438b 100644 --- a/src/fw_iso_ctx.c +++ b/src/fw_iso_ctx.c @@ -334,76 +334,12 @@ void hinoko_fw_iso_ctx_register_chunk(HinokoFwIsoCtx *self, gboolean skip, GError **error) { HinokoFwIsoCtxPrivate *priv; - struct fw_cdev_iso_packet *datum; g_return_if_fail(HINOKO_IS_FW_ISO_CTX(self)); - g_return_if_fail(skip == TRUE || skip == FALSE); - g_return_if_fail(error == NULL || *error == NULL); - - g_return_if_fail(tags == 0 || - tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG0 || - tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG1 || - tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG2 || - tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG3); - - g_return_if_fail(sy < 16); - priv = hinoko_fw_iso_ctx_get_instance_private(self); - if (priv->mode == HINOKO_FW_ISO_CTX_MODE_TX) { - if (!skip) { - g_return_if_fail(header_length == priv->header_size); - g_return_if_fail(payload_length <= priv->bytes_per_chunk); - } else { - g_return_if_fail(payload_length == 0); - g_return_if_fail(header_length == 0); - g_return_if_fail(header == NULL); - } - } else if (priv->mode == HINOKO_FW_ISO_CTX_MODE_RX_SINGLE || - priv->mode == HINOKO_FW_ISO_CTX_MODE_RX_MULTIPLE) { - g_return_if_fail(tags == 0); - g_return_if_fail(sy == 0); - g_return_if_fail(header == NULL); - g_return_if_fail(header_length == 0); - g_return_if_fail(payload_length == 0); - } - - g_return_if_fail(priv->data_length + sizeof(*datum) + header_length <= priv->alloc_data_length); - - if (priv->fd < 0) { - generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_ALLOCATED); - return; - } - - if (priv->addr == NULL) { - generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_MAPPED); - return; - } - - datum = (struct fw_cdev_iso_packet *)(priv->data + priv->data_length); - priv->data_length += sizeof(*datum) + header_length; - ++priv->registered_chunk_count; - - if (priv->mode == HINOKO_FW_ISO_CTX_MODE_TX) { - if (!skip) - memcpy(datum->header, header, header_length); - } else { - payload_length = priv->bytes_per_chunk; - - if (priv->mode == HINOKO_FW_ISO_CTX_MODE_RX_SINGLE) - header_length = priv->header_size; - } - - datum->control = - FW_CDEV_ISO_PAYLOAD_LENGTH(payload_length) | - FW_CDEV_ISO_TAG(tags) | - FW_CDEV_ISO_SY(sy) | - FW_CDEV_ISO_HEADER_LENGTH(header_length); - - if (skip) - datum->control |= FW_CDEV_ISO_SKIP; - if (schedule_interrupt) - datum->control |= FW_CDEV_ISO_INTERRUPT; + (void)fw_iso_ctx_state_register_chunk(priv, skip, tags, sy, header, header_length, + payload_length, schedule_interrupt, error); } static void fw_iso_ctx_queue_chunks(HinokoFwIsoCtx *self, GError **error) diff --git a/src/fw_iso_ctx_private.c b/src/fw_iso_ctx_private.c index 2923991..fdf5392 100644 --- a/src/fw_iso_ctx_private.c +++ b/src/fw_iso_ctx_private.c @@ -188,3 +188,98 @@ void fw_iso_ctx_state_unmap_buffer(struct fw_iso_ctx_state *state) state->addr = NULL; state->data = NULL; } + +/** + * fw_iso_ctx_state_register_chunk: + * @state: A [struct@FwIsoCtxState]. + * @skip: Whether to skip packet transmission or not. + * @tags: The value of tag field for isochronous packet to handle. + * @sy: The value of sy field for isochronous packet to handle. + * @header: (array length=header_length) (element-type guint8): The content of header for IT + * context, nothing for IR context. + * @header_length: The number of bytes for @header. + * @payload_length: The number of bytes for payload of isochronous context. + * @schedule_interrupt: schedule hardware interrupt at isochronous cycle for the chunk. + * @error: A [struct@GLib.Error]. + * + * Register data on buffer for payload of isochronous context. + */ +gboolean fw_iso_ctx_state_register_chunk(struct fw_iso_ctx_state *state, gboolean skip, + HinokoFwIsoCtxMatchFlag tags, guint sy, + const guint8 *header, guint header_length, + guint payload_length, gboolean schedule_interrupt, + GError **error) +{ + struct fw_cdev_iso_packet *datum; + + g_return_val_if_fail(skip == TRUE || skip == FALSE, FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + + g_return_val_if_fail(tags == 0 || + tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG0 || + tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG1 || + tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG2 || + tags == HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG3, FALSE); + + g_return_val_if_fail(sy < 16, FALSE); + + if (state->mode == HINOKO_FW_ISO_CTX_MODE_TX) { + if (!skip) { + g_return_val_if_fail(header_length == state->header_size, FALSE); + g_return_val_if_fail(payload_length <= state->bytes_per_chunk, FALSE); + } else { + g_return_val_if_fail(payload_length == 0, FALSE); + g_return_val_if_fail(header_length == 0, FALSE); + g_return_val_if_fail(header == NULL, FALSE); + } + } else if (state->mode == HINOKO_FW_ISO_CTX_MODE_RX_SINGLE || + state->mode == HINOKO_FW_ISO_CTX_MODE_RX_MULTIPLE) { + g_return_val_if_fail(tags == 0, FALSE); + g_return_val_if_fail(sy == 0, FALSE); + g_return_val_if_fail(header == NULL, FALSE); + g_return_val_if_fail(header_length == 0, FALSE); + g_return_val_if_fail(payload_length == 0, FALSE); + } + + g_return_val_if_fail( + state->data_length + sizeof(*datum) + header_length <= state->alloc_data_length, + FALSE); + + if (state->fd < 0) { + generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_ALLOCATED); + return FALSE; + } + + if (state->addr == NULL) { + generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_MAPPED); + return FALSE; + } + + datum = (struct fw_cdev_iso_packet *)(state->data + state->data_length); + state->data_length += sizeof(*datum) + header_length; + ++state->registered_chunk_count; + + if (state->mode == HINOKO_FW_ISO_CTX_MODE_TX) { + if (!skip) + memcpy(datum->header, header, header_length); + } else { + payload_length = state->bytes_per_chunk; + + if (state->mode == HINOKO_FW_ISO_CTX_MODE_RX_SINGLE) + header_length = state->header_size; + } + + datum->control = + FW_CDEV_ISO_PAYLOAD_LENGTH(payload_length) | + FW_CDEV_ISO_TAG(tags) | + FW_CDEV_ISO_SY(sy) | + FW_CDEV_ISO_HEADER_LENGTH(header_length); + + if (skip) + datum->control |= FW_CDEV_ISO_SKIP; + + if (schedule_interrupt) + datum->control |= FW_CDEV_ISO_INTERRUPT; + + return TRUE; +} diff --git a/src/fw_iso_ctx_private.h b/src/fw_iso_ctx_private.h index b4530fa..e8203fb 100644 --- a/src/fw_iso_ctx_private.h +++ b/src/fw_iso_ctx_private.h @@ -52,6 +52,12 @@ gboolean fw_iso_ctx_state_map_buffer(struct fw_iso_ctx_state *state, guint bytes guint chunks_per_buffer, GError **error); void fw_iso_ctx_state_unmap_buffer(struct fw_iso_ctx_state *state); +gboolean fw_iso_ctx_state_register_chunk(struct fw_iso_ctx_state *state, gboolean skip, + HinokoFwIsoCtxMatchFlag tags, guint sy, + const guint8 *header, guint header_length, + guint payload_length, gboolean schedule_interrupt, + GError **error); + void hinoko_fw_iso_ctx_allocate(HinokoFwIsoCtx *self, const char *path, HinokoFwIsoCtxMode mode, HinokoFwScode scode, guint channel, guint header_size, |