diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 0ac2fb808734..da62c5496e50 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -173,7 +173,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver * Validate that the driver implements all of the callbacks * so that we don't have to every time we make them. */ - if ((!driver->buffer_send) || (!driver->buffer_cancel) || + if ((!driver->message_send) || (!driver->message_cancel) || (!driver->submit_svc)) { pr_err("Must implement all greybus_host_driver callbacks!\n"); return NULL; diff --git a/drivers/staging/greybus/es1.c b/drivers/staging/greybus/es1.c index b9fd5111d3f9..55f8c7558dd4 100644 --- a/drivers/staging/greybus/es1.c +++ b/drivers/staging/greybus/es1.c @@ -214,26 +214,21 @@ static void free_urb(struct es1_ap_dev *es1, struct urb *urb) * error otherwise. If the caller wishes to cancel the in-flight * buffer, it must supply the returned cookie to the cancel routine. */ -static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, - void *buffer, size_t buffer_size, gfp_t gfp_mask) +static void *message_send(struct greybus_host_device *hd, u16 cport_id, + struct gb_message *message, gfp_t gfp_mask) { struct es1_ap_dev *es1 = hd_to_es1(hd); struct usb_device *udev = es1->usb_dev; - u8 *transfer_buffer = buffer; + u8 *transfer_buffer; + size_t buffer_size; int transfer_buffer_size; int retval; struct urb *urb; - if (!buffer) { - pr_err("null buffer supplied to send\n"); - return ERR_PTR(-EINVAL); - } - if (buffer_size > (size_t)INT_MAX) { - pr_err("bad buffer size (%zu) supplied to send\n", buffer_size); - return ERR_PTR(-EINVAL); - } - transfer_buffer--; - transfer_buffer_size = buffer_size + 1; + buffer_size = hd->buffer_headroom + sizeof(*message->header) + + message->payload_size; + transfer_buffer = message->buffer + hd->buffer_headroom - 1; + transfer_buffer_size = buffer_size - (hd->buffer_headroom - 1); /* * The data actually transferred will include an indication @@ -259,7 +254,7 @@ static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, es1->cport_out_endpoint), transfer_buffer, transfer_buffer_size, - cport_out_callback, hd); + cport_out_callback, message); retval = usb_submit_urb(urb, gfp_mask); if (retval) { pr_err("error %d submitting URB\n", retval); @@ -271,17 +266,17 @@ static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, } /* - * The cookie value supplied is the value that buffer_send() - * returned to its caller. It identifies the buffer that should be + * The cookie value supplied is the value that message_send() + * returned to its caller. It identifies the message that should be * canceled. This function must also handle (which is to say, * ignore) a null cookie value. */ -static void buffer_cancel(void *cookie) +static void message_cancel(void *cookie) { /* * We really should be defensive and track all outstanding - * (sent) buffers rather than trusting the cookie provided + * (sent) messages rather than trusting the cookie provided * is valid. For the time being, this will do. */ if (cookie) @@ -290,8 +285,8 @@ static void buffer_cancel(void *cookie) static struct greybus_host_driver es1_driver = { .hd_priv_size = sizeof(struct es1_ap_dev), - .buffer_send = buffer_send, - .buffer_cancel = buffer_cancel, + .message_send = message_send, + .message_cancel = message_cancel, .submit_svc = submit_svc, }; @@ -439,18 +434,17 @@ static void cport_in_callback(struct urb *urb) static void cport_out_callback(struct urb *urb) { - struct greybus_host_device *hd = urb->context; + struct gb_message *message = urb->context; + struct greybus_host_device *hd = message->operation->connection->hd; struct es1_ap_dev *es1 = hd_to_es1(hd); int status = check_urb_status(urb); - u8 *data = urb->transfer_buffer + 1; /* - * Tell the submitter that the buffer send (attempt) is - * complete, and report the status. The submitter's buffer - * starts after the one-byte CPort id we inserted. + * Tell the submitter that the message send (attempt) is + * complete, and report the status. */ - data = urb->transfer_buffer + 1; - greybus_data_sent(hd, data, status); + greybus_message_sent(hd, message, status); + free_urb(es1, urb); } diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c index 526e23c8b416..10b21df253a0 100644 --- a/drivers/staging/greybus/es2.c +++ b/drivers/staging/greybus/es2.c @@ -214,26 +214,21 @@ static void free_urb(struct es1_ap_dev *es1, struct urb *urb) * error otherwise. If the caller wishes to cancel the in-flight * buffer, it must supply the returned cookie to the cancel routine. */ -static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, - void *buffer, size_t buffer_size, gfp_t gfp_mask) +static void *message_send(struct greybus_host_device *hd, u16 cport_id, + struct gb_message *message, gfp_t gfp_mask) { struct es1_ap_dev *es1 = hd_to_es1(hd); struct usb_device *udev = es1->usb_dev; - u8 *transfer_buffer = buffer; + u8 *transfer_buffer; + size_t buffer_size; int transfer_buffer_size; int retval; struct urb *urb; - if (!buffer) { - pr_err("null buffer supplied to send\n"); - return ERR_PTR(-EINVAL); - } - if (buffer_size > (size_t)INT_MAX) { - pr_err("bad buffer size (%zu) supplied to send\n", buffer_size); - return ERR_PTR(-EINVAL); - } - transfer_buffer--; - transfer_buffer_size = buffer_size + 1; + buffer_size = hd->buffer_headroom + sizeof(*message->header) + + message->payload_size; + transfer_buffer = message->buffer + hd->buffer_headroom - 1; + transfer_buffer_size = buffer_size - (hd->buffer_headroom - 1); /* * The data actually transferred will include an indication @@ -259,7 +254,7 @@ static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, es1->cport_out_endpoint), transfer_buffer, transfer_buffer_size, - cport_out_callback, hd); + cport_out_callback, message); retval = usb_submit_urb(urb, gfp_mask); if (retval) { pr_err("error %d submitting URB\n", retval); @@ -271,17 +266,17 @@ static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, } /* - * The cookie value supplied is the value that buffer_send() - * returned to its caller. It identifies the buffer that should be + * The cookie value supplied is the value that message_send() + * returned to its caller. It identifies the message that should be * canceled. This function must also handle (which is to say, * ignore) a null cookie value. */ -static void buffer_cancel(void *cookie) +static void message_cancel(void *cookie) { /* * We really should be defensive and track all outstanding - * (sent) buffers rather than trusting the cookie provided + * (sent) messages rather than trusting the cookie provided * is valid. For the time being, this will do. */ if (cookie) @@ -290,8 +285,8 @@ static void buffer_cancel(void *cookie) static struct greybus_host_driver es1_driver = { .hd_priv_size = sizeof(struct es1_ap_dev), - .buffer_send = buffer_send, - .buffer_cancel = buffer_cancel, + .message_send = message_send, + .message_cancel = message_cancel, .submit_svc = submit_svc, }; @@ -439,18 +434,17 @@ static void cport_in_callback(struct urb *urb) static void cport_out_callback(struct urb *urb) { - struct greybus_host_device *hd = urb->context; + struct gb_message *message = urb->context; + struct greybus_host_device *hd = message->operation->connection->hd; struct es1_ap_dev *es1 = hd_to_es1(hd); int status = check_urb_status(urb); - u8 *data = urb->transfer_buffer + 1; /* - * Tell the submitter that the buffer send (attempt) is - * complete, and report the status. The submitter's buffer - * starts after the one-byte CPort id we inserted. + * Tell the submitter that the message send (attempt) is + * complete, and report the status. */ - data = urb->transfer_buffer + 1; - greybus_data_sent(hd, data, status); + greybus_message_sent(hd, message, status); + free_urb(es1, urb); } diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index fb90f96e0375..6f156e5b08c9 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -85,9 +85,9 @@ struct svc_msg; struct greybus_host_driver { size_t hd_priv_size; - void *(*buffer_send)(struct greybus_host_device *hd, u16 dest_cport_id, - void *buffer, size_t buffer_size, gfp_t gfp_mask); - void (*buffer_cancel)(void *cookie); + void *(*message_send)(struct greybus_host_device *hd, u16 dest_cport_id, + struct gb_message *message, gfp_t gfp_mask); + void (*message_cancel)(void *cookie); int (*submit_svc)(struct svc_msg *svc_msg, struct greybus_host_device *hd); }; diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 2dbb1e98b509..cdfb8938c236 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -140,16 +140,14 @@ gb_operation_find(struct gb_connection *connection, u16 operation_id) static int gb_message_send(struct gb_message *message) { - size_t message_size = sizeof(*message->header) + message->payload_size; struct gb_connection *connection = message->operation->connection; int ret = 0; void *cookie; mutex_lock(&gb_message_mutex); - cookie = connection->hd->driver->buffer_send(connection->hd, + cookie = connection->hd->driver->message_send(connection->hd, connection->hd_cport_id, - message->header, - message_size, + message, GFP_KERNEL); if (IS_ERR(cookie)) ret = PTR_ERR(cookie); @@ -161,8 +159,7 @@ static int gb_message_send(struct gb_message *message) } /* - * Cancel a message whose buffer we have passed to the host device - * layer to be sent. + * Cancel a message we have passed to the host device layer to be sent. */ static void gb_message_cancel(struct gb_message *message) { @@ -171,7 +168,7 @@ static void gb_message_cancel(struct gb_message *message) struct greybus_host_device *hd; hd = message->operation->connection->hd; - hd->driver->buffer_cancel(message->cookie); + hd->driver->message_cancel(message->cookie); } mutex_unlock(&gb_message_mutex); } @@ -225,25 +222,6 @@ static void gb_operation_work(struct work_struct *work) gb_operation_put(operation); } - -/* - * Given a pointer to the header in a message sent on a given host - * device, return the associated message structure. (This "header" - * is just the buffer pointer we supply to the host device for - * sending.) - */ -static struct gb_message * -gb_hd_message_find(struct greybus_host_device *hd, void *header) -{ - struct gb_message *message; - u8 *result; - - result = (u8 *)header - hd->buffer_headroom - sizeof(*message); - message = (struct gb_message *)result; - - return message; -} - static void gb_operation_message_init(struct greybus_host_device *hd, struct gb_message *message, u16 operation_id, size_t payload_size, u8 type) @@ -737,18 +715,14 @@ int gb_operation_response_send(struct gb_operation *operation, int errno) EXPORT_SYMBOL_GPL(gb_operation_response_send); /* - * This function is called when a buffer send request has completed. - * The "header" is the message header--the beginning of what we - * asked to have sent. + * This function is called when a message send request has completed. */ -void -greybus_data_sent(struct greybus_host_device *hd, void *header, int status) +void greybus_message_sent(struct greybus_host_device *hd, + struct gb_message *message, int status) { - struct gb_message *message; struct gb_operation *operation; /* Get the message and record that it is no longer in flight */ - message = gb_hd_message_find(hd, header); message->cookie = NULL; /* @@ -773,7 +747,7 @@ greybus_data_sent(struct greybus_host_device *hd, void *header, int status) queue_work(gb_operation_workqueue, &operation->work); } } -EXPORT_SYMBOL_GPL(greybus_data_sent); +EXPORT_SYMBOL_GPL(greybus_message_sent); /* * We've received data on a connection, and it doesn't look like a diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index 5ed1f6e3e97e..cbd347c6b427 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -147,8 +147,8 @@ int gb_operation_response_send(struct gb_operation *operation, int errno); void gb_operation_cancel(struct gb_operation *operation, int errno); -void greybus_data_sent(struct greybus_host_device *hd, - void *header, int status); +void greybus_message_sent(struct greybus_host_device *hd, + struct gb_message *message, int status); int gb_operation_sync(struct gb_connection *connection, int type, void *request, int request_size,