From bc46fabccdf4565f1228d4d775680d9c85934024 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 17 Nov 2014 18:08:35 -0600 Subject: [PATCH] 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: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/operation.c | 38 ++++++++++++----------------- drivers/staging/greybus/operation.h | 2 +- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index ab03e3edc807..7eaea71f8604 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -72,7 +72,7 @@ static void gb_pending_operation_insert(struct gb_operation *operation) spin_unlock_irq(&gb_operations_lock); /* 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); } @@ -125,7 +125,7 @@ int gb_operation_wait(struct gb_operation *operation) ret = wait_for_completion_interruptible(&operation->completion); /* If interrupted, cancel the in-flight buffer */ if (ret < 0) - greybus_kill_gbuf(operation->request.gbuf); + greybus_kill_gbuf(&operation->request.gbuf); return ret; } @@ -135,7 +135,7 @@ static void gb_operation_request_handle(struct gb_operation *operation) struct gb_protocol *protocol = operation->connection->protocol; 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 @@ -165,7 +165,7 @@ static void gb_operation_recv_work(struct work_struct *recv_work) bool incoming_request; 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) gb_operation_request_handle(operation); gb_operation_complete(operation); @@ -212,6 +212,7 @@ static int gb_operation_message_init(struct gb_operation *operation, if (size > GB_OPERATION_MESSAGE_SIZE_MAX) return -E2BIG; + size += sizeof(*header); if (request) { message = &operation->request; @@ -219,25 +220,19 @@ static int gb_operation_message_init(struct gb_operation *operation, message = &operation->response; type |= GB_OPERATION_TYPE_RESPONSE; } + gbuf = &message->gbuf; + if (data_out) dest_cport_id = connection->interface_cport_id; else 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->dest_cport_id = dest_cport_id; gbuf->status = -EBADR; /* Initial value--means "never set" */ ret = hd->driver->alloc_gbuf_data(gbuf, size, gfp_flags); - if (ret) { - greybus_free_gbuf(gbuf); + if (ret) return ret; - } /* Fill in the header structure */ header = (struct gb_operation_msg_hdr *)gbuf->transfer_buffer; @@ -247,7 +242,6 @@ static int gb_operation_message_init(struct gb_operation *operation, message->payload = header + 1; message->operation = operation; - message->gbuf = gbuf; return 0; } @@ -256,9 +250,7 @@ static void gb_operation_message_exit(struct gb_message *message) { message->operation = NULL; message->payload = NULL; - message->gbuf->hd->driver->free_gbuf_data(message->gbuf); - greybus_free_gbuf(message->gbuf); - message->gbuf = NULL; + message->gbuf.hd->driver->free_gbuf_data(&message->gbuf); } /* @@ -375,7 +367,7 @@ int gb_operation_request_send(struct gb_operation *operation, */ operation->callback = callback; 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) return ret; @@ -440,7 +432,7 @@ void gb_connection_operation_recv(struct gb_connection *connection, } cancel_delayed_work(&operation->timeout_work); gb_pending_operation_remove(operation); - gbuf = operation->response.gbuf; + gbuf = &operation->response.gbuf; if (size > gbuf->transfer_buffer_length) { operation->result = GB_OP_OVERFLOW; gb_connection_err(connection, "recv buffer too small"); @@ -455,7 +447,7 @@ void gb_connection_operation_recv(struct gb_connection *connection, gb_connection_err(connection, "can't create operation"); return; } - gbuf = operation->request.gbuf; + gbuf = &operation->request.gbuf; } memcpy(gbuf->transfer_buffer, data, msg_size); @@ -470,9 +462,9 @@ void gb_connection_operation_recv(struct gb_connection *connection, void gb_operation_cancel(struct gb_operation *operation) { operation->canceled = true; - greybus_kill_gbuf(operation->request.gbuf); - if (operation->response.gbuf) - greybus_kill_gbuf(operation->response.gbuf); + greybus_kill_gbuf(&operation->request.gbuf); + if (operation->response.gbuf.transfer_buffer) + greybus_kill_gbuf(&operation->response.gbuf); } int gb_operation_init(void) diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index a18713457ba1..f43531dbcf33 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -38,7 +38,7 @@ struct gbuf { struct gb_message { void *payload; struct gb_operation *operation; - struct gbuf *gbuf; + struct gbuf gbuf; }; /* -- 2.39.5