OSDN Git Service

greybus: don't let i2c code assume non-null payload pointer
authorAlex Elder <elder@linaro.org>
Wed, 3 Dec 2014 18:27:43 +0000 (12:27 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 3 Dec 2014 23:08:17 +0000 (15:08 -0800)
This is in preparation for an upcoming patch, which makes the
payload pointer be NULL when a message has zero bytes of payload.

It ensures a null payload pointer never gets dereferenced.  To do
this we pass the response structure to gb_i2c_transfer_response()
rather than just its data, and if it's null, returning immediately.

Rearrange the logic in gb_i2c_transfer_operation() a bit.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/i2c-gb.c

index 8936389..f63b60e 100644 (file)
@@ -258,11 +258,15 @@ gb_i2c_transfer_request(struct gb_connection *connection,
 }
 
 static void gb_i2c_transfer_response(struct i2c_msg *msgs, u32 msg_count,
-                                       void *data)
+                               struct gb_i2c_transfer_response *response)
 {
        struct i2c_msg *msg = msgs;
+       u8 *data;
        u32 i;
 
+       if (!response)
+               return;
+       data = response->data;
        for (i = 0; i < msg_count; i++) {
                if (msg->flags & I2C_M_RD) {
                        memcpy(msg->buf, data, msg->len);
@@ -276,7 +280,6 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
                                        struct i2c_msg *msgs, u32 msg_count)
 {
        struct gb_connection *connection = gb_i2c_dev->connection;
-       struct gb_i2c_transfer_response *response;
        struct gb_operation *operation;
        int ret;
 
@@ -284,15 +287,15 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
        if (!operation)
                return -ENOMEM;
 
-       /* Synchronous operation--no callback */
        ret = gb_operation_request_send_sync(operation);
-       if (ret) {
-               if (ret != -EAGAIN)
-                       pr_err("transfer operation failed (%d)\n", ret);
-       } else {
+       if (!ret) {
+               struct gb_i2c_transfer_response *response;
+
                response = operation->response->payload;
-               gb_i2c_transfer_response(msgs, msg_count, response->data);
+               gb_i2c_transfer_response(msgs, msg_count, response);
                ret = msg_count;
+       } else if (ret != -EAGAIN) {
+               pr_err("transfer operation failed (%d)\n", ret);
        }
        gb_operation_destroy(operation);