static void do_battery_test(fwts_framework *fw, const uint32_t index) { char name[PATH_MAX]; char state[1024]; *state = '\0'; fwts_battery_get_name(fw, index, name); fwts_log_info(fw, "Test battery '%s'.", name); fwts_printf(fw, "==== Please PLUG IN the AC power of the machine ====\n"); fwts_press_enter(fw); fwts_printf(fw, "==== Please now UNPLUG the AC power of the machine ====\n"); wait_for_acpi_event(fw, name); check_discharging(fw, index, name); fwts_printf(fw, "==== Please wait 30 seconds while the battery is discharged a little ====\n"); battery_discharge(fw, 30); fwts_printf(fw, "==== Please now PLUG IN the AC power of the machine ====\n"); wait_for_acpi_event(fw, name); check_charging(fw, index, name); check_battery_cycle_count(fw, index, name); check_battery_trip_point(fw, index, name); }
static void check_discharging( fwts_framework *fw, const uint32_t index, const char *name) { uint32_t i; /* when we get here we KNOW the state is "discharging" */ uint32_t initial_value; fwts_printf(fw, "==== Waiting to see if battery '%s' discharges ====\n", name); fwts_cpu_consume_start(); initial_value = get_full(fw, index); for (i = 0; i <= 120; i++) { uint32_t new_value = get_full(fw, index); if (new_value<initial_value) { fwts_passed(fw, "Battery %s charge is decrementing as expected.", name); fwts_cpu_consume_complete(); return; } fwts_printf(fw, "Waiting %3.3d/120\r", 120-i); sleep(1); } fwts_cpu_consume_complete(); fwts_failed(fw, LOG_LEVEL_MEDIUM, "BatteryNotDischarging", "Battery %s claims it is discharging but no charge is used.", name); }
static int hotkey_check_key(fwts_framework *fw, struct input_event *ev, fwts_list *hotkeys) { static int scancode = 0; if ((ev->code == MSC_SCAN) && (ev->type == EV_MSC)) scancode = ev->value; if ((ev->type == EV_KEY) && (ev->value != 0)) { fwts_list_link *item; int found = 0; fwts_list_foreach(item, hotkeys) { fwts_keycode *keycode = fwts_list_data(fwts_keycode*, item); if (keycode->scancode == scancode) { fwts_printf(fw, "Scancode: 0x%2.2x Eventcode 0x%3.3x (%s) '%s'\n", scancode, ev->code, keycode->keyname, keycode->keytext); found = 1; break; } }
static void check_battery_trip_point( fwts_framework *fw, const uint32_t index, const char *name) { uint32_t trip_point; uint32_t trip_point_org; fwts_printf(fw, "==== Checking trip point of battery '%s' ====\n", name); if (!fwts_battery_check_trip_point_support(fw, index)) { fwts_printf(fw, "==== Not supported - skip test ====\n"); return; } if (fwts_battery_get_trip_point(fw, index, &trip_point) == FWTS_OK) trip_point_org = trip_point; else trip_point_org = 0; fwts_log_info(fw, "Test battery '%s' downward trip point.", name); fwts_printf(fw, "==== Please now UNPLUG the AC power of the machine ====\n"); fwts_press_enter(fw); sleep(1); trip_point = get_full(fw, index) - 5; fwts_battery_set_trip_point(fw, index, trip_point); fwts_cpu_consume_start(); wait_for_acpi_event(fw, name); fwts_cpu_consume_complete(); fwts_log_info(fw, "Test battery '%s' upwards trip point.", name); fwts_printf(fw, "==== Please PLUG IN the AC power of the machine ====\n"); fwts_press_enter(fw); sleep(1); trip_point = get_full(fw, index) + 3; fwts_battery_set_trip_point(fw, index, trip_point); wait_for_acpi_event(fw, name); if (trip_point_org != 0) fwts_battery_set_trip_point(fw, index, trip_point_org); }
static void battery_discharge(fwts_framework *fw, const int secs) { int i; fwts_cpu_consume_start(); for (i = 0; i < secs; i++) { fwts_printf(fw, "Waiting %2.2d/%d\r", secs-i, secs); sleep(1); } fwts_cpu_consume_complete(); }
static int lid_test2(fwts_framework *fw) { int ret; fwts_printf(fw, "==== Please close laptop lid for 2 seconds and then re-open. ====\n"); if ((ret = lid_test_state(fw, FWTS_BUTTON_LID_CLOSED)) != FWTS_OK) return ret; if ((ret = lid_test_state(fw, FWTS_BUTTON_LID_OPENED)) != FWTS_OK) return ret; return FWTS_OK; }
static int lid_test1(fwts_framework *fw) { int matching = 0; int not_matching = 0; fwts_printf(fw, "==== Make sure laptop lid is open. ====\n"); fwts_press_enter(fw); lid_check_field_poll(fw, FWTS_BUTTON_LID_OPENED, &matching, ¬_matching); if ((matching == 0) || (not_matching > 0)) fwts_failed(fw, LOG_LEVEL_HIGH, "LidNotOpen", "Detected a closed LID state."); else fwts_passed(fw, "Detected open LID state."); return FWTS_OK; }
static int lid_test3(fwts_framework *fw) { int i; fwts_log_info(fw, "Some machines may have EC or ACPI faults that cause detection of multiple open/close events to fail."); for (i = 1; i < 4; i++) { int ret; fwts_printf(fw, "==== %d of %d: Please close laptop lid for 2 seconds and then re-open. ====\n", i,3); if ((ret = lid_test_state(fw, FWTS_BUTTON_LID_CLOSED)) != FWTS_OK) return ret; if ((ret = lid_test_state(fw, FWTS_BUTTON_LID_OPENED)) != FWTS_OK) return ret; } return FWTS_OK; }
static void check_battery_cycle_count( fwts_framework *fw, const uint32_t index, const char *name) { uint32_t cycle_count; fwts_printf(fw, "==== Checking cycle count of battery '%s' ====\n", name); if (fwts_battery_get_cycle_count(fw, index, &cycle_count) == FWTS_OK) { if (cycle_count == 0) { fwts_log_info(fw, "Please ignore this error with a new battery"); fwts_failed(fw, LOG_LEVEL_LOW, "BatteryZeroCycleCount", "System firmware may not support cycle count interface " "or it reports it incorrectly for battery %s.", name); } } }
static int lid_test_state(fwts_framework *fw, int button) { int gpe_count = 0; int fd; int matching = 0; int not_matching = 0; int events = 0; size_t len; char *state; int i; fwts_gpe *gpes_start; fwts_gpe *gpes_end; switch (button) { case FWTS_BUTTON_LID_OPENED: state = "open"; break; case FWTS_BUTTON_LID_CLOSED: state = "closed"; break; default: state = "unknown"; break; } if ((gpe_count = fwts_gpe_read(&gpes_start)) == FWTS_ERROR) { fwts_log_error(fw, "Cannot read GPEs."); return FWTS_ERROR; } if ((fd = fwts_acpi_event_open()) < 0) { fwts_log_error(fw, "Cannot connect to acpid."); fwts_gpe_free(gpes_start, gpe_count); return FWTS_ERROR; } for (i = 0; i <= 20; i++) { char *buffer; if ((buffer = fwts_acpi_event_read(fd, &len, 1)) != NULL) { if (strstr(buffer, "button/lid")) { events++; lid_check_field_poll(fw, button, &matching, ¬_matching); break; } free(buffer); } fwts_printf(fw, "Waiting %2.2d/20\r", 20-i); } fwts_acpi_event_close(fd); if ((gpe_count = fwts_gpe_read(&gpes_end)) == FWTS_ERROR) { fwts_log_error(fw, "Cannot read GPEs."); fwts_gpe_free(gpes_start, gpe_count); return FWTS_ERROR; } fwts_gpe_test(fw, gpes_start, gpes_end, gpe_count); fwts_gpe_free(gpes_start, gpe_count); fwts_gpe_free(gpes_end, gpe_count); if (events == 0) fwts_failed(fw, LOG_LEVEL_HIGH, "NoLidEvents", "Did not detect any ACPI LID events while waiting for to LID %s.", state); else { fwts_passed(fw, "Detected ACPI LID events while waiting for LID to %s.", state); if ((matching == 0) || (not_matching > 0)) fwts_failed(fw, LOG_LEVEL_HIGH, "NoLidState", "Could not detect lid %s state.", state); else fwts_passed(fw, "Detected lid %s state.", state); } return FWTS_OK; }
static int wait_for_acpi_event(fwts_framework *fw, const char *name) { int gpe_count = 0; int fd; int events = 0; int matching = 0; size_t len; int i; fwts_gpe *gpes_start; fwts_gpe *gpes_end; if ((gpe_count = fwts_gpe_read(&gpes_start)) == FWTS_ERROR) { fwts_log_error(fw, "Cannot read GPEs."); return FWTS_ERROR; } if ((fd = fwts_acpi_event_open()) < 0) { fwts_log_error(fw, "Cannot connect to acpid."); fwts_gpe_free(gpes_start, gpe_count); return FWTS_ERROR; } for (i = 0; i <= 20; i++) { char *buffer; if ((buffer = fwts_acpi_event_read(fd, &len, 1)) != NULL) { char *str; if ((str = strstr(buffer, "battery")) != NULL) { events++; if (strstr(str, name) != NULL) { matching++; free(buffer); break; } } free(buffer); } fwts_printf(fw, "Waiting %2.2d/20\r", 20-i); } fwts_acpi_event_close(fd); if ((gpe_count = fwts_gpe_read(&gpes_end)) == FWTS_ERROR) { fwts_log_error(fw, "Cannot read GPEs."); fwts_gpe_free(gpes_start, gpe_count); return FWTS_ERROR; } fwts_gpe_test(fw, gpes_start, gpes_end, gpe_count); fwts_gpe_free(gpes_start, gpe_count); fwts_gpe_free(gpes_end, gpe_count); if (events == 0) fwts_failed(fw, LOG_LEVEL_HIGH, "BatteryNoEvents", "Did not detect any ACPI battery events."); else { fwts_passed(fw, "Detected ACPI battery events."); if (matching == 0) fwts_failed(fw, LOG_LEVEL_HIGH, "BatteryNoEvents", "Could not detect ACPI events for battery %s.", name); else fwts_passed(fw, "Detected ACPI event for battery %s.", name); } return FWTS_OK; }