Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/dev/usb Pull up following revision(s) (requested by m...



details:   https://anonhg.NetBSD.org/src/rev/2168ff51b571
branches:  netbsd-8
changeset: 446018:2168ff51b571
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Nov 20 16:05:38 2018 +0000

description:
Pull up following revision(s) (requested by manu in ticket #1099):

        sys/dev/usb/usb_quirks.c: revision 1.90
        sys/dev/usb/usbdi.c: revision 1.179
        sys/dev/usb/usb_quirks.h: revision 1.29
        sys/dev/usb/usbdi.c: revision 1.180

Workaround NBP PN533 USB toggle bit bugs

The PN533 is known to mishandle the USB toggle bit, causing replies to
be filtered out by the host controller. As a result, the kernel sees
a timed out operation.

Vendor errata suggests that userland applications should detect the
situation on read timeout, and write a dumy frame to resync the toggle bit.
NFC Tools's libnfc does just that, but in order to succeed, the dummy
frame write must not be reported as timed out.

We therefore introduce a new USB quirk for devices known to miss output
acks. When that occur, we pretend that the operation succeeded, leaving
userland the duty to check that everything went okay.

This workaround lets libnfc recover from interrupted communications
without the need te reboot the system.

 -

Build fix
>From David H. Gutteridge

diffstat:

 sys/dev/usb/usb_quirks.c |  23 +++++++++++++++++------
 sys/dev/usb/usb_quirks.h |   3 ++-
 sys/dev/usb/usbdi.c      |  29 ++++++++++++++++++++++++-----
 3 files changed, 43 insertions(+), 12 deletions(-)

diffs (121 lines):

diff -r b35bfe3b7318 -r 2168ff51b571 sys/dev/usb/usb_quirks.c
--- a/sys/dev/usb/usb_quirks.c  Tue Nov 20 16:02:50 2018 +0000
+++ b/sys/dev/usb/usb_quirks.c  Tue Nov 20 16:05:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_quirks.c,v 1.86.8.1 2018/11/12 16:01:35 martin Exp $       */
+/*     $NetBSD: usb_quirks.c,v 1.86.8.2 2018/11/20 16:05:38 martin Exp $       */
 /*     $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $     */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.86.8.1 2018/11/12 16:01:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.86.8.2 2018/11/20 16:05:38 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -310,13 +310,24 @@
  { USB_VENDOR_ZOOM,            USB_PRODUCT_ZOOM_3095,                  ANY,
        { UQ_LOST_CS_DESC, NULL }},
 
- /* NXP PN533 corrupts its USB configuration descriptors */
+ /*
+  * NXP PN533 bugs
+  * 
+  * 1. It corrupts its USB descriptors. The quirk is to provide hardcoded
+  *    descriptors instead of getting them from the device.
+  * 2. It mishandles the USB toggle bit. This causes some replies to be
+  *    filered out by the USB host controller and be reported as timed out.
+  *    NFC tool's libnfc workaround this bug by sending a dummy frame to
+  *    resync the toggle bit, but in order to succeed, that operation must
+  *    not be reported as failed. The quirk is therefore to pretend to 
+  *    userland that output timeouts are successes.
+  */
  { USB_VENDOR_PHILIPSSEMI,     USB_PRODUCT_PHILIPSSEMI_PN533,          ANY,
-       { UQ_DESC_CORRUPT, desc_pn533 }},
+       { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
  { USB_VENDOR_SHUTTLE,         USB_PRODUCT_SHUTTLE_SCL3711,            ANY,
-       { UQ_DESC_CORRUPT, desc_pn533 }},
+       { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
  { USB_VENDOR_SHUTTLE,         USB_PRODUCT_SHUTTLE_SCL3712,            ANY,
-       { UQ_DESC_CORRUPT, desc_pn533 }},
+       { UQ_DESC_CORRUPT | UQ_MISS_OUT_ACK, desc_pn533 }},
  { 0, 0, 0, { 0, NULL } }
 };
 
diff -r b35bfe3b7318 -r 2168ff51b571 sys/dev/usb/usb_quirks.h
--- a/sys/dev/usb/usb_quirks.h  Tue Nov 20 16:02:50 2018 +0000
+++ b/sys/dev/usb/usb_quirks.h  Tue Nov 20 16:05:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_quirks.h,v 1.27.10.1 2018/11/12 16:01:35 martin Exp $      */
+/*     $NetBSD: usb_quirks.h,v 1.27.10.2 2018/11/20 16:05:38 martin Exp $      */
 /*     $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $  */
 
 /*
@@ -50,6 +50,7 @@
 #define UQ_LOST_CS_DESC 0x10000 /* look everywhere for the CS descriptors */
 #define UQ_APPLE_ISO   0x20000 /* force ISO layout on Apple keyboards */
 #define UQ_DESC_CORRUPT        0x40000 /* may corrupt its config descriptors */
+#define UQ_MISS_OUT_ACK        0x80000 /* may fail to ack output */
        const usb_descriptor_t **desc;  /* Replacement for UQ_DESC_CORRUPT */
 };
 
diff -r b35bfe3b7318 -r 2168ff51b571 sys/dev/usb/usbdi.c
--- a/sys/dev/usb/usbdi.c       Tue Nov 20 16:02:50 2018 +0000
+++ b/sys/dev/usb/usbdi.c       Tue Nov 20 16:05:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usbdi.c,v 1.173.2.3 2018/09/27 14:52:26 martin Exp $   */
+/*     $NetBSD: usbdi.c,v 1.173.2.4 2018/11/20 16:05:38 martin Exp $   */
 
 /*
  * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.3 2018/09/27 14:52:26 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.173.2.4 2018/11/20 16:05:38 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -897,9 +897,7 @@
        struct usbd_pipe *pipe = xfer->ux_pipe;
        struct usbd_bus *bus = pipe->up_dev->ud_bus;
        int sync = xfer->ux_flags & USBD_SYNCHRONOUS;
-       int erred =
-           xfer->ux_status == USBD_CANCELLED ||
-           xfer->ux_status == USBD_TIMEOUT;
+       int erred;
        int polling = bus->ub_usepolling;
        int repeat = pipe->up_repeat;
 
@@ -914,6 +912,27 @@
            xfer->ux_state);
        KASSERT(pipe != NULL);
 
+       /*
+        * If device is known to miss out ack, then pretend that
+        * output timeout is a success. Userland should handle
+        * the logic to verify that the operation succeeded.
+        */
+       if (pipe->up_dev->ud_quirks &&
+           pipe->up_dev->ud_quirks->uq_flags & UQ_MISS_OUT_ACK &&
+           xfer->ux_status == USBD_TIMEOUT &&
+           !usbd_xfer_isread(xfer)) {
+               USBHIST_LOG(usbdebug, "Possible output ack miss for xfer %#jx: "
+                   "hiding write timeout to %d.%s for %d bytes written",
+                   (uintptr_t)xfer, curlwp->l_proc->p_pid, curlwp->l_lid,
+                   xfer->ux_length);
+
+               xfer->ux_status = USBD_NORMAL_COMPLETION;
+               xfer->ux_actlen = xfer->ux_length;
+       }
+
+       erred = xfer->ux_status == USBD_CANCELLED ||
+               xfer->ux_status == USBD_TIMEOUT;
+
        if (!repeat) {
                /* Remove request from queue. */
 



Home | Main Index | Thread Index | Old Index