From: Alex Elder Date: Wed, 3 Dec 2014 14:35:09 +0000 (-0600) Subject: greybus: introduce gb_operation_request_send_sync() X-Git-Tag: v4.9-rc1~119^2~378^2~21^2~1784 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=c25572ca943a1f8c2db7a8063c166d12480bb69d;p=karo-tx-linux.git greybus: introduce gb_operation_request_send_sync() Define a new function used to initiate a synchronous operation. It sends the operation request message and doesn't return until the response has been received and/or the operation's result has been set. This gets rid of the convention that a null callback pointer signifies a synchronous operation. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/i2c-gb.c b/drivers/staging/greybus/i2c-gb.c index 19a7df91565a..bd1bada3b372 100644 --- a/drivers/staging/greybus/i2c-gb.c +++ b/drivers/staging/greybus/i2c-gb.c @@ -285,7 +285,7 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev, return -ENOMEM; /* Synchronous operation--no callback */ - ret = gb_operation_request_send(operation, NULL); + ret = gb_operation_request_send_sync(operation); if (ret) { if (ret != -EAGAIN) pr_err("transfer operation failed (%d)\n", ret); diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index 15a6e3b24a7c..c62f20072b3e 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -641,7 +641,6 @@ int gb_operation_request_send(struct gb_operation *operation, struct gb_operation_msg_hdr *header; unsigned long timeout; unsigned int cycle; - int ret; if (connection->state != GB_CONNECTION_STATE_ENABLED) return -ENOTCONN; @@ -652,11 +651,12 @@ int gb_operation_request_send(struct gb_operation *operation, */ gb_operation_get(operation); - /* A null callback pointer means synchronous return */ - if (callback) - operation->callback = callback; - else - operation->callback = gb_operation_sync_callback; + /* + * Record the callback function, which is executed in + * non-atomic (workqueue) context when the final result + * of an operation has been set. + */ + operation->callback = callback; /* * Assign the operation's id, and store it in the request header. @@ -677,8 +677,22 @@ int gb_operation_request_send(struct gb_operation *operation, /* All set, send the request */ gb_operation_result_set(operation, -EINPROGRESS); - ret = gb_message_send(operation->request); - if (ret || callback) + + return gb_message_send(operation->request); +} + +/* + * Send a synchronous operation. This function is expected to + * block, returning only when the response has arrived, (or when an + * error is detected. The return value is the result of the + * operation. + */ +int gb_operation_request_send_sync(struct gb_operation *operation) +{ + int ret; + + ret = gb_operation_request_send(operation, gb_operation_sync_callback); + if (ret) return ret; /* Cancel the operation if interrupted */ @@ -923,8 +937,7 @@ int gb_operation_sync(struct gb_connection *connection, int type, if (request_size) memcpy(operation->request->payload, request, request_size); - /* Synchronous operation--no callback */ - ret = gb_operation_request_send(operation, NULL); + ret = gb_operation_request_send_sync(operation); if (ret) pr_err("version operation failed (%d)\n", ret); else diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h index c73d9b92b5c5..3415e8b56eb6 100644 --- a/drivers/staging/greybus/operation.h +++ b/drivers/staging/greybus/operation.h @@ -115,6 +115,7 @@ bool gb_operation_response_alloc(struct gb_operation *operation, int gb_operation_request_send(struct gb_operation *operation, gb_operation_callback callback); +int gb_operation_request_send_sync(struct gb_operation *operation); int gb_operation_response_send(struct gb_operation *operation, int errno); void gb_operation_cancel(struct gb_operation *operation, int errno); diff --git a/drivers/staging/greybus/usb-gb.c b/drivers/staging/greybus/usb-gb.c index ab4e093b62af..e5da72a60b89 100644 --- a/drivers/staging/greybus/usb-gb.c +++ b/drivers/staging/greybus/usb-gb.c @@ -169,7 +169,7 @@ static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) memcpy(&request->payload, urb->transfer_buffer, urb->transfer_buffer_length); - ret = gb_operation_request_send(operation, NULL); + ret = gb_operation_request_send_sync(operation); gb_operation_destroy(operation); return ret;