From owner-svn-src-stable-11@freebsd.org Sat Oct 22 16:38:41 2016 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 75C96C1CFCC; Sat, 22 Oct 2016 16:38:41 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3638E3AF; Sat, 22 Oct 2016 16:38:41 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u9MGce7J015398; Sat, 22 Oct 2016 16:38:40 GMT (envelope-from gonzo@FreeBSD.org) Received: (from gonzo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u9MGcdXp015392; Sat, 22 Oct 2016 16:38:39 GMT (envelope-from gonzo@FreeBSD.org) Message-Id: <201610221638.u9MGcdXp015392@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gonzo set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko Date: Sat, 22 Oct 2016 16:38:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r307777 - in stable/11/sys/dev: evdev usb/input X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 Oct 2016 16:38:41 -0000 Author: gonzo Date: Sat Oct 22 16:38:39 2016 New Revision: 307777 URL: https://svnweb.freebsd.org/changeset/base/307777 Log: MFC r306647, r306855, r306857 r306647: const-ify struct evdev_methods Submitted by: Vladimir Kondratiev Suggested by: hselasky r306855: Allow using of driver's mutex instead internal one for evdev locking. Add new API call: evdev_register_mtx which takes lock argument that should be used instead of internal one for evdev locking. Useful for cases if evdev_push_event() is always called with driver's lock taken and reduces amount of lock aquisitions. This allows to avoid LOR between ev_open/ev_close invocations and evdev_push_event() Such LOR can happen when ev_open/ev_close methods acquire driver lock and evdev_push_event() is called with this lock taken. Submitted by: Vladimir Kondratiev r306857: Implement EVDEV_FLAG_MT_AUTOREL flag (autorelease touchpoints) Automaticaly release (send ABS_MT_TRACKING_ID = -1) MT-slots that has not been listed in current MT protocol type B report. Slot is counted as listed if corresponding ABS_MT_SLOT event has been sent regardless of other MT events. Events are sent on SYN_REPORT event. Submitted by: Vladimir Kondratiev Modified: stable/11/sys/dev/evdev/evdev.c stable/11/sys/dev/evdev/evdev.h stable/11/sys/dev/evdev/evdev_mt.c stable/11/sys/dev/evdev/evdev_private.h stable/11/sys/dev/usb/input/ukbd.c stable/11/sys/dev/usb/input/ums.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/evdev/evdev.c ============================================================================== --- stable/11/sys/dev/evdev/evdev.c Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/evdev/evdev.c Sat Oct 22 16:38:39 2016 (r307777) @@ -187,8 +187,8 @@ evdev_estimate_report_size(struct evdev_ return (size); } -int -evdev_register(struct evdev_dev *evdev) +static int +evdev_register_common(struct evdev_dev *evdev) { int ret; @@ -196,7 +196,6 @@ evdev_register(struct evdev_dev *evdev) evdev->ev_shortname, evdev->ev_name, evdev->ev_serial); /* Initialize internal structures */ - mtx_init(&evdev->ev_mtx, "evmtx", NULL, MTX_DEF); LIST_INIT(&evdev->ev_clients); if (evdev_event_supported(evdev, EV_REP) && @@ -228,6 +227,19 @@ evdev_register(struct evdev_dev *evdev) /* Create char device node */ ret = evdev_cdev_create(evdev); bail_out: + return (ret); +} + +int +evdev_register(struct evdev_dev *evdev) +{ + int ret; + + evdev->ev_lock_type = EV_LOCK_INTERNAL; + evdev->ev_lock = &evdev->ev_mtx; + mtx_init(&evdev->ev_mtx, "evmtx", NULL, MTX_DEF); + + ret = evdev_register_common(evdev); if (ret != 0) mtx_destroy(&evdev->ev_mtx); @@ -235,6 +247,15 @@ bail_out: } int +evdev_register_mtx(struct evdev_dev *evdev, struct mtx *mtx) +{ + + evdev->ev_lock_type = EV_LOCK_MTX; + evdev->ev_lock = mtx; + return (evdev_register_common(evdev)); +} + +int evdev_unregister(struct evdev_dev *evdev) { struct evdev_client *client; @@ -257,7 +278,7 @@ evdev_unregister(struct evdev_dev *evdev /* destroy_dev can sleep so release lock */ ret = evdev_cdev_destroy(evdev); evdev->ev_cdev = NULL; - if (ret == 0) + if (ret == 0 && evdev->ev_lock_type == EV_LOCK_INTERNAL) mtx_destroy(&evdev->ev_mtx); evdev_free_absinfo(evdev->ev_absinfo); @@ -302,7 +323,7 @@ evdev_set_serial(struct evdev_dev *evdev inline void evdev_set_methods(struct evdev_dev *evdev, void *softc, - struct evdev_methods *methods) + const struct evdev_methods *methods) { evdev->ev_methods = methods; @@ -665,6 +686,8 @@ evdev_sparse_event(struct evdev_dev *evd case EV_SYN: if (code == SYN_REPORT) { + /* Count empty reports as well as non empty */ + evdev->ev_report_count++; /* Skip empty reports */ if (!evdev->ev_report_opened) return (EV_SKIP_EVENT); @@ -701,10 +724,7 @@ evdev_propagate_event(struct evdev_dev * EVDEV_CLIENT_UNLOCKQ(client); } - /* Update counters */ evdev->ev_event_count++; - if (type == EV_SYN && code == SYN_REPORT) - evdev->ev_report_count++; } void @@ -735,16 +755,24 @@ evdev_push_event(struct evdev_dev *evdev int32_t value) { + if (evdev->ev_lock_type != EV_LOCK_INTERNAL) + EVDEV_LOCK_ASSERT(evdev); + if (evdev_check_event(evdev, type, code, value) != 0) return (EINVAL); - EVDEV_LOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_LOCK(evdev); evdev_modify_event(evdev, type, code, &value); + if (type == EV_SYN && code == SYN_REPORT && + bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL)) + evdev_send_mt_autorel(evdev); if (type == EV_SYN && code == SYN_REPORT && evdev->ev_report_opened && bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT)) evdev_send_mt_compat(evdev); evdev_send_event(evdev, type, code, value); - EVDEV_UNLOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_UNLOCK(evdev); return (0); } Modified: stable/11/sys/dev/evdev/evdev.h ============================================================================== --- stable/11/sys/dev/evdev/evdev.h Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/evdev/evdev.h Sat Oct 22 16:38:39 2016 (r307777) @@ -70,6 +70,8 @@ extern int evdev_rcpt_mask; #define EVDEV_FLAG_SOFTREPEAT 0x00 /* use evdev to repeat keys */ #define EVDEV_FLAG_MT_STCOMPAT 0x01 /* autogenerate ST-compatible events * for MT protocol type B reports */ +#define EVDEV_FLAG_MT_AUTOREL 0x02 /* Autorelease MT-slots not listed in + * current MT protocol type B report */ #define EVDEV_FLAG_MAX 0x1F #define EVDEV_FLAG_CNT (EVDEV_FLAG_MAX + 1) @@ -89,8 +91,10 @@ void evdev_set_name(struct evdev_dev *, void evdev_set_id(struct evdev_dev *, uint16_t, uint16_t, uint16_t, uint16_t); void evdev_set_phys(struct evdev_dev *, const char *); void evdev_set_serial(struct evdev_dev *, const char *); -void evdev_set_methods(struct evdev_dev *, void *, struct evdev_methods *); +void evdev_set_methods(struct evdev_dev *, void *, + const struct evdev_methods *); int evdev_register(struct evdev_dev *); +int evdev_register_mtx(struct evdev_dev *, struct mtx *); int evdev_unregister(struct evdev_dev *); int evdev_push_event(struct evdev_dev *, uint16_t, uint16_t, int32_t); int evdev_sync(struct evdev_dev *); Modified: stable/11/sys/dev/evdev/evdev_mt.c ============================================================================== --- stable/11/sys/dev/evdev/evdev_mt.c Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/evdev/evdev_mt.c Sat Oct 22 16:38:39 2016 (r307777) @@ -112,6 +112,7 @@ void evdev_set_last_mt_slot(struct evdev_dev *evdev, int32_t slot) { + evdev->ev_mt->ev_mt_slots[slot].ev_report = evdev->ev_report_count; evdev->ev_mt->ev_mt_last_reported_slot = slot; } @@ -128,10 +129,6 @@ evdev_set_mt_value(struct evdev_dev *evd int32_t value) { - if (code == ABS_MT_TRACKING_ID && value == -1) - evdev->ev_mt->ev_mt_slots[slot].ev_report = - evdev->ev_report_count; - evdev->ev_mt->ev_mt_slots[slot].ev_mt_states[ABS_MT_INDEX(code)] = value; } @@ -227,9 +224,13 @@ void evdev_push_nfingers(struct evdev_dev *evdev, int32_t nfingers) { - EVDEV_LOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_LOCK(evdev); + else + EVDEV_LOCK_ASSERT(evdev); evdev_send_nfingers(evdev, nfingers); - EVDEV_UNLOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_UNLOCK(evdev); } void @@ -263,7 +264,29 @@ void evdev_push_mt_compat(struct evdev_dev *evdev) { - EVDEV_LOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_LOCK(evdev); + else + EVDEV_LOCK_ASSERT(evdev); evdev_send_mt_compat(evdev); - EVDEV_UNLOCK(evdev); + if (evdev->ev_lock_type == EV_LOCK_INTERNAL) + EVDEV_UNLOCK(evdev); +} + +void +evdev_send_mt_autorel(struct evdev_dev *evdev) +{ + int32_t slot; + + EVDEV_LOCK_ASSERT(evdev); + + for (slot = 0; slot <= MAXIMAL_MT_SLOT(evdev); slot++) { + if (evdev->ev_mt->ev_mt_slots[slot].ev_report != + evdev->ev_report_count && + evdev_get_mt_value(evdev, slot, ABS_MT_TRACKING_ID) != -1){ + evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot); + evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, + -1); + } + } } Modified: stable/11/sys/dev/evdev/evdev_private.h ============================================================================== --- stable/11/sys/dev/evdev/evdev_private.h Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/evdev/evdev_private.h Sat Oct 22 16:38:39 2016 (r307777) @@ -71,6 +71,12 @@ enum evdev_clock_id EV_CLOCK_BOOTTIME /* monotonic, suspend-awared */ }; +enum evdev_lock_type +{ + EV_LOCK_INTERNAL = 0, /* Internal evdev mutex */ + EV_LOCK_MTX, /* Driver`s mutex */ +}; + struct evdev_dev { char ev_name[NAMELEN]; @@ -78,6 +84,8 @@ struct evdev_dev char ev_serial[NAMELEN]; struct cdev * ev_cdev; int ev_unit; + enum evdev_lock_type ev_lock_type; + struct mtx * ev_lock; struct mtx ev_mtx; struct input_id ev_id; struct evdev_client * ev_grabber; @@ -116,16 +124,16 @@ struct evdev_dev uint64_t ev_report_count; /* Parent driver callbacks: */ - struct evdev_methods * ev_methods; + const struct evdev_methods * ev_methods; void * ev_softc; LIST_ENTRY(evdev_dev) ev_link; LIST_HEAD(, evdev_client) ev_clients; }; -#define EVDEV_LOCK(evdev) mtx_lock(&(evdev)->ev_mtx) -#define EVDEV_UNLOCK(evdev) mtx_unlock(&(evdev)->ev_mtx) -#define EVDEV_LOCK_ASSERT(evdev) mtx_assert(&(evdev)->ev_mtx, MA_OWNED) +#define EVDEV_LOCK(evdev) mtx_lock((evdev)->ev_lock) +#define EVDEV_UNLOCK(evdev) mtx_unlock((evdev)->ev_lock) +#define EVDEV_LOCK_ASSERT(evdev) mtx_assert((evdev)->ev_lock, MA_OWNED) struct evdev_client { @@ -184,6 +192,7 @@ void evdev_set_last_mt_slot(struct evdev int32_t evdev_get_mt_value(struct evdev_dev *, int32_t, int16_t); void evdev_set_mt_value(struct evdev_dev *, int32_t, int16_t, int32_t); void evdev_send_mt_compat(struct evdev_dev *); +void evdev_send_mt_autorel(struct evdev_dev *); /* Utility functions: */ void evdev_client_dumpqueue(struct evdev_client *); Modified: stable/11/sys/dev/usb/input/ukbd.c ============================================================================== --- stable/11/sys/dev/usb/input/ukbd.c Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/usb/input/ukbd.c Sat Oct 22 16:38:39 2016 (r307777) @@ -387,7 +387,7 @@ static device_detach_t ukbd_detach; static device_resume_t ukbd_resume; #ifdef EVDEV_SUPPORT -static struct evdev_methods ukbd_evdev_methods = { +static const struct evdev_methods ukbd_evdev_methods = { .ev_event = evdev_ev_kbd_event, }; #endif Modified: stable/11/sys/dev/usb/input/ums.c ============================================================================== --- stable/11/sys/dev/usb/input/ums.c Sat Oct 22 16:24:12 2016 (r307776) +++ stable/11/sys/dev/usb/input/ums.c Sat Oct 22 16:38:39 2016 (r307777) @@ -191,7 +191,7 @@ static struct usb_fifo_methods ums_fifo_ }; #ifdef EVDEV_SUPPORT -static struct evdev_methods ums_evdev_methods = { +static const struct evdev_methods ums_evdev_methods = { .ev_open = &ums_ev_open, .ev_close = &ums_ev_close, };