aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-05 16:16:39 +0900
committer坂本 貴史 <o-takashi@sakamocchi.jp>2022-05-05 20:51:53 +0900
commit02b890b12bdb04b7265e6f9dba80291b683c3efe (patch)
tree3170711efe91fba456c3679fc85d2f748f772a5c
parent087961c0793c922399927033d8f8a89d8ea73be1 (diff)
downloadlibhinoko-02b890b12bdb04b7265e6f9dba80291b683c3efe.tar.gz
fw_iso_resource: handle event of bus reset
This commit adds handlers for event of bus reset. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--src/fw_iso_resource_auto.c12
-rw-r--r--src/fw_iso_resource_once.c12
-rw-r--r--src/fw_iso_resource_private.c26
-rw-r--r--src/fw_iso_resource_private.h3
4 files changed, 53 insertions, 0 deletions
diff --git a/src/fw_iso_resource_auto.c b/src/fw_iso_resource_auto.c
index 13460b3..870996e 100644
--- a/src/fw_iso_resource_auto.c
+++ b/src/fw_iso_resource_auto.c
@@ -183,6 +183,15 @@ static void handle_iso_resource_event(HinokoFwIsoResourceAuto *self,
g_clear_error(&error);
}
+static void handle_bus_reset_event(HinokoFwIsoResourceAuto *self,
+ const struct fw_cdev_event_bus_reset *ev)
+{
+ HinokoFwIsoResourceAutoPrivate *priv =
+ hinoko_fw_iso_resource_auto_get_instance_private(self);
+
+ memcpy(&priv->state.bus_state, ev, sizeof(*ev));
+}
+
void fw_iso_resource_auto_handle_event(HinokoFwIsoResource *inst, const union fw_cdev_event *event)
{
HinokoFwIsoResourceAuto *self;
@@ -195,6 +204,9 @@ void fw_iso_resource_auto_handle_event(HinokoFwIsoResource *inst, const union fw
case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED:
handle_iso_resource_event(self, &event->iso_resource);
break;
+ case FW_CDEV_EVENT_BUS_RESET:
+ handle_bus_reset_event(self, &event->bus_reset);
+ break;
default:
break;
}
diff --git a/src/fw_iso_resource_once.c b/src/fw_iso_resource_once.c
index 651eb42..c126435 100644
--- a/src/fw_iso_resource_once.c
+++ b/src/fw_iso_resource_once.c
@@ -75,6 +75,15 @@ static void handle_iso_resource_event(HinokoFwIsoResourceOnce *self,
g_clear_error(&error);
}
+static void handle_bus_reset_event(HinokoFwIsoResourceOnce *self,
+ const struct fw_cdev_event_bus_reset *ev)
+{
+ HinokoFwIsoResourceOncePrivate *priv =
+ hinoko_fw_iso_resource_once_get_instance_private(self);
+
+ memcpy(&priv->state.bus_state, ev, sizeof(*ev));
+}
+
void fw_iso_resource_once_handle_event(HinokoFwIsoResource *inst, const union fw_cdev_event *event)
{
HinokoFwIsoResourceOnce *self;
@@ -87,6 +96,9 @@ void fw_iso_resource_once_handle_event(HinokoFwIsoResource *inst, const union fw
case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED:
handle_iso_resource_event(self, &event->iso_resource);
break;
+ case FW_CDEV_EVENT_BUS_RESET:
+ handle_bus_reset_event(self, &event->bus_reset);
+ break;
default:
break;
}
diff --git a/src/fw_iso_resource_private.c b/src/fw_iso_resource_private.c
index 257d783..98f9294 100644
--- a/src/fw_iso_resource_private.c
+++ b/src/fw_iso_resource_private.c
@@ -69,6 +69,11 @@ gboolean fw_iso_resource_state_open(struct fw_iso_resource_state *state, const g
return FALSE;
}
+ if (!fw_iso_resource_state_cache_bus_state(state, error)) {
+ fw_iso_resource_state_release(state);
+ return FALSE;
+ }
+
return TRUE;
}
@@ -109,6 +114,7 @@ static gboolean dispatch_src(GSource *source, GSourceFunc cb, gpointer user_data
switch (ev->common.type) {
case FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED:
case FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED:
+ case FW_CDEV_EVENT_BUS_RESET:
src->handle_event(src->self, ev);
break;
default:
@@ -159,6 +165,26 @@ gboolean fw_iso_resource_state_create_source(struct fw_iso_resource_state *state
src->self = g_object_ref(inst);
src->handle_event = handle_event;
+ if (!fw_iso_resource_state_cache_bus_state(state, error)) {
+ g_source_unref(*source);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean fw_iso_resource_state_cache_bus_state(struct fw_iso_resource_state *state, GError **error)
+{
+ struct fw_cdev_get_info get_info = {0};
+
+ get_info.version = 5;
+ get_info.bus_reset = (__u64)&state->bus_state;
+
+ if (ioctl(state->fd, FW_CDEV_IOC_GET_INFO, &get_info) < 0) {
+ generate_syscall_error(error, errno, "ioctl(%s)", "FW_CDEV_IOC_GET_INFO");
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/src/fw_iso_resource_private.h b/src/fw_iso_resource_private.h
index d33ae61..5e9fa9a 100644
--- a/src/fw_iso_resource_private.h
+++ b/src/fw_iso_resource_private.h
@@ -18,6 +18,7 @@
struct fw_iso_resource_state {
int fd;
+ struct fw_cdev_event_bus_reset bus_state;
};
void fw_iso_resource_state_init(struct fw_iso_resource_state *state);
@@ -33,6 +34,8 @@ gboolean fw_iso_resource_state_create_source(struct fw_iso_resource_state *state
const union fw_cdev_event *event),
GSource **source, GError **error);
+gboolean fw_iso_resource_state_cache_bus_state(struct fw_iso_resource_state *state, GError **error);
+
struct fw_iso_resource_waiter {
GMutex mutex;
GCond cond;