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

greybus: record gbuf->operation

Currently a gbuf records a pointer to the connection it's associated
with.  We now know only use gbufs in operation messages, so we can
point a gbuf at its operation instead.  This still gives access to
the connection where needed, but it also will provide all the
context we'll ever need for a gbuf, and this allows us (in the next
patch) to remove the gbuf->context field as well.

So switch to recording in a gbuf the operation rather than the
connection it is associated with.
Signed-off-by: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent c69a50f2
...@@ -96,6 +96,7 @@ static void cport_out_callback(struct urb *urb); ...@@ -96,6 +96,7 @@ static void cport_out_callback(struct urb *urb);
static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size, static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
gfp_t gfp_mask) gfp_t gfp_mask)
{ {
struct gb_connection *connection = gbuf->operation->connection;
u32 cport_reserve = gbuf->outbound ? 1 : 0; u32 cport_reserve = gbuf->outbound ? 1 : 0;
u8 *buffer; u8 *buffer;
...@@ -121,16 +122,16 @@ static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size, ...@@ -121,16 +122,16 @@ static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
* we will encode the cport number in the first byte of the buffer, so * we will encode the cport number in the first byte of the buffer, so
* set the second byte to be the "transfer buffer" * set the second byte to be the "transfer buffer"
*/ */
if (gbuf->connection->interface_cport_id > (u16)U8_MAX) { if (connection->interface_cport_id > (u16)U8_MAX) {
pr_err("gbuf->interface_cport_id (%hd) is out of range!\n", pr_err("gbuf->interface_cport_id (%hd) is out of range!\n",
gbuf->connection->interface_cport_id); connection->interface_cport_id);
kfree(buffer); kfree(buffer);
return -EINVAL; return -EINVAL;
} }
/* Insert the cport id for outbound buffers */ /* Insert the cport id for outbound buffers */
if (gbuf->outbound) if (gbuf->outbound)
*buffer++ = gbuf->connection->interface_cport_id; *buffer++ = connection->interface_cport_id;
gbuf->transfer_buffer = buffer; gbuf->transfer_buffer = buffer;
gbuf->transfer_buffer_length = size; gbuf->transfer_buffer_length = size;
...@@ -208,7 +209,7 @@ static struct urb *next_free_urb(struct es1_ap_dev *es1, gfp_t gfp_mask) ...@@ -208,7 +209,7 @@ static struct urb *next_free_urb(struct es1_ap_dev *es1, gfp_t gfp_mask)
static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask) static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
{ {
struct greybus_host_device *hd = gbuf->connection->hd; struct greybus_host_device *hd = gbuf->operation->connection->hd;
struct es1_ap_dev *es1 = hd_to_es1(hd); struct es1_ap_dev *es1 = hd_to_es1(hd);
struct usb_device *udev = es1->usb_dev; struct usb_device *udev = es1->usb_dev;
int retval; int retval;
...@@ -394,7 +395,7 @@ static void cport_in_callback(struct urb *urb) ...@@ -394,7 +395,7 @@ static void cport_in_callback(struct urb *urb)
static void cport_out_callback(struct urb *urb) static void cport_out_callback(struct urb *urb)
{ {
struct gbuf *gbuf = urb->context; struct gbuf *gbuf = urb->context;
struct es1_ap_dev *es1 = hd_to_es1(gbuf->connection->hd); struct es1_ap_dev *es1 = hd_to_es1(gbuf->operation->connection->hd);
unsigned long flags; unsigned long flags;
int i; int i;
......
...@@ -35,13 +35,14 @@ static struct kmem_cache *gbuf_head_cache; ...@@ -35,13 +35,14 @@ static struct kmem_cache *gbuf_head_cache;
* that the driver can then fill up with the data to be sent out. Curse * that the driver can then fill up with the data to be sent out. Curse
* hardware designers for this issue... * hardware designers for this issue...
*/ */
struct gbuf *greybus_alloc_gbuf(struct gb_connection *connection, struct gbuf *greybus_alloc_gbuf(struct gb_operation *operation,
gbuf_complete_t complete, gbuf_complete_t complete,
unsigned int size, unsigned int size,
bool outbound, bool outbound,
gfp_t gfp_mask, gfp_t gfp_mask,
void *context) void *context)
{ {
struct greybus_host_device *hd = operation->connection->hd;
struct gbuf *gbuf; struct gbuf *gbuf;
int retval; int retval;
...@@ -50,14 +51,14 @@ struct gbuf *greybus_alloc_gbuf(struct gb_connection *connection, ...@@ -50,14 +51,14 @@ struct gbuf *greybus_alloc_gbuf(struct gb_connection *connection,
return NULL; return NULL;
kref_init(&gbuf->kref); kref_init(&gbuf->kref);
gbuf->connection = connection; gbuf->operation = operation;
gbuf->outbound = outbound; gbuf->outbound = outbound;
gbuf->complete = complete; gbuf->complete = complete;
gbuf->context = context; gbuf->context = context;
gbuf->status = -EBADR; /* Initial value--means "never set" */ gbuf->status = -EBADR; /* Initial value--means "never set" */
/* Host controller specific allocation for the actual buffer */ /* Host controller specific allocation for the actual buffer */
retval = connection->hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask); retval = hd->driver->alloc_gbuf_data(gbuf, size, gfp_mask);
if (retval) { if (retval) {
kmem_cache_free(gbuf_head_cache, gbuf); kmem_cache_free(gbuf_head_cache, gbuf);
return NULL; return NULL;
...@@ -72,8 +73,9 @@ static DEFINE_MUTEX(gbuf_mutex); ...@@ -72,8 +73,9 @@ static DEFINE_MUTEX(gbuf_mutex);
static void free_gbuf(struct kref *kref) static void free_gbuf(struct kref *kref)
{ {
struct gbuf *gbuf = container_of(kref, struct gbuf, kref); struct gbuf *gbuf = container_of(kref, struct gbuf, kref);
struct greybus_host_device *hd = gbuf->operation->connection->hd;
gbuf->connection->hd->driver->free_gbuf_data(gbuf); hd->driver->free_gbuf_data(gbuf);
kmem_cache_free(gbuf_head_cache, gbuf); kmem_cache_free(gbuf_head_cache, gbuf);
mutex_unlock(&gbuf_mutex); mutex_unlock(&gbuf_mutex);
...@@ -97,7 +99,7 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf); ...@@ -97,7 +99,7 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf);
int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask) int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
{ {
struct greybus_host_device *hd = gbuf->connection->hd; struct greybus_host_device *hd = gbuf->operation->connection->hd;
gbuf->status = -EINPROGRESS; gbuf->status = -EINPROGRESS;
...@@ -106,7 +108,7 @@ int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask) ...@@ -106,7 +108,7 @@ int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
void greybus_kill_gbuf(struct gbuf *gbuf) void greybus_kill_gbuf(struct gbuf *gbuf)
{ {
struct greybus_host_device *hd = gbuf->connection->hd; struct greybus_host_device *hd = gbuf->operation->connection->hd;
if (gbuf->status != -EINPROGRESS) if (gbuf->status != -EINPROGRESS)
return; return;
......
...@@ -126,7 +126,7 @@ typedef void (*gbuf_complete_t)(struct gbuf *gbuf); ...@@ -126,7 +126,7 @@ typedef void (*gbuf_complete_t)(struct gbuf *gbuf);
struct gbuf { struct gbuf {
struct kref kref; struct kref kref;
struct gb_connection *connection; struct gb_operation *operation;
int status; int status;
void *transfer_buffer; void *transfer_buffer;
u32 transfer_buffer_length; u32 transfer_buffer_length;
...@@ -194,7 +194,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id, ...@@ -194,7 +194,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id,
u8 *data, size_t length); u8 *data, size_t length);
void greybus_gbuf_finished(struct gbuf *gbuf); void greybus_gbuf_finished(struct gbuf *gbuf);
struct gbuf *greybus_alloc_gbuf(struct gb_connection *connection, struct gbuf *greybus_alloc_gbuf(struct gb_operation *operation,
gbuf_complete_t complete, unsigned int size, gbuf_complete_t complete, unsigned int size,
bool outbound, gfp_t gfp_mask, void *context); bool outbound, gfp_t gfp_mask, void *context);
void greybus_free_gbuf(struct gbuf *gbuf); void greybus_free_gbuf(struct gbuf *gbuf);
......
...@@ -295,13 +295,12 @@ static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation, ...@@ -295,13 +295,12 @@ static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation,
u8 type, size_t size, u8 type, size_t size,
bool data_out) bool data_out)
{ {
struct gb_connection *connection = operation->connection;
struct gb_operation_msg_hdr *header; struct gb_operation_msg_hdr *header;
struct gbuf *gbuf; struct gbuf *gbuf;
gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC; gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC;
size += sizeof(*header); size += sizeof(*header);
gbuf = greybus_alloc_gbuf(connection, gb_operation_gbuf_complete, gbuf = greybus_alloc_gbuf(operation, gb_operation_gbuf_complete,
size, data_out, gfp_flags, operation); size, data_out, gfp_flags, operation);
if (!gbuf) if (!gbuf)
return NULL; return NULL;
......
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