boot menu: turn the touchpad driver off, and trace its steps

The ASUS TUF A15 freezes at the default resolution shortly after the
loader hands over -- screen dark, Caps Lock dead -- and it is the only
machine here with an I2C-HID touchpad, which the driver added in the same
release now probes at boot. "Touchpad driver: on/off" in the F8 menu
answers whether it is the cause on the machine itself, through a new
SCHBOOT_OFF_FLAGS byte the kernel checks before starting the driver.

A verbose boot now prints each step of the probe before taking it, so if it
is the cause, the last line on the screen says which step.

Also: S in the menu wrapped at five entries whatever the count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 23:33:25 +02:00
commit c79b1d6d6d
3 changed files with 49 additions and 16 deletions

View file

@ -43,6 +43,8 @@
#include "core/param.h"
#include "core/spinlock.h"
#include "arch/mmu.h"
#include "arch/memlayout.h"
#include "arch/schboot.h"
#include "dev/hid.h"
#include "dev/acpi.h"
@ -51,6 +53,10 @@
#include <uacpi/namespace.h>
#include <uacpi/resources.h>
// Each step said before it is taken, in a verbose boot: a machine that stops
// here stops with the step it was on as the last line on the screen.
#define STEP(...) do { if(boot_verbose) cprintf(__VA_ARGS__); } while(0)
// ---------------------------------------------------------------------------
// DesignWare I2C
// ---------------------------------------------------------------------------
@ -171,6 +177,7 @@ dw_init(struct dwi2c *c, uacpi_namespace_node *node, uint32 speed)
c->regs = ioremap(c->phys, 0x1000);
if(c->regs == 0)
return -1;
STEP("i2c: controller registers at 0x%lx\n", c->phys);
type = rd(c, IC_COMP_TYPE);
if(type != DW_COMP_TYPE){
cprintf("i2c: controller at 0x%lx is not DesignWare (0x%x)\n",
@ -533,19 +540,24 @@ probe(void *user, uacpi_namespace_node *node, uacpi_u32 depth)
memset(d, 0, sizeof(*d));
memmove(d->name, uacpi_namespace_node_name(node).text, 4);
STEP("i2c-hid: %s: reading its resources\n", d->name);
if(resources(node, &f) < 0 || !f.i2c){
cprintf("i2c-hid: %s has no I2C connection\n", d->name);
return UACPI_ITERATION_DECISION_CONTINUE;
}
STEP("i2c-hid: %s: _DSM\n", d->name);
if(hid_desc_register(node, &descreg) < 0){
cprintf("i2c-hid: %s: _DSM gave no descriptor register\n", d->name);
return UACPI_ITERATION_DECISION_CONTINUE;
}
STEP("i2c-hid: %s: controller %s, address 0x%x\n", d->name, f.bus, f.addr);
if((d->c = controller(f.bus, f.speed)) == 0)
return UACPI_ITERATION_DECISION_CONTINUE;
d->addr = f.addr;
STEP("i2c-hid: %s: _PS0\n", d->name);
uacpi_execute(node, "_PS0", 0);
STEP("i2c-hid: %s: HID descriptor at register 0x%x\n", d->name, descreg);
if(reg_read(d, descreg, desc, sizeof(desc)) < 0 ||
(desc[0] | desc[1] << 8) != 30){
cprintf("i2c-hid: %s at 0x%x does not answer\n", d->name, d->addr);
@ -563,6 +575,8 @@ probe(void *user, uacpi_namespace_node *node, uacpi_u32 depth)
d->pin = interrupt_pin(&f);
d->active_low = f.active_low;
STEP("i2c-hid: %s: power on and reset, pin %s\n", d->name,
d->pin ? "watched" : "none");
command(d, OP_SET_POWER, 0); // 0 = on
wait_ticks(2);
command(d, OP_RESET, 0);
@ -577,6 +591,7 @@ probe(void *user, uacpi_namespace_node *node, uacpi_u32 depth)
if(dw_xfer(d->c, d->addr, 0, 0, d->buf, d->maxin) < 0)
break;
STEP("i2c-hid: %s: report descriptor, %d bytes\n", d->name, rlen);
if(reg_read(d, rreg, rdesc, rlen) < 0){
cprintf("i2c-hid: %s: report descriptor unreadable\n", d->name);
kfree((char *)rdesc);
@ -603,7 +618,9 @@ i2c_hid_thread(void)
static const char *const ids[] = { "PNP0C50", "ACPI0C50", 0 };
int i, n;
STEP("i2c-hid: looking for touchpads\n");
uacpi_find_devices_at(uacpi_namespace_root(), ids, probe, 0);
STEP("i2c-hid: %d found\n", ndev);
if(ndev == 0)
for(;;)
wait_ticks(1000000);
@ -630,6 +647,10 @@ i2c_hid_start(void)
{
if(acpi_rsdp_phys() == 0)
return;
if(*(volatile uchar *)P2V(SCHBOOT_OFF_FLAGS) & SCHBOOT_OFF_I2C_HID){
cprintf("i2c-hid: off, as chosen at the boot menu\n");
return;
}
if(kthread_create(i2c_hid_thread, "i2chid") < 0)
cprintf("i2c-hid: no thread; touchpads will not work\n");
}