|
@@ -882,6 +882,52 @@ static int synx_match_payload(struct synx_kernel_payload *cb_payload,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+/* Timer Callback function. This will be called when timer expires */
|
|
|
+void synx_timer_cb(struct timer_list *data)
|
|
|
+{
|
|
|
+ struct synx_client *client;
|
|
|
+ struct synx_handle_coredata *synx_data;
|
|
|
+ struct synx_coredata *synx_obj;
|
|
|
+ struct synx_cb_data *synx_cb = container_of(data, struct synx_cb_data, synx_timer);
|
|
|
+
|
|
|
+ client = synx_get_client(synx_cb->session);
|
|
|
+ if (IS_ERR_OR_NULL(client)) {
|
|
|
+ dprintk(SYNX_ERR,
|
|
|
+ "invalid session data 0x%x in cb payload\n",
|
|
|
+ synx_cb->session);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ synx_data = synx_util_acquire_handle(client, synx_cb->h_synx);
|
|
|
+ synx_obj = synx_util_obtain_object(synx_data);
|
|
|
+ if (IS_ERR_OR_NULL(synx_obj)) {
|
|
|
+ dprintk(SYNX_ERR,
|
|
|
+ "[sess :0x%llx] invalid handle access 0x%x\n",
|
|
|
+ synx_cb->session, synx_cb->h_synx);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dprintk(SYNX_VERB,
|
|
|
+ "Timer expired for synx_cb 0x%x timeout 0x%llx. Deleting the timer.\n",
|
|
|
+ synx_cb, synx_cb->timeout);
|
|
|
+
|
|
|
+ synx_cb->status = SYNX_STATE_TIMEOUT;
|
|
|
+ del_timer(&synx_cb->synx_timer);
|
|
|
+ list_del_init(&synx_cb->node);
|
|
|
+ queue_work(synx_dev->wq_cb, &synx_cb->cb_dispatch);
|
|
|
+}
|
|
|
+
|
|
|
+static int synx_start_timer(struct synx_cb_data *synx_cb)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ timer_setup(&synx_cb->synx_timer, synx_timer_cb, 0);
|
|
|
+ rc = mod_timer(&synx_cb->synx_timer, jiffies + msecs_to_jiffies(synx_cb->timeout));
|
|
|
+ dprintk(SYNX_VERB,
|
|
|
+ "Timer started for synx_cb 0x%x timeout 0x%llx\n",
|
|
|
+ synx_cb, synx_cb->timeout);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int synx_async_wait(struct synx_session *session,
|
|
|
struct synx_callback_params *params)
|
|
|
{
|
|
@@ -897,9 +943,6 @@ int synx_async_wait(struct synx_session *session,
|
|
|
if (IS_ERR_OR_NULL(session) || IS_ERR_OR_NULL(params))
|
|
|
return -SYNX_INVALID;
|
|
|
|
|
|
- if (params->timeout_ms != SYNX_NO_TIMEOUT)
|
|
|
- return -SYNX_NOSUPPORT;
|
|
|
-
|
|
|
client = synx_get_client(session);
|
|
|
if (IS_ERR_OR_NULL(client))
|
|
|
return -SYNX_INVALID;
|
|
@@ -952,6 +995,8 @@ int synx_async_wait(struct synx_session *session,
|
|
|
|
|
|
synx_cb->session = session;
|
|
|
synx_cb->idx = idx;
|
|
|
+ synx_cb->h_synx = params->h_synx;
|
|
|
+
|
|
|
INIT_WORK(&synx_cb->cb_dispatch, synx_util_cb_dispatch);
|
|
|
|
|
|
/* add callback if object still ACTIVE, dispatch if SIGNALED */
|
|
@@ -959,6 +1004,17 @@ int synx_async_wait(struct synx_session *session,
|
|
|
dprintk(SYNX_VERB,
|
|
|
"[sess :%llu] callback added for handle %u\n",
|
|
|
client->id, params->h_synx);
|
|
|
+ synx_cb->timeout = params->timeout_ms;
|
|
|
+ if (params->timeout_ms != SYNX_NO_TIMEOUT) {
|
|
|
+ rc = synx_start_timer(synx_cb);
|
|
|
+ if (rc != SYNX_SUCCESS) {
|
|
|
+ dprintk(SYNX_ERR,
|
|
|
+ "[sess :%llu] timer start failed - synx_cb: 0x%x, params->timeout_ms: 0x%llx, handle: 0x%x, ret : %d\n",
|
|
|
+ client->id, synx_cb, params->timeout_ms,
|
|
|
+ params->h_synx, rc);
|
|
|
+ goto release;
|
|
|
+ }
|
|
|
+ }
|
|
|
list_add(&synx_cb->node, &synx_obj->reg_cbs_list);
|
|
|
} else {
|
|
|
synx_cb->status = status;
|
|
@@ -1024,7 +1080,7 @@ int synx_cancel_async_wait(
|
|
|
status = synx_util_get_object_status(synx_obj);
|
|
|
if (status != SYNX_STATE_ACTIVE) {
|
|
|
dprintk(SYNX_ERR,
|
|
|
- "handle %u already signaled cannot cancel\n",
|
|
|
+ "handle %u already signaled or timed out, cannot cancel\n",
|
|
|
params->h_synx);
|
|
|
rc = -SYNX_INVALID;
|
|
|
goto release;
|
|
@@ -1052,6 +1108,12 @@ int synx_cancel_async_wait(
|
|
|
|
|
|
cb_payload = &client->cb_table[synx_cb->idx];
|
|
|
ret = synx_match_payload(&cb_payload->kernel_cb, &payload);
|
|
|
+ if (synx_cb->timeout != SYNX_NO_TIMEOUT) {
|
|
|
+ dprintk(SYNX_VERB,
|
|
|
+ "Deleting timer synx_cb 0x%x, timeout 0x%llx\n",
|
|
|
+ synx_cb, synx_cb->timeout);
|
|
|
+ del_timer(&synx_cb->synx_timer);
|
|
|
+ }
|
|
|
switch (ret) {
|
|
|
case 1:
|
|
|
/* queue the cancel cb work */
|