aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-08 15:33:32 +0900
committer坂本 貴史 <o-takashi@sakamocchi.jp>2022-05-08 15:36:32 +0900
commit5bd9aac7914af335eeb9ff5cc52b3cf5d857c3a5 (patch)
tree7c461d2c9becd68e825dfbfc8bfb72de6d107ded
parent44a5037c9489ce7d146c8dc4cdc03647e84fe3a3 (diff)
downloadlibhinoko-5bd9aac7914af335eeb9ff5cc52b3cf5d857c3a5.tar.gz
fw_iso_ctx_private: add macro and helper function for cycle match in IR/IT context
The layout of cycleMatch field in IT.contextControl and IR.contextMatch registers is defined in 1394 OHCI specification. On the other hand, Linux FireWire subsystem forces userspace application to compute the value of field before system call. This commit adds macro and helper function to operate the value. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--src/fw_iso_ctx_private.c32
-rw-r--r--src/fw_iso_ctx_private.h6
-rw-r--r--src/fw_iso_rx_multiple.c4
-rw-r--r--src/fw_iso_rx_single.c4
-rw-r--r--src/fw_iso_tx.c4
5 files changed, 41 insertions, 9 deletions
diff --git a/src/fw_iso_ctx_private.c b/src/fw_iso_ctx_private.c
index f005f03..dde99a8 100644
--- a/src/fw_iso_ctx_private.c
+++ b/src/fw_iso_ctx_private.c
@@ -434,6 +434,16 @@ gboolean fw_iso_ctx_state_queue_chunks(struct fw_iso_ctx_state *state, GError **
return TRUE;
}
+#define FW_CDEV_CYCLE_MATCH_SEC_MASK 0x00007000
+#define FW_CDEV_CYCLE_MATCH_SEC_SHIFT 13
+#define FW_CDEV_CYCLE_MATCH_CYCLE_MASK 0x00001fff
+
+static guint fw_cdev_cycle_match_from_fields(guint sec, guint cycle)
+{
+ return ((sec << FW_CDEV_CYCLE_MATCH_SEC_SHIFT) & FW_CDEV_CYCLE_MATCH_SEC_MASK) |
+ (cycle & FW_CDEV_CYCLE_MATCH_CYCLE_MASK);
+}
+
/**
* fw_iso_ctx_state_start:
* @state: A [struct@FwIsoCtxState].
@@ -465,19 +475,18 @@ gboolean fw_iso_ctx_state_start(struct fw_iso_ctx_state *state, const guint16 *c
return FALSE;
}
- if (cycle_match == NULL) {
- cycle = -1;
- } else {
- g_return_val_if_fail(cycle_match[0] < 4, FALSE);
- g_return_val_if_fail(cycle_match[1] < 8000, FALSE);
-
- cycle = (cycle_match[0] << 13) | cycle_match[1];
- }
-
if (state->mode == HINOKO_FW_ISO_CTX_MODE_TX) {
+ g_return_val_if_fail(cycle_match == NULL ||
+ cycle_match[0] <= OHCI1394_IT_contextControl_cycleMatch_MAX_SEC ||
+ cycle_match[1] <= OHCI1394_IT_contextControl_cycleMatch_MAX_CYCLE,
+ FALSE);
g_return_val_if_fail(sync_code == 0, FALSE);
g_return_val_if_fail(tags == 0, FALSE);
} else {
+ g_return_val_if_fail(cycle_match == NULL ||
+ cycle_match[0] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_SEC ||
+ cycle_match[1] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_CYCLE,
+ FALSE);
g_return_val_if_fail(sync_code <= IEEE1394_MAX_SYNC_CODE, FALSE);
g_return_val_if_fail(tags <= (HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG0 |
HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG1 |
@@ -485,6 +494,11 @@ gboolean fw_iso_ctx_state_start(struct fw_iso_ctx_state *state, const guint16 *c
HINOKO_FW_ISO_CTX_MATCH_FLAG_TAG3), FALSE);
}
+ if (cycle_match == NULL)
+ cycle = -1;
+ else
+ cycle = fw_cdev_cycle_match_from_fields(cycle_match[0], cycle_match[1]);
+
// Not prepared.
if (state->data_length == 0) {
generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_CHUNK_UNREGISTERED);
diff --git a/src/fw_iso_ctx_private.h b/src/fw_iso_ctx_private.h
index 45d3e2c..e8e8d31 100644
--- a/src/fw_iso_ctx_private.h
+++ b/src/fw_iso_ctx_private.h
@@ -50,6 +50,12 @@ static inline guint ohci1394_isoc_desc_tstamp_to_cycle(guint32 tstamp)
return (tstamp & OHCI1394_ISOC_DESC_timeStmap_CYCLE_MASK);
}
+#define OHCI1394_IR_contextMatch_cycleMatch_MAX_SEC 3
+#define OHCI1394_IR_contextMatch_cycleMatch_MAX_CYCLE 7999
+
+#define OHCI1394_IT_contextControl_cycleMatch_MAX_SEC 3
+#define OHCI1394_IT_contextControl_cycleMatch_MAX_CYCLE 7999
+
struct fw_iso_ctx_state {
int fd;
guint handle;
diff --git a/src/fw_iso_rx_multiple.c b/src/fw_iso_rx_multiple.c
index 8763533..bd453fe 100644
--- a/src/fw_iso_rx_multiple.c
+++ b/src/fw_iso_rx_multiple.c
@@ -458,6 +458,10 @@ gboolean hinoko_fw_iso_rx_multiple_start(HinokoFwIsoRxMultiple *self, const guin
int i;
g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_MULTIPLE(self), FALSE);
+ g_return_val_if_fail(cycle_match == NULL ||
+ cycle_match[0] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_SEC ||
+ cycle_match[1] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_CYCLE,
+ FALSE);
g_return_val_if_fail(sync_code <= IEEE1394_MAX_SYNC_CODE, FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
diff --git a/src/fw_iso_rx_single.c b/src/fw_iso_rx_single.c
index 3ffb3a2..afac268 100644
--- a/src/fw_iso_rx_single.c
+++ b/src/fw_iso_rx_single.c
@@ -348,6 +348,10 @@ gboolean hinoko_fw_iso_rx_single_start(HinokoFwIsoRxSingle *self, const guint16
HinokoFwIsoRxSinglePrivate *priv;
g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_SINGLE(self), FALSE);
+ g_return_val_if_fail(cycle_match == NULL ||
+ cycle_match[0] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_SEC ||
+ cycle_match[1] <= OHCI1394_IR_contextMatch_cycleMatch_MAX_CYCLE,
+ FALSE);
g_return_val_if_fail(sync_code <= IEEE1394_MAX_SYNC_CODE, FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
diff --git a/src/fw_iso_tx.c b/src/fw_iso_tx.c
index aba8b31..dabb77c 100644
--- a/src/fw_iso_tx.c
+++ b/src/fw_iso_tx.c
@@ -297,6 +297,10 @@ gboolean hinoko_fw_iso_tx_start(HinokoFwIsoTx *self, const guint16 *cycle_match,
HinokoFwIsoTxPrivate *priv;
g_return_val_if_fail(HINOKO_IS_FW_ISO_TX(self), FALSE);
+ g_return_val_if_fail(cycle_match == NULL ||
+ cycle_match[0] <= OHCI1394_IT_contextControl_cycleMatch_MAX_SEC ||
+ cycle_match[1] <= OHCI1394_IT_contextControl_cycleMatch_MAX_CYCLE,
+ FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
priv = hinoko_fw_iso_tx_get_instance_private(self);