1
0
Fork 0

greybus: operation: add incoming-operation flag

Add flag field to struct gb_operation, and a first flag
GB_OPERATION_FLAG_INCOMING to identify incoming operations.

Pass an initial set of flags when allocating new operations, and use
these to identify incoming operations rather than overloading the
meaning of GB_OPERATION_TYPE_INVALID. This also allows us to set the
type for all operations during allocation.

Also add convenience helper to identify incoming operations.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
hifive-unleashed-5.1
Johan Hovold 2015-07-01 12:37:26 +02:00 committed by Greg Kroah-Hartman
parent 73f9d73f12
commit 710067e2ef
2 changed files with 19 additions and 9 deletions

View File

@ -413,7 +413,7 @@ EXPORT_SYMBOL_GPL(gb_operation_response_alloc);
static struct gb_operation * static struct gb_operation *
gb_operation_create_common(struct gb_connection *connection, u8 type, gb_operation_create_common(struct gb_connection *connection, u8 type,
size_t request_size, size_t response_size, size_t request_size, size_t response_size,
gfp_t gfp_flags) unsigned long op_flags, gfp_t gfp_flags)
{ {
struct greybus_host_device *hd = connection->hd; struct greybus_host_device *hd = connection->hd;
struct gb_operation *operation; struct gb_operation *operation;
@ -431,11 +431,13 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
operation->request->operation = operation; operation->request->operation = operation;
/* Allocate the response buffer for outgoing operations */ /* Allocate the response buffer for outgoing operations */
if (type != GB_OPERATION_TYPE_INVALID) { if (!(op_flags & GB_OPERATION_FLAG_INCOMING)) {
if (!gb_operation_response_alloc(operation, response_size)) if (!gb_operation_response_alloc(operation, response_size))
goto err_request; goto err_request;
operation->type = type;
} }
operation->flags = op_flags;
operation->type = type;
operation->errno = -EBADR; /* Initial value--means "never set" */ operation->errno = -EBADR; /* Initial value--means "never set" */
INIT_WORK(&operation->work, gb_operation_work); INIT_WORK(&operation->work, gb_operation_work);
@ -475,7 +477,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
type &= ~GB_MESSAGE_TYPE_RESPONSE; type &= ~GB_MESSAGE_TYPE_RESPONSE;
return gb_operation_create_common(connection, type, return gb_operation_create_common(connection, type,
request_size, response_size, gfp); request_size, response_size, 0, gfp);
} }
EXPORT_SYMBOL_GPL(gb_operation_create); EXPORT_SYMBOL_GPL(gb_operation_create);
@ -493,16 +495,15 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id,
{ {
struct gb_operation *operation; struct gb_operation *operation;
size_t request_size; size_t request_size;
unsigned long flags = GB_OPERATION_FLAG_INCOMING;
/* Caller has made sure we at least have a message header. */ /* Caller has made sure we at least have a message header. */
request_size = size - sizeof(struct gb_operation_msg_hdr); request_size = size - sizeof(struct gb_operation_msg_hdr);
operation = gb_operation_create_common(connection, operation = gb_operation_create_common(connection, type,
GB_OPERATION_TYPE_INVALID, request_size, 0, flags, GFP_ATOMIC);
request_size, 0, GFP_ATOMIC);
if (operation) { if (operation) {
operation->id = id; operation->id = id;
operation->type = type;
memcpy(operation->request->header, data, size); memcpy(operation->request->header, data, size);
} }

View File

@ -89,6 +89,8 @@ struct gb_message {
void *hcpriv; void *hcpriv;
}; };
#define GB_OPERATION_FLAG_INCOMING BIT(0)
/* /*
* A Greybus operation is a remote procedure call performed over a * A Greybus operation is a remote procedure call performed over a
* connection between two UniPro interfaces. * connection between two UniPro interfaces.
@ -113,8 +115,9 @@ struct gb_operation {
struct gb_connection *connection; struct gb_connection *connection;
struct gb_message *request; struct gb_message *request;
struct gb_message *response; struct gb_message *response;
u8 type;
unsigned long flags;
u8 type;
u16 id; u16 id;
int errno; /* Operation result */ int errno; /* Operation result */
@ -126,6 +129,12 @@ struct gb_operation {
struct list_head links; /* connection->operations */ struct list_head links; /* connection->operations */
}; };
static inline bool
gb_operation_is_incoming(struct gb_operation *operation)
{
return operation->flags & GB_OPERATION_FLAG_INCOMING;
}
void gb_connection_recv(struct gb_connection *connection, void gb_connection_recv(struct gb_connection *connection,
void *data, size_t size); void *data, size_t size);