int verify_key(int c, int r, int pressed) { struct host_cmd_handler_args args; uint8_t mkbp_out[KEYBOARD_COLS]; int i; if (c >= 0 && r >= 0) { ccprintf("Verify %s (%d, %d)\n", action[pressed], c, r); set_state(c, r, pressed); } else { ccprintf("Verify last state\n"); } args.version = 0; args.command = EC_CMD_MKBP_STATE; args.params = NULL; args.params_size = 0; args.response = mkbp_out; args.response_max = sizeof(mkbp_out); args.response_size = 0; if (host_command_process(&args) != EC_RES_SUCCESS) return 0; for (i = 0; i < KEYBOARD_COLS; ++i) if (mkbp_out[i] != state[i]) return 0; return 1; }
int mkbp_config(struct ec_params_mkbp_set_config params) { struct host_cmd_handler_args args; args.version = 0; args.command = EC_CMD_MKBP_SET_CONFIG; args.params = ¶ms; args.params_size = sizeof(params); args.response = NULL; args.response_max = 0; args.response_size = 0; return host_command_process(&args) == EC_RES_SUCCESS; }
void host_command_task(void) { host_command_init(); while (1) { /* Wait for the next command event */ int evt = task_wait_event(-1); /* Process it */ if ((evt & TASK_EVENT_CMD_PENDING) && pending_args) { pending_args->result = host_command_process(pending_args); host_send_response(pending_args); } } }
void host_command_received(struct host_cmd_handler_args *args) { /* * TODO(crosbug.com/p/23806): should warn if we already think we're in * a command. */ /* * If this is the reboot command, reboot immediately. This gives the * host processor a way to unwedge the EC even if it's busy with some * other command. */ if (args->command == EC_CMD_REBOOT) { system_reset(SYSTEM_RESET_HARD); /* Reset should never return; if it does, post an error */ args->result = EC_RES_ERROR; } #ifdef CONFIG_AP_HANG_DETECT /* If hang detection is enabled, check stop on host command */ hang_detect_stop_on_host_command(); #endif if (args->result) { ; /* driver has signalled an error, respond now */ #ifdef CONFIG_HOST_COMMAND_STATUS } else if (args->command == EC_CMD_GET_COMMS_STATUS) { args->result = host_command_process(args); #endif } else { /* Save the command */ pending_args = args; /* Wake up the task to handle the command */ task_set_event(TASK_ID_HOSTCMD, TASK_EVENT_CMD_PENDING, 0); return; } /* * TODO (crosbug.com/p/29315): This is typically running in interrupt * context, so it woud be better not to send the response here, and to * let the host command task send the response. */ /* Send the response now */ host_send_response(args); }
static int command_host_command(int argc, char **argv) { struct host_cmd_handler_args args; char *cmd_params; enum ec_status res; char *e; int rv; /* Use shared memory for command params space */ if (shared_mem_acquire(EC_PROTO2_MAX_PARAM_SIZE, &cmd_params)) { ccputs("Can't acquire shared memory buffer.\n"); return EC_ERROR_UNKNOWN; } /* Assume no version or params unless proven otherwise */ args.version = 0; args.params_size = 0; args.params = cmd_params; if (argc < 2) { shared_mem_release(cmd_params); return EC_ERROR_PARAM_COUNT; } args.command = strtoi(argv[1], &e, 0); if (*e) { shared_mem_release(cmd_params); return EC_ERROR_PARAM1; } if (argc > 2) { args.version = strtoi(argv[2], &e, 0); if (*e) { shared_mem_release(cmd_params); return EC_ERROR_PARAM2; } } if (argc > 3) { rv = parse_params(argv[3], cmd_params); if (rv < 0) { shared_mem_release(cmd_params); return EC_ERROR_PARAM3; } args.params_size = rv; } args.response = cmd_params; args.response_max = EC_PROTO2_MAX_PARAM_SIZE; args.response_size = 0; res = host_command_process(&args); if (res != EC_RES_SUCCESS) ccprintf("Command returned %d\n", res); else if (args.response_size) ccprintf("Response: %.*h\n", args.response_size, cmd_params); else ccprintf("Command succeeded; no response.\n"); shared_mem_release(cmd_params); return EC_SUCCESS; }