greybus: start using struct gb_message
This converts some of the operation code to start leveraging the new gb_message type. Instead of creating the request and response gbufs, we initialize (and tear down with a new function) the request and response message structures. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
parent
3690a826fa
commit
c7f82d5dc0
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX This needs to be coordinated with host driver parameters
|
* XXX This needs to be coordinated with host driver parameters
|
||||||
|
* XXX May need to reduce to allow for message header within a page
|
||||||
*/
|
*/
|
||||||
#define GB_OPERATION_MESSAGE_SIZE_MAX 4096
|
#define GB_OPERATION_MESSAGE_SIZE_MAX 4096
|
||||||
|
|
||||||
@ -196,36 +197,56 @@ static void operation_timeout(struct work_struct *work)
|
|||||||
* initialize it here (it'll be overwritten by the incoming
|
* initialize it here (it'll be overwritten by the incoming
|
||||||
* message).
|
* message).
|
||||||
*/
|
*/
|
||||||
static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation,
|
static int gb_operation_message_init(struct gb_operation *operation,
|
||||||
u8 type, size_t size,
|
u8 type, size_t size,
|
||||||
bool data_out)
|
bool request, bool data_out)
|
||||||
{
|
{
|
||||||
struct gb_connection *connection = operation->connection;
|
struct gb_connection *connection = operation->connection;
|
||||||
|
struct gb_message *message;
|
||||||
struct gb_operation_msg_hdr *header;
|
struct gb_operation_msg_hdr *header;
|
||||||
struct gbuf *gbuf;
|
|
||||||
gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC;
|
gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC;
|
||||||
u16 dest_cport_id;
|
u16 dest_cport_id;
|
||||||
|
|
||||||
if (size > GB_OPERATION_MESSAGE_SIZE_MAX)
|
if (size > GB_OPERATION_MESSAGE_SIZE_MAX)
|
||||||
return NULL; /* Message too big */
|
return -E2BIG;
|
||||||
|
|
||||||
|
if (request) {
|
||||||
|
message = &operation->request;
|
||||||
|
} else {
|
||||||
|
message = &operation->response;
|
||||||
|
type |= GB_OPERATION_TYPE_RESPONSE;
|
||||||
|
}
|
||||||
if (data_out)
|
if (data_out)
|
||||||
dest_cport_id = connection->interface_cport_id;
|
dest_cport_id = connection->interface_cport_id;
|
||||||
else
|
else
|
||||||
dest_cport_id = CPORT_ID_BAD;
|
dest_cport_id = CPORT_ID_BAD;
|
||||||
|
|
||||||
|
if (message->gbuf)
|
||||||
|
return -EALREADY; /* Sanity check */
|
||||||
size += sizeof(*header);
|
size += sizeof(*header);
|
||||||
gbuf = greybus_alloc_gbuf(connection->hd, dest_cport_id,
|
message->gbuf = greybus_alloc_gbuf(connection->hd, dest_cport_id,
|
||||||
size, gfp_flags);
|
size, gfp_flags);
|
||||||
if (!gbuf)
|
if (!message->gbuf)
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Fill in the header structure */
|
/* Fill in the header structure */
|
||||||
header = (struct gb_operation_msg_hdr *)gbuf->transfer_buffer;
|
header = (struct gb_operation_msg_hdr *)message->gbuf->transfer_buffer;
|
||||||
header->size = cpu_to_le16(size);
|
header->size = cpu_to_le16(size);
|
||||||
header->id = 0; /* Filled in when submitted */
|
header->id = 0; /* Filled in when submitted */
|
||||||
header->type = type;
|
header->type = type;
|
||||||
|
|
||||||
return gbuf;
|
message->payload = header + 1;
|
||||||
|
message->operation = operation;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_operation_message_exit(struct gb_message *message)
|
||||||
|
{
|
||||||
|
message->operation = NULL;
|
||||||
|
message->payload = NULL;
|
||||||
|
greybus_free_gbuf(message->gbuf);
|
||||||
|
message->gbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -251,32 +272,23 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
|
|||||||
struct gb_operation *operation;
|
struct gb_operation *operation;
|
||||||
gfp_t gfp_flags = response_size ? GFP_KERNEL : GFP_ATOMIC;
|
gfp_t gfp_flags = response_size ? GFP_KERNEL : GFP_ATOMIC;
|
||||||
bool outgoing = response_size != 0;
|
bool outgoing = response_size != 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
|
operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
|
||||||
if (!operation)
|
if (!operation)
|
||||||
return NULL;
|
return NULL;
|
||||||
operation->connection = connection;
|
operation->connection = connection;
|
||||||
|
|
||||||
operation->request.gbuf = gb_operation_gbuf_create(operation, type,
|
ret = gb_operation_message_init(operation, type, request_size,
|
||||||
request_size,
|
true, outgoing);
|
||||||
outgoing);
|
if (ret)
|
||||||
if (!operation->request.gbuf)
|
|
||||||
goto err_cache;
|
goto err_cache;
|
||||||
operation->request.operation = operation;
|
|
||||||
operation->request.payload = operation->request.gbuf->transfer_buffer +
|
|
||||||
sizeof(struct gb_operation_msg_hdr);
|
|
||||||
|
|
||||||
if (outgoing) {
|
if (outgoing) {
|
||||||
type |= GB_OPERATION_TYPE_RESPONSE;
|
ret = gb_operation_message_init(operation, type, response_size,
|
||||||
operation->response.gbuf = gb_operation_gbuf_create(operation,
|
false, false);
|
||||||
type, response_size,
|
if (ret)
|
||||||
false);
|
|
||||||
if (!operation->response.gbuf)
|
|
||||||
goto err_request;
|
goto err_request;
|
||||||
operation->response.operation = operation;
|
|
||||||
operation->response.payload =
|
|
||||||
operation->response.gbuf->transfer_buffer +
|
|
||||||
sizeof(struct gb_operation_msg_hdr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_WORK(&operation->recv_work, gb_operation_recv_work);
|
INIT_WORK(&operation->recv_work, gb_operation_recv_work);
|
||||||
@ -292,7 +304,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
|
|||||||
return operation;
|
return operation;
|
||||||
|
|
||||||
err_request:
|
err_request:
|
||||||
greybus_free_gbuf(operation->request.gbuf);
|
gb_operation_message_exit(&operation->request);
|
||||||
err_cache:
|
err_cache:
|
||||||
kmem_cache_free(gb_operation_cache, operation);
|
kmem_cache_free(gb_operation_cache, operation);
|
||||||
|
|
||||||
@ -313,8 +325,8 @@ static void _gb_operation_destroy(struct kref *kref)
|
|||||||
list_del(&operation->links);
|
list_del(&operation->links);
|
||||||
spin_unlock_irq(&gb_operations_lock);
|
spin_unlock_irq(&gb_operations_lock);
|
||||||
|
|
||||||
greybus_free_gbuf(operation->response.gbuf);
|
gb_operation_message_exit(&operation->response);
|
||||||
greybus_free_gbuf(operation->request.gbuf);
|
gb_operation_message_exit(&operation->request);
|
||||||
|
|
||||||
kmem_cache_free(gb_operation_cache, operation);
|
kmem_cache_free(gb_operation_cache, operation);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user