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: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
parent
c69a50f2ce
commit
ef45fa33a4
@ -96,6 +96,7 @@ static void cport_out_callback(struct urb *urb);
|
||||
static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
struct gb_connection *connection = gbuf->operation->connection;
|
||||
u32 cport_reserve = gbuf->outbound ? 1 : 0;
|
||||
u8 *buffer;
|
||||
|
||||
@ -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
|
||||
* 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",
|
||||
gbuf->connection->interface_cport_id);
|
||||
connection->interface_cport_id);
|
||||
kfree(buffer);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Insert the cport id for outbound buffers */
|
||||
if (gbuf->outbound)
|
||||
*buffer++ = gbuf->connection->interface_cport_id;
|
||||
*buffer++ = connection->interface_cport_id;
|
||||
gbuf->transfer_buffer = buffer;
|
||||
gbuf->transfer_buffer_length = size;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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 usb_device *udev = es1->usb_dev;
|
||||
int retval;
|
||||
@ -394,7 +395,7 @@ exit:
|
||||
static void cport_out_callback(struct urb *urb)
|
||||
{
|
||||
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;
|
||||
int i;
|
||||
|
||||
|
@ -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
|
||||
* 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,
|
||||
unsigned int size,
|
||||
bool outbound,
|
||||
gfp_t gfp_mask,
|
||||
void *context)
|
||||
{
|
||||
struct greybus_host_device *hd = operation->connection->hd;
|
||||
struct gbuf *gbuf;
|
||||
int retval;
|
||||
|
||||
@ -50,14 +51,14 @@ struct gbuf *greybus_alloc_gbuf(struct gb_connection *connection,
|
||||
return NULL;
|
||||
|
||||
kref_init(&gbuf->kref);
|
||||
gbuf->connection = connection;
|
||||
gbuf->operation = operation;
|
||||
gbuf->outbound = outbound;
|
||||
gbuf->complete = complete;
|
||||
gbuf->context = context;
|
||||
gbuf->status = -EBADR; /* Initial value--means "never set" */
|
||||
|
||||
/* 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) {
|
||||
kmem_cache_free(gbuf_head_cache, gbuf);
|
||||
return NULL;
|
||||
@ -72,8 +73,9 @@ static DEFINE_MUTEX(gbuf_mutex);
|
||||
static void free_gbuf(struct kref *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);
|
||||
mutex_unlock(&gbuf_mutex);
|
||||
@ -97,7 +99,7 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf);
|
||||
|
||||
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;
|
||||
|
||||
@ -106,7 +108,7 @@ int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
|
||||
|
||||
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)
|
||||
return;
|
||||
|
@ -126,7 +126,7 @@ typedef void (*gbuf_complete_t)(struct gbuf *gbuf);
|
||||
struct gbuf {
|
||||
struct kref kref;
|
||||
|
||||
struct gb_connection *connection;
|
||||
struct gb_operation *operation;
|
||||
int status;
|
||||
void *transfer_buffer;
|
||||
u32 transfer_buffer_length;
|
||||
@ -194,7 +194,7 @@ void greybus_cport_in(struct greybus_host_device *hd, u16 cport_id,
|
||||
u8 *data, size_t length);
|
||||
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,
|
||||
bool outbound, gfp_t gfp_mask, void *context);
|
||||
void greybus_free_gbuf(struct gbuf *gbuf);
|
||||
|
@ -295,13 +295,12 @@ static struct gbuf *gb_operation_gbuf_create(struct gb_operation *operation,
|
||||
u8 type, size_t size,
|
||||
bool data_out)
|
||||
{
|
||||
struct gb_connection *connection = operation->connection;
|
||||
struct gb_operation_msg_hdr *header;
|
||||
struct gbuf *gbuf;
|
||||
gfp_t gfp_flags = data_out ? GFP_KERNEL : GFP_ATOMIC;
|
||||
|
||||
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);
|
||||
if (!gbuf)
|
||||
return NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user