goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "line count response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "activate response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "deactivate response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "get direction response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "direction in response %hhu",
response->status);
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;
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "direction out response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "get value response %hhu",
response->status);
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;
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set value response %hhu",
response->status);
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);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set debounce response %hhu",
response->status);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "functionality response %hhu",
response->status);
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 */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "timeout response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->retries = retries;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "retries response %hhu",
response->status);
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];
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
if (response->status == GB_OP_RETRY) {
ret = -EAGAIN;
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);
}
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;
}
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
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);
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);
}
return operation;
err_request:
- greybus_free_gbuf(operation->request);
+ greybus_free_gbuf(operation->request.gbuf);
err_cache:
kmem_cache_free(gb_operation_cache, operation);
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);
}
*/
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;
}
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");
gb_connection_err(connection, "can't create operation");
return;
}
- gbuf = operation->request;
+ gbuf = operation->request.gbuf;
}
memcpy(gbuf->transfer_buffer, data, msg_size);
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)
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.
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;
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,
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "version response %hhu",
response->status);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "pwm count response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "activate response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "deactivate response %hhu",
response->status);
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;
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "config response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
request->polarity = polarity;
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "set polarity response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "enable response %hhu",
response->status);
sizeof(*request), sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->which = which;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "disable response %hhu",
response->status);
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);
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send data response %hhu",
response->status);
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 */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send line coding response %hhu",
response->status);
sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->control = cpu_to_le16(control);
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send control response %hhu",
response->status);
sizeof(*response));
if (!operation)
return -ENOMEM;
- request = operation->request_payload;
+ request = operation->request.payload;
request->state = state;
/* Synchronous operation--no callback */
goto out;
}
- response = operation->response_payload;
+ response = operation->response.payload;
if (response->status) {
gb_connection_err(connection, "send break response %hhu",
response->status);