in svc.c [1221:1284]
static int gb_svc_request_handler(struct gb_operation *op)
{
struct gb_connection *connection = op->connection;
struct gb_svc *svc = gb_connection_get_data(connection);
u8 type = op->type;
int ret = 0;
/*
* SVC requests need to follow a specific order (at least initially) and
* below code takes care of enforcing that. The expected order is:
* - PROTOCOL_VERSION
* - SVC_HELLO
* - Any other request, but the earlier two.
*
* Incoming requests are guaranteed to be serialized and so we don't
* need to protect 'state' for any races.
*/
switch (type) {
case GB_SVC_TYPE_PROTOCOL_VERSION:
if (svc->state != GB_SVC_STATE_RESET)
ret = -EINVAL;
break;
case GB_SVC_TYPE_SVC_HELLO:
if (svc->state != GB_SVC_STATE_PROTOCOL_VERSION)
ret = -EINVAL;
break;
default:
if (svc->state != GB_SVC_STATE_SVC_HELLO)
ret = -EINVAL;
break;
}
if (ret) {
dev_warn(&svc->dev, "unexpected request 0x%02x received (state %u)\n",
type, svc->state);
return ret;
}
switch (type) {
case GB_SVC_TYPE_PROTOCOL_VERSION:
ret = gb_svc_version_request(op);
if (!ret)
svc->state = GB_SVC_STATE_PROTOCOL_VERSION;
return ret;
case GB_SVC_TYPE_SVC_HELLO:
ret = gb_svc_hello(op);
if (!ret)
svc->state = GB_SVC_STATE_SVC_HELLO;
return ret;
case GB_SVC_TYPE_INTF_RESET:
return gb_svc_intf_reset_recv(op);
case GB_SVC_TYPE_MODULE_INSERTED:
return gb_svc_module_inserted_recv(op);
case GB_SVC_TYPE_MODULE_REMOVED:
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;
}
}