aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2023-06-26 08:38:29 +0900
committer坂本 貴史 <o-takashi@sakamocchi.jp>2023-06-28 17:06:14 +0900
commitbb128c47f78b6a4e9264f59b32597fd07850f652 (patch)
tree6f3ae9fa1cd6c42e3d34da96987bbccc72c4ed5d
parent49c18c144e56db09883a2ce657560490e9a1148f (diff)
downloadlibhinawa-bb128c47f78b6a4e9264f59b32597fd07850f652.tar.gz
fw_resp: implement requested3 signal
This commit implements the requested3 signal. The old requested and requested2 signals are deprecated now. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--src/fw_node.c3
-rw-r--r--src/fw_resp.c63
-rw-r--r--src/internal.h1
3 files changed, 67 insertions, 0 deletions
diff --git a/src/fw_node.c b/src/fw_node.c
index 4e2f97b..7cca438 100644
--- a/src/fw_node.c
+++ b/src/fw_node.c
@@ -519,6 +519,9 @@ static gboolean dispatch_src(GSource *gsrc, GSourceFunc cb, gpointer user_data)
case FW_CDEV_EVENT_REQUEST2:
hinawa_fw_resp_handle_request2(resp, &event->request2);
break;
+ case FW_CDEV_EVENT_REQUEST3:
+ hinawa_fw_resp_handle_request3(resp, &event->request3);
+ break;
default:
break;
}
diff --git a/src/fw_resp.c b/src/fw_resp.c
index b2911dd..041fbf6 100644
--- a/src/fw_resp.c
+++ b/src/fw_resp.c
@@ -481,6 +481,11 @@ void hinawa_fw_resp_handle_request(HinawaFwResp *self, const struct fw_cdev_even
if (!priv->node || event->length > priv->width) {
rcode = RCODE_CONFLICT_ERROR;
+ } else if (klass->requested3 != NULL ||
+ g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, TRUE)) {
+ g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, event->tcode,
+ event->offset, G_MAXUINT, G_MAXUINT, G_MAXUINT, G_MAXUINT,
+ G_MAXUINT, event->data, event->length, &rcode);
} else if (klass->requested2 != NULL ||
g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ2], 0, TRUE)) {
// Pass arguments as much as possible, else fill with invalid value (G_MAX_UINT).
@@ -526,6 +531,64 @@ void hinawa_fw_resp_handle_request2(HinawaFwResp *self, const struct fw_cdev_eve
if (!priv->node || event->length > priv->width) {
rcode = RCODE_CONFLICT_ERROR;
+ } else if (klass->requested3 != NULL ||
+ g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, TRUE)) {
+ g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, event->tcode,
+ event->offset, event->source_node_id, event->destination_node_id,
+ event->card, event->generation, G_MAXUINT, event->data, event->length,
+ &rcode);
+ } else if (klass->requested2 != NULL ||
+ g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ2], 0, TRUE)) {
+ g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ2], 0, event->tcode,
+ event->offset, event->source_node_id, event->destination_node_id,
+ event->card, event->generation, event->data, event->length, &rcode);
+ } else if (klass->requested != NULL ||
+ g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ], 0, TRUE)) {
+ // For backward compatibility to use Hinawa.FwResp.get_req_frame().
+ memcpy(priv->req_frame, event->data, event->length);
+ priv->req_length = event->length;
+
+ g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ], 0, event->tcode, &rcode);
+ } else {
+ rcode = HINAWA_FW_RCODE_ADDRESS_ERROR;
+ }
+
+ if (priv->resp_length > 0) {
+ resp.length = priv->resp_length;
+ resp.data = (guint64)priv->resp_frame;
+ }
+
+ // Ignore ioctl error.
+ resp.rcode = (__u32)rcode;
+ resp.handle = event->handle;
+ hinawa_fw_node_ioctl(priv->node, FW_CDEV_IOC_SEND_RESPONSE, &resp, &error);
+ g_clear_error(&error);
+}
+
+// NOTE: For HinawaFwNode, internal.
+void hinawa_fw_resp_handle_request3(HinawaFwResp *self, const struct fw_cdev_event_request3 *event)
+{
+ HinawaFwRespPrivate *priv;
+ HinawaFwRespClass *klass;
+ struct fw_cdev_send_response resp = {0};
+ HinawaFwRcode rcode;
+ GError *error = NULL;
+
+ g_return_if_fail(HINAWA_IS_FW_RESP(self));
+ priv = hinawa_fw_resp_get_instance_private(self);
+ klass = HINAWA_FW_RESP_GET_CLASS(self);
+
+ memset(priv->resp_frame, 0, priv->width);
+ priv->resp_length = 0;
+
+ if (!priv->node || event->length > priv->width) {
+ rcode = RCODE_CONFLICT_ERROR;
+ } else if (klass->requested3 != NULL ||
+ g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, TRUE)) {
+ g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ3], 0, event->tcode,
+ event->offset, event->source_node_id, event->destination_node_id,
+ event->card, event->generation, event->tstamp, event->data,
+ event->length, &rcode);
} else if (klass->requested2 != NULL ||
g_signal_has_handler_pending(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ2], 0, TRUE)) {
g_signal_emit(self, fw_resp_sigs[FW_RESP_SIG_TYPE_REQ2], 0, event->tcode,
diff --git a/src/internal.h b/src/internal.h
index efc8350..c5147f0 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -9,6 +9,7 @@ void hinawa_fw_node_invalidate_transaction(HinawaFwNode *self, HinawaFwReq *req)
void hinawa_fw_resp_handle_request(HinawaFwResp *self, const struct fw_cdev_event_request *event);
void hinawa_fw_resp_handle_request2(HinawaFwResp *self, const struct fw_cdev_event_request2 *event);
+void hinawa_fw_resp_handle_request3(HinawaFwResp *self, const struct fw_cdev_event_request3 *event);
void hinawa_fw_req_handle_response(HinawaFwReq *self, const struct fw_cdev_event_response *event);
void hinawa_snd_unit_write(HinawaSndUnit *self, const void *buf, size_t length,