Re: tap-and-drag on ALPS touchpads

2015-08-22 Thread Ulf Brosziewski

On 08/22/2015 12:35 PM, Martin Pieuchot wrote:

On 15/08/15(Sat) 01:32, Ulf Brosziewski wrote:


The tap-and-drag gesture doesn't work reliably with the ALPS touchpads
supported by pms. To make it work, it is necessary to start dragging
immediately with the second touch, which doesn't always succeed.
Increasing the tap timeout helps, but doesn't change the principle. The
patch below solves that problem. Tests and comments would be welcome.

In case someone is interested in the background: I have observed the
same problem with a Linux installation on a machine with an ALPS
touchpad; however, increasing the tap timeout to a sufficiently high
value (>= 260ms) makes it work normally. The somewhat special behaviour
of those ALPS models is described in this LKML posting:
 https://lkml.org/lkml/2004/7/28/210
The approach put forward there - which is partially reproduced in the
current version of pms - is improved by the patch as follows: When the
hardware signals a tap, the handler does nothing. The missing events
will be emulated when the next packet arrives, which either signals the
end of the gesture, or the start of a drag action. No timeout will occur
even if the hardware introduces a long delay between the first and the
second packet (which just happens when the finger is resting after the
second contact).


This looks good to me.

Did you get reports from other ALPS users?



No, I haven't received any reports.


Index: dev/pckbc/pms.c
===
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.64
diff -u -p -r1.64 pms.c
--- dev/pckbc/pms.c 20 Jul 2015 00:55:06 -  1.64
+++ dev/pckbc/pms.c 14 Aug 2015 18:27:57 -
@@ -120,7 +120,8 @@ struct alps_softc {

int min_x, min_y;
int max_x, max_y;
-   int old_fin;
+
+   u_int gesture;

u_int sec_buttons;  /* trackpoint */

@@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc)
  {
struct alps_softc *alps = sc->alps;
int x, y, z, w, dx, dy;
-   u_int buttons;
-   int fin, ges;
+   u_int buttons, gesture;

if ((alps->model&  ALPS_DUALPOINT)&&  alps_sec_proc(sc))
return;
@@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc)
y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;

if (alps->wsmode == WSMOUSE_NATIVE) {
-   ges = sc->packet[2]&  0x01;
-   fin = sc->packet[2]&  0x02;
+   if (alps->gesture == ALPS_TAP) {
+   /* Report a touch with the tap coordinates. */
+   wsmouse_input(sc->sc_wsmousedev, buttons,
+   alps->old_x, alps->old_y, ALPS_PRESSURE, 4,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   if (z>  0) {
+   /*
+* The hardware doesn't send a null pressure
+* event when dragging starts.
+*/
+   wsmouse_input(sc->sc_wsmousedev, buttons,
+   alps->old_x, alps->old_y, 0, 0,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   }
+   }

-   /* Simulate click (tap) */
-   if (ges&&  !fin)
-   z = 35;
-
-   /* Generate a null pressure event (needed for tap&  drag) */
-   if (ges&&  fin&&  !alps->old_fin)
-   z = 0;
-
-   /* Generate a width value corresponding to one finger */
-   if (z>  0)
-   w = 4;
-   else
-   w = 0;
+   gesture = sc->packet[2]&  0x03;
+   if (gesture != ALPS_TAP) {
+   w = z ? 4 : 0;
+   wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
+   WSMOUSE_INPUT_ABSOLUTE_X
+   | WSMOUSE_INPUT_ABSOLUTE_Y
+   | WSMOUSE_INPUT_ABSOLUTE_Z
+   | WSMOUSE_INPUT_ABSOLUTE_W);
+   }

-   wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
-   WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
-   WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
+   if (alps->gesture != ALPS_DRAG || gesture != ALPS_TAP)
+   alps->gesture = gesture;
+
+   alps->old_x = x;
+   alps->old_y = y;

-   alps->old_fin = fin;
} else

Re: tap-and-drag on ALPS touchpads

2015-08-22 Thread Martin Pieuchot
On 15/08/15(Sat) 01:32, Ulf Brosziewski wrote:
> 
> The tap-and-drag gesture doesn't work reliably with the ALPS touchpads
> supported by pms. To make it work, it is necessary to start dragging
> immediately with the second touch, which doesn't always succeed.
> Increasing the tap timeout helps, but doesn't change the principle. The
> patch below solves that problem. Tests and comments would be welcome.
> 
> In case someone is interested in the background: I have observed the
> same problem with a Linux installation on a machine with an ALPS
> touchpad; however, increasing the tap timeout to a sufficiently high
> value (>= 260ms) makes it work normally. The somewhat special behaviour
> of those ALPS models is described in this LKML posting:
> https://lkml.org/lkml/2004/7/28/210
> The approach put forward there - which is partially reproduced in the
> current version of pms - is improved by the patch as follows: When the
> hardware signals a tap, the handler does nothing. The missing events
> will be emulated when the next packet arrives, which either signals the
> end of the gesture, or the start of a drag action. No timeout will occur
> even if the hardware introduces a long delay between the first and the
> second packet (which just happens when the finger is resting after the
> second contact).

This looks good to me.

Did you get reports from other ALPS users?

> Index: dev/pckbc/pms.c
> ===
> RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
> retrieving revision 1.64
> diff -u -p -r1.64 pms.c
> --- dev/pckbc/pms.c   20 Jul 2015 00:55:06 -  1.64
> +++ dev/pckbc/pms.c   14 Aug 2015 18:27:57 -
> @@ -120,7 +120,8 @@ struct alps_softc {
> 
>   int min_x, min_y;
>   int max_x, max_y;
> - int old_fin;
> +
> + u_int gesture;
> 
>   u_int sec_buttons;  /* trackpoint */
> 
> @@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc)
>  {
>   struct alps_softc *alps = sc->alps;
>   int x, y, z, w, dx, dy;
> - u_int buttons;
> - int fin, ges;
> + u_int buttons, gesture;
> 
>   if ((alps->model & ALPS_DUALPOINT) && alps_sec_proc(sc))
>   return;
> @@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc)
>   y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;
> 
>   if (alps->wsmode == WSMOUSE_NATIVE) {
> - ges = sc->packet[2] & 0x01;
> - fin = sc->packet[2] & 0x02;
> + if (alps->gesture == ALPS_TAP) {
> + /* Report a touch with the tap coordinates. */
> + wsmouse_input(sc->sc_wsmousedev, buttons,
> + alps->old_x, alps->old_y, ALPS_PRESSURE, 4,
> + WSMOUSE_INPUT_ABSOLUTE_X
> + | WSMOUSE_INPUT_ABSOLUTE_Y
> + | WSMOUSE_INPUT_ABSOLUTE_Z
> + | WSMOUSE_INPUT_ABSOLUTE_W);
> + if (z > 0) {
> + /*
> +  * The hardware doesn't send a null pressure
> +  * event when dragging starts.
> +  */
> + wsmouse_input(sc->sc_wsmousedev, buttons,
> + alps->old_x, alps->old_y, 0, 0,
> + WSMOUSE_INPUT_ABSOLUTE_X
> + | WSMOUSE_INPUT_ABSOLUTE_Y
> + | WSMOUSE_INPUT_ABSOLUTE_Z
> + | WSMOUSE_INPUT_ABSOLUTE_W);
> + }
> + }
> 
> - /* Simulate click (tap) */
> - if (ges && !fin)
> - z = 35;
> -
> - /* Generate a null pressure event (needed for tap & drag) */
> - if (ges && fin && !alps->old_fin)
> - z = 0;
> -
> - /* Generate a width value corresponding to one finger */
> - if (z > 0)
> - w = 4;
> - else
> - w = 0;
> + gesture = sc->packet[2] & 0x03;
> + if (gesture != ALPS_TAP) {
> + w = z ? 4 : 0;
> + wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
> + WSMOUSE_INPUT_ABSOLUTE_X
> + | WSMOUSE_INPUT_ABSOLUTE_Y
> + | WSMOUSE_INPUT_ABSOLUTE_Z
> + | WSMOUSE_INPUT_ABSOLUTE_W);
> + }
> 
> - wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
> - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
> - WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
> + if (alps->gesture != ALPS_DRAG || gesture != ALPS_TAP)
> + alps->gesture = gesture;
> +
> + alps->old_x = x;
> + alps->old_y = y;
> 
> - alps->old_fin = fin;
>   } else {
> 

Re: v6 autoconf, where have my connected routes gone?

2015-08-22 Thread Martin Pieuchot
On 20/08/15(Thu) 19:32, Sebastian Reitenbach wrote:
> On 08/19/15 17:51, Martin Pieuchot wrote:
> [...]
> With the patch below, together with the other patch you mention above,
> my problem is gone, network works as I expect it.

Thanks for testing, I'd appreciate reviews and oks for the first diff I
sent then.

M.



Re: Fix ndp -p unaligned access (kernel and userland)

2015-08-22 Thread Martin Pieuchot
On 20/08/15(Thu) 17:48, Christian Weisgerber wrote:
> Currently, ndp -p will trigger unaligned accesses in the kernel and
> userland on architectures that require strict alignment for 64-bit
> types (e.g. sparc64).
> 
> This is actually fallout from the time_t change.
> 
> The sysctl used to pass the prefix list uses a packed format:
>   one struct in6_prefix, several struct sockaddr_in6,
>   one struct in6_prefix, several struct sockaddr_in6,
>   ...
> This worked dandily when both structs had the same alignment
> requirement (int32_t).  However, there's a time_t in in6_prefix
> which pushed that struct's alignment to int64_t... boom!
> 
> The patches below are taken from NetBSD (Martin Husemann):
> http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet6/nd6.c.diff?r1=1.145&r2=1.146
> http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.sbin/ndp/ndp.c.diff?r1=1.41&r2=1.42
> 
> Use simple byte pointer arithmetic and memcpy from/to aligned stack
> variables to handle the "packed" binary format passed out to userland
> when querying the prefix/router list.
> 
> OK?

ok mpi@

> 
> Index: sys/netinet6/nd6.c
> ===
> RCS file: /cvs/src/sys/netinet6/nd6.c,v
> retrieving revision 1.143
> diff -u -p -r1.143 nd6.c
> --- sys/netinet6/nd6.c16 Jul 2015 15:31:35 -  1.143
> +++ sys/netinet6/nd6.c20 Aug 2015 14:36:19 -
> @@ -1877,45 +1877,43 @@ fill_prlist(void *oldp, size_t *oldlenp,
>  {
>   int error = 0, s;
>   struct nd_prefix *pr;
> - struct in6_prefix *p = NULL;
> - struct in6_prefix *pe = NULL;
> + char *p = NULL, *ps = NULL;
> + char *pe = NULL;
>   size_t l;
>  
>   s = splsoftnet();
>  
>   if (oldp) {
> - p = (struct in6_prefix *)oldp;
> - pe = (struct in6_prefix *)((caddr_t)oldp + *oldlenp);
> + ps = p = (char *)oldp;
> + pe = (char *)oldp + *oldlenp;
>   }
>   l = 0;
>  
>   LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
>   u_short advrtrs;
> - size_t advance;
> - struct sockaddr_in6 *sin6;
> - struct sockaddr_in6 *s6;
> + struct sockaddr_in6 sin6;
>   struct nd_pfxrouter *pfr;
> + struct in6_prefix pfx;
>   char addr[INET6_ADDRSTRLEN];
>  
> - if (oldp && p + 1 <= pe)
> - {
> - bzero(p, sizeof(*p));
> - sin6 = (struct sockaddr_in6 *)(p + 1);
> -
> - p->prefix = pr->ndpr_prefix;
> - if (in6_recoverscope(&p->prefix,
> - &p->prefix.sin6_addr, pr->ndpr_ifp) != 0)
> + if (oldp && p + sizeof(struct in6_prefix) <= pe) {
> + memset(&pfx, 0, sizeof(pfx));
> + ps = p;
> +
> + pfx.prefix = pr->ndpr_prefix;
> + if (in6_recoverscope(&pfx.prefix,
> + &pfx.prefix.sin6_addr, pr->ndpr_ifp) != 0)
>   log(LOG_ERR,
>   "scope error in prefix list (%s)\n",
> - inet_ntop(AF_INET6, &p->prefix.sin6_addr,
> + inet_ntop(AF_INET6, &pfx.prefix.sin6_addr,
>   addr, sizeof(addr)));
> - p->raflags = pr->ndpr_raf;
> - p->prefixlen = pr->ndpr_plen;
> - p->vltime = pr->ndpr_vltime;
> - p->pltime = pr->ndpr_pltime;
> - p->if_index = pr->ndpr_ifp->if_index;
> + pfx.raflags = pr->ndpr_raf;
> + pfx.prefixlen = pr->ndpr_plen;
> + pfx.vltime = pr->ndpr_vltime;
> + pfx.pltime = pr->ndpr_pltime;
> + pfx.if_index = pr->ndpr_ifp->if_index;
>   if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
> - p->expire = 0;
> + pfx.expire = 0;
>   else {
>   time_t maxexpire;
>  
> @@ -1924,40 +1922,44 @@ fill_prlist(void *oldp, size_t *oldlenp,
>   ((sizeof(maxexpire) * 8) - 1));
>   if (pr->ndpr_vltime <
>   maxexpire - pr->ndpr_lastupdate) {
> - p->expire = pr->ndpr_lastupdate +
> + pfx.expire = pr->ndpr_lastupdate +
>   pr->ndpr_vltime;
>   } else
> - p->expire = maxexpire;
> + pfx.expire = maxexpire;
>   }
> - p->refcnt = pr->ndpr_refcnt;
> - p->flags = pr->ndpr_stateflags;
> - p->origin = PR_ORIG_RA;
> 

Re: Kill IN6_IFF_NODAD

2015-08-22 Thread Martin Pieuchot
On 19/08/15(Wed) 13:31, Martin Pieuchot wrote:
> KAME people chose to add states to the address descriptors in order
> to implement various IPv6 automagic features.  But IN6_IFF_NODAD is
> not a real state, it's just a hack for some spaghetti code.
> 
> Diff belows get rids of this flag by shuffling some code around and
> only using the IN6_IFF_TENTATIVE flag.

Updated diff, this one contains a splsoftnet() missed in previous and
kindly reported by sthen@.


Index: net/if_spppsubr.c
===
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.136
diff -u -p -r1.136 if_spppsubr.c
--- net/if_spppsubr.c   18 Jul 2015 15:51:16 -  1.136
+++ net/if_spppsubr.c   22 Aug 2015 10:19:41 -
@@ -4790,9 +4790,6 @@ sppp_set_ip6_addr(struct sppp *sp, const
 */
ifra->ifra_prefixmask.sin6_family = AF_UNSPEC;
 
-   /* DAD is redundant after an IPv6CP exchange. */
-   ifra->ifra_flags |= IN6_IFF_NODAD;
-
task_add(systq, &sp->ipv6cp.set_addr_task);
 }
 
Index: netinet6/in6.c
===
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.165
diff -u -p -r1.165 in6.c
--- netinet6/in6.c  19 Aug 2015 13:27:38 -  1.165
+++ netinet6/in6.c  22 Aug 2015 10:25:19 -
@@ -468,11 +468,19 @@ in6_control(struct socket *so, u_long cm
/* reject read-only flags */
if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
(ifra->ifra_flags & IN6_IFF_DETACHED) != 0 ||
-   (ifra->ifra_flags & IN6_IFF_NODAD) != 0 ||
(ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0 ||
(ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0) {
return (EINVAL);
}
+
+   /*
+* Make the address tentative before joining multicast
+* addresses, so that corresponding MLD responses would
+* not have a tentative source address.
+*/
+   if ((ia6 == NULL) && in6if_do_dad(ifp))
+   ifra->ifra_flags |= IN6_IFF_TENTATIVE;
+
/*
 * first, make or update the interface address structure,
 * and link it to the list. try to enable inet6 if there
@@ -497,6 +505,11 @@ in6_control(struct socket *so, u_long cm
break;
}
 
+   /* Perform DAD, if needed. */
+   if (ia6->ia6_flags & IN6_IFF_TENTATIVE)
+   nd6_dad_start(&ia6->ia_ifa);
+
+
plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL);
if (plen == 128) {
dohooks(ifp->if_addrhooks, 0);
@@ -753,15 +766,6 @@ in6_update_ifa(struct ifnet *ifp, struct
 * configure address flags.
 */
ia6->ia6_flags = ifra->ifra_flags;
-   /*
-* Make the address tentative before joining multicast addresses,
-* so that corresponding MLD responses would not have a tentative
-* source address.
-*/
-   ia6->ia6_flags &= ~IN6_IFF_DUPLICATED;  /* safety */
-   if (hostIsNew && in6if_do_dad(ifp) &&
-   (ifra->ifra_flags & IN6_IFF_NODAD) == 0)
-   ia6->ia6_flags |= IN6_IFF_TENTATIVE;
 
/*
 * We are done if we have simply modified an existing address.
@@ -906,17 +910,6 @@ in6_update_ifa(struct ifnet *ifp, struct
if (!imm)
goto cleanup;
LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain);
-   }
-
-   /*
-* Perform DAD, if needed.
-* XXX It may be of use, if we can administratively
-* disable DAD.
-*/
-   if (hostIsNew && in6if_do_dad(ifp) &&
-   (ifra->ifra_flags & IN6_IFF_NODAD) == 0)
-   {
-   nd6_dad_start(&ia6->ia_ifa, NULL);
}
 
return (error);
Index: netinet6/in6_ifattach.c
===
RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v
retrieving revision 1.91
diff -u -p -r1.91 in6_ifattach.c
--- netinet6/in6_ifattach.c 17 Aug 2015 10:57:24 -  1.91
+++ netinet6/in6_ifattach.c 22 Aug 2015 10:19:41 -
@@ -292,7 +292,6 @@ success:
 int
 in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid)
 {
-   struct in6_ifaddr *ia6;
struct in6_aliasreq ifra;
int  s, error;
 
@@ -332,12 +331,6 @@ in6_ifattach_linklocal(struct ifnet *ifp
ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
 
/*
-* Do not let in6_update_ifa() do DAD, since we need a random delay
-* before sending an NS at the first time the interface becomes up.
-*/
-   ifra.ifra_flags |= IN6_IFF_NODAD;
-
-   /*
 * Now call in6_update_ifa() to do a bunch of procedures to configure
 * a link