diff --git a/drivers/staging/greybus/gbuf.c b/drivers/staging/greybus/gbuf.c index 1d0dd4acfa2a..5ffd257de68f 100644 --- a/drivers/staging/greybus/gbuf.c +++ b/drivers/staging/greybus/gbuf.c @@ -38,32 +38,12 @@ struct gbuf *greybus_alloc_gbuf(struct greybus_host_device *hd, unsigned int size, gfp_t gfp_mask) { - struct gbuf *gbuf; - int retval; - - gbuf = kmem_cache_zalloc(gbuf_head_cache, gfp_mask); - if (!gbuf) - return NULL; - - gbuf->hd = hd; - gbuf->dest_cport_id = dest_cport_id; - gbuf->status = -EBADR; /* Initial value--means "never set" */ - - /* Host controller specific allocation for the actual buffer */ - retval = hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask); - if (retval) { - kmem_cache_free(gbuf_head_cache, gbuf); - return NULL; - } - - return gbuf; + return kmem_cache_zalloc(gbuf_head_cache, gfp_mask); } EXPORT_SYMBOL_GPL(greybus_alloc_gbuf); void greybus_free_gbuf(struct gbuf *gbuf) { - gbuf->hd->driver->free_gbuf_data(gbuf); - kmem_cache_free(gbuf_head_cache, gbuf); } EXPORT_SYMBOL_GPL(greybus_free_gbuf); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index d6bfe6b2f70f..e1f918d50df2 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -106,7 +106,8 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id, u8 *data, size_t length); struct gbuf *greybus_alloc_gbuf(struct greybus_host_device *hd, - u16 dest_cport_id, unsigned int size, + u16 dest_cport_id, + unsigned int size, gfp_t gfp_mask); void greybus_free_gbuf(struct gbuf *gbuf); diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 18186fd2db8c..ab03e3edc807 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -202,10 +202,13 @@ static int gb_operation_message_init(struct gb_operation *operation, bool request, bool data_out) { struct gb_connection *connection = operation->connection; + struct greybus_host_device *hd = connection->hd; struct gb_message *message; struct gb_operation_msg_hdr *header; + struct gbuf *gbuf; gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC; u16 dest_cport_id; + int ret; if (size > GB_OPERATION_MESSAGE_SIZE_MAX) return -E2BIG; @@ -224,19 +227,27 @@ static int gb_operation_message_init(struct gb_operation *operation, if (message->gbuf) return -EALREADY; /* Sanity check */ size += sizeof(*header); - message->gbuf = greybus_alloc_gbuf(connection->hd, dest_cport_id, - size, gfp_flags); - if (!message->gbuf) + 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); + return ret; + } /* Fill in the header structure */ - header = (struct gb_operation_msg_hdr *)message->gbuf->transfer_buffer; + header = (struct gb_operation_msg_hdr *)gbuf->transfer_buffer; header->size = cpu_to_le16(size); header->id = 0; /* Filled in when submitted */ header->type = type; message->payload = header + 1; message->operation = operation; + message->gbuf = gbuf; return 0; } @@ -245,6 +256,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; }