aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-05 11:37:24 +0900
committer坂本 貴史 <o-takashi@sakamocchi.jp>2022-05-05 16:09:50 +0900
commitf0362d6820570d68b9b0f271901202ace481108a (patch)
treeaf56c666469e20a87d229293c979fffe18bb3572
parent76056ca42762fe9509fc30a510fa5d1cdc3ca657 (diff)
downloadlibhinoko-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.c68
-rw-r--r--src/fw_iso_ctx_private.c95
-rw-r--r--src/fw_iso_ctx_private.h6
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,