From owner-svn-src-stable-10@FreeBSD.ORG Wed Feb 5 08:40:04 2014 Return-Path: Delivered-To: svn-src-stable-10@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 7965C40D; Wed, 5 Feb 2014 08:40:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 624641DCF; Wed, 5 Feb 2014 08:40:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s158e4MB033869; Wed, 5 Feb 2014 08:40:04 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s158e3FI033851; Wed, 5 Feb 2014 08:40:03 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201402050840.s158e3FI033851@svn.freebsd.org> From: Hans Petter Selasky Date: Wed, 5 Feb 2014 08:40:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r261509 - in stable/10: etc sys/conf sys/dev/usb sys/dev/usb/input sys/modules/usb sys/modules/usb/wsp X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Feb 2014 08:40:04 -0000 Author: hselasky Date: Wed Feb 5 08:40:02 2014 New Revision: 261509 URL: http://svnweb.freebsd.org/changeset/base/261509 Log: MFC r261260, r261262, r261315 and r261343: Add support for trackpads found in Apple MacBook products. While at it add some missing devd entries. Added: stable/10/sys/dev/usb/input/wsp.c - copied, changed from r261260, head/sys/dev/usb/input/wsp.c stable/10/sys/modules/usb/wsp/ - copied from r261260, head/sys/modules/usb/wsp/ Modified: stable/10/etc/devd.conf stable/10/sys/conf/NOTES stable/10/sys/conf/files stable/10/sys/dev/usb/usbdevs stable/10/sys/modules/usb/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/etc/devd.conf ============================================================================== --- stable/10/etc/devd.conf Wed Feb 5 08:29:24 2014 (r261508) +++ stable/10/etc/devd.conf Wed Feb 5 08:40:02 2014 (r261509) @@ -119,6 +119,15 @@ notify 100 { match "system" "DEVFS"; match "subsystem" "CDEV"; match "type" "CREATE"; + match "cdev" "atp[0-9]+"; + + action "/etc/rc.d/moused quietstart $cdev"; +}; + +notify 100 { + match "system" "DEVFS"; + match "subsystem" "CDEV"; + match "type" "CREATE"; match "cdev" "ums[0-9]+"; action "/etc/rc.d/moused quietstart $cdev"; @@ -127,6 +136,15 @@ notify 100 { notify 100 { match "system" "DEVFS"; match "subsystem" "CDEV"; + match "type" "CREATE"; + match "cdev" "wsp[0-9]+"; + + action "/etc/rc.d/moused quietstart $cdev"; +}; + +notify 100 { + match "system" "DEVFS"; + match "subsystem" "CDEV"; match "type" "DESTROY"; match "cdev" "ums[0-9]+"; Modified: stable/10/sys/conf/NOTES ============================================================================== --- stable/10/sys/conf/NOTES Wed Feb 5 08:29:24 2014 (r261508) +++ stable/10/sys/conf/NOTES Wed Feb 5 08:40:02 2014 (r261509) @@ -2656,6 +2656,9 @@ device umct device umodem # USB mouse device ums +# USB touchpad(s) +device atp +device wsp # eGalax USB touch screen device uep # Diamond Rio 500 MP3 player Modified: stable/10/sys/conf/files ============================================================================== --- stable/10/sys/conf/files Wed Feb 5 08:29:24 2014 (r261508) +++ stable/10/sys/conf/files Wed Feb 5 08:40:02 2014 (r261509) @@ -2434,6 +2434,7 @@ dev/usb/input/uep.c optional uep dev/usb/input/uhid.c optional uhid dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums +dev/usb/input/wsp.c optional wsp # # USB quirks # Copied and modified: stable/10/sys/dev/usb/input/wsp.c (from r261260, head/sys/dev/usb/input/wsp.c) ============================================================================== --- head/sys/dev/usb/input/wsp.c Wed Jan 29 10:42:01 2014 (r261260, copy source) +++ stable/10/sys/dev/usb/input/wsp.c Wed Feb 5 08:40:02 2014 (r261509) @@ -123,6 +123,25 @@ SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_ho #define WSP_IFACE_INDEX 1 +/* + * Some tables, structures, definitions and initialisation values for + * the touchpad protocol has been copied from Linux's + * "drivers/input/mouse/bcm5974.c" which has the following copyright + * holders under GPLv2. All device specific code in this driver has + * been written from scratch. The decoding algorithm is based on + * output from usbdump. + * + * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) + * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com) + * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) + * Copyright (C) 2005 Stelian Pop (stelian@popies.net) + * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) + * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) + * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) + * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) + */ + /* button data structure */ struct bt_data { uint8_t unknown1; /* constant */ @@ -569,15 +588,11 @@ static const STRUCT_USB_HOST_ID wsp_devs enum { WSP_INTR_DT, - WSP_RESET, WSP_N_TRANSFER, }; struct wsp_softc { - device_t sc_dev; struct usb_device *sc_usb_device; -#define MODE_LENGTH 8 - uint8_t sc_mode_bytes[MODE_LENGTH]; /* device mode */ struct mtx sc_mutex; /* for synchronization */ struct usb_xfer *sc_xfer[WSP_N_TRANSFER]; struct usb_fifo_sc sc_fifo; @@ -609,7 +624,8 @@ struct wsp_softc { int dz_count; #define WSP_DZ_MAX_COUNT 32 int dt_sum; /* T-axis cumulative movement */ - + + uint8_t o_ntouch; /* old touch finger status */ uint8_t finger; /* 0 or 1 *, check which finger moving */ uint16_t intr_count; #define WSP_TAP_THRESHOLD 3 @@ -648,8 +664,6 @@ static struct usb_fifo_methods wsp_fifo_ }; /* device initialization and shutdown */ -static usb_error_t wsp_req_get_report(struct usb_device *udev, void *data); -static int wsp_set_device_mode(device_t dev, interface_mode mode); static int wsp_enable(struct wsp_softc *sc); static void wsp_disable(struct wsp_softc *sc); @@ -662,7 +676,6 @@ static device_probe_t wsp_probe; static device_attach_t wsp_attach; static device_detach_t wsp_detach; static usb_callback_t wsp_intr_callback; -static usb_callback_t wsp_reset_callback; static struct usb_config wsp_config[WSP_N_TRANSFER] = { [WSP_INTR_DT] = { @@ -676,87 +689,36 @@ static struct usb_config wsp_config[WSP_ .bufsize = 0, /* use wMaxPacketSize */ .callback = &wsp_intr_callback, }, - [WSP_RESET] = { - .type = UE_CONTROL, - .endpoint = 0, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request) + MODE_LENGTH, - .callback = &wsp_reset_callback, - .interval = 0, /* no pre-delay */ - }, }; -usb_error_t -wsp_req_get_report(struct usb_device *udev, void *data) -{ - struct usb_device_request req; - - req.bmRequestType = UT_READ_CLASS_INTERFACE; - req.bRequest = UR_GET_REPORT; - USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ ); - USETW(req.wIndex, 0); - USETW(req.wLength, MODE_LENGTH); - - return (usbd_do_request(udev, NULL /* mutex */ , &req, data)); -} - -static int -wsp_set_device_mode(device_t dev, interface_mode mode) +static usb_error_t +wsp_set_device_mode(struct wsp_softc *sc, interface_mode mode) { - struct wsp_softc *sc; - usb_device_request_t req; + uint8_t mode_bytes[8]; usb_error_t err; - if ((mode != RAW_SENSOR_MODE) && (mode != HID_MODE)) - return (ENXIO); + err = usbd_req_get_report(sc->sc_usb_device, NULL, + mode_bytes, sizeof(mode_bytes), 0, + 0x03, 0x00); - sc = device_get_softc(dev); - - sc->sc_mode_bytes[0] = mode; - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_REPORT; - USETW2(req.wValue, (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ ); - USETW(req.wIndex, 0); - USETW(req.wLength, MODE_LENGTH); - err = usbd_do_request(sc->sc_usb_device, NULL, &req, sc->sc_mode_bytes); - if (err != USB_ERR_NORMAL_COMPLETION) - return (ENXIO); - - return (0); -} - -static void -wsp_reset_callback(struct usb_xfer *xfer, usb_error_t error) -{ - usb_device_request_t req; - struct usb_page_cache *pc; - struct wsp_softc *sc = usbd_xfer_softc(xfer); + if (err != USB_ERR_NORMAL_COMPLETION) { + DPRINTF("Failed to read device mode (%d)\n", err); + return (err); + } - switch (USB_GET_STATE(xfer)) { - case USB_ST_SETUP: - sc->sc_mode_bytes[0] = RAW_SENSOR_MODE; - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_REPORT; - USETW2(req.wValue, - (uint8_t)0x03 /* type */ , (uint8_t)0x00 /* id */ ); - USETW(req.wIndex, 0); - USETW(req.wLength, MODE_LENGTH); + /* + * XXX Need to wait at least 250ms for hardware to get + * ready. The device mode handling appears to be handled + * asynchronously and we should not issue these commands too + * quickly. + */ + pause("WHW", hz / 4); - pc = usbd_xfer_get_frame(xfer, 0); - usbd_copy_in(pc, 0, &req, sizeof(req)); - pc = usbd_xfer_get_frame(xfer, 1); - usbd_copy_in(pc, 0, sc->sc_mode_bytes, MODE_LENGTH); - - usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); - usbd_xfer_set_frame_len(xfer, 1, MODE_LENGTH); - usbd_xfer_set_frames(xfer, 2); - usbd_transfer_submit(xfer); - break; + mode_bytes[0] = mode; - case USB_ST_TRANSFERRED: - default: - break; - } + return (usbd_req_set_report(sc->sc_usb_device, NULL, + mode_bytes, sizeof(mode_bytes), 0, + 0x03, 0x00)); } static int @@ -820,27 +782,35 @@ wsp_attach(device_t dev) DPRINTFN(WSP_LLEVEL_INFO, "sc=%p\n", sc); - sc->sc_dev = dev; sc->sc_usb_device = uaa->device; /* - * By default the touchpad behaves like an HID device, sending + * By default the touchpad behaves like a HID device, sending * packets with reportID = 8. Such reports contain only * limited information. They encode movement deltas and button * events, but do not include data from the pressure * sensors. The device input mode can be switched from HID * reports to raw sensor data using vendor-specific USB - * control commands; but first the mode must be read. + * control commands: */ - err = wsp_req_get_report(sc->sc_usb_device, sc->sc_mode_bytes); + + /* + * During re-enumeration of the device we need to force the + * device back into HID mode before switching it to RAW + * mode. Else the device does not work like expected. + */ + err = wsp_set_device_mode(sc, HID_MODE); if (err != USB_ERR_NORMAL_COMPLETION) { - DPRINTF("failed to read device mode (%d)\n", err); + DPRINTF("Failed to set mode to HID MODE (%d)\n", err); return (ENXIO); } - if (wsp_set_device_mode(dev, RAW_SENSOR_MODE) != 0) { - DPRINTF("failed to set mode to 'RAW_SENSOR' (%d)\n", err); + + err = wsp_set_device_mode(sc, RAW_SENSOR_MODE); + if (err != USB_ERR_NORMAL_COMPLETION) { + DPRINTF("failed to set mode to RAW MODE (%d)\n", err); return (ENXIO); } + mtx_init(&sc->sc_mutex, "wspmtx", NULL, MTX_DEF | MTX_RECURSE); /* get device specific configuration */ @@ -891,7 +861,7 @@ wsp_detach(device_t dev) { struct wsp_softc *sc = device_get_softc(dev); - wsp_set_device_mode(dev, HID_MODE); + (void) wsp_set_device_mode(sc, HID_MODE); mtx_lock(&sc->sc_mutex); if (sc->sc_state & WSP_ENABLED) @@ -921,7 +891,6 @@ wsp_intr_callback(struct usb_xfer *xfer, int dx = 0; int dy = 0; int dz = 0; - int n = 0; int len; int i; @@ -986,13 +955,9 @@ wsp_intr_callback(struct usb_xfer *xfer, f[i].tool_major, f[i].tool_minor, f[i].orientation, f[i].touch_major, f[i].touch_minor, f[i].multi); - if (f[i].touch_major < tun.pressure_untouch_threshold) - continue; - - sc->pos_x[n] = f[i].abs_x; - sc->pos_y[n] = params->y.min + params->y.max - f[i].abs_y; - sc->index[n] = &f[i]; - n++; + sc->pos_x[i] = f[i].abs_x; + sc->pos_y[i] = params->y.min + params->y.max - f[i].abs_y; + sc->index[i] = &f[i]; } sc->sc_status.flags &= ~MOUSE_POSCHANGED; @@ -1007,8 +972,8 @@ wsp_intr_callback(struct usb_xfer *xfer, if (h->q2 == 4) sc->intr_count++; - if (sc->ntaps < n) { - switch (n) { + if (sc->ntaps < ntouch) { + switch (ntouch) { case 1: if (f[0].touch_major > tun.pressure_tap_threshold) sc->ntaps = 1; @@ -1028,7 +993,7 @@ wsp_intr_callback(struct usb_xfer *xfer, break; } } - if (n == 2) { + if (ntouch == 2) { sc->distance = max(sc->distance, max( abs(sc->pos_x[0] - sc->pos_x[1]), abs(sc->pos_y[0] - sc->pos_y[1]))); @@ -1100,15 +1065,34 @@ wsp_intr_callback(struct usb_xfer *xfer, if (sc->sc_touch == WSP_SECOND_TOUCH) sc->sc_touch = WSP_TOUCHING; - if (n != 0 && + if (ntouch != 0 && h->q2 == 4 && f[0].touch_major >= tun.pressure_touch_threshold) { dx = sc->pos_x[0] - sc->pre_pos_x; dy = sc->pos_y[0] - sc->pre_pos_y; - if (n == 2 && sc->sc_status.button != 0) { + + /* Ignore movement from ibt=1 to ibt=0 */ + if (sc->sc_status.obutton != 0 && + sc->sc_status.button == 0) { + dx = 0; + dy = 0; + } + /* Ignore movement if ntouch changed */ + if (sc->o_ntouch != ntouch) { + dx = 0; + dy = 0; + } + + if (ntouch == 2 && sc->sc_status.button != 0) { dx = sc->pos_x[sc->finger] - sc->pre_pos_x; dy = sc->pos_y[sc->finger] - sc->pre_pos_y; - if (f[0].origin == 0 || f[1].origin == 0) { + + /* + * Ignore movement of switch finger or + * movement from ibt=0 to ibt=1 + */ + if (f[0].origin == 0 || f[1].origin == 0 || + sc->sc_status.obutton != sc->sc_status.button) { dx = 0; dy = 0; sc->finger = 0; @@ -1142,7 +1126,7 @@ wsp_intr_callback(struct usb_xfer *xfer, sc->dx_sum += dx; sc->dy_sum += dy; - if (n == 2 && sc->sc_status.button == 0) { + if (ntouch == 2 && sc->sc_status.button == 0) { if (sc->scr_mode == WSP_SCR_NONE && abs(sc->dx_sum) + abs(sc->dy_sum) > 50) sc->scr_mode = abs(sc->dx_sum) > @@ -1184,10 +1168,12 @@ wsp_intr_callback(struct usb_xfer *xfer, sc->pre_pos_x = sc->pos_x[0]; sc->pre_pos_y = sc->pos_y[0]; - if (n == 2 && sc->sc_status.button != 0) { + if (ntouch == 2 && sc->sc_status.button != 0) { sc->pre_pos_x = sc->pos_x[sc->finger]; sc->pre_pos_y = sc->pos_y[sc->finger]; } + sc->o_ntouch = ntouch; + case USB_ST_SETUP: tr_setup: /* check if we can put more data into the FIFO */ Modified: stable/10/sys/dev/usb/usbdevs ============================================================================== --- stable/10/sys/dev/usb/usbdevs Wed Feb 5 08:29:24 2014 (r261508) +++ stable/10/sys/dev/usb/usbdevs Wed Feb 5 08:40:02 2014 (r261509) @@ -1073,12 +1073,54 @@ product APPLE DUMMY 0x0000 Dummy produc product APPLE IMAC_KBD 0x0201 USB iMac Keyboard product APPLE KBD 0x0202 USB Keyboard M2452 product APPLE EXT_KBD 0x020c Apple Extended USB Keyboard -product APPLE KBD_TP_ANSI 0x0223 Apple Internal Keyboard/Trackpad (Wellspring/ANSI) -product APPLE KBD_TP_ISO 0x0224 Apple Internal Keyboard/Trackpad (Wellspring/ISO) -product APPLE KBD_TP_JIS 0x0225 Apple Internal Keyboard/Trackpad (Wellspring/JIS) -product APPLE KBD_TP_ANSI2 0x0230 Apple Internal Keyboard/Trackpad (Wellspring2/ANSI) -product APPLE KBD_TP_ISO2 0x0231 Apple Internal Keyboard/Trackpad (Wellspring2/ISO) -product APPLE KBD_TP_JIS2 0x0232 Apple Internal Keyboard/Trackpad (Wellspring2/JIS) +/* MacbookAir, aka wellspring */ +product APPLE WELLSPRING_ANSI 0x0223 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING_ISO 0x0224 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING_JIS 0x0225 Apple Internal Keyboard/Trackpad +/* MacbookProPenryn, aka wellspring2 */ +product APPLE WELLSPRING2_ANSI 0x0230 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING2_ISO 0x0231 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING2_JIS 0x0232 Apple Internal Keyboard/Trackpad +/* Macbook5,1 (unibody), aka wellspring3 */ +product APPLE WELLSPRING3_ANSI 0x0236 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING3_ISO 0x0237 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING3_JIS 0x0238 Apple Internal Keyboard/Trackpad +/* MacbookAir3,2 (unibody), aka wellspring4 */ +product APPLE WELLSPRING4_ANSI 0x023f Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING4_ISO 0x0240 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING4_JIS 0x0241 Apple Internal Keyboard/Trackpad +/* MacbookAir3,1 (unibody), aka wellspring4 */ +product APPLE WELLSPRING4A_ANSI 0x0242 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING4A_ISO 0x0243 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING4A_JIS 0x0244 Apple Internal Keyboard/Trackpad +/* Macbook8 (unibody, March 2011) */ +product APPLE WELLSPRING5_ANSI 0x0245 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING5_ISO 0x0246 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING5_JIS 0x0247 Apple Internal Keyboard/Trackpad +/* MacbookAir4,1 (unibody, July 2011) */ +product APPLE WELLSPRING6A_ANSI 0x0249 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING6A_ISO 0x024a Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING6A_JIS 0x024b Apple Internal Keyboard/Trackpad +/* MacbookAir4,2 (unibody, July 2011) */ +product APPLE WELLSPRING6_ANSI 0x024c Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING6_ISO 0x024d Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING6_JIS 0x024e Apple Internal Keyboard/Trackpad +/* Macbook8,2 (unibody) */ +product APPLE WELLSPRING5A_ANSI 0x0252 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING5A_ISO 0x0253 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING5A_JIS 0x0254 Apple Internal Keyboard/Trackpad +/* MacbookPro10,1 (unibody, June 2012) */ +product APPLE WELLSPRING7_ANSI 0x0262 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING7_ISO 0x0263 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING7_JIS 0x0264 Apple Internal Keyboard/Trackpad +/* MacbookPro10,2 (unibody, October 2012) */ +product APPLE WELLSPRING7A_ANSI 0x0259 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING7A_ISO 0x025a Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING7A_JIS 0x025b Apple Internal Keyboard/Trackpad +/* MacbookAir6,2 (unibody, June 2013) */ +product APPLE WELLSPRING8_ANSI 0x0290 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING8_ISO 0x0291 Apple Internal Keyboard/Trackpad +product APPLE WELLSPRING8_JIS 0x0292 Apple Internal Keyboard/Trackpad product APPLE MOUSE 0x0301 Mouse M4848 product APPLE OPTMOUSE 0x0302 Optical mouse product APPLE MIGHTYMOUSE 0x0304 Mighty Mouse Modified: stable/10/sys/modules/usb/Makefile ============================================================================== --- stable/10/sys/modules/usb/Makefile Wed Feb 5 08:29:24 2014 (r261508) +++ stable/10/sys/modules/usb/Makefile Wed Feb 5 08:40:02 2014 (r261509) @@ -35,7 +35,7 @@ SUBDIR += ${_dwc_otg} ehci ${_musb} ohci ${_atmegadci} ${_avr32dci} ${_rsu} ${_rsufw} SUBDIR += ${_rum} ${_run} ${_runfw} ${_uath} upgt usie ural ${_zyd} ${_urtw} SUBDIR += ${_urtwn} ${_urtwnfw} -SUBDIR += atp uhid ukbd ums udbp ufm uep +SUBDIR += atp uhid ukbd ums udbp ufm uep wsp SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \ umct umcs umodem umoscom uplcom uslcom uvisor uvscom SUBDIR += uether aue axe cdce cue ${_kue} mos rue smsc udav uhso ipheth