greybus: define struct gb_message

A Greybus buffer (gbuf) is a generic buffer used for data transfer
over a Greybus interconnect.  We only ever use gbufs in operations,
which always involve exactly two of them.  The lifetime of a gbuf is
therefore directly connected to the lifetime of an operation, so
there no real need to manage gbufs separate from operations.

This patch begins the process of removing the gbuf abstraction, on
favor of a new data type, gb_message.  The purpose of a gb_message
is--like a gbuf--to represent data to be transferred over Greybus.
However a gb_message is oriented toward the more restrictive way
we do Greybus transfers--as operation messages (either a request or
a response).

This patch simply defines the structure in its initial form, and
defines the request and response fields in a Greybus operation
structure as embedded instances of that type.  The gbuf pointer
is defined within the gb_message structure, and as a result lots
of code needs to be tweaked to reference the request and response
gbufs as subfields of the request and response structures.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Alex Elder 2014-11-17 18:08:31 -06:00 коммит произвёл Greg Kroah-Hartman
Родитель 3c3cef400e
Коммит 3690a826fa
6 изменённых файлов: 78 добавлений и 74 удалений

Просмотреть файл

@ -153,7 +153,7 @@ static int gb_gpio_proto_version_operation(struct gb_gpio_controller *gb_gpio_co
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
@ -199,7 +199,7 @@ static int gb_gpio_line_count_operation(struct gb_gpio_controller *gb_gpio_contr
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "line count response %hhu",
response->status);
@ -234,7 +234,7 @@ static int gb_gpio_activate_operation(struct gb_gpio_controller *gb_gpio_control
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -244,7 +244,7 @@ static int gb_gpio_activate_operation(struct gb_gpio_controller *gb_gpio_control
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "activate response %hhu",
response->status);
@ -278,7 +278,7 @@ static int gb_gpio_deactivate_operation(struct gb_gpio_controller *gb_gpio_contr
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -288,7 +288,7 @@ static int gb_gpio_deactivate_operation(struct gb_gpio_controller *gb_gpio_contr
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "deactivate response %hhu",
response->status);
@ -320,7 +320,7 @@ static int gb_gpio_get_direction_operation(struct gb_gpio_controller *gb_gpio_co
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -330,7 +330,7 @@ static int gb_gpio_get_direction_operation(struct gb_gpio_controller *gb_gpio_co
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "get direction response %hhu",
response->status);
@ -369,7 +369,7 @@ static int gb_gpio_direction_in_operation(struct gb_gpio_controller *gb_gpio_con
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -379,7 +379,7 @@ static int gb_gpio_direction_in_operation(struct gb_gpio_controller *gb_gpio_con
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "direction in response %hhu",
response->status);
@ -412,7 +412,7 @@ static int gb_gpio_direction_out_operation(struct gb_gpio_controller *gb_gpio_co
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
request->value = value_high ? 1 : 0;
@ -423,7 +423,7 @@ static int gb_gpio_direction_out_operation(struct gb_gpio_controller *gb_gpio_co
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "direction out response %hhu",
response->status);
@ -456,7 +456,7 @@ static int gb_gpio_get_value_operation(struct gb_gpio_controller *gb_gpio_contro
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -466,7 +466,7 @@ static int gb_gpio_get_value_operation(struct gb_gpio_controller *gb_gpio_contro
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "get value response %hhu",
response->status);
@ -507,7 +507,7 @@ static int gb_gpio_set_value_operation(struct gb_gpio_controller *gb_gpio_contro
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
request->value = value_high ? 1 : 0;
@ -518,7 +518,7 @@ static int gb_gpio_set_value_operation(struct gb_gpio_controller *gb_gpio_contro
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set value response %hhu",
response->status);
@ -554,7 +554,7 @@ static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *gb_gpio_con
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
request->usec = cpu_to_le16(debounce_usec);
@ -565,7 +565,7 @@ static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *gb_gpio_con
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set debounce response %hhu",
response->status);

Просмотреть файл

@ -118,7 +118,7 @@ static int gb_i2c_proto_version_operation(struct gb_i2c_device *gb_i2c_dev)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
@ -170,7 +170,7 @@ static int gb_i2c_functionality_operation(struct gb_i2c_device *gb_i2c_dev)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "functionality response %hhu",
response->status);
@ -198,7 +198,7 @@ static int gb_i2c_timeout_operation(struct gb_i2c_device *gb_i2c_dev, u16 msec)
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->msec = cpu_to_le16(msec);
/* Synchronous operation--no callback */
@ -208,7 +208,7 @@ static int gb_i2c_timeout_operation(struct gb_i2c_device *gb_i2c_dev, u16 msec)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "timeout response %hhu",
response->status);
@ -235,7 +235,7 @@ static int gb_i2c_retries_operation(struct gb_i2c_device *gb_i2c_dev,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->retries = retries;
/* Synchronous operation--no callback */
@ -245,7 +245,7 @@ static int gb_i2c_retries_operation(struct gb_i2c_device *gb_i2c_dev,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "retries response %hhu",
response->status);
@ -321,7 +321,7 @@ gb_i2c_transfer_request(struct gb_connection *connection,
if (!operation)
return NULL;
request = operation->request_payload;
request = operation->request.payload;
request->op_count = cpu_to_le16(op_count);
/* Fill in the ops array */
op = &request->ops[0];
@ -380,7 +380,7 @@ static int gb_i2c_transfer_operation(struct gb_i2c_device *gb_i2c_dev,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
if (response->status == GB_OP_RETRY) {
ret = -EAGAIN;

Просмотреть файл

@ -71,7 +71,7 @@ static void gb_pending_operation_insert(struct gb_operation *operation)
spin_unlock_irq(&gb_operations_lock);
/* Store the operation id in the request header */
header = operation->request->transfer_buffer;
header = operation->request.gbuf->transfer_buffer;
header->id = cpu_to_le16(operation->id);
}
@ -124,7 +124,7 @@ int gb_operation_wait(struct gb_operation *operation)
ret = wait_for_completion_interruptible(&operation->completion);
/* If interrupted, cancel the in-flight buffer */
if (ret < 0)
greybus_kill_gbuf(operation->request);
greybus_kill_gbuf(operation->request.gbuf);
return ret;
}
@ -134,7 +134,7 @@ static void gb_operation_request_handle(struct gb_operation *operation)
struct gb_protocol *protocol = operation->connection->protocol;
struct gb_operation_msg_hdr *header;
header = operation->request->transfer_buffer;
header = operation->request.gbuf->transfer_buffer;
/*
* If the protocol has no incoming request handler, report
@ -164,7 +164,7 @@ static void gb_operation_recv_work(struct work_struct *recv_work)
bool incoming_request;
operation = container_of(recv_work, struct gb_operation, recv_work);
incoming_request = operation->response == NULL;
incoming_request = operation->response.gbuf == NULL;
if (incoming_request)
gb_operation_request_handle(operation);
gb_operation_complete(operation);
@ -257,23 +257,25 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
return NULL;
operation->connection = connection;
operation->request = gb_operation_gbuf_create(operation, type,
operation->request.gbuf = gb_operation_gbuf_create(operation, type,
request_size,
outgoing);
if (!operation->request)
if (!operation->request.gbuf)
goto err_cache;
operation->request_payload = operation->request->transfer_buffer +
operation->request.operation = operation;
operation->request.payload = operation->request.gbuf->transfer_buffer +
sizeof(struct gb_operation_msg_hdr);
if (outgoing) {
type |= GB_OPERATION_TYPE_RESPONSE;
operation->response = gb_operation_gbuf_create(operation,
operation->response.gbuf = gb_operation_gbuf_create(operation,
type, response_size,
false);
if (!operation->response)
if (!operation->response.gbuf)
goto err_request;
operation->response_payload =
operation->response->transfer_buffer +
operation->response.operation = operation;
operation->response.payload =
operation->response.gbuf->transfer_buffer +
sizeof(struct gb_operation_msg_hdr);
}
@ -290,7 +292,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
return operation;
err_request:
greybus_free_gbuf(operation->request);
greybus_free_gbuf(operation->request.gbuf);
err_cache:
kmem_cache_free(gb_operation_cache, operation);
@ -311,8 +313,8 @@ static void _gb_operation_destroy(struct kref *kref)
list_del(&operation->links);
spin_unlock_irq(&gb_operations_lock);
greybus_free_gbuf(operation->response);
greybus_free_gbuf(operation->request);
greybus_free_gbuf(operation->response.gbuf);
greybus_free_gbuf(operation->request.gbuf);
kmem_cache_free(gb_operation_cache, operation);
}
@ -349,7 +351,7 @@ int gb_operation_request_send(struct gb_operation *operation,
*/
operation->callback = callback;
gb_pending_operation_insert(operation);
ret = greybus_submit_gbuf(operation->request, GFP_KERNEL);
ret = greybus_submit_gbuf(operation->request.gbuf, GFP_KERNEL);
if (ret)
return ret;
@ -414,7 +416,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
}
cancel_delayed_work(&operation->timeout_work);
gb_pending_operation_remove(operation);
gbuf = operation->response;
gbuf = operation->response.gbuf;
if (size > gbuf->transfer_buffer_length) {
operation->result = GB_OP_OVERFLOW;
gb_connection_err(connection, "recv buffer too small");
@ -429,7 +431,7 @@ void gb_connection_operation_recv(struct gb_connection *connection,
gb_connection_err(connection, "can't create operation");
return;
}
gbuf = operation->request;
gbuf = operation->request.gbuf;
}
memcpy(gbuf->transfer_buffer, data, msg_size);
@ -444,9 +446,9 @@ void gb_connection_operation_recv(struct gb_connection *connection,
void gb_operation_cancel(struct gb_operation *operation)
{
operation->canceled = true;
greybus_kill_gbuf(operation->request);
if (operation->response)
greybus_kill_gbuf(operation->response);
greybus_kill_gbuf(operation->request.gbuf);
if (operation->response.gbuf)
greybus_kill_gbuf(operation->response.gbuf);
}
int gb_operation_init(void)

Просмотреть файл

@ -35,6 +35,12 @@ struct gbuf {
void *hcd_data; /* for the HCD to track the gbuf */
};
struct gb_message {
void *payload;
struct gb_operation *operation;
struct gbuf *gbuf;
};
/*
* A Greybus operation is a remote procedure call performed over a
* connection between the AP and a function on Greybus module.
@ -66,8 +72,8 @@ struct gbuf {
typedef void (*gb_operation_callback)(struct gb_operation *);
struct gb_operation {
struct gb_connection *connection;
struct gbuf *request;
struct gbuf *response;
struct gb_message request;
struct gb_message response;
u16 id;
bool canceled;
@ -79,10 +85,6 @@ struct gb_operation {
struct kref kref;
struct list_head links; /* connection->{operations,pending} */
/* These are what's used by caller */
void *request_payload;
void *response_payload;
};
void gb_connection_operation_recv(struct gb_connection *connection,

Просмотреть файл

@ -110,7 +110,7 @@ static int gb_pwm_proto_version_operation(struct gb_pwm_chip *pwmc)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
@ -151,7 +151,7 @@ static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "pwm count response %hhu",
response->status);
@ -181,7 +181,7 @@ static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -191,7 +191,7 @@ static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "activate response %hhu",
response->status);
@ -220,7 +220,7 @@ static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -230,7 +230,7 @@ static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "deactivate response %hhu",
response->status);
@ -258,7 +258,7 @@ static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
request->duty = duty;
request->period = period;
@ -270,7 +270,7 @@ static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "config response %hhu",
response->status);
@ -299,7 +299,7 @@ static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
request->polarity = polarity;
@ -310,7 +310,7 @@ static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set polarity response %hhu",
response->status);
@ -339,7 +339,7 @@ static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -349,7 +349,7 @@ static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "enable response %hhu",
response->status);
@ -378,7 +378,7 @@ static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
@ -388,7 +388,7 @@ static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "disable response %hhu",
response->status);

Просмотреть файл

@ -229,7 +229,7 @@ static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->size = cpu_to_le16(size);
memcpy(&request->data[0], data, size);
@ -241,7 +241,7 @@ static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send data response %hhu",
response->status);
@ -267,7 +267,7 @@ static int send_line_coding(struct gb_tty *tty,
sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
memcpy(&request->line_coding, line_coding, sizeof(*line_coding));
/* Synchronous operation--no callback */
@ -278,7 +278,7 @@ static int send_line_coding(struct gb_tty *tty,
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send line coding response %hhu",
response->status);
@ -304,7 +304,7 @@ static int send_control(struct gb_tty *tty, u16 control)
sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->control = cpu_to_le16(control);
/* Synchronous operation--no callback */
@ -315,7 +315,7 @@ static int send_control(struct gb_tty *tty, u16 control)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send control response %hhu",
response->status);
@ -345,7 +345,7 @@ static int send_break(struct gb_tty *tty, u8 state)
sizeof(*response));
if (!operation)
return -ENOMEM;
request = operation->request_payload;
request = operation->request.payload;
request->state = state;
/* Synchronous operation--no callback */
@ -356,7 +356,7 @@ static int send_break(struct gb_tty *tty, u8 state)
goto out;
}
response = operation->response_payload;
response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send break response %hhu",
response->status);