diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2023-06-26 08:38:29 +0900 |
---|---|---|
committer | 坂本 貴史 <o-takashi@sakamocchi.jp> | 2023-06-28 17:06:14 +0900 |
commit | bb128c47f78b6a4e9264f59b32597fd07850f652 (patch) | |
tree | 6f3ae9fa1cd6c42e3d34da96987bbccc72c4ed5d | |
parent | 49c18c144e56db09883a2ce657560490e9a1148f (diff) | |
download | libhinawa-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.c | 3 | ||||
-rw-r--r-- | src/fw_resp.c | 63 | ||||
-rw-r--r-- | src/internal.h | 1 |
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, |