summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2008-12-12 02:11:40 -0800
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2008-12-12 02:38:15 -0800
commit62014a51da02bea5f22f89373463366cb20f6341 (patch)
treeb407e3b712a1c5805cde508c0cf76d7461c72c8d
parent05391ddafc687f06fd2850338387e6064de09f1f (diff)
libwimaxll: callbacks take "void *" priv pointers
Change the callback model not to require a typed context and make it completely up to the application. The reason we had it before using an specific type that could be wrapped was that we had the callback pre-handler, when de-marshalled the arguments for the callback, to store in there the result of the demarshalling. However, that's kind of silly -- there is nothing the callback can do in case of error, as it doesn't even get called. So changed to just print an error message and return to wimaxll_gnl_cb(), which will just skip the bad netlink message. As part of this, we can move all the definitions of 'wimaxll_gnl_cb_context' to internal.h. Note as well that we cannot always set the context passed by wimaxll_recv(), as that'd mean -EBUSY from the user-set callbacks in wmx would leak to wimaxll_recv(), when their mission was to force nl_recvmsgs() to stop processing messages and return to wimaxll_recv()'s caller inmediately. So we need to consider -EBUSY as no error but just a code and in that case, consider that result is "zero". Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
-rw-r--r--include/wimaxll.h178
-rw-r--r--lib/internal.h131
-rw-r--r--lib/op-msg.c38
-rw-r--r--lib/op-open.c40
-rw-r--r--lib/re-state-change.c55
5 files changed, 205 insertions, 237 deletions
diff --git a/include/wimaxll.h b/include/wimaxll.h
index 6dc71ff..fe3275d 100644
--- a/include/wimaxll.h
+++ b/include/wimaxll.h
@@ -227,14 +227,8 @@
#include <stdarg.h>
#include <linux/wimax.h>
-/**
- * A WiMax control pipe handle
- *
- * This type is opaque to the user
- */
struct wimaxll_handle;
-struct wimaxll_gnl_cb_context;
struct nlattr;
@@ -247,18 +241,10 @@ struct nlattr;
* wimaxll_recv().
*
* Callbacks are always passed a pointer to a private context as set
- * by the application. The context is always of type struct
- * wimaxll_gnl_cb_context and is meant to be used wrapped in an
- * application-specific structure where private information can be
- * stored.
- *
- * When an application specific context is created, the
- * wimaxll_gnl_cb_context part of it should be initialized (with
- * WIMAXLL_GNL_CB_CONTEXT_INIT() or
- * wimaxll_gnl_cb_context_init()). Callback functions can safely
- * update it's \e result field with wimaxll_cb_context_set_result().
+ * by the application.
*/
+
/**
* Callback for a \e message \e to \e user generic netlink message
*
@@ -272,20 +258,20 @@ struct nlattr;
* guidelines for using callbacks.
*
* \param wmx WiMAX device handle
- * \param ctx Context passed by the user with
+ * \param priv Context passed by the user with
* wimaxll_pipe_set_cb_msg_to_user().
* \param pipe_name Name of the pipe the message is sent for
* \param data Pointer to a buffer with the message data.
* \param size Size of the buffer
- * \return 0 if it is ok to keep processing messages, -EBUSY if
+ * \return >= 0 if it is ok to keep processing messages, -EBUSY if
* message processing should stop and control be returned to the
- * caller. -EINPROGRESS if the callback wants to ignore the
- * message.
+ * caller. Any other negative error code to continue processing
+ * messages skipping the current one.
*
* \ingroup the_messaging_interface
*/
typedef int (*wimaxll_msg_to_user_cb_f)(struct wimaxll_handle *wmx,
- struct wimaxll_gnl_cb_context *ctx,
+ void *priv,
const char *pipe_name,
const void *data, size_t size);
@@ -300,150 +286,22 @@ typedef int (*wimaxll_msg_to_user_cb_f)(struct wimaxll_handle *wmx,
* guidelines for using callbacks.
*
* \param wmx WiMAX device handle
- * \param ctx Context passed by the user with
- * wimaxll_set_cb_state_change(). This is a pointer to a standard
- * context structure than can be wrapped in application-specific
- * ones.
+ * \param priv ctx Context passed by the user with
+ * wimaxll_set_cb_state_change().
* \param old_state State the WiMAX device left
* \param new_state State the WiMAX device entered
- * \return 0 if it is ok to keep processing messages, -EBUSY if
+ * \return >= 0 if it is ok to keep processing messages, -EBUSY if
* message processing should stop and control be returned to the
- * caller.
+ * caller. Any other negative error code to continue processing
+ * messages skipping the current one.
*
* \ingroup state_change_group
*/
typedef int (*wimaxll_state_change_cb_f)(
- struct wimaxll_handle *, struct wimaxll_gnl_cb_context *,
+ struct wimaxll_handle *, void *priv,
enum wimax_st old_state, enum wimax_st new_state);
-/**
- * General structure for storing callback context
- *
- * \ingroup callbacks
- *
- * Callbacks set by the user receive a user-set pointer to a context
- * structure. The user can wrap this struct in a bigger context struct
- * and use wimaxll_container_of() during the callback to obtain its
- * pointer.
- *
- * Usage:
- *
- * \code
- * ...
- * struct wimaxll_handle *wmx;
- * ...
- * struct my_context {
- * struct wimaxll_gnl_cb_context ctx;
- * <my data>
- * } my_ctx = {
- * .ctx = WIMAXLL_GNL_CB_CONTEXT_INIT(wmx),
- * <my data initialization>
- * };
- * ...
- * wimaxll_set_cb_SOMECALLBACK(wmx, my_callback, &my_ctx.ctx);
- * ...
- * result = wimaxll_pipe_read(wmx);
- * ...
- *
- * // When my_callback() is called
- * my_callback(wmx, ctx, ...)
- * {
- * struct my_context *my_ctx = wimaxll_container_of(
- * ctx, struct my_callback, ctx);
- * ...
- * // do stuff with my_ctx
- * }
- * \endcode
- *
- * \param wmx WiMAX handle this context refers to (for usage by the
- * callback).
- * \param result Result of the handling of the message. For usage by
- * the callback. Should not be set to -EINPROGRESS, as this will
- * be interpreted by the message handler as no processing was done
- * on the message.
- *
- * \internal
- *
- * \param msg_done This is used internally to mark when the acks (or
- * errors) for a message have been received and the message
- * receiving loop can be considered done.
- */
-struct wimaxll_gnl_cb_context {
- struct wimaxll_handle *wmx;
- ssize_t result;
- unsigned msg_done:1; /* internal */
-};
-
-
-/**
- * Initialize a definition of struct wimaxll_gnl_cb_context
- *
- * \param _wmx pointer to the WiMAX device handle this will be
- * associated to
- *
- * Use as:
- *
- * \code
- * struct wimaxll_handle *wmx;
- * ...
- * struct wimaxll_gnl_cb_context my_context = WIMAXLL_GNL_CB_CONTEXT_INIT(wmx);
- * \endcode
- *
- * \ingroup callbacks
- */
-#define WIMAXLL_GNL_CB_CONTEXT_INIT(_wmx) { \
- .wmx = (_wmx), \
- .result = -EINPROGRESS, \
-}
-
-
-static inline // ugly workaround for doxygen
-/**
- * Initialize a struct wimaxll_gnl_cb_context
- *
- * \param ctx Pointer to the struct wimaxll_gnl_cb_context.
- * \param wmx pointer to the WiMAX device handle this will be
- * associated to
- *
- * Use as:
- *
- * \code
- * struct wimaxll_handle *wmx;
- * ...
- * struct wimaxll_gnl_cb_context my_context;
- * ...
- * wimaxll_gnl_cb_context(&my_context, wmx);
- * \endcode
- *
- * \ingroup callbacks
- * \fn static void wimaxll_gnl_cb_context_init(struct wimaxll_gnl_cb_context *ctx, struct wimaxll_handle *wmx)
- */
-void wimaxll_gnl_cb_context_init(struct wimaxll_gnl_cb_context *ctx,
- struct wimaxll_handle *wmx)
-{
- ctx->wmx = wmx;
- ctx->result = -EINPROGRESS;
-}
-
-
-static inline // ugly workaround for doxygen
-/**
- * Set the result value in a callback context
- *
- * \param ctx Context where to set -- if NULL, no action will be taken
- * \param val value to set for \a result
- *
- * \ingroup callbacks
- * \fn static void wimaxll_cb_maybe_set_result(struct wimaxll_gnl_cb_context *ctx, int val)
- */
-void wimaxll_cb_maybe_set_result(struct wimaxll_gnl_cb_context *ctx, int val)
-{
- if (ctx != NULL && ctx->result == -EINPROGRESS)
- ctx->result = val;
-}
-
-
/* Basic handle management */
struct wimaxll_handle *wimaxll_open(const char *device_name);
void wimaxll_close(struct wimaxll_handle *);
@@ -458,11 +316,9 @@ ssize_t wimaxll_msg_write(struct wimaxll_handle *, const char *,
const void *, size_t);
void wimaxll_get_cb_msg_to_user(struct wimaxll_handle *,
- wimaxll_msg_to_user_cb_f *,
- struct wimaxll_gnl_cb_context **);
+ wimaxll_msg_to_user_cb_f *, void **);
void wimaxll_set_cb_msg_to_user(struct wimaxll_handle *,
- wimaxll_msg_to_user_cb_f,
- struct wimaxll_gnl_cb_context *);
+ wimaxll_msg_to_user_cb_f, void *);
#define WIMAX_PIPE_ANY (NULL-1)
ssize_t wimaxll_msg_read(struct wimaxll_handle *, const char *pine_name,
@@ -475,10 +331,10 @@ int wimaxll_reset(struct wimaxll_handle *);
void wimaxll_get_cb_state_change(
struct wimaxll_handle *, wimaxll_state_change_cb_f *,
- struct wimaxll_gnl_cb_context **);
+ void **);
void wimaxll_set_cb_state_change(
struct wimaxll_handle *, wimaxll_state_change_cb_f,
- struct wimaxll_gnl_cb_context *);
+ void *);
ssize_t wimaxll_wait_for_state_change(struct wimaxll_handle *wmx,
enum wimax_st *old_state,
enum wimax_st *new_state);
diff --git a/lib/internal.h b/lib/internal.h
index 2d63e6f..8998cf5 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -50,6 +50,133 @@ enum {
/**
+ * General structure for storing callback context
+ *
+ * \ingroup callbacks
+ *
+ * Callbacks set by the user receive a user-set pointer to a context
+ * structure. The user can wrap this struct in a bigger context struct
+ * and use wimaxll_container_of() during the callback to obtain its
+ * pointer.
+ *
+ * Usage:
+ *
+ * \code
+ * ...
+ * struct wimaxll_handle *wmx;
+ * ...
+ * struct my_context {
+ * struct wimaxll_gnl_cb_context ctx;
+ * <my data>
+ * } my_ctx = {
+ * .ctx = WIMAXLL_GNL_CB_CONTEXT_INIT(wmx),
+ * <my data initialization>
+ * };
+ * ...
+ * wimaxll_set_cb_SOMECALLBACK(wmx, my_callback, &my_ctx.ctx);
+ * ...
+ * result = wimaxll_pipe_read(wmx);
+ * ...
+ *
+ * // When my_callback() is called
+ * my_callback(wmx, ctx, ...)
+ * {
+ * struct my_context *my_ctx = wimaxll_container_of(
+ * ctx, struct my_callback, ctx);
+ * ...
+ * // do stuff with my_ctx
+ * }
+ * \endcode
+ *
+ * \param wmx WiMAX handle this context refers to (for usage by the
+ * callback).
+ * \param result Result of the handling of the message. For usage by
+ * the callback. Should not be set to -EINPROGRESS, as this will
+ * be interpreted by the message handler as no processing was done
+ * on the message.
+ *
+ * \internal
+ *
+ * \param msg_done This is used internally to mark when the acks (or
+ * errors) for a message have been received and the message
+ * receiving loop can be considered done.
+ */
+struct wimaxll_gnl_cb_context {
+ struct wimaxll_handle *wmx;
+ ssize_t result;
+ unsigned msg_done:1; /* internal */
+};
+
+
+/**
+ * Initialize a definition of struct wimaxll_gnl_cb_context
+ *
+ * \param _wmx pointer to the WiMAX device handle this will be
+ * associated to
+ *
+ * Use as:
+ *
+ * \code
+ * struct wimaxll_handle *wmx;
+ * ...
+ * struct wimaxll_gnl_cb_context my_context = WIMAXLL_GNL_CB_CONTEXT_INIT(wmx);
+ * \endcode
+ *
+ * \ingroup callbacks
+ */
+#define WIMAXLL_GNL_CB_CONTEXT_INIT(_wmx) { \
+ .wmx = (_wmx), \
+ .result = -EINPROGRESS, \
+}
+
+
+static inline // ugly workaround for doxygen
+/**
+ * Initialize a struct wimaxll_gnl_cb_context
+ *
+ * \param ctx Pointer to the struct wimaxll_gnl_cb_context.
+ * \param wmx pointer to the WiMAX device handle this will be
+ * associated to
+ *
+ * Use as:
+ *
+ * \code
+ * struct wimaxll_handle *wmx;
+ * ...
+ * struct wimaxll_gnl_cb_context my_context;
+ * ...
+ * wimaxll_gnl_cb_context(&my_context, wmx);
+ * \endcode
+ *
+ * \ingroup callbacks
+ * \fn static void wimaxll_gnl_cb_context_init(struct wimaxll_gnl_cb_context *ctx, struct wimaxll_handle *wmx)
+ */
+void wimaxll_gnl_cb_context_init(struct wimaxll_gnl_cb_context *ctx,
+ struct wimaxll_handle *wmx)
+{
+ ctx->wmx = wmx;
+ ctx->result = -EINPROGRESS;
+}
+
+
+static inline // ugly workaround for doxygen
+/**
+ * Set the result value in a callback context
+ *
+ * \param ctx Context where to set -- if NULL, no action will be taken
+ * \param val value to set for \a result
+ *
+ * \ingroup callbacks
+ * \fn static void wimaxll_cb_maybe_set_result(struct wimaxll_gnl_cb_context *ctx, int val)
+ */
+void wimaxll_cb_maybe_set_result(struct wimaxll_gnl_cb_context *ctx, int val)
+{
+ if (ctx != NULL && ctx->result == -EINPROGRESS)
+ ctx->result = val;
+}
+
+
+/**
* A WiMax control pipe handle
*
* This type is opaque to the user
@@ -91,10 +218,10 @@ struct wimaxll_handle {
struct nl_handle *nlh_rx;
wimaxll_msg_to_user_cb_f msg_to_user_cb;
- struct wimaxll_gnl_cb_context *msg_to_user_context;
+ void *msg_to_user_priv;
wimaxll_state_change_cb_f state_change_cb;
- struct wimaxll_gnl_cb_context *state_change_context;
+ void *state_change_priv;
};
diff --git a/lib/op-msg.c b/lib/op-msg.c
index 9faced4..0b774c4 100644
--- a/lib/op-msg.c
+++ b/lib/op-msg.c
@@ -142,7 +142,7 @@ struct nla_policy wimaxll_gnl_msg_from_user_policy[WIMAX_GNL_ATTR_MAX + 1] = {
* \param wmx WiMAX device handle
* \param mch Pointer to \c struct wimaxll_mc_handle
* \param msg Pointer to netlink message
- * \return \c enum nl_cb_action
+ * \return 0 if ok, < 0 errno code on error
*
* wimaxll_recv() calls libnl's nl_recvmsgs() to receive messages;
* when a valid message is received, wimax_gnl__cb() that selects a
@@ -161,7 +161,6 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx,
struct nlmsghdr *nl_hdr;
struct genlmsghdr *gnl_hdr;
struct nlattr *tb[WIMAX_GNL_ATTR_MAX+1];
- struct wimaxll_gnl_cb_context *ctx = wmx->msg_to_user_context;
const char *pipe_name;
void *data;
@@ -177,29 +176,24 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx,
if (result < 0) {
wimaxll_msg(wmx, "E: %s: genlmsg_parse() failed: %d\n",
__func__, result);
- wimaxll_cb_maybe_set_result(ctx, result);
- result = NL_SKIP;
goto error_parse;
}
/* Find if the message is for the interface wmx represents */
if (tb[WIMAX_GNL_MSG_IFIDX] == NULL) {
wimaxll_msg(wmx, "E: %s: cannot find IFIDX attribute\n",
__func__);
- wimaxll_cb_maybe_set_result(ctx, -ENODEV);
- result = NL_SKIP;
+ result = -EINVAL;
goto error_no_attrs;
-
}
if (wmx->ifidx != nla_get_u32(tb[WIMAX_GNL_MSG_IFIDX])) {
- result = NL_SKIP;
+ result = -ENODEV;
goto error_no_attrs;
}
/* Extract marshalled arguments */
if (tb[WIMAX_GNL_MSG_DATA] == NULL) {
wimaxll_msg(wmx, "E: %s: cannot find MSG_DATA attribute\n",
__func__);
- wimaxll_cb_maybe_set_result(ctx, -ENXIO);
- result = NL_SKIP;
+ result = -ENXIO;
goto error_no_attrs;
}
@@ -218,11 +212,8 @@ int wimaxll_gnl_handle_msg_to_user(struct wimaxll_handle *wmx,
d_dump(2, wmx, data, size);
/* Now execute the callback for handling msg-to-user */
- result = wmx->msg_to_user_cb(wmx, ctx, pipe_name, data, size);
- if (result == -EBUSY)
- result = NL_STOP;
- else
- result = NL_OK;
+ result = wmx->msg_to_user_cb(wmx, wmx->msg_to_user_priv,
+ pipe_name, data, size);
error_no_attrs:
error_not_for_us:
error_parse:
@@ -246,11 +237,12 @@ struct wimaxll_cb_msg_to_user_context {
*/
static
int wimaxll_msg_read_cb(struct wimaxll_handle *wmx,
- struct wimaxll_gnl_cb_context *ctx,
+ void *_ctx,
const char *pipe_name,
const void *data, size_t data_size)
{
int result;
+ struct wimaxll_gnl_cb_context *ctx = _ctx;
struct wimaxll_cb_msg_to_user_context *mtu_ctx =
wimaxll_container_of(
ctx, struct wimaxll_cb_msg_to_user_context, ctx);
@@ -343,7 +335,7 @@ ssize_t wimaxll_msg_read(struct wimaxll_handle *wmx,
.data = (void *) pipe_name,
};
wimaxll_msg_to_user_cb_f prev_cb = NULL;
- struct wimaxll_gnl_cb_context *prev_priv = NULL;
+ void *prev_priv = NULL;
d_fnstart(3, wmx, "(wmx %p pipe_name %s, buf %p)\n",
wmx, pipe_name, buf);
@@ -465,17 +457,17 @@ error_msg_alloc:
*
* \param wmx WiMAX handle.
* \param cb Where to store the current callback function.
- * \param context Where to store the private data pointer passed to the
+ * \param priv Where to store the private data pointer passed to the
* callback.
*
* \ingroup the_messaging_interface_group
*/
void wimaxll_get_cb_msg_to_user(
struct wimaxll_handle *wmx, wimaxll_msg_to_user_cb_f *cb,
- struct wimaxll_gnl_cb_context **context)
+ void **priv)
{
*cb = wmx->msg_to_user_cb;
- *context = wmx->msg_to_user_context;
+ *priv = wmx->msg_to_user_priv;
}
@@ -487,7 +479,7 @@ void wimaxll_get_cb_msg_to_user(
*
* \param wmx WiMAX handle.
* \param cb Callback function to set
- * \param context Private data pointer to pass to the callback
+ * \param priv Private data pointer to pass to the callback
* function (wrap a \a struct wimaxll_gnl_cb_context in your context
* struct and pass a pointer to it; then use wimaxll_container_of()
* to extract it back).
@@ -496,8 +488,8 @@ void wimaxll_get_cb_msg_to_user(
*/
void wimaxll_set_cb_msg_to_user(
struct wimaxll_handle *wmx, wimaxll_msg_to_user_cb_f cb,
- struct wimaxll_gnl_cb_context *context)
+ void *priv)
{
wmx->msg_to_user_cb = cb;
- wmx->msg_to_user_context = context;
+ wmx->msg_to_user_priv = priv;
}
diff --git a/lib/op-open.c b/lib/op-open.c
index 936624a..1d24ff6 100644
--- a/lib/op-open.c
+++ b/lib/op-open.c
@@ -113,11 +113,19 @@ static
* In wimaxll_recv(), -ENODATA is considered a retryable error --
* effectively, the message is skipped.
*
+ * The wimaxll_gnl_handle_*() functions need to return:
+ *
+ * - >= 0 to indicate message processing should continue
+ * - -EBUSY to indicate message processing should stop
+ * - any other < 0 error code to indicate an error and that the
+ * message should be skipped.
+ *
* \fn int wimaxll_gnl_cb(struct nl_msg *msg, void *_ctx)
*/
int wimaxll_gnl_cb(struct nl_msg *msg, void *_ctx)
{
ssize_t result;
+ enum nl_cb_action result_nl;
struct wimaxll_gnl_cb_context *ctx = _ctx;
struct wimaxll_handle *wmx = ctx->wmx;
struct nlmsghdr *nl_hdr;
@@ -134,35 +142,33 @@ int wimaxll_gnl_cb(struct nl_msg *msg, void *_ctx)
if (wmx->msg_to_user_cb)
result = wimaxll_gnl_handle_msg_to_user(wmx, msg);
else
- goto out_no_handler;
+ result = -ENODATA;
break;
case WIMAX_GNL_RE_STATE_CHANGE:
if (wmx->state_change_cb)
result = wimaxll_gnl_handle_state_change(wmx, msg);
else
- goto out_no_handler;
+ result = -ENODATA;
break;
default:
- goto error_unknown_msg;
+ d_printf(3, wmx, "E: %s: received unknown gnl message %d\n",
+ __func__, gnl_hdr->cmd);
+ result = -ENODATA;
}
- if (result == NL_STOP)
- wimaxll_cb_maybe_set_result(ctx, 0);
- d_fnend(3, wmx, "(msg %p ctx %p) = %zd\n", msg, ctx, result);
- return result;
-
-error_unknown_msg:
- d_printf(3, wmx, "E: %s: received unknown gnl message %d\n",
- __func__, gnl_hdr->cmd);
-out_no_handler:
- wimaxll_cb_maybe_set_result(ctx, -ENODATA);
- result = NL_SKIP;
+ if (result == -EBUSY) { /* stop signal from the user's callback */
+ result_nl = NL_STOP;
+ result = 0;
+ }
+ else if (result < 0)
+ result_nl = NL_SKIP;
+ else
+ result_nl = NL_OK;
+ wimaxll_cb_maybe_set_result(ctx, result);
d_fnend(3, wmx, "(msg %p ctx %p) = %zd\n", msg, ctx, result);
- return result;
+ return result_nl;
}
-
-
/**
* Return the file descriptor associated to a WiMAX handle
*
diff --git a/lib/re-state-change.c b/lib/re-state-change.c
index 80f6bec..369e713 100644
--- a/lib/re-state-change.c
+++ b/lib/re-state-change.c
@@ -124,10 +124,9 @@ int wimaxll_gnl_handle_state_change(struct wimaxll_handle *wmx,
struct nlmsghdr *nl_hdr;
struct genlmsghdr *gnl_hdr;
struct nlattr *tb[WIMAX_GNL_ATTR_MAX+1];
- struct wimaxll_gnl_cb_context *ctx = wmx->state_change_context;
enum wimax_st old_state, new_state;
- d_fnstart(7, wmx, "(msg %p)\n", msg);
+ d_fnstart(7, wmx, "(wmx %p msg %p)\n", wmx, msg);
nl_hdr = nlmsg_hdr(msg);
gnl_hdr = nlmsg_data(nl_hdr);
@@ -139,29 +138,25 @@ int wimaxll_gnl_handle_state_change(struct wimaxll_handle *wmx,
if (result < 0) {
wimaxll_msg(wmx, "E: %s: genlmsg_parse() failed: %d\n",
__func__, result);
- wimaxll_cb_maybe_set_result(ctx, result);
- result = NL_SKIP;
goto error_parse;
}
/* Find if the message is for the interface wmx represents */
if (tb[WIMAX_GNL_STCH_IFIDX] == NULL) {
wimaxll_msg(wmx, "E: %s: cannot find IFIDX attribute\n",
__func__);
- wimaxll_cb_maybe_set_result(ctx, -ENODEV);
- result = NL_SKIP;
+ result = -EINVAL;
goto error_no_attrs;
}
if (wmx->ifidx != nla_get_u32(tb[WIMAX_GNL_STCH_IFIDX])) {
- result = NL_SKIP;
+ result = -ENODEV;
goto error_no_attrs;
}
if (tb[WIMAX_GNL_STCH_STATE_OLD] == NULL) {
wimaxll_msg(wmx, "E: %s: cannot find STCH_STATE_OLD "
"attribute\n", __func__);
- wimaxll_cb_maybe_set_result(ctx, -ENXIO);
- result = NL_SKIP;
+ result = -ENXIO;
goto error_no_attrs;
}
@@ -170,8 +165,7 @@ int wimaxll_gnl_handle_state_change(struct wimaxll_handle *wmx,
if (tb[WIMAX_GNL_STCH_STATE_NEW] == NULL) {
wimaxll_msg(wmx, "E: %s: cannot find STCH_STATE_NEW "
"attribute\n", __func__);
- wimaxll_cb_maybe_set_result(ctx, -ENXIO);
- result = NL_SKIP;
+ result = -EINVAL;
goto error_no_attrs;
}
@@ -182,15 +176,11 @@ int wimaxll_gnl_handle_state_change(struct wimaxll_handle *wmx,
/* Now execute the callback for handling re-state-change; if
* it doesn't update the context's result code, we'll do. */
- result = wmx->state_change_cb(wmx, ctx, old_state, new_state);
- wimaxll_cb_maybe_set_result(ctx, result);
- if (result == -EBUSY)
- result = NL_STOP;
- else
- result = NL_OK;
+ result = wmx->state_change_cb(wmx, wmx->state_change_priv,
+ old_state, new_state);
error_no_attrs:
error_parse:
- d_fnend(7, wmx, "(msg %p ctx %p) = %zd\n", msg, ctx, result);
+ d_fnend(7, wmx, "(wmx %p msg %p) = %zd\n", wmx, msg, result);
return result;
}
@@ -211,17 +201,16 @@ struct wimaxll_state_change_context {
*
* \param wmx WiMAX handle.
* \param cb Where to store the current callback function.
- * \param context Where to store the private data pointer passed to the
+ * \param priv Where to store the private data pointer passed to the
* callback.
*
* \ingroup state_change_group
*/
void wimaxll_get_cb_state_change(struct wimaxll_handle *wmx,
- wimaxll_state_change_cb_f *cb,
- struct wimaxll_gnl_cb_context **context)
+ wimaxll_state_change_cb_f *cb, void **priv)
{
*cb = wmx->state_change_cb;
- *context = wmx->state_change_context;
+ *priv = wmx->state_change_priv;
}
@@ -230,16 +219,15 @@ void wimaxll_get_cb_state_change(struct wimaxll_handle *wmx,
*
* \param wmx WiMAX handle.
* \param cb Callback function to set
- * \param context Private data pointer to pass to the callback function.
+ * \param priv Private data pointer to pass to the callback function.
*
* \ingroup state_change_group
*/
void wimaxll_set_cb_state_change(struct wimaxll_handle *wmx,
- wimaxll_state_change_cb_f cb,
- struct wimaxll_gnl_cb_context *context)
+ wimaxll_state_change_cb_f cb, void *priv)
{
wmx->state_change_cb = cb;
- wmx->state_change_context = context;
+ wmx->state_change_priv = priv;
}
@@ -247,11 +235,10 @@ void wimaxll_set_cb_state_change(struct wimaxll_handle *wmx,
* Default callback we use in wimaxll_wait_for_state_change()
*/
static
-int wimaxll_cb_state_change(struct wimaxll_handle *wmx,
- struct wimaxll_gnl_cb_context *ctx,
- enum wimax_st old_state,
- enum wimax_st new_state)
+int wimaxll_cb_state_change(struct wimaxll_handle *wmx, void *_ctx,
+ enum wimax_st old_state, enum wimax_st new_state)
{
+ struct wimaxll_gnl_cb_context *ctx = _ctx;
struct wimaxll_state_change_context *stch_ctx =
wimaxll_container_of(ctx, struct wimaxll_state_change_context,
ctx);
@@ -261,7 +248,7 @@ int wimaxll_cb_state_change(struct wimaxll_handle *wmx,
*stch_ctx->old_state = old_state;
*stch_ctx->new_state = new_state;
stch_ctx->set = 1;
- return 0;
+ return -EBUSY;
}
@@ -296,7 +283,7 @@ ssize_t wimaxll_wait_for_state_change(struct wimaxll_handle *wmx,
{
ssize_t result;
wimaxll_state_change_cb_f prev_cb = NULL;
- struct wimaxll_gnl_cb_context *prev_ctx = NULL;
+ void *prev_priv = NULL;
struct wimaxll_state_change_context ctx = {
.ctx = WIMAXLL_GNL_CB_CONTEXT_INIT(wmx),
.old_state = old_state,
@@ -306,11 +293,11 @@ ssize_t wimaxll_wait_for_state_change(struct wimaxll_handle *wmx,
d_fnstart(3, wmx, "(wmx %p old_state %p new_state %p)\n",
wmx, old_state, new_state);
- wimaxll_get_cb_state_change(wmx, &prev_cb, &prev_ctx);
+ wimaxll_get_cb_state_change(wmx, &prev_cb, &prev_priv);
wimaxll_set_cb_state_change(wmx, wimaxll_cb_state_change, &ctx.ctx);
result = wimaxll_recv(wmx);
/* the callback filled out *old_state and *new_state if ok */
- wimaxll_set_cb_state_change(wmx, prev_cb, prev_ctx);
+ wimaxll_set_cb_state_change(wmx, prev_cb, prev_priv);
d_fnend(3, wmx, "(wmx %p old_state %p [%u] new_state %p [%u])\n",
wmx, old_state, *old_state, new_state, *new_state);
return result;