i2c-hid: the touchpad crash was a printf format, not the driver
The PSOGM on the ASUS TUF A15 was a page fault in cprintf, from probe(), in the touchpad driver's own success message. cprintf had no field widths: "%04x" printed literally and consumed no argument, so the "%s" after it was handed the product ID as a string pointer. "%lx" misprinted the same way -- "0x4275838976x" for 0xFEDC2000 -- on the line before. The driver's formats are fixed, and cprintf now steps over flags and widths and takes l/ll/z as 64-bit, so a directive it does not render can no longer shift every argument after it. Until now any %ld or %lu printed the number followed by a stray letter. The touchpad on/off entry in the boot menu has served its purpose and is gone; the verbose step trace stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
b15fb2fdaa
commit
5ea03c4cf5
5 changed files with 43 additions and 45 deletions
|
|
@ -119,20 +119,39 @@ vcprintf(char *fmt, va_list ap)
|
|||
continue;
|
||||
}
|
||||
c = fmt[++i] & 0xff;
|
||||
// Flags and a width are stepped over, and l/ll/z make the conversion
|
||||
// 64-bit. Not because the output honours them -- it does not pad -- but
|
||||
// because a conversion this function did not understand used to consume
|
||||
// no argument, and every one after it then read the wrong one. "%04x"
|
||||
// before a "%s" handed the %s an integer as a string, and the touchpad
|
||||
// driver's first message on real hardware was a page fault in here.
|
||||
while (c == '0' || c == '-' || c == '+' || c == ' ' || c == '#')
|
||||
c = fmt[++i] & 0xff;
|
||||
while (c >= '1' && c <= '9')
|
||||
c = fmt[++i] & 0xff;
|
||||
while (c >= '0' && c <= '9')
|
||||
c = fmt[++i] & 0xff;
|
||||
int wide = 0;
|
||||
while (c == 'l' || c == 'z') {
|
||||
wide = 1;
|
||||
c = fmt[++i] & 0xff;
|
||||
}
|
||||
if (c == 0)
|
||||
break;
|
||||
switch(c) {
|
||||
case 'd':
|
||||
print_int(va_arg(ap, int), 10, 1);
|
||||
case 'i':
|
||||
print_int(wide ? va_arg(ap, int64) : va_arg(ap, int), 10, 1);
|
||||
break;
|
||||
case 'u':
|
||||
print_int(va_arg(ap, uint32), 10, 0);
|
||||
break;
|
||||
case 'l':
|
||||
print_int(va_arg(ap, int64), 10, 1);
|
||||
print_int(wide ? va_arg(ap, uint64) : va_arg(ap, uint32), 10, 0);
|
||||
break;
|
||||
case 'x':
|
||||
print_int(va_arg(ap, uint32), 16, 0);
|
||||
case 'X':
|
||||
print_int(wide ? va_arg(ap, uint64) : va_arg(ap, uint32), 16, 0);
|
||||
break;
|
||||
case 'c':
|
||||
consputc(va_arg(ap, int));
|
||||
break;
|
||||
case 'p':
|
||||
print_int(va_arg(ap, uint64), 16, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue