NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/60652: pms(4) misdetects Perixx PS/2 wheel mouse as 5-button protocol



The following reply was made to PR kern/60652; it has been noted by GNATS.

From: netbsd.6u9%lmigfernandes.addymail.com@localhost
To: gnats-bugs%netbsd.org@localhost
Cc: kern-bug-people%netbsd.org@localhost, gnats-admin%netbsd.org@localhost,
 netbsd-bugs%netbsd.org@localhost
Subject: Re: kern/60652: pms(4) misdetects Perixx PS/2 wheel mouse as
 5-button protocol
Date: Wed, 02 Sep 2026 02:31:22 +0000

 --3aM0YAsB
 Content-Type: text/plain; charset=utf-8
 Content-Transfer-Encoding: quoted-printable
 
 Quick note on why 200/80/40 why isn't an arbitrary number, plus a
 cleaned=
 -up patch.
 
 The 200/200/80 probe only gets the mouse to report device I=
 D 0x04. It
 doesn't put IntelliMouse 4.0-class devices (like this Perixx m=
 ouse)
 into the mode where they actually emit correct packets. That's a
 =
 second step. 200/80/40 is Linux's own documented trigger for it:
 drivers/=
 input/mouse/psmouse-base.c, im_explorer_detect(), commented as
 "Magic to =
 enable horizontal scrolling on IntelliMouse 4.0." So it's the
 second half=
  of the real init handshake, not a guessed value.
 
 Also confirmed: all =
 three steps matter, not just the final rate. I
 tried collapsing it to a s=
 ingle SET_SAMPLE_RATE(40), and got garbled
 cursor movement on the same ha=
 rdware. Skipping the step-down leaves
 the packet framing desynced. Keep t=
 he three-step sequence intact.
 
 Updated patch replaces the three copy-p=
 asted blocks with a loop over
 the same values. Same behavior, less duplic=
 ation:
 
 --- sys/dev/pckbport/pms.c.orig
 +++ sys/dev/pckbport/pms.c
 =
 @@ -128,6 +128,28 @@
 if (resp[0] =3D=3D p->response) {
 DPRINTF(("pms_pr=
 otocol: found mouse protocol %d\n",
 tries[j]));
 +
 +=09=09=09if (tries=
 [j] =3D=3D PMS_SCROLL5) {
 +=09=09=09=09/*
 +=09=09=09=09 * This controll=
 er garbles/desyncs the byte
 +=09=09=09=09 * stream unless the sample rate=
  is stepped
 +=09=09=09=09 * down through 200 -> 80 -> 40 after the
 +=09=
 =09=09=09 * enable knock; jumping straight to 40
 +=09=09=09=09 * leaves i=
 t misframed.
 +=09=09=09=09 */
 +=09=09=09=09static const u_char rates[] =
 =3D { 200, 80, 40 };
 +=09=09=09=09u_int k;
 +
 +=09=09=09=09cmd[0] =3D =
 PMS_SET_SAMPLE;
 +=09=09=09=09for (k =3D 0; k < __arraycount(rates); k++) =
 {
 +=09=09=09=09=09cmd[1] =3D rates[k];
 +=09=09=09=09=09res =3D pckbport=
 _enqueue_cmd(tag, slot,
 +=09=09=09=09=09=C2=A0=C2=A0=C2=A0 cmd, 2, 0, 1, =
 0);
 +=09=09=09=09=09if (res)
 +=09=09=09=09=09=09return PMS_UNKNOWN;
 +=
 =09=09=09=09}
 +=09=09=09}
 +
 return tries[j];
 }
 }
 
 Rebuilt and=
  rebooted on the same NetBSD 11.0/amd64 machine; movement
 and wheel scrol=
 ling both work, no regression from the original patch.
 
 --3aM0YAsB
 Content-Type: text/html; charset=utf-8
 Content-Transfer-Encoding: quoted-printable
 
 <html>
   <head>
     <meta http-equiv=3D"content-type" content=3D"text/h=
 tml; charset=3DUTF-8">
   </head>
   <body>
 <div dir=3D"auto">Quick not=
 e on why 200/80/40 why isn't an arbitrary number, plus a<br></div><div dir=
 =3D"auto">cleaned-up patch.<br></div><div dir=3D"auto"><br></div><div dir=
 =3D"auto">The 200/200/80 probe only gets the mouse to report device ID 0x04=
 . It<br></div><div dir=3D"auto">doesn't put IntelliMouse 4.0-class devices =
 (like this Perixx mouse)<br></div><div dir=3D"auto">into the mode where the=
 y actually emit correct packets. That's a<br></div><div dir=3D"auto">second=
  step. 200/80/40 is Linux's own documented trigger for it:<br></div><div di=
 r=3D"auto">drivers/input/mouse/psmouse-base.c, im_explorer_detect(), commen=
 ted as<br></div><div dir=3D"auto">"Magic to enable horizontal scrolling on =
 IntelliMouse 4.0." So it's the<br></div><div dir=3D"auto">second half of th=
 e real init handshake, not a guessed value.<br></div><div dir=3D"auto"><br>=
 </div><div dir=3D"auto">Also confirmed: all three steps matter, not just th=
 e final rate. I<br></div><div dir=3D"auto">tried collapsing it to a single =
 SET_SAMPLE_RATE(40), and got garbled<br></div><div dir=3D"auto">cursor move=
 ment on the same hardware. Skipping the step-down leaves<br></div><div dir=
 =3D"auto">the packet framing desynced. Keep the three-step sequence intact.=
 <br></div><div dir=3D"auto"><br></div><div dir=3D"auto">Updated patch repla=
 ces the three copy-pasted blocks with a loop over<br></div><div dir=3D"auto=
 ">the same values. Same behavior, less duplication:<br></div><div dir=3D"au=
 to"><br></div><div dir=3D"auto">--- sys/dev/pckbport/pms.c.orig<br></div><d=
 iv dir=3D"auto">+++ sys/dev/pckbport/pms.c<br></div><div dir=3D"auto">@@ -1=
 28,6 +128,28 @@<br></div><div dir=3D"auto">if (resp[0] =3D=3D p-&gt;respons=
 e) {<br></div><div dir=3D"auto">DPRINTF(("pms_protocol: found mouse protoco=
 l %d\n",<br></div><div dir=3D"auto">tries[j]));<br></div><div dir=3D"auto">=
 +<br></div><div dir=3D"auto">+=09=09=09if (tries[j] =3D=3D PMS_SCROLL5) {<b=
 r></div><div dir=3D"auto">+=09=09=09=09/*<br></div><div dir=3D"auto">+=09=
 =09=09=09 * This controller garbles/desyncs the byte<br></div><div dir=3D"a=
 uto">+=09=09=09=09 * stream unless the sample rate is stepped<br></div><div=
  dir=3D"auto">+=09=09=09=09 * down through 200 -&gt; 80 -&gt; 40 after the<=
 br></div><div dir=3D"auto">+=09=09=09=09 * enable knock; jumping straight t=
 o 40<br></div><div dir=3D"auto">+=09=09=09=09 * leaves it misframed.<br></d=
 iv><div dir=3D"auto">+=09=09=09=09 */<br></div><div dir=3D"auto">+=09=09=09=
 =09static const u_char rates[] =3D { 200, 80, 40 };<br></div><div dir=3D"au=
 to">+=09=09=09=09u_int k;<br></div><div dir=3D"auto">+<br></div><div dir=3D=
 "auto">+=09=09=09=09cmd[0] =3D PMS_SET_SAMPLE;<br></div><div dir=3D"auto">+=
 =09=09=09=09for (k =3D 0; k &lt; __arraycount(rates); k++) {<br></div><div =
 dir=3D"auto">+=09=09=09=09=09cmd[1] =3D rates[k];<br></div><div dir=3D"auto=
 ">+=09=09=09=09=09res =3D pckbport_enqueue_cmd(tag, slot,<br></div><div dir=
 =3D"auto">+=09=09=09=09=09&nbsp;&nbsp;&nbsp; cmd, 2, 0, 1, 0);<br></div><di=
 v dir=3D"auto">+=09=09=09=09=09if (res)<br></div><div dir=3D"auto">+=09=09=
 =09=09=09=09return PMS_UNKNOWN;<br></div><div dir=3D"auto">+=09=09=09=09}<b=
 r></div><div dir=3D"auto">+=09=09=09}<br></div><div dir=3D"auto">+<br></div=
 ><div dir=3D"auto">return tries[j];<br></div><div dir=3D"auto">}<br></div><=
 div dir=3D"auto">}<br></div><div dir=3D"auto"><br></div><div dir=3D"auto">R=
 ebuilt and rebooted on the same NetBSD 11.0/amd64 machine; movement<br></di=
 v><div dir=3D"auto">and wheel scrolling both work, no regression from the o=
 riginal patch.<br></div>  </body>
 </html>
 
 --3aM0YAsB--
 




Home | Main Index | Thread Index | Old Index