Commit bc46fabc authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

greybus: embed gbufs into operation message structure

Embed the gbuf structures for operation messages into the message
structure rather than pointing to a dynamically allocated one.

Use a null gbuf->transfer_buffer pointer rather than a null gbuf
pointer to indicate an unused gbuf.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent f7935e33
...@@ -72,7 +72,7 @@ static void gb_pending_operation_insert(struct gb_operation *operation) ...@@ -72,7 +72,7 @@ static void gb_pending_operation_insert(struct gb_operation *operation)
spin_unlock_irq(&gb_operations_lock); spin_unlock_irq(&gb_operations_lock);
/* Store the operation id in the request header */ /* Store the operation id in the request header */
header = operation->request.gbuf->transfer_buffer; header = operation->request.gbuf.transfer_buffer;
header->id = cpu_to_le16(operation->id); header->id = cpu_to_le16(operation->id);
} }
...@@ -125,7 +125,7 @@ int gb_operation_wait(struct gb_operation *operation) ...@@ -125,7 +125,7 @@ int gb_operation_wait(struct gb_operation *operation)
ret = wait_for_completion_interruptible(&operation->completion); ret = wait_for_completion_interruptible(&operation->completion);
/* If interrupted, cancel the in-flight buffer */ /* If interrupted, cancel the in-flight buffer */
if (ret < 0) if (ret < 0)
greybus_kill_gbuf(operation->request.gbuf); greybus_kill_gbuf(&operation->request.gbuf);
return ret; return ret;
} }
...@@ -135,7 +135,7 @@ static void gb_operation_request_handle(struct gb_operation *operation) ...@@ -135,7 +135,7 @@ static void gb_operation_request_handle(struct gb_operation *operation)
struct gb_protocol *protocol = operation->connection->protocol; struct gb_protocol *protocol = operation->connection->protocol;
struct gb_operation_msg_hdr *header; struct gb_operation_msg_hdr *header;
header = operation->request.gbuf->transfer_buffer; header = operation->request.gbuf.transfer_buffer;
/* /*
* If the protocol has no incoming request handler, report * If the protocol has no incoming request handler, report
...@@ -165,7 +165,7 @@ static void gb_operation_recv_work(struct work_struct *recv_work) ...@@ -165,7 +165,7 @@ static void gb_operation_recv_work(struct work_struct *recv_work)
bool incoming_request; bool incoming_request;
operation = container_of(recv_work, struct gb_operation, recv_work); operation = container_of(recv_work, struct gb_operation, recv_work);
incoming_request = operation->response.gbuf == NULL; incoming_request = operation->response.gbuf.transfer_buffer == NULL;
if (incoming_request) if (incoming_request)
gb_operation_request_handle(operation); gb_operation_request_handle(operation);
gb_operation_complete(operation); gb_operation_complete(operation);
...@@ -212,6 +212,7 @@ static int gb_operation_message_init(struct gb_operation *operation, ...@@ -212,6 +212,7 @@ static int gb_operation_message_init(struct gb_operation *operation,
if (size > GB_OPERATION_MESSAGE_SIZE_MAX) if (size > GB_OPERATION_MESSAGE_SIZE_MAX)
return -E2BIG; return -E2BIG;
size += sizeof(*header);
if (request) { if (request) {
message = &operation->request; message = &operation->request;
...@@ -219,25 +220,19 @@ static int gb_operation_message_init(struct gb_operation *operation, ...@@ -219,25 +220,19 @@ static int gb_operation_message_init(struct gb_operation *operation,
message = &operation->response; message = &operation->response;
type |= GB_OPERATION_TYPE_RESPONSE; type |= GB_OPERATION_TYPE_RESPONSE;
} }
gbuf = &message->gbuf;
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);
gbuf = greybus_alloc_gbuf(hd, dest_cport_id, size, gfp_flags);
if (!gbuf)
return -ENOMEM;
gbuf->hd = hd; gbuf->hd = hd;
gbuf->dest_cport_id = dest_cport_id; gbuf->dest_cport_id = dest_cport_id;
gbuf->status = -EBADR; /* Initial value--means "never set" */ gbuf->status = -EBADR; /* Initial value--means "never set" */
ret = hd->driver->alloc_gbuf_data(gbuf, size, gfp_flags); ret = hd->driver->alloc_gbuf_data(gbuf, size, gfp_flags);
if (ret) { if (ret)
greybus_free_gbuf(gbuf);
return ret; return ret;
}
/* 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 *)gbuf->transfer_buffer;
...@@ -247,7 +242,6 @@ static int gb_operation_message_init(struct gb_operation *operation, ...@@ -247,7 +242,6 @@ static int gb_operation_message_init(struct gb_operation *operation,
message->payload = header + 1; message->payload = header + 1;
message->operation = operation; message->operation = operation;
message->gbuf = gbuf;
return 0; return 0;
} }
...@@ -256,9 +250,7 @@ static void gb_operation_message_exit(struct gb_message *message) ...@@ -256,9 +250,7 @@ static void gb_operation_message_exit(struct gb_message *message)
{ {
message->operation = NULL; message->operation = NULL;
message->payload = NULL; message->payload = NULL;
message->gbuf->hd->driver->free_gbuf_data(message->gbuf); message->gbuf.hd->driver->free_gbuf_data(&message->gbuf);
greybus_free_gbuf(message->gbuf);
message->gbuf = NULL;
} }
/* /*
...@@ -375,7 +367,7 @@ int gb_operation_request_send(struct gb_operation *operation, ...@@ -375,7 +367,7 @@ int gb_operation_request_send(struct gb_operation *operation,
*/ */
operation->callback = callback; operation->callback = callback;
gb_pending_operation_insert(operation); gb_pending_operation_insert(operation);
ret = greybus_submit_gbuf(operation->request.gbuf, GFP_KERNEL); ret = greybus_submit_gbuf(&operation->request.gbuf, GFP_KERNEL);
if (ret) if (ret)
return ret; return ret;
...@@ -440,7 +432,7 @@ void gb_connection_operation_recv(struct gb_connection *connection, ...@@ -440,7 +432,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
} }
cancel_delayed_work(&operation->timeout_work); cancel_delayed_work(&operation->timeout_work);
gb_pending_operation_remove(operation); gb_pending_operation_remove(operation);
gbuf = operation->response.gbuf; gbuf = &operation->response.gbuf;
if (size > gbuf->transfer_buffer_length) { if (size > gbuf->transfer_buffer_length) {
operation->result = GB_OP_OVERFLOW; operation->result = GB_OP_OVERFLOW;
gb_connection_err(connection, "recv buffer too small"); gb_connection_err(connection, "recv buffer too small");
...@@ -455,7 +447,7 @@ void gb_connection_operation_recv(struct gb_connection *connection, ...@@ -455,7 +447,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
gb_connection_err(connection, "can't create operation"); gb_connection_err(connection, "can't create operation");
return; return;
} }
gbuf = operation->request.gbuf; gbuf = &operation->request.gbuf;
} }
memcpy(gbuf->transfer_buffer, data, msg_size); memcpy(gbuf->transfer_buffer, data, msg_size);
...@@ -470,9 +462,9 @@ void gb_connection_operation_recv(struct gb_connection *connection, ...@@ -470,9 +462,9 @@ void gb_connection_operation_recv(struct gb_connection *connection,
void gb_operation_cancel(struct gb_operation *operation) void gb_operation_cancel(struct gb_operation *operation)
{ {
operation->canceled = true; operation->canceled = true;
greybus_kill_gbuf(operation->request.gbuf); greybus_kill_gbuf(&operation->request.gbuf);
if (operation->response.gbuf) if (operation->response.gbuf.transfer_buffer)
greybus_kill_gbuf(operation->response.gbuf); greybus_kill_gbuf(&operation->response.gbuf);
} }
int gb_operation_init(void) int gb_operation_init(void)
......
...@@ -38,7 +38,7 @@ struct gbuf { ...@@ -38,7 +38,7 @@ struct gbuf {
struct gb_message { struct gb_message {
void *payload; void *payload;
struct gb_operation *operation; struct gb_operation *operation;
struct gbuf *gbuf; struct gbuf gbuf;
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment