greybus: define greybus_data_sent()
authorAlex Elder <elder@linaro.org>
Thu, 20 Nov 2014 22:09:17 +0000 (16:09 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 21 Nov 2014 20:24:48 +0000 (12:24 -0800)
Define greybus_data_sent(), which is a callback the host driver
makes when a buffer send request has completed.  The main use for
this is to actively detect errors that can occur while sending.
(Something like this existed at one time and was removed.)

This also defines gb_hd_message_find(), which looks up a message
pointer associated with a buffer sent over a given host device.
This is now a pretty trival mapping.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/es1-ap-usb.c
drivers/staging/greybus/operation.c
drivers/staging/greybus/operation.h

index 88436436fcb21a815fcd8134b5d97f3fb9a978a2..f32c981d184cc75c36b3cc8a58f82d71e1981ae9 100644 (file)
@@ -407,9 +407,18 @@ static void cport_out_callback(struct urb *urb)
        struct greybus_host_device *hd = urb->context;
        struct es1_ap_dev *es1 = hd_to_es1(hd);
        unsigned long flags;
-       /* int status = check_urb_status(urb); */
+       int status = check_urb_status(urb);
+       u8 *data = urb->transfer_buffer + 1;
        int i;
 
+       /*
+        * 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.
+        */
+       data = urb->transfer_buffer + 1;
+       greybus_data_sent(hd, data, status);
+
        /*
         * See if this was an urb in our pool, if so mark it "free", otherwise
         * we need to free it ourselves.
index c9988fd790e36b46222658a12b4ffef0f4eef78b..74dd48a5a489fe50d93a797fe4c96c9e58de2bd2 100644 (file)
@@ -229,6 +229,24 @@ static void operation_timeout(struct work_struct *work)
        gb_operation_complete(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;
+}
+
 /*
  * Allocate a message to be used for an operation request or
  * response.  For outgoing messages, both types of message contain a
@@ -473,6 +491,32 @@ int gb_operation_response_send(struct gb_operation *operation)
        return 0;
 }
 
+/*
+ * 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.
+ *
+ * XXX Mismatch between errno here and operation result code
+ */
+void
+greybus_data_sent(struct greybus_host_device *hd, void *header, int status)
+{
+       struct gb_message *message;
+       struct gb_operation *operation;
+
+       /* If there's no error, there's really nothing to do */
+       if (!status)
+               return; /* Mark it complete? */
+
+       /* XXX Right now we assume we're an outgoing request */
+       message = gb_hd_message_find(hd, header);
+       operation = message->operation;
+       gb_connection_err(operation->connection, "send error %d\n", status);
+       operation->result = status;     /* XXX */
+       gb_operation_complete(operation);
+}
+EXPORT_SYMBOL_GPL(greybus_data_sent);
+
 /*
  * We've received data on a connection, and it doesn't look like a
  * response, so we assume it's a request.
index 2fdb41c154a8d33d833a7452e3da6806851c98ef..3e5e1f570f3e37f5cf4228e1a981169a53422bce 100644 (file)
@@ -103,6 +103,9 @@ int gb_operation_wait(struct gb_operation *operation);
 
 int gb_operation_status_map(u8 status);
 
+void greybus_data_sent(struct greybus_host_device *hd,
+                               void *header, int status);
+
 int gb_operation_init(void);
 void gb_operation_exit(void);