Date: Sun, 18 May 2014 17:58:33 +0000 (UTC) From: Jakub Wojciech Klama <jceel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r266413 - in user/jceel/soc2014_evdev/head/sys: amd64/conf conf dev/evdev dev/usb/input Message-ID: <201405181758.s4IHwXgH074987@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jceel Date: Sun May 18 17:58:33 2014 New Revision: 266413 URL: http://svnweb.freebsd.org/changeset/base/266413 Log: Initial work on evdev support. Includes evdev chardev driver with basic ioctls support (enough to run X with evdev-driven mouse) and a modified ums(4) driver reporting to evdev layer. Userspace interface headers (input.h and uinput.h) are for now borrowed from Linux and adapted to BSD ioctl specifics. Added: user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV user/jceel/soc2014_evdev/head/sys/dev/evdev/ user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c (contents, props changed) user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c (contents, props changed) user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.h (contents, props changed) user/jceel/soc2014_evdev/head/sys/dev/evdev/input.h (contents, props changed) user/jceel/soc2014_evdev/head/sys/dev/evdev/uinput.h (contents, props changed) Modified: user/jceel/soc2014_evdev/head/sys/conf/files user/jceel/soc2014_evdev/head/sys/conf/options user/jceel/soc2014_evdev/head/sys/dev/usb/input/ums.c Added: user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/jceel/soc2014_evdev/head/sys/amd64/conf/EVDEV Sun May 18 17:58:33 2014 (r266413) @@ -0,0 +1,358 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/amd64 +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD: head/sys/amd64/conf/GENERIC 263749 2014-03-25 22:08:31Z imp $ + +cpu HAMMER +ident GENERIC + +makeoptions DEBUG=-g +makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support + +options SCHED_ULE # ULE scheduler +options PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options TCP_OFFLOAD # TCP offload +options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options MD_ROOT # MD is a potential root device +options NFSCL # New Network Filesystem Client +options NFSD # New Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_RAID # Soft RAID functionality. +options GEOM_LABEL # Provides labelization +options COMPAT_FREEBSD32 # Compatible with i386 binaries +options COMPAT_FREEBSD4 # Compatible with FreeBSD4 +options COMPAT_FREEBSD5 # Compatible with FreeBSD5 +options COMPAT_FREEBSD6 # Compatible with FreeBSD6 +options COMPAT_FREEBSD7 # Compatible with FreeBSD7 +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options STACK # stack(9) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options AUDIT # Security event auditing +options CAPABILITY_MODE # Capsicum capability mode +options CAPABILITIES # Capsicum capabilities +options MAC # TrustedBSD MAC Framework +options KDTRACE_FRAME # Ensure frames are compiled in +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # Kernel ELF linker loads CTF data +options INCLUDE_CONFIG_FILE # Include this file in kernel + +# Debugging support. Always need this: +options KDB # Enable kernel debugger support. +options KDB_TRACE # Print a stack trace for a panic. +# For full debugger support use (turn off in stable branch): +options DDB # Support DDB. +options GDB # Support remote GDB. +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones + +# Make an SMP-capable kernel by default +options SMP # Symmetric MultiProcessor Kernel + +# evdev +options EVDEV + +# CPU frequency control +device cpufreq + +# Bus support. +device acpi +options ACPI_DMAR +device pci + +# Floppy drives +device fdc + +# ATA controllers +device ahci # AHCI-compatible SATA controllers +device ata # Legacy ATA/SATA controllers +options ATA_STATIC_ID # Static device numbering +device mvs # Marvell 88SX50XX/88SX60XX/88SX70XX/SoC SATA +device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA + +# SCSI Controllers +device ahc # AHA2940 and onboard AIC7xxx devices +options AHC_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~128k to driver. +device ahd # AHA39320/29320 and onboard AIC79xx devices +options AHD_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~215k to driver. +device esp # AMD Am53C974 (Tekram DC-390(T)) +device hptiop # Highpoint RocketRaid 3xxx series +device isp # Qlogic family +#device ispfw # Firmware for QLogic HBAs- normally a module +device mpt # LSI-Logic MPT-Fusion +device mps # LSI-Logic MPT-Fusion 2 +#device ncr # NCR/Symbios Logic +device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') +device trm # Tekram DC395U/UW/F DC315U adapters + +device adv # Advansys SCSI adapters +device adw # Advansys wide SCSI adapters +device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60. +device bt # Buslogic/Mylex MultiMaster SCSI adapters +device isci # Intel C600 SAS controller + +# ATA/SCSI peripherals +device scbus # SCSI bus (required for ATA/SCSI) +device ch # SCSI media changers +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct ATA/SCSI access) +device ses # Enclosure Services (SES and SAF-TE) +#device ctl # CAM Target Layer + +# RAID controllers interfaced to the SCSI subsystem +device amr # AMI MegaRAID +device arcmsr # Areca SATA II RAID +#XXX it is not 64-bit clean, -scottl +#device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID +device ciss # Compaq Smart RAID 5* +device dpt # DPT Smartcache III, IV - See NOTES for options +device hptmv # Highpoint RocketRAID 182x +device hptnr # Highpoint DC7280, R750 +device hptrr # Highpoint RocketRAID 17xx, 22xx, 23xx, 25xx +device hpt27xx # Highpoint RocketRAID 27xx +device iir # Intel Integrated RAID +device ips # IBM (Adaptec) ServeRAID +device mly # Mylex AcceleRAID/eXtremeRAID +device twa # 3ware 9000 series PATA/SATA RAID +device tws # LSI 3ware 9750 SATA+SAS 6Gb/s RAID controller + +# RAID controllers +device aac # Adaptec FSA RAID +device aacp # SCSI passthrough for aac (requires CAM) +device aacraid # Adaptec by PMC RAID +device ida # Compaq Smart RAID +device mfi # LSI MegaRAID SAS +device mlx # Mylex DAC960 family +#XXX pointer/int warnings +#device pst # Promise Supertrak SX6000 +device twe # 3ware ATA RAID + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse + +device kbdmux # keyboard multiplexer + +device vga # VGA video card driver +options VESA # Add support for VESA BIOS Extensions (VBE) + +device splash # Splash screen and screen saver support + +# syscons is the default console driver, resembling an SCO console +device sc +options SC_PIXEL_MODE # add support for the raster text mode + +device agp # support several AGP chipsets + +# PCCARD (PCMCIA) support +# PCMCIA and cardbus bridge support +device cbb # cardbus (yenta) bridge +device pccard # PC Card (16-bit) bus +device cardbus # CardBus (32-bit) bus + +# Serial (COM) ports +device uart # Generic UART driver + +# Parallel port +device ppc +device ppbus # Parallel port bus (required) +device lpt # Printer +device ppi # Parallel port interface device +#device vpo # Requires scbus and da + +device puc # Multi I/O cards and multi-channel UARTs + +# PCI Ethernet NICs. +device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE +device de # DEC/Intel DC21x4x (``Tulip'') +device em # Intel PRO/1000 Gigabit Ethernet Family +device igb # Intel PRO/1000 PCIE Server Gigabit Family +device ixgbe # Intel PRO/10GbE PCIE Ethernet Family +device le # AMD Am7900 LANCE and Am79C9xx PCnet +device ti # Alteon Networks Tigon I/II gigabit Ethernet +device txp # 3Com 3cR990 (``Typhoon'') +device vx # 3Com 3c590, 3c595 (``Vortex'') + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support +device ae # Attansic/Atheros L2 FastEthernet +device age # Attansic/Atheros L1 Gigabit Ethernet +device alc # Atheros AR8131/AR8132 Ethernet +device ale # Atheros AR8121/AR8113/AR8114 Ethernet +device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet +device bfe # Broadcom BCM440x 10/100 Ethernet +device bge # Broadcom BCM570xx Gigabit Ethernet +device cas # Sun Cassini/Cassini+ and NS DP83065 Saturn +device dc # DEC/Intel 21143 and various workalikes +device et # Agere ET1310 10/100/Gigabit Ethernet +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device gem # Sun GEM/Sun ERI/Apple GMAC +device hme # Sun HME (Happy Meal Ethernet) +device jme # JMicron JMC250 Gigabit/JMC260 Fast Ethernet +device lge # Level 1 LXT1001 gigabit Ethernet +device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet +device nfe # nVidia nForce MCP on-board Ethernet +device nge # NatSemi DP83820 gigabit Ethernet +device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') +device re # RealTek 8139C+/8169/8169S/8110S +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sge # Silicon Integrated Systems SiS190/191 +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet +device ste # Sundance ST201 (D-Link DFE-550TX) +device stge # Sundance/Tamarack TC9021 gigabit Ethernet +device tl # Texas Instruments ThunderLAN +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vge # VIA VT612x gigabit Ethernet +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') + +# ISA Ethernet NICs. pccard NICs included. +device cs # Crystal Semiconductor CS89x0 NIC +# 'device ed' requires 'device miibus' +device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards +device ex # Intel EtherExpress Pro/10 and Pro/10+ +device ep # Etherlink III based cards +device fe # Fujitsu MB8696x based cards +device sn # SMC's 9000 series of Ethernet chips +device xe # Xircom pccard Ethernet + +# Wireless NIC cards +device wlan # 802.11 support +options IEEE80211_DEBUG # enable debug msgs +options IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's +options IEEE80211_SUPPORT_MESH # enable 802.11s draft support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm +device an # Aironet 4500/4800 802.11 wireless NICs. +device ath # Atheros NICs +device ath_pci # Atheros pci/cardbus glue +device ath_hal # pci/cardbus chip support +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_AR5416_INTERRUPT_MITIGATION # AR5416 interrupt mitigation +options ATH_ENABLE_11N # Enable 802.11n support for AR5416 and later +device ath_rate_sample # SampleRate tx rate control for ath +#device bwi # Broadcom BCM430x/BCM431x wireless NICs. +#device bwn # Broadcom BCM43xx wireless NICs. +device ipw # Intel 2100 wireless NICs. +device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. +device iwn # Intel 4965/1000/5000/6000 wireless NICs. +device malo # Marvell Libertas wireless NICs. +device mwl # Marvell 88W8363 802.11n wireless NICs. +device ral # Ralink Technology RT2500 wireless NICs. +device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. +device wpi # Intel 3945ABG wireless NICs. + +# Pseudo devices. +device loop # Network loopback +device random # Entropy device +device padlock_rng # VIA Padlock RNG +device rdrand_rng # Intel Bull Mountain RNG +device ether # Ethernet support +device vlan # 802.1Q VLAN support +device tun # Packet tunnel. +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) +device firmware # firmware assist module + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +# Note that 'bpf' is required for DHCP. +device bpf # Berkeley packet filter + +# USB support +options USB_DEBUG # enable debug msgs +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device ehci # EHCI PCI->USB interface (USB 2.0) +device xhci # XHCI PCI->USB interface (USB 3.0) +device usb # USB Bus (required) +device ukbd # Keyboard +device umass # Disks/Mass storage - Requires scbus and da +device ums +device ukbd + +# Sound support +device sound # Generic sound driver (required) +device snd_cmi # CMedia CMI8338/CMI8738 +device snd_csa # Crystal Semiconductor CS461x/428x +device snd_emu10kx # Creative SoundBlaster Live! and Audigy +device snd_es137x # Ensoniq AudioPCI ES137x +device snd_hda # Intel High Definition Audio +device snd_ich # Intel, NVidia and other ICH AC'97 Audio +device snd_via8233 # VIA VT8233x Audio + +# MMC/SD +device mmc # MMC/SD bus +device mmcsd # MMC/SD memory card +device sdhci # Generic PCI SD Host Controller + +# VirtIO support +device virtio # Generic VirtIO bus (required) +device virtio_pci # VirtIO PCI device +device vtnet # VirtIO Ethernet device +device virtio_blk # VirtIO Block device +device virtio_scsi # VirtIO SCSI device +device virtio_balloon # VirtIO Memory Balloon device + +# HyperV drivers +device hyperv # HyperV drivers + +# Xen HVM Guest Optimizations +# NOTE: XENHVM depends on xenpci. They must be added or removed together. +options XENHVM # Xen HVM kernel infrastructure +device xenpci # Xen HVM Hypervisor services driver + +# VMware support +device vmx # VMware VMXNET3 Ethernet + Modified: user/jceel/soc2014_evdev/head/sys/conf/files ============================================================================== --- user/jceel/soc2014_evdev/head/sys/conf/files Sun May 18 17:46:48 2014 (r266412) +++ user/jceel/soc2014_evdev/head/sys/conf/files Sun May 18 17:58:33 2014 (r266413) @@ -1361,6 +1361,8 @@ dev/etherswitch/mdio.c optional miipro dev/etherswitch/miiproxy.c optional miiproxy dev/etherswitch/rtl8366/rtl8366rb.c optional rtl8366rb dev/etherswitch/ukswitch/ukswitch.c optional ukswitch +dev/evdev/evdev.c optional evdev +dev/evdev/cdev.c optional evdev dev/ex/if_ex.c optional ex dev/ex/if_ex_isa.c optional ex isa dev/ex/if_ex_pccard.c optional ex pccard Modified: user/jceel/soc2014_evdev/head/sys/conf/options ============================================================================== --- user/jceel/soc2014_evdev/head/sys/conf/options Sun May 18 17:46:48 2014 (r266412) +++ user/jceel/soc2014_evdev/head/sys/conf/options Sun May 18 17:58:33 2014 (r266413) @@ -918,3 +918,6 @@ RANDOM_YARROW opt_random.h RANDOM_FORTUNA opt_random.h RANDOM_DEBUG opt_random.h RANDOM_RWFILE opt_random.h + +# evdev protocol support +EVDEV opt_evdev.h Added: user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/cdev.c Sun May 18 17:58:33 2014 (r266413) @@ -0,0 +1,461 @@ +/*- + * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/conf.h> +#include <sys/uio.h> +#include <sys/proc.h> +#include <sys/poll.h> +#include <sys/selinfo.h> +#include <sys/malloc.h> + +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> + +#define DEBUG +#ifdef DEBUG +#define debugf(fmt, args...) printf("evdev: " fmt "\n", ##args); +#else +#define debugf(fmt, args...) +#endif + +#define IOCNUM(x) (x & 0xff) + +static int evdev_open(struct cdev *, int, int, struct thread *); +static int evdev_close(struct cdev *, int, int, struct thread *); +static int evdev_read(struct cdev *, struct uio *, int); +static int evdev_write(struct cdev *, struct uio *, int); +static int evdev_ioctl(struct cdev *, u_long, caddr_t, int, struct thread *); +static int evdev_poll(struct cdev *, int, struct thread *); +static int evdev_kqfilter(struct cdev *, struct knote *); +static int evdev_kqread(struct knote *kn, long hint); +static void evdev_kqdetach(struct knote *kn); +static void evdev_dtor(void *); + +static void evdev_notify_event(struct evdev_client *, void *); +static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t); + +static struct cdevsw evdev_cdevsw = { + .d_version = D_VERSION, + .d_open = evdev_open, + .d_close = evdev_close, + .d_read = evdev_read, + .d_write = evdev_write, + .d_ioctl = evdev_ioctl, + .d_poll = evdev_poll, + .d_kqfilter = evdev_kqfilter, + .d_name = "evdev", +}; + +static struct filterops evdev_cdev_filterops = { + .f_isfd = 1, + .f_attach = NULL, + .f_detach = evdev_kqdetach, + .f_event = evdev_kqread, +}; + +struct evdev_cdev_softc +{ + struct evdev_dev * ecs_evdev; + int ecs_open_count; + + LIST_ENTRY(evdev_cdev_softc) ecs_link; +}; + +struct evdev_cdev_state +{ + struct mtx ecs_mtx; + struct evdev_client * ecs_client; + struct selinfo ecs_selp; + struct sigio * ecs_sigio; +}; + +static int evdev_cdev_count = 0; + +static int +evdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct evdev_cdev_softc *sc = dev->si_drv1; + struct evdev_cdev_state *state; + int ret; + + state = malloc(sizeof(struct evdev_cdev_state), M_EVDEV, M_WAITOK | M_ZERO); + + ret = evdev_register_client(sc->ecs_evdev, &state->ecs_client); + if (ret != 0) { + debugf("cdev: cannot register evdev client"); + return (ret); + } + + state->ecs_client->ec_ev_notify = &evdev_notify_event; + state->ecs_client->ec_ev_arg = state; + + knlist_init_mtx(&state->ecs_selp.si_note, NULL); + + sc->ecs_open_count++; + devfs_set_cdevpriv(state, evdev_dtor); + return (0); +} + +static int +evdev_close(struct cdev *dev, int fflag, int devtype, struct thread *td) +{ + struct evdev_cdev_softc *sc = dev->si_drv1; + + sc->ecs_open_count--; + return (0); +} + +static void +evdev_dtor(void *data) +{ + struct evdev_cdev_state *state = (struct evdev_cdev_state *)data; + + seldrain(&state->ecs_selp); + evdev_dispose_client(state->ecs_client); + free(data, M_EVDEV); +} + +static int +evdev_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct evdev_cdev_state *state; + struct evdev_client *client; + struct input_event *event; + int ret = 0; + int remaining; + + debugf("cdev: read %ld bytes by thread %d", uio->uio_resid, + uio->uio_td->td_tid); + + ret = devfs_get_cdevpriv((void **)&state); + if (ret != 0) + return (ret); + + client = state->ecs_client; + + if (uio->uio_resid % sizeof(struct input_event) != 0) { + debugf("read size not multiple of struct input_event size"); + return (EINVAL); + } + + remaining = uio->uio_resid / sizeof(struct input_event); + + EVDEV_CLIENT_LOCKQ(client); + + if (EVDEV_CLIENT_EMPTYQ(client)) + mtx_sleep(client, &client->ec_buffer_mtx, 0, "evrea", 0); + + for (;;) { + if (EVDEV_CLIENT_EMPTYQ(client)) + /* Short read :-( */ + break; + + event = &client->ec_buffer[client->ec_buffer_head]; + client->ec_buffer_head = (client->ec_buffer_head + 1) % client->ec_buffer_size; + remaining--; + + EVDEV_CLIENT_UNLOCKQ(client); + uiomove(event, sizeof(struct input_event), uio); + EVDEV_CLIENT_LOCKQ(client); + + if (remaining == 0) + break; + } + + EVDEV_CLIENT_UNLOCKQ(client); + + return (0); +} + +static int +evdev_write(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct evdev_cdev_state *state; + int ret = 0; + + debugf("cdev: write %ld bytes by thread %d", uio->uio_resid, + uio->uio_td->td_tid); + + ret = devfs_get_cdevpriv((void **)&state); + if (ret != 0) + return (ret); + + if (uio->uio_resid % sizeof(struct input_event) != 0) { + debugf("write size not multiple of struct input_event size"); + return (EINVAL); + } + + return (0); +} + +static int +evdev_poll(struct cdev *dev, int events, struct thread *td) +{ + struct evdev_client *client; + struct evdev_cdev_state *state; + int ret; + int revents = 0; + + debugf("cdev: poll by thread %d", td->td_tid); + + ret = devfs_get_cdevpriv((void **)&state); + if (ret != 0) + return (ret); + + client = state->ecs_client; + + if (events & (POLLIN | POLLRDNORM)) { + EVDEV_CLIENT_LOCKQ(client); + if (!EVDEV_CLIENT_EMPTYQ(client)) + revents = events & (POLLIN | POLLRDNORM); + else + selrecord(td, &state->ecs_selp); + EVDEV_CLIENT_UNLOCKQ(client); + } + + return (revents); +} + +static int +evdev_kqfilter(struct cdev *dev, struct knote *kn) +{ + struct evdev_cdev_state *state; + int ret; + + ret = devfs_get_cdevpriv((void **)&state); + if (ret != 0) + return (ret); + + kn->kn_hook = (caddr_t)state; + kn->kn_fop = &evdev_cdev_filterops; + + knlist_add(&state->ecs_selp.si_note, kn, 0); + return (0); +} + +static int +evdev_kqread(struct knote *kn, long hint) +{ + struct evdev_client *client; + struct evdev_cdev_state *state; + int ret; + + state = (struct evdev_cdev_state *)kn->kn_hook; + client = state->ecs_client; + + EVDEV_CLIENT_LOCKQ(client); + ret = !EVDEV_CLIENT_EMPTYQ(client); + EVDEV_CLIENT_UNLOCKQ(client); + return (ret); +} + +static void +evdev_kqdetach(struct knote *kn) +{ + struct evdev_cdev_state *state; + + state = (struct evdev_cdev_state *)kn->kn_hook; + knlist_remove(&state->ecs_selp.si_note, kn, 0); +} + +static int +evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + struct evdev_cdev_softc *sc = dev->si_drv1; + struct evdev_dev *evdev = sc->ecs_evdev; + int len, num; + + len = IOCPARM_LEN(cmd); + cmd = IOCBASECMD(cmd); + num = IOCNUM(cmd); + + debugf("cdev: ioctl called: cmd=0x%08lx, data=%p", cmd, data); + + switch (cmd) { + case EVIOCGVERSION: + data = (caddr_t)EV_VERSION; + break; + + case EVIOCGID: + break; + + case EVIOCGREP: + break; + + case EVIOCSREP: + break; + + case EVIOCGKEYCODE: + break; + + case EVIOCGKEYCODE_V2: + break; + + case EVIOCSKEYCODE: + break; + + case EVIOCSKEYCODE_V2: + break; + + case EVIOCGNAME(0): + debugf("EVIOCGNAME: data=%p, ev_name=%s, len=%d", data, evdev->ev_name, len); + strlcpy(data, evdev->ev_name, len); + break; + + case EVIOCGPHYS(0): + strlcpy(data, evdev->ev_shortname, len); + break; + + case EVIOCGUNIQ(0): + strlcpy(data, evdev->ev_serial, len); + break; + + case EVIOCGPROP(0): + memcpy(data, evdev->ev_type_flags, len); + break; + + case EVIOCGKEY(0): + memcpy(data, evdev->ev_key_flags, len); + break; + + case EVIOCGLED(0): + break; + + case EVIOCGSND(0): + break; + + case EVIOCGSW(0): + break; + } + + if (IOCGROUP(cmd) != 'E') + return (EINVAL); + + /* Handle EVIOCGBIT variants */ + if (num >= IOCNUM(EVIOCGBIT(0, 0)) && + num < IOCNUM(EVIOCGBIT(EV_MAX, 0))) { + int type_num = num - IOCNUM(EVIOCGBIT(0, 0)); + debugf("cdev: EVIOCGBIT(%d): data=%p, len=%d", type_num, data, len); + return (evdev_ioctl_eviocgbit(evdev, type_num, len, data)); + } + + return (0); +} + +static int +evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) +{ + uint32_t *bitmap; + int limit; + + switch (type) { + case 0: + bitmap = evdev->ev_type_flags; + limit = EV_CNT; + break; + case EV_KEY: + bitmap = evdev->ev_key_flags; + limit = KEY_CNT; + break; + case EV_REL: + bitmap = evdev->ev_rel_flags; + limit = REL_CNT; + break; + case EV_ABS: + bitmap = evdev->ev_abs_flags; + limit = ABS_CNT; + break; + case EV_MSC: + bitmap = evdev->ev_msc_flags; + limit = MSC_CNT; + break; + case EV_LED: + bitmap = evdev->ev_led_flags; + limit = LED_CNT; + break; + case EV_SND: + bitmap = evdev->ev_snd_flags; + limit = SND_CNT; + break; + case EV_SW: + bitmap = evdev->ev_sw_flags; + limit = SW_CNT; + break; + + default: + return (ENOTTY); + } + + /* + * Clear ioctl data buffer in case it's bigger than + * bitmap size + */ + bzero(data, len); + + limit = howmany(limit, 8); + len = MIN(limit, len); + memcpy(data, bitmap, len); + return (0); +} + +static void +evdev_notify_event(struct evdev_client *client, void *data) +{ + struct evdev_cdev_state *state = (struct evdev_cdev_state *)data; + + selwakeup(&state->ecs_selp); +} + +int +evdev_cdev_create(struct evdev_dev *evdev) +{ + struct evdev_cdev_softc *sc; + struct cdev *cdev; + + cdev = make_dev(&evdev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + "input/event%d", evdev_cdev_count++); + + sc = malloc(sizeof(struct evdev_cdev_softc), M_EVDEV, M_WAITOK | M_ZERO); + + sc->ecs_evdev = evdev; + evdev->ev_cdev = cdev; + cdev->si_drv1 = sc; + return (0); +} + +int +evdev_cdev_destroy(struct evdev_dev *evdev) +{ + destroy_dev(evdev->ev_cdev); + return (0); +} Added: user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/jceel/soc2014_evdev/head/sys/dev/evdev/evdev.c Sun May 18 17:58:33 2014 (r266413) @@ -0,0 +1,284 @@ +/*- + * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/conf.h> +#include <sys/malloc.h> + +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> + +#define DEBUG +#ifdef DEBUG +#define debugf(fmt, args...) printf("evdev: " fmt "\n", ##args) +#else +#define debugf(fmt, args...) +#endif + +MALLOC_DEFINE(M_EVDEV, "evdev", "evdev memory"); + +static struct evdev_client *evdev_client_alloc(void); +static void evdev_client_push(struct evdev_client *, uint16_t, uint16_t, + int32_t); + +struct evdev_dev * +evdev_alloc(void) +{ + return malloc(sizeof(struct evdev_dev), M_EVDEV, M_WAITOK | M_ZERO); +} + +int +evdev_register(device_t dev, struct evdev_dev *evdev) +{ + int ret; + + device_printf(dev, "registered evdev provider: %s <%s>\n", + evdev->ev_name, evdev->ev_serial); + + /* Initialize internal structures */ + evdev->ev_dev = dev; + strlcpy(evdev->ev_shortname, device_get_nameunit(dev), NAMELEN); + LIST_INIT(&evdev->ev_clients); + + /* Create char device node */ + ret = evdev_cdev_create(evdev); + if (ret != 0) + return (ret); + + return (0); +} + +int +evdev_unregister(device_t dev, struct evdev_dev *evdev) +{ + int ret; + device_printf(dev, "unregistered evdev provider: %s\n", evdev->ev_name); + + ret = evdev_cdev_destroy(evdev); + if (ret != 0) + return (ret); + + return (0); +} + +inline void +evdev_set_name(struct evdev_dev *evdev, const char *name) +{ + snprintf(evdev->ev_name, NAMELEN, "%s", name); +} + +inline void +evdev_set_serial(struct evdev_dev *evdev, const char *serial) +{ + snprintf(evdev->ev_serial, NAMELEN, "%s", serial); +} + +inline void +evdev_set_methods(struct evdev_dev *evdev, struct evdev_methods *methods) +{ + evdev->ev_methods = methods; +} + +inline void +evdev_set_softc(struct evdev_dev *evdev, void *softc) +{ + evdev->ev_softc = softc; +} + +inline void +evdev_support_event(struct evdev_dev *evdev, uint16_t type) +{ + + setbit(&evdev->ev_type_flags, type); +} + +inline void +evdev_support_key(struct evdev_dev *evdev, uint16_t code) +{ + + setbit(&evdev->ev_key_flags, code); +} + +inline void +evdev_support_rel(struct evdev_dev *evdev, uint16_t code) +{ + + setbit(&evdev->ev_rel_flags, code); +} + +inline void +evdev_support_abs(struct evdev_dev *evdev, uint16_t code) +{ + + setbit(&evdev->ev_abs_flags, code); +} + + +inline void +evdev_support_msc(struct evdev_dev *evdev, uint16_t code) +{ + + setbit(&evdev->ev_msc_flags, code); +} + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405181758.s4IHwXgH074987>