greybus: greybus-driver: Add intf_oops operation
Add intf_oops operation to SVC Protocol. This operation will notify the AP about a fatal error in a module. The request has two arguments: -u8 intf - the interface in question -u8 reason - reason of the error The response has no payload. Upon receiving the Request, the driver disables the Interface. Signed-off-by: Georgi Dobrev <gdobrev@mm-sol.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Ashwin Chaugule <ashwinch@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Родитель
127bada1a1
Коммит
57fa2de1e5
|
@ -1018,6 +1018,7 @@ struct gb_spi_transfer_response {
|
|||
#define GB_SVC_TYPE_INTF_ACTIVATE 0x27
|
||||
#define GB_SVC_TYPE_INTF_RESUME 0x28
|
||||
#define GB_SVC_TYPE_INTF_MAILBOX_EVENT 0x29
|
||||
#define GB_SVC_TYPE_INTF_OOPS 0x2a
|
||||
|
||||
/* Greybus SVC protocol status values */
|
||||
#define GB_SVC_OP_SUCCESS 0x00
|
||||
|
@ -1357,6 +1358,12 @@ struct gb_svc_intf_mailbox_event_request {
|
|||
} __packed;
|
||||
/* intf_mailbox_event response has no payload */
|
||||
|
||||
struct gb_svc_intf_oops_request {
|
||||
__u8 intf_id;
|
||||
__u8 reason;
|
||||
} __packed;
|
||||
/* intf_oops response has no payload */
|
||||
|
||||
|
||||
/* RAW */
|
||||
|
||||
|
|
|
@ -1112,6 +1112,37 @@ static void gb_svc_process_module_removed(struct gb_operation *operation)
|
|||
gb_module_put(module);
|
||||
}
|
||||
|
||||
static void gb_svc_process_intf_oops(struct gb_operation *operation)
|
||||
{
|
||||
struct gb_svc_intf_oops_request *request;
|
||||
struct gb_connection *connection = operation->connection;
|
||||
struct gb_svc *svc = gb_connection_get_data(connection);
|
||||
struct gb_interface *intf;
|
||||
u8 intf_id;
|
||||
u8 reason;
|
||||
|
||||
/* The request message size has already been verified. */
|
||||
request = operation->request->payload;
|
||||
intf_id = request->intf_id;
|
||||
reason = request->reason;
|
||||
|
||||
intf = gb_svc_interface_lookup(svc, intf_id);
|
||||
if (!intf) {
|
||||
dev_warn(&svc->dev, "unexpected interface-oops event %u\n",
|
||||
intf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_info(&svc->dev, "Deactivating interface %u, interface oops reason = %u\n",
|
||||
intf_id, reason);
|
||||
|
||||
mutex_lock(&intf->mutex);
|
||||
intf->disconnected = true;
|
||||
gb_interface_disable(intf);
|
||||
gb_interface_deactivate(intf);
|
||||
mutex_unlock(&intf->mutex);
|
||||
}
|
||||
|
||||
static void gb_svc_process_intf_mailbox_event(struct gb_operation *operation)
|
||||
{
|
||||
struct gb_svc_intf_mailbox_event_request *request;
|
||||
|
@ -1165,6 +1196,9 @@ static void gb_svc_process_deferred_request(struct work_struct *work)
|
|||
case GB_SVC_TYPE_INTF_MAILBOX_EVENT:
|
||||
gb_svc_process_intf_mailbox_event(operation);
|
||||
break;
|
||||
case GB_SVC_TYPE_INTF_OOPS:
|
||||
gb_svc_process_intf_oops(operation);
|
||||
break;
|
||||
default:
|
||||
dev_err(&svc->dev, "bad deferred request type: 0x%02x\n", type);
|
||||
}
|
||||
|
@ -1251,6 +1285,20 @@ static int gb_svc_module_removed_recv(struct gb_operation *op)
|
|||
return gb_svc_queue_deferred_request(op);
|
||||
}
|
||||
|
||||
static int gb_svc_intf_oops_recv(struct gb_operation *op)
|
||||
{
|
||||
struct gb_svc *svc = gb_connection_get_data(op->connection);
|
||||
struct gb_svc_intf_oops_request *request;
|
||||
|
||||
if (op->request->payload_size < sizeof(*request)) {
|
||||
dev_warn(&svc->dev, "short intf-oops request received (%zu < %zu)\n",
|
||||
op->request->payload_size, sizeof(*request));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return gb_svc_queue_deferred_request(op);
|
||||
}
|
||||
|
||||
static int gb_svc_intf_mailbox_event_recv(struct gb_operation *op)
|
||||
{
|
||||
struct gb_svc *svc = gb_connection_get_data(op->connection);
|
||||
|
@ -1326,6 +1374,8 @@ static int gb_svc_request_handler(struct gb_operation *op)
|
|||
return gb_svc_module_removed_recv(op);
|
||||
case GB_SVC_TYPE_INTF_MAILBOX_EVENT:
|
||||
return gb_svc_intf_mailbox_event_recv(op);
|
||||
case GB_SVC_TYPE_INTF_OOPS:
|
||||
return gb_svc_intf_oops_recv(op);
|
||||
default:
|
||||
dev_warn(&svc->dev, "unsupported request 0x%02x\n", type);
|
||||
return -EINVAL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче