* 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;
* 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
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);
}
/*
- * 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)
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,
};
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);
}
* 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
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);
}
/*
- * 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)
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,
};
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);
}
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);
};
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);
}
/*
- * 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)
{
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);
}
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)
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;
/*
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
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,