# This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # uartlirc/ # uartlirc/Makefile # uartlirc/export_syms # uartlirc/lirc.h # uartlirc/uartlirc.h # uartlirc/uartlirc_bus.h # uartlirc/uartlirc_bus_acpi.c # uartlirc/uartlirc_bus_ebus.c # uartlirc/uartlirc_bus_fdt.c # uartlirc/uartlirc_bus_isa.c # uartlirc/uartlirc_bus_pccard.c # uartlirc/uartlirc_bus_pci.c # uartlirc/uartlirc_bus_puc.c # uartlirc/uartlirc_bus_scc.c # uartlirc/uartlirc_core.c # uartlirc/uartlirc_cpu.h # uartlirc/uartlirc_cpu_amd64.c # uartlirc/uartlirc_cpu_i386.c # uartlirc/uartlirc_cpu_ia64.c # uartlirc/uartlirc_cpu_pc98.c # uartlirc/uartlirc_cpu_powerpc.c # uartlirc/uartlirc_cpu_sparc64.c # uartlirc/uartlirc_dbg.c # uartlirc/uartlirc_dev_ns8250.c # uartlirc/uartlirc_dev_quicc.c # uartlirc/uartlirc_dev_sab82532.c # uartlirc/uartlirc_dev_z8530.c # uartlirc/uartlirc_if.m # uartlirc/uartlirc_kbd_sun.c # uartlirc/uartlirc_kbd_sun.h # uartlirc/uartlirc_kbd_sun_tables.h # uartlirc/uartlirc_lircdev.c # uartlirc/uartlirc_lircdev.h # uartlirc/uartlirc_subr.c # uartlirc/uartlirc_tty.c # echo c - uartlirc/ mkdir -p uartlirc/ > /dev/null 2>&1 echo x - uartlirc/Makefile sed 's/^X//' >uartlirc/Makefile << 'ab2822d0eee1d9c733b44d001e3d6044' X# $FreeBSD: src/sys/modules/uart/Makefile,v 1.21.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X X#.PATH: ${.CURDIR}/../../dev/uart X X#.if ${MACHINE_CPUARCH} == "sparc64" X#uartlirc_bus_ebus= uartlirc_bus_ebus.c X#ofw_bus_if= ofw_bus_if.h X#.endif X XKMOD= uartlirc XSRCS= uartlirc_bus_acpi.c ${uartlirc_bus_ebus} uartlirc_bus_isa.c uartlirc_bus_pccard.c \ X uartlirc_bus_pci.c uartlirc_bus_puc.c uartlirc_bus_scc.c \ X uartlirc_core.c uartlirc_dbg.c \ X uartlirc_dev_ns8250.c uartlirc_dev_quicc.c uartlirc_dev_sab82532.c \ X uartlirc_dev_z8530.c \ X uartlirc_if.c uartlirc_if.h uartlirc_subr.c uartlirc_tty.c \ X uartlirc_lircdev.c X.if exists(${.CURDIR}/uartlirc_cpu_${MACHINE}.c) XSRCS+= uartlirc_cpu_${MACHINE}.c X.endif XSRCS+= bus_if.h card_if.h device_if.h isa_if.h ${ofw_bus_if} pci_if.h \ X power_if.h pccarddevs.h serdev_if.h X XMFILES= dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \ X dev/ofw/ofw_bus_if.m isa/isa_if.m kern/bus_if.m \ X kern/device_if.m kern/serdev_if.m X Xuartlirc_if.h: uartlirc_if.m X ${AWK} -f @/tools/makeobjops.awk uartlirc_if.m -h X Xuartlirc_if.c: uartlirc_if.m X ${AWK} -f @/tools/makeobjops.awk uartlirc_if.m -c X Xdevuart: X mkdir -p uart X for i in *.[chm]; do \ X sed -e '/uartlirc.ko/n' \ X -e 's/uartlirc/uart/g' \ X -e 's/UARTLIRC/UART/g' \ X -e '/#include "uart_if.h"/n' \ X -e 's/#include "\(uart.*h\)"/#include /' \ X <$$i >uart/$$(echo $$i |sed s/uartlirc/uart/); \ X done X Xclean: X @-rm -r uart @ machine x86 *.bak *.o *.ko* *_if.[ch] pccarddevs.h X X.include ab2822d0eee1d9c733b44d001e3d6044 echo x - uartlirc/export_syms sed 's/^X//' >uartlirc/export_syms << 'b370a01c2823c2482b28edaeae15c82d' b370a01c2823c2482b28edaeae15c82d echo x - uartlirc/lirc.h sed 's/^X//' >uartlirc/lirc.h << 'a9cd28c8467d3d76a83c2bef80c6604a' X/* X * lirc.h - linux infrared remote control header file X * last modified 2010/06/03 by Jarod Wilson X */ X X#ifndef _LINUX_LIRC_H X#define _LINUX_LIRC_H X X#if defined(__linux__) X#include X#include X#elif defined(_NetBSD_) || defined(__FreeBSD__) X#if !_KERNEL X#include X#endif X#elif defined(_CYGWIN_) X#define __USE_LINUX_IOCTL_DEFS X#include X#endif X#ifndef __linux__ X#if _KERNEL X#include X#else X#include X#endif X#define __u32 uint32_t X#define __u64 uint64_t X#endif X X#define PULSE_BIT 0x01000000 X#define PULSE_MASK 0x00FFFFFF X X#define LIRC_MODE2_SPACE 0x00000000 X#define LIRC_MODE2_PULSE 0x01000000 X#define LIRC_MODE2_FREQUENCY 0x02000000 X#define LIRC_MODE2_TIMEOUT 0x03000000 X X#define LIRC_VALUE_MASK 0x00FFFFFF X#define LIRC_MODE2_MASK 0xFF000000 X X#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) X#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) X#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) X#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) X X#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) X#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) X X#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) X#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) X#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) X#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) X X#define lirc_t int X X/*** lirc compatible hardware features ***/ X X#define LIRC_MODE2SEND(x) (x) X#define LIRC_SEND2MODE(x) (x) X#define LIRC_MODE2REC(x) ((x) << 16) X#define LIRC_REC2MODE(x) ((x) >> 16) X X#define LIRC_MODE_RAW 0x00000001 X#define LIRC_MODE_PULSE 0x00000002 X#define LIRC_MODE_MODE2 0x00000004 X#define LIRC_MODE_LIRCCODE 0x00000010 X X X#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) X#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) X#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) X#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) X X#define LIRC_CAN_SEND_MASK 0x0000003f X X#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 X#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 X#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 X X#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) X#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) X#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) X#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) X X#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) X X#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) X#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) X X#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 X#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 X#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 X#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 X#define LIRC_CAN_SET_REC_FILTER 0x08000000 X X#define LIRC_CAN_MEASURE_CARRIER 0x02000000 X X#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) X#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) X X#define LIRC_CAN_NOTIFY_DECODE 0x01000000 X X/*** IOCTL commands for lirc driver ***/ X X#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) X X#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) X#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) X#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) X#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) X#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) X#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) X#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) X X#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32) X#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32) X X#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32) X#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32) X#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32) X#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32) X X/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ X#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) X X#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) X#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) X/* Note: these can reset the according pulse_width */ X#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) X#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) X#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) X#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) X#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) X X/* X * when a timeout != 0 is set the driver will send a X * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is X * never sent, timeout is disabled by default X */ X#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32) X X/* 1 enables, 0 disables timeout reports in MODE2 */ X#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32) X X/* X * pulses shorter than this are filtered out by hardware (software X * emulation in lirc_dev?) X */ X#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32) X/* X * spaces shorter than this are filtered out by hardware (software X * emulation in lirc_dev?) X */ X#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) X/* X * if filter cannot be set independantly for pulse/space, this should X * be used X */ X#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) X X/* X * if enabled from the next key press on the driver will send X * LIRC_MODE2_FREQUENCY packets X */ X#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) X X/* X * to set a range use X * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the X * lower bound first and later X * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound X */ X X#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) X#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) X X#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) X X#define LIRC_SETUP_START _IO('i', 0x00000021) X#define LIRC_SETUP_END _IO('i', 0x00000022) X X#endif a9cd28c8467d3d76a83c2bef80c6604a echo x - uartlirc/uartlirc.h sed 's/^X//' >uartlirc/uartlirc.h << 'e6e486cb2b61fd32477c2aeea7c95c60' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X * X * $FreeBSD: src/sys/dev/uart/uart.h,v 1.10.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X */ X X#ifndef _DEV_UARTLIRC_H_ X#define _DEV_UARTLIRC_H_ X X/* X * Bus access structure. This structure holds the minimum information needed X * to access the UART. The rclk field, although not important to actually X * access the UART, is important for baudrate programming, delay loops and X * other timing related computations. X */ Xstruct uartlirc_bas { X bus_space_tag_t bst; X bus_space_handle_t bsh; X u_int chan; X u_int rclk; X u_int regshft; X}; X X#define uartlirc_regofs(bas, reg) ((reg) << (bas)->regshft) X X#define uartlirc_getreg(bas, reg) \ X bus_space_read_1((bas)->bst, (bas)->bsh, uartlirc_regofs(bas, reg)) X#define uartlirc_setreg(bas, reg, value) \ X bus_space_write_1((bas)->bst, (bas)->bsh, uartlirc_regofs(bas, reg), value) X X/* X * XXX we don't know the length of the bus space address range in use by X * the UART. Since barriers don't use the length field currently, we put X * a zero there for now. X */ X#define uartlirc_barrier(bas) \ X bus_space_barrier((bas)->bst, (bas)->bsh, 0, 0, \ X BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) X X/* X * UART device classes. X */ Xstruct uartlirc_class; X Xextern struct uartlirc_class uartlirc_ns8250_class __attribute__((weak)); Xextern struct uartlirc_class uartlirc_quicc_class __attribute__((weak)); Xextern struct uartlirc_class uartlirc_sab82532_class __attribute__((weak)); Xextern struct uartlirc_class uartlirc_sbbc_class __attribute__((weak)); Xextern struct uartlirc_class uartlirc_z8530_class __attribute__((weak)); X X#ifdef PC98 Xstruct uartlirc_class *uartlirc_pc98_getdev(u_long port); X#endif X X/* X * Device flags. X */ X#define UARTLIRC_FLAGS_CONSOLE(f) ((f) & 0x10) X#define UARTLIRC_FLAGS_DBGPORT(f) ((f) & 0x80) X#define UARTLIRC_FLAGS_FCR_RX_LOW(f) ((f) & 0x100) X#define UARTLIRC_FLAGS_FCR_RX_MEDL(f) ((f) & 0x200) X#define UARTLIRC_FLAGS_FCR_RX_MEDH(f) ((f) & 0x400) X#define UARTLIRC_FLAGS_FCR_RX_HIGH(f) ((f) & 0x800) X X/* X * Data parity values (magical numbers related to ns8250). X */ X#define UARTLIRC_PARITY_NONE 0 X#define UARTLIRC_PARITY_ODD 1 X#define UARTLIRC_PARITY_EVEN 3 X#define UARTLIRC_PARITY_MARK 5 X#define UARTLIRC_PARITY_SPACE 7 X X#endif /* _DEV_UARTLIRC_H_ */ e6e486cb2b61fd32477c2aeea7c95c60 echo x - uartlirc/uartlirc_bus.h sed 's/^X//' >uartlirc/uartlirc_bus.h << '7d7fb9204ccc8bc3e7f7f06c52c48f2d' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X * X * $FreeBSD: src/sys/dev/uart/uartlirc_bus.h,v 1.16.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X */ X X#ifndef _DEV_UARTLIRC_BUS_H_ X#define _DEV_UARTLIRC_BUS_H_ X X#ifndef KLD_MODULE X#include "opt_uartlirc.h" X#endif X X#include X#include X#include X#include X#include X X/* Drain and flush targets. */ X#define UARTLIRC_DRAIN_RECEIVER 0x0001 X#define UARTLIRC_DRAIN_TRANSMITTER 0x0002 X#define UARTLIRC_FLUSH_RECEIVER UARTLIRC_DRAIN_RECEIVER X#define UARTLIRC_FLUSH_TRANSMITTER UARTLIRC_DRAIN_TRANSMITTER X X/* Received character status bits. */ X#define UARTLIRC_STAT_BREAK 0x0100 X#define UARTLIRC_STAT_FRAMERR 0x0200 X#define UARTLIRC_STAT_OVERRUN 0x0400 X#define UARTLIRC_STAT_PARERR 0x0800 X X#ifdef UARTLIRC_PPS_ON_CTS X#define UARTLIRC_SIG_DPPS SER_DCTS X#define UARTLIRC_SIG_PPS SER_CTS X#else X#define UARTLIRC_SIG_DPPS SER_DDCD X#define UARTLIRC_SIG_PPS SER_DCD X#endif X X/* UARTLIRC_IOCTL() requests */ X#define UARTLIRC_IOCTL_BREAK 1 X#define UARTLIRC_IOCTL_IFLOW 2 X#define UARTLIRC_IOCTL_OFLOW 3 X#define UARTLIRC_IOCTL_BAUD 4 X X/* X * UART class & instance (=softc) X */ Xstruct uartlirc_class { X KOBJ_CLASS_FIELDS; X struct uartlirc_ops *uc_ops; /* Low-level console operations. */ X u_int uc_range; /* Bus space address range. */ X u_int uc_rclk; /* Default rclk for this device. */ X}; X Xstruct uartlirc_softc { X KOBJ_FIELDS; X struct uartlirc_class *sc_class; X struct uartlirc_bas sc_bas; X device_t sc_dev; X X struct mtx sc_hwmtx_s; /* Spinlock protecting hardware. */ X struct mtx *sc_hwmtx; X X struct resource *sc_rres; /* Register resource. */ X int sc_rrid; X int sc_rtype; /* SYS_RES_{IOPORT|MEMORY}. */ X struct resource *sc_ires; /* Interrupt resource. */ X void *sc_icookie; X int sc_irid; X struct callout sc_timer; X X int sc_callout:1; /* This UART is opened for callout. */ X int sc_fastintr:1; /* This UART uses fast interrupts. */ X int sc_hwiflow:1; /* This UART has HW input flow ctl. */ X int sc_hwoflow:1; /* This UART has HW output flow ctl. */ X int sc_leaving:1; /* This UART is going away. */ X int sc_opened:1; /* This UART is open for business. */ X int sc_polled:1; /* This UART has no interrupts. */ X int sc_txbusy:1; /* This UART is transmitting. */ X int sc_isquelch:1; /* This UART has input squelched. */ X X struct uartlirc_devinfo *sc_sysdev; /* System device (or NULL). */ X X int sc_altbrk; /* State for alt break sequence. */ X uint32_t sc_hwsig; /* Signal state. Used by HW driver. */ X X /* Receiver data. */ X uint16_t *sc_rxbuf; X int sc_rxbufsz; X int sc_rxput; X int sc_rxget; X int sc_rxfifosz; /* Size of RX FIFO. */ X X /* Transmitter data. */ X uint8_t *sc_txbuf; X int sc_txdatasz; X int sc_txfifosz; /* Size of TX FIFO and buffer. */ X X /* Pulse capturing support (PPS). */ X struct pps_state sc_pps; X X /* Upper layer data. */ X void *sc_softih; X uint32_t sc_ttypend; X union { X /* TTY specific data. */ X struct { X struct tty *tp; X } u_tty; X /* Keyboard specific data. */ X struct { X } u_kbd; X } sc_u; X X /* lirc device node */ X struct cdev *sc_lirc_cdev; X struct mtx sc_lirc_lock; X int sc_lircstate; X int sc_lirc_sigxor; X /* lirc receiver fifo */ X struct buf_ring *sc_lirc_rcv_fifo; X struct mtx sc_lirc_rcv_fifo_lock; X struct selinfo sc_lirc_rsel; X /* time of last received lirc event */ X struct timeval sc_lirc_rcv_time; X uint32_t sc_lirc_lastevent; X}; X Xextern devclass_t uartlirc_devclass; Xextern char uartlirc_driver_name[]; X Xint uartlirc_bus_attach(device_t dev); Xint uartlirc_bus_detach(device_t dev); Xserdev_intr_t *uartlirc_bus_ihand(device_t dev, int ipend); Xint uartlirc_bus_ipend(device_t dev); Xint uartlirc_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan); Xint uartlirc_bus_sysdev(device_t dev); X Xvoid uartlirc_sched_softih(struct uartlirc_softc *, uint32_t); X Xint uartlirc_tty_attach(struct uartlirc_softc *); Xint uartlirc_tty_detach(struct uartlirc_softc *); Xvoid uartlirc_tty_intr(void *arg); X X/* X * Receive buffer operations. X */ Xstatic __inline int Xuartlirc_rx_empty(struct uartlirc_softc *sc) X{ X return ((sc->sc_rxget == sc->sc_rxput) ? 1 : 0); X} X Xstatic __inline int Xuartlirc_rx_full(struct uartlirc_softc *sc) X{ X return ((sc->sc_rxput + 1 < sc->sc_rxbufsz) X ? (sc->sc_rxput + 1 == sc->sc_rxget) : (sc->sc_rxget == 0)); X} X Xstatic __inline int Xuartlirc_rx_get(struct uartlirc_softc *sc) X{ X int ptr, xc; X X ptr = sc->sc_rxget; X if (ptr == sc->sc_rxput) X return (-1); X xc = sc->sc_rxbuf[ptr++]; X sc->sc_rxget = (ptr < sc->sc_rxbufsz) ? ptr : 0; X return (xc); X} X Xstatic __inline int Xuartlirc_rx_next(struct uartlirc_softc *sc) X{ X int ptr; X X ptr = sc->sc_rxget; X if (ptr == sc->sc_rxput) X return (-1); X ptr += 1; X sc->sc_rxget = (ptr < sc->sc_rxbufsz) ? ptr : 0; X return (0); X} X Xstatic __inline int Xuartlirc_rx_peek(struct uartlirc_softc *sc) X{ X int ptr; X X ptr = sc->sc_rxget; X return ((ptr == sc->sc_rxput) ? -1 : sc->sc_rxbuf[ptr]); X} X Xstatic __inline int Xuartlirc_rx_put(struct uartlirc_softc *sc, int xc) X{ X int ptr; X X ptr = (sc->sc_rxput + 1 < sc->sc_rxbufsz) ? sc->sc_rxput + 1 : 0; X if (ptr == sc->sc_rxget) X return (ENOSPC); X sc->sc_rxbuf[sc->sc_rxput] = xc; X sc->sc_rxput = ptr; X return (0); X} X X#endif /* _DEV_UARTLIRC_BUS_H_ */ 7d7fb9204ccc8bc3e7f7f06c52c48f2d echo x - uartlirc/uartlirc_bus_acpi.c sed 's/^X//' >uartlirc/uartlirc_bus_acpi.c << 'eb78b35c639b7d1abd076681ddd6922e' X/*- X * Copyright (c) 2001 M. Warner Losh. All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_acpi.c,v 1.4.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X Xstatic int uartlirc_acpi_probe(device_t dev); X Xstatic device_method_t uartlirc_acpi_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_acpi_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X { 0, 0 } X}; X Xstatic driver_t uartlirc_acpi_driver = { X uartlirc_driver_name, X uartlirc_acpi_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic struct isa_pnp_id acpi_ns8250_ids[] = { X {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ X {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ X {0x04f0235c, "Wacom Tablet PC Screen"}, /* WACF004 */ X {0} X}; X Xstatic int Xuartlirc_acpi_probe(device_t dev) X{ X struct uartlirc_softc *sc; X device_t parent; X X parent = device_get_parent(dev); X sc = device_get_softc(dev); X X if (!ISA_PNP_PROBE(parent, dev, acpi_ns8250_ids)) { X sc->sc_class = &uartlirc_ns8250_class; X return (uartlirc_bus_probe(dev, 0, 0, 0, 0)); X } X X /* Add checks for non-ns8250 IDs here. */ X return (ENXIO); X} X XDRIVER_MODULE(uartlirc, acpi, uartlirc_acpi_driver, uartlirc_devclass, 0, 0); eb78b35c639b7d1abd076681ddd6922e echo x - uartlirc/uartlirc_bus_ebus.c sed 's/^X//' >uartlirc/uartlirc_bus_ebus.c << '43432ed31a42ce76bd2ab86186bbc6cb' X/*- X * Copyright (c) 2001 by Thomas Moestl . X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, X * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES X * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR X * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER X * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_ebus.c,v 1.13.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X X#include X X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X Xstatic int uartlirc_ebus_probe(device_t dev); X Xstatic device_method_t uartlirc_ebus_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_ebus_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X { 0, 0 } X}; X Xstatic driver_t uartlirc_ebus_driver = { X uartlirc_driver_name, X uartlirc_ebus_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic int Xuartlirc_ebus_probe(device_t dev) X{ X const char *nm, *cmpt; X struct uartlirc_softc *sc; X struct uartlirc_devinfo dummy; X X sc = device_get_softc(dev); X sc->sc_class = NULL; X X nm = ofw_bus_get_name(dev); X cmpt = ofw_bus_get_compat(dev); X if (cmpt == NULL) X cmpt = ""; X if (!strcmp(nm, "lom-console") || !strcmp(nm, "su") || X !strcmp(nm, "su_pnp") || !strcmp(cmpt, "rsc-console") || X !strcmp(cmpt, "rsc-control") || !strcmp(cmpt, "su") || X !strcmp(cmpt, "su16550") || !strcmp(cmpt, "su16552")) { X /* X * On AXi and AXmp boards the NS16550 (used to connect X * keyboard/mouse) share their IRQ lines with the i8042. X * Any IRQ activity (typically during attach) of the X * NS16550 used to connect the keyboard when actually the X * PS/2 keyboard is selected in OFW causes interaction X * with the OBP i8042 driver resulting in a hang and vice X * versa. As RS232 keyboards and mice obviously aren't X * meant to be used in parallel with PS/2 ones on these X * boards don't attach to the NS16550 in case the RS232 X * keyboard isn't selected in order to prevent such hangs. X */ X if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") || X !strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) && X uartlirc_cpu_getdev(UARTLIRC_DEV_KEYBOARD, &dummy)) { X device_disable(dev); X return (ENXIO); X } X sc->sc_class = &uartlirc_ns8250_class; X return (uartlirc_bus_probe(dev, 0, 0, 0, 0)); X } X X return (ENXIO); X} X XDRIVER_MODULE(uartlirc, ebus, uartlirc_ebus_driver, uartlirc_devclass, 0, 0); 43432ed31a42ce76bd2ab86186bbc6cb echo x - uartlirc/uartlirc_bus_fdt.c sed 's/^X//' >uartlirc/uartlirc_bus_fdt.c << 'fa7de9987ebb1b295ebb4f58b73cacb1' X/*- X * Copyright (c) 2009-2010 The FreeBSD Foundation X * All rights reserved. X * X * This software was developed by Semihalf under sponsorship from X * the FreeBSD Foundation. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_fdt.c,v 1.3.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X X#include X#include X X#include X#include X#include X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X Xstatic int uartlirc_fdt_probe(device_t); X Xstatic device_method_t uartlirc_fdt_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_fdt_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X { 0, 0 } X}; X Xstatic driver_t uartlirc_fdt_driver = { X uartlirc_driver_name, X uartlirc_fdt_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic int Xuartlirc_fdt_get_clock(phandle_t node, pcell_t *cell) X{ X pcell_t clock; X X if ((OF_getprop(node, "clock-frequency", &clock, X sizeof(clock))) <= 0) X return (ENXIO); X X if (clock == 0) X /* Try to retrieve parent 'bus-frequency' */ X /* XXX this should go to simple-bus fixup or so */ X if ((OF_getprop(OF_parent(node), "bus-frequency", &clock, X sizeof(clock))) <= 0) X clock = 0; X X *cell = fdt32_to_cpu(clock); X return (0); X} X Xstatic int Xuartlirc_fdt_get_shift(phandle_t node, pcell_t *cell) X{ X pcell_t shift; X X if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0) X shift = 0; X *cell = fdt32_to_cpu(shift); X return (0); X} X Xstatic int Xuartlirc_fdt_probe(device_t dev) X{ X struct uartlirc_softc *sc; X phandle_t node; X pcell_t clock, shift; X int err; X X if (!ofw_bus_is_compatible(dev, "ns16550")) X return (ENXIO); X X sc = device_get_softc(dev); X sc->sc_class = &uartlirc_ns8250_class; X X node = ofw_bus_get_node(dev); X X if ((err = uartlirc_fdt_get_clock(node, &clock)) != 0) X return (err); X uartlirc_fdt_get_shift(node, &shift); X X return (uartlirc_bus_probe(dev, (int)shift, (int)clock, 0, 0)); X} X XDRIVER_MODULE(uartlirc, simplebus, uartlirc_fdt_driver, uartlirc_devclass, 0, 0); X X/* X * UART console routines. X */ Xbus_space_tag_t uartlirc_bus_space_io; Xbus_space_tag_t uartlirc_bus_space_mem; X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X char buf[64]; X struct uartlirc_class *class; X phandle_t node, chosen; X pcell_t shift, br, rclk; X u_long start, size; X int err; X X uartlirc_bus_space_mem = fdtbus_bs_tag; X uartlirc_bus_space_io = NULL; X X /* Allow overriding the FDT uning the environment. */ X class = &uartlirc_ns8250_class; X err = uartlirc_getenv(devtype, di, class); X if (!err) X return (0); X X if (devtype != UARTLIRC_DEV_CONSOLE) X return (ENXIO); X X /* X * Retrieve /chosen/std{in,out}. X */ X if ((chosen = OF_finddevice("/chosen")) == -1) X return (ENXIO); X if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0) X return (ENXIO); X if ((node = OF_finddevice(buf)) == -1) X return (ENXIO); X if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0) X return (ENXIO); X if (OF_finddevice(buf) != node) X /* Only stdin == stdout is supported. */ X return (ENXIO); X /* X * Retrieve serial attributes. X */ X uartlirc_fdt_get_shift(node, &shift); X X if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0) X br = 0; X br = fdt32_to_cpu(br); X X if ((err = uartlirc_fdt_get_clock(node, &rclk)) != 0) X return (err); X /* X * Finalize configuration. X */ X class = &uartlirc_quicc_class; X if (fdt_is_compatible(node, "ns16550")) X class = &uartlirc_ns8250_class; X X di->bas.chan = 0; X di->bas.regshft = (u_int)shift; X di->baudrate = br; X di->bas.rclk = (u_int)rclk; X di->ops = uartlirc_getops(class); X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X di->bas.bst = uartlirc_bus_space_mem; X X err = fdt_regsize(node, &start, &size); X if (err) X return (ENXIO); X start += fdt_immr_va; X X return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh)); X} fa7de9987ebb1b295ebb4f58b73cacb1 echo x - uartlirc/uartlirc_bus_isa.c sed 's/^X//' >uartlirc/uartlirc_bus_isa.c << '6bdcb989fcf03cd7a5678f8218e0b441' X/*- X * Copyright (c) 2008 TAKAHASHI Yoshihiro X * Copyright (c) 2008 Marcel Moolenaar X * Copyright (c) 2001 M. Warner Losh X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_isa.c,v 1.7.4.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X Xstatic int uartlirc_isa_probe(device_t dev); X Xstatic device_method_t uartlirc_isa_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_isa_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X { 0, 0 } X}; X Xstatic driver_t uartlirc_isa_driver = { X uartlirc_driver_name, X uartlirc_isa_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic struct isa_pnp_id isa_ns8250_ids[] = { X {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ X {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ X {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */ X {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */ X {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */ X /* Devices that do not have a compatid */ X {0x12206804, NULL}, /* ACH2012 - 5634BTS 56K Video Ready Modem */ X {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ X {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ X {0x21107905, NULL}, /* AKY1021 - 56K Plug&Play Modem */ X {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ X {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ X {0x56159008, NULL}, /* BDP1556 - B.D. Smart One 56SPS,Voice Modem*/ X {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ X {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ X {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ X {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ X {0x0094490a, NULL}, /* BRI9400 - Boca K56Flex PnP */ X {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ X {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ X {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ X {0x01308c0e, NULL}, /* CTL3001 - Creative Labs Phoneblaster */ X {0x36033610, NULL}, /* DAV0336 - DAVICOM 336PNP MODEM */ X {0x01009416, NULL}, /* ETT0001 - E-Tech Bullet 33k6 PnP */ X {0x0000aa1a, NULL}, /* FUJ0000 - FUJITSU Modem 33600 PNP/I2 */ X {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ X {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ X {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ X {0x0116c31e, NULL}, /* GVC1601 - Rockwell V.34 Plug & Play Modem */ X {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ X {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ X {0x9062f91e, NULL}, /* GWY6290 - Telepath with x2 Technology */ X {0x8100e425, NULL}, /* IOD0081 - I-O DATA DEVICE,INC. IFML-560 */ X {0x71004d24, NULL}, /* IBM0071 - IBM ThinkPad 240 IrDA controller*/ X {0x21002534, NULL}, /* MAE0021 - Jetstream Int V.90 56k Voice Series 2*/ X {0x0000f435, NULL}, /* MOT0000 - Motorola ModemSURFR 33.6 Intern */ X {0x5015f435, NULL}, /* MOT1550 - Motorola ModemSURFR 56K Modem */ X {0xf015f435, NULL}, /* MOT15F0 - Motorola VoiceSURFR 56K Modem */ X {0x6045f435, NULL}, /* MOT4560 - Motorola ? */ X {0x61e7a338, NULL}, /* NECE761 - 33.6Modem */ X {0x0160633a, NULL}, /* NSC6001 - National Semi's IrDA Controller*/ X {0x08804f3f, NULL}, /* OZO8008 - Zoom (33.6k Modem) */ X {0x0f804f3f, NULL}, /* OZO800f - Zoom 2812 (56k Modem) */ X {0x39804f3f, NULL}, /* OZO8039 - Zoom 56k flex */ X {0x00914f3f, NULL}, /* OZO9100 - Zoom 2919 (K56 Faxmodem) */ X {0x3024a341, NULL}, /* PMC2430 - Pace 56 Voice Internal Modem */ X {0x1000eb49, NULL}, /* ROK0010 - Rockwell ? */ X {0x1200b23d, NULL}, /* RSS0012 - OMRON ME5614ISA */ X {0x5002734a, NULL}, /* RSS0250 - 5614Jx3(G) Internal Modem */ X {0x6202734a, NULL}, /* RSS0262 - 5614Jx3[G] V90+K56Flex Modem */ X {0x1010104d, NULL}, /* SHP1010 - Rockwell 33600bps Modem */ X {0x10f0a34d, NULL}, /* SMCF010 - SMC IrCC*/ X {0xc100ad4d, NULL}, /* SMM00C1 - Leopard 56k PnP */ X {0x9012b04e, NULL}, /* SUP1290 - Supra ? */ X {0x1013b04e, NULL}, /* SUP1310 - SupraExpress 336i PnP */ X {0x8013b04e, NULL}, /* SUP1380 - SupraExpress 288i PnP Voice */ X {0x8113b04e, NULL}, /* SUP1381 - SupraExpress 336i PnP Voice */ X {0x5016b04e, NULL}, /* SUP1650 - Supra 336i Sp Intl */ X {0x7016b04e, NULL}, /* SUP1670 - Supra 336i V+ Intl */ X {0x7420b04e, NULL}, /* SUP2070 - Supra ? */ X {0x8020b04e, NULL}, /* SUP2080 - Supra ? */ X {0x8420b04e, NULL}, /* SUP2084 - SupraExpress 56i PnP */ X {0x7121b04e, NULL}, /* SUP2171 - SupraExpress 56i Sp? */ X {0x8024b04e, NULL}, /* SUP2480 - Supra ? */ X {0x01007256, NULL}, /* USR0001 - U.S. Robotics Inc., Sportster W */ X {0x02007256, NULL}, /* USR0002 - U.S. Robotics Inc. Sportster 33. */ X {0x04007256, NULL}, /* USR0004 - USR Sportster 14.4k */ X {0x06007256, NULL}, /* USR0006 - USR Sportster 33.6k */ X {0x11007256, NULL}, /* USR0011 - USR ? */ X {0x01017256, NULL}, /* USR0101 - USR ? */ X {0x30207256, NULL}, /* USR2030 - U.S.Robotics Inc. Sportster 560 */ X {0x50207256, NULL}, /* USR2050 - U.S.Robotics Inc. Sportster 33. */ X {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ X {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ X {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ X {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ X {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ X {0x90307256, NULL}, /* USR3090 - USR ? */ X {0x70917256, NULL}, /* USR9170 - U.S. Robotics 56K FAX INT */ X {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ X {0x04f0235c, NULL}, /* WACF004 - Wacom Tablet PC Screen*/ X {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ X {0x01a0896a, NULL}, /* ZTIA001 - Zoom Internal V90 Faxmodem */ X {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ X /* The following are found in PC98 hardware. */ X {0x4180a3b8, NULL}, /* NEC8041 - PC-9821CB-B04 */ X {0x0181a3b8, NULL}, /* NEC8101 - PC-9821CB2-B04 */ X {0x5181a3b8, NULL}, /* NEC8151 - Internal FAX/Modem for Cx3, Cb3 */ X {0x9181a3b8, NULL}, /* NEC8191 - PC-9801-120 */ X {0xe181a3b8, NULL}, /* NEC81E1 - Internal FAX/Modem */ X {0x1182a3b8, NULL}, /* NEC8211 - PC-9801-123 */ X {0x3182a3b8, NULL}, /* NEC8231 - Internal FAX/Modem (Voice) */ X {0x4182a3b8, NULL}, /* NEC8241 - PC-9821NR-B05 */ X {0x5182a3b8, NULL}, /* NEC8251 - Internel FAX/Modem */ X {0x7182a3b8, NULL}, /* NEC8271 - PC-9801-125 */ X {0x11802fbf, NULL}, /* OYO8011 - Internal FAX/Modem (Ring) */ X {0} X}; X Xstatic int Xuartlirc_isa_probe(device_t dev) X{ X struct uartlirc_softc *sc; X device_t parent; X X parent = device_get_parent(dev); X sc = device_get_softc(dev); X X /* Check PnP IDs */ X if (ISA_PNP_PROBE(parent, dev, isa_ns8250_ids) == ENXIO) X return (ENXIO); X X /* Probe PnP _and_ non-PnP ns8250 here. */ X#ifdef PC98 X if (isa_get_logicalid(dev)) X sc->sc_class = &uartlirc_ns8250_class; X else X sc->sc_class = uartlirc_pc98_getdev(bus_get_resource_start(dev, X SYS_RES_IOPORT, 0)); X#else X sc->sc_class = &uartlirc_ns8250_class; X#endif X return (uartlirc_bus_probe(dev, 0, 0, 0, 0)); X} X XDRIVER_MODULE(uartlirc, isa, uartlirc_isa_driver, uartlirc_devclass, 0, 0); 6bdcb989fcf03cd7a5678f8218e0b441 echo x - uartlirc/uartlirc_bus_pccard.c sed 's/^X//' >uartlirc/uartlirc_bus_pccard.c << '34d02ced403405cddd21034b5743277b' X/*- X * Copyright (c) 2001 M. Warner Losh. All rights reserved. X * Copyright (c) 2003 Norikatsu Shigemura, Takenori Watanabe All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_pccard.c,v 1.11.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X X#include "pccarddevs.h" X Xstatic int uartlirc_pccard_probe(device_t dev); Xstatic int uartlirc_pccard_attach(device_t dev); X Xstatic device_method_t uartlirc_pccard_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_pccard_probe), X DEVMETHOD(device_attach, uartlirc_pccard_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X X { 0, 0 } X}; X Xstatic driver_t uartlirc_pccard_driver = { X uartlirc_driver_name, X uartlirc_pccard_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic int Xuartlirc_pccard_probe(device_t dev) X{ X int error; X uint32_t fcn; X X fcn = PCCARD_FUNCTION_UNSPEC; X error = pccard_get_function(dev, &fcn); X if (error != 0) X return (error); X /* X * If a serial card, we are likely the right driver. However, X * some serial cards are better serviced by other drivers, so X * allow other drivers to claim it, if they want. X */ X if (fcn == PCCARD_FUNCTION_SERIAL) X return (BUS_PROBE_GENERIC); X X return (ENXIO); X} X Xstatic int Xuartlirc_pccard_attach(device_t dev) X{ X struct uartlirc_softc *sc; X int error; X X sc = device_get_softc(dev); X sc->sc_class = &uartlirc_ns8250_class; X X error = uartlirc_bus_probe(dev, 0, 0, 0, 0); X if (error > 0) X return (error); X return (uartlirc_bus_attach(dev)); X} X XDRIVER_MODULE(uartlirc, pccard, uartlirc_pccard_driver, uartlirc_devclass, 0, 0); 34d02ced403405cddd21034b5743277b echo x - uartlirc/uartlirc_bus_pci.c sed 's/^X//' >uartlirc/uartlirc_bus_pci.c << '6525c56c169d1074696af4ed7a2592e0' X/*- X * Copyright (c) 2006 Marcel Moolenaar X * Copyright (c) 2001 M. Warner Losh X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_pci.c,v 1.19.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X X#define DEFAULT_RCLK 1843200 X Xstatic int uartlirc_pci_probe(device_t dev); X Xstatic device_method_t uartlirc_pci_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_pci_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X { 0, 0 } X}; X Xstatic driver_t uartlirc_pci_driver = { X uartlirc_driver_name, X uartlirc_pci_methods, X sizeof(struct uartlirc_softc), X}; X Xstruct pci_id { X uint16_t vendor; X uint16_t device; X uint16_t subven; X uint16_t subdev; X const char *desc; X int rid; X int rclk; X}; X Xstatic struct pci_id pci_ns8250_ids[] = { X{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14, X 128 * DEFAULT_RCLK }, X{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14, X 128 * DEFAULT_RCLK }, X{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 }, X{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 }, X{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2", X 0x10 }, X{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 }, X{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 }, X{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 }, X{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 }, X{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 }, X{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 }, X{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 }, X{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 }, X{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 }, X{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 }, X{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 }, X{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 }, X{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 }, X{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 }, X{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530", X 0x18 }, X{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 }, X{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 }, X{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 }, X{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10, X 8 * DEFAULT_RCLK }, X{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10, X 8 * DEFAULT_RCLK }, X{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10, X 8 * DEFAULT_RCLK }, X{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10, X 8 * DEFAULT_RCLK }, X{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10, X 8 * DEFAULT_RCLK }, X{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART", X 0x10, 16384000 }, X{ 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, X{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, X{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 }, X{ 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 }, X{ 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller", X 0x10 }, X{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 }, X{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 }, X{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 }, X{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 }, X{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 }, X{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, X{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, X{ 0x9710, 0x9900, 0xa000, 0x1000, X "MosChip MCS9900 PCIe to Peripheral Controller", 0x10 }, X{ 0x9710, 0x9901, 0xa000, 0x1000, X "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 }, X{ 0x9710, 0x9904, 0xa000, 0x1000, X "MosChip MCS9904 PCIe to Peripheral Controller", 0x10 }, X{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, X{ 0xffff, 0, 0xffff, 0, NULL, 0, 0} X}; X Xstatic struct pci_id * Xuartlirc_pci_match(device_t dev, struct pci_id *id) X{ X uint16_t device, subdev, subven, vendor; X X vendor = pci_get_vendor(dev); X device = pci_get_device(dev); X while (id->vendor != 0xffff && X (id->vendor != vendor || id->device != device)) X id++; X if (id->vendor == 0xffff) X return (NULL); X if (id->subven == 0xffff) X return (id); X subven = pci_get_subvendor(dev); X subdev = pci_get_subdevice(dev); X while (id->vendor == vendor && id->device == device && X (id->subven != subven || id->subdev != subdev)) X id++; X return ((id->vendor == vendor && id->device == device) ? id : NULL); X} X Xstatic int Xuartlirc_pci_probe(device_t dev) X{ X struct uartlirc_softc *sc; X struct pci_id *id; X X sc = device_get_softc(dev); X X id = uartlirc_pci_match(dev, pci_ns8250_ids); X if (id != NULL) { X sc->sc_class = &uartlirc_ns8250_class; X goto match; X } X /* Add checks for non-ns8250 IDs here. */ X return (ENXIO); X X match: X if (id->desc) X device_set_desc(dev, id->desc); X return (uartlirc_bus_probe(dev, 0, id->rclk, id->rid, 0)); X} X XDRIVER_MODULE(uartlirc, pci, uartlirc_pci_driver, uartlirc_devclass, 0, 0); 6525c56c169d1074696af4ed7a2592e0 echo x - uartlirc/uartlirc_bus_puc.c sed 's/^X//' >uartlirc/uartlirc_bus_puc.c << '58d7c5a2e39994d7f76a0d2c848acb42' X/*- X * Copyright (c) 2006 Marcel Moolenaar. All rights reserved. X * Copyright (c) 2002 JF Hay. All rights reserved. X * Copyright (c) 2001 M. Warner Losh. All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_puc.c,v 1.3.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X Xstatic int uartlirc_puc_probe(device_t dev); X Xstatic device_method_t uartlirc_puc_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_puc_probe), X DEVMETHOD(device_attach, uartlirc_bus_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X /* Serdev interface */ X DEVMETHOD(serdev_ihand, uartlirc_bus_ihand), X DEVMETHOD(serdev_ipend, uartlirc_bus_ipend), X { 0, 0 } X}; X Xstatic driver_t uartlirc_puc_driver = { X uartlirc_driver_name, X uartlirc_puc_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic int Xuartlirc_puc_probe(device_t dev) X{ X device_t parent; X struct uartlirc_softc *sc; X uintptr_t rclk, type; X X parent = device_get_parent(dev); X sc = device_get_softc(dev); X X if (BUS_READ_IVAR(parent, dev, PUC_IVAR_TYPE, &type)) X return (ENXIO); X if (type != PUC_TYPE_SERIAL) X return (ENXIO); X X sc->sc_class = &uartlirc_ns8250_class; X X if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk)) X rclk = 0; X return (uartlirc_bus_probe(dev, 0, rclk, 0, 0)); X} X XDRIVER_MODULE(uartlirc, puc, uartlirc_puc_driver, uartlirc_devclass, 0, 0); 58d7c5a2e39994d7f76a0d2c848acb42 echo x - uartlirc/uartlirc_bus_scc.c sed 's/^X//' >uartlirc/uartlirc_bus_scc.c << '579edd11ef07c41a1f134b192afed525' X/*- X * Copyright (c) 2004-2006 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_bus_scc.c,v 1.2.4.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X Xstatic int uartlirc_scc_attach(device_t dev); Xstatic int uartlirc_scc_probe(device_t dev); X Xstatic device_method_t uartlirc_scc_methods[] = { X /* Device interface */ X DEVMETHOD(device_probe, uartlirc_scc_probe), X DEVMETHOD(device_attach, uartlirc_scc_attach), X DEVMETHOD(device_detach, uartlirc_bus_detach), X /* Serdev interface */ X DEVMETHOD(serdev_ihand, uartlirc_bus_ihand), X DEVMETHOD(serdev_sysdev, uartlirc_bus_sysdev), X { 0, 0 } X}; X Xstatic driver_t uartlirc_scc_driver = { X uartlirc_driver_name, X uartlirc_scc_methods, X sizeof(struct uartlirc_softc), X}; X Xstatic int Xuartlirc_scc_attach(device_t dev) X{ X device_t parent; X struct uartlirc_softc *sc; X uintptr_t mtx; X X parent = device_get_parent(dev); X sc = device_get_softc(dev); X X if (BUS_READ_IVAR(parent, dev, SCC_IVAR_HWMTX, &mtx)) X return (ENXIO); X sc->sc_hwmtx = (struct mtx *)(void *)mtx; X return (uartlirc_bus_attach(dev)); X} X Xstatic int Xuartlirc_scc_probe(device_t dev) X{ X device_t parent; X struct uartlirc_softc *sc; X uintptr_t ch, cl, md, rs; X X parent = device_get_parent(dev); X sc = device_get_softc(dev); X X if (BUS_READ_IVAR(parent, dev, SCC_IVAR_MODE, &md) || X BUS_READ_IVAR(parent, dev, SCC_IVAR_CLASS, &cl)) X return (ENXIO); X if (md != SCC_MODE_ASYNC) X return (ENXIO); X switch (cl) { X case SCC_CLASS_QUICC: X sc->sc_class = &uartlirc_quicc_class; X break; X case SCC_CLASS_SAB82532: X sc->sc_class = &uartlirc_sab82532_class; X break; X case SCC_CLASS_Z8530: X sc->sc_class = &uartlirc_z8530_class; X break; X default: X return (ENXIO); X } X if (BUS_READ_IVAR(parent, dev, SCC_IVAR_CHANNEL, &ch) || X BUS_READ_IVAR(parent, dev, SCC_IVAR_CLOCK, &cl) || X BUS_READ_IVAR(parent, dev, SCC_IVAR_REGSHFT, &rs)) X return (ENXIO); X X return (uartlirc_bus_probe(dev, rs, cl, 0, ch)); X} X XDRIVER_MODULE(uartlirc, scc, uartlirc_scc_driver, uartlirc_devclass, 0, 0); 579edd11ef07c41a1f134b192afed525 echo x - uartlirc/uartlirc_core.c sed 's/^X//' >uartlirc/uartlirc_core.c << '89a7092e214918cc121a565dc3e7a273' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_core.c,v 1.29.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X#include "uartlirc_lircdev.h" X X#include "uartlirc_if.h" X Xdevclass_t uartlirc_devclass; Xchar uartlirc_driver_name[] = "uartlirc"; X XSLIST_HEAD(uartlirc_devinfo_list, uartlirc_devinfo) uartlirc_sysdevs = X SLIST_HEAD_INITIALIZER(uartlirc_sysdevs); X Xstatic MALLOC_DEFINE(M_UARTLIRC, "UARTLIRC", "UART driver"); X X#ifndef UARTLIRC_POLL_FREQ X#define UARTLIRC_POLL_FREQ 50 X#endif Xstatic int uartlirc_poll_freq = UARTLIRC_POLL_FREQ; XTUNABLE_INT("debug.uartlirc_poll_freq", &uartlirc_poll_freq); X Xvoid Xuartlirc_add_sysdev(struct uartlirc_devinfo *di) X{ X SLIST_INSERT_HEAD(&uartlirc_sysdevs, di, next); X} X Xconst char * Xuartlirc_getname(struct uartlirc_class *uc) X{ X return ((uc != NULL) ? uc->name : NULL); X} X Xstruct uartlirc_ops * Xuartlirc_getops(struct uartlirc_class *uc) X{ X return ((uc != NULL) ? uc->uc_ops : NULL); X} X Xint Xuartlirc_getrange(struct uartlirc_class *uc) X{ X return ((uc != NULL) ? uc->uc_range : 0); X} X X/* X * Schedule a soft interrupt. We do this on the 0 to !0 transition X * of the TTY pending interrupt status. X */ Xvoid Xuartlirc_sched_softih(struct uartlirc_softc *sc, uint32_t ipend) X{ X uint32_t new, old; X X do { X old = sc->sc_ttypend; X new = old | ipend; X } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); X X if ((old & SER_INT_MASK) == 0) X swi_sched(sc->sc_softih, 0); X} X X/* X * A break condition has been detected. We treat the break condition as X * a special case that should not happen during normal operation. When X * the break condition is to be passed to higher levels in the form of X * a NUL character, we really want the break to be in the right place in X * the input stream. The overhead to achieve that is not in relation to X * the exceptional nature of the break condition, so we permit ourselves X * to be sloppy. X */ Xstatic __inline int Xuartlirc_intr_break(void *arg) X{ X struct uartlirc_softc *sc = arg; X X#if defined(KDB) X if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UARTLIRC_DEV_CONSOLE) { X if (kdb_break()) X return (0); X } X#endif X if (sc->sc_opened) X uartlirc_sched_softih(sc, SER_INT_BREAK); X return (0); X} X X/* X * Handle a receiver overrun situation. We lost at least 1 byte in the X * input stream and it's our job to contain the situation. We grab as X * much of the data we can, but otherwise flush the receiver FIFO to X * create some breathing room. The net effect is that we avoid the X * overrun condition to happen for the next X characters, where X is X * related to the FIFO size at the cost of loosing data right away. X * So, instead of having multiple overrun interrupts in close proximity X * to each other and possibly pessimizing UART interrupt latency for X * other UARTs in a multiport configuration, we create a longer segment X * of missing characters by freeing up the FIFO. X * Each overrun condition is marked in the input buffer by a token. The X * token represents the loss of at least one, but possible more bytes in X * the input stream. X */ Xstatic __inline int Xuartlirc_intr_overrun(void *arg) X{ X struct uartlirc_softc *sc = arg; X X if (sc->sc_opened) { X UARTLIRC_RECEIVE(sc); X if (uartlirc_rx_put(sc, UARTLIRC_STAT_OVERRUN)) X sc->sc_rxbuf[sc->sc_rxput] = UARTLIRC_STAT_OVERRUN; X uartlirc_sched_softih(sc, SER_INT_RXREADY); X } X UARTLIRC_FLUSH(sc, UARTLIRC_FLUSH_RECEIVER); X return (0); X} X X/* X * Received data ready. X */ Xstatic __inline int Xuartlirc_intr_rxready(void *arg) X{ X struct uartlirc_softc *sc = arg; X int rxp; X X rxp = sc->sc_rxput; X UARTLIRC_RECEIVE(sc); X#if defined(KDB) X if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UARTLIRC_DEV_CONSOLE) { X while (rxp != sc->sc_rxput) { X kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk); X if (rxp == sc->sc_rxbufsz) X rxp = 0; X } X } X#endif X if (sc->sc_opened) X uartlirc_sched_softih(sc, SER_INT_RXREADY); X else X sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */ X return (1); X} X X/* X * Line or modem status change (OOB signalling). X * We pass the signals to the software interrupt handler for further X * processing. Note that we merge the delta bits, but set the state X * bits. This is to avoid loosing state transitions due to having more X * than 1 hardware interrupt between software interrupts. X */ Xstatic __inline int Xuartlirc_intr_sigchg(void *arg) X{ X struct uartlirc_softc *sc = arg; X int new, old, sig; X X sig = UARTLIRC_GETSIG(sc); X X if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) { X if (sig & UARTLIRC_SIG_DPPS) { X pps_capture(&sc->sc_pps); X pps_event(&sc->sc_pps, (sig & UARTLIRC_SIG_PPS) ? X PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); X } X } X X if (sc->sc_lircstate) X uartlirc_lircdev_sig(arg, sig); X X /* X * Keep track of signal changes, even when the device is not X * opened. This allows us to inform upper layers about a X * possible loss of DCD and thus the existence of a (possibly) X * different connection when we have DCD back, during the time X * that the device was closed. X */ X do { X old = sc->sc_ttypend; X new = old & ~SER_MASK_STATE; X new |= sig & SER_INT_SIGMASK; X } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); X X if (sc->sc_opened) X uartlirc_sched_softih(sc, SER_INT_SIGCHG); X return (1); X} X X/* X * The transmitter can accept more data. X */ Xstatic __inline int Xuartlirc_intr_txidle(void *arg) X{ X struct uartlirc_softc *sc = arg; X X if (sc->sc_txbusy) { X sc->sc_txbusy = 0; X uartlirc_sched_softih(sc, SER_INT_TXIDLE); X } X return (0); X} X Xstatic int Xuartlirc_intr(void *arg) X{ X struct uartlirc_softc *sc = arg; X int flag = 0, ipend; X X while (!sc->sc_leaving && (ipend = UARTLIRC_IPEND(sc)) != 0) { X flag = 1; X if (ipend & SER_INT_OVERRUN) X uartlirc_intr_overrun(sc); X if (ipend & SER_INT_BREAK) X uartlirc_intr_break(sc); X if (ipend & SER_INT_RXREADY) X uartlirc_intr_rxready(sc); X if (ipend & SER_INT_SIGCHG) X uartlirc_intr_sigchg(sc); X if (ipend & SER_INT_TXIDLE) X uartlirc_intr_txidle(sc); X } X X if (sc->sc_polled) { X callout_reset(&sc->sc_timer, hz / uartlirc_poll_freq, X (timeout_t *)uartlirc_intr, sc); X } X X return((flag)?FILTER_HANDLED:FILTER_STRAY); X} X Xserdev_intr_t * Xuartlirc_bus_ihand(device_t dev, int ipend) X{ X X switch (ipend) { X case SER_INT_BREAK: X return (uartlirc_intr_break); X case SER_INT_OVERRUN: X return (uartlirc_intr_overrun); X case SER_INT_RXREADY: X return (uartlirc_intr_rxready); X case SER_INT_SIGCHG: X return (uartlirc_intr_sigchg); X case SER_INT_TXIDLE: X return (uartlirc_intr_txidle); X } X return (NULL); X} X Xint Xuartlirc_bus_ipend(device_t dev) X{ X struct uartlirc_softc *sc; X X sc = device_get_softc(dev); X return (UARTLIRC_IPEND(sc)); X} X Xint Xuartlirc_bus_sysdev(device_t dev) X{ X struct uartlirc_softc *sc; X X sc = device_get_softc(dev); X return ((sc->sc_sysdev != NULL) ? 1 : 0); X} X Xint Xuartlirc_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan) X{ X struct uartlirc_softc *sc; X struct uartlirc_devinfo *sysdev; X int error; X X sc = device_get_softc(dev); X X /* X * All uartlirc_class references are weak. Check that the needed X * class has been compiled-in. Fail if not. X */ X if (sc->sc_class == NULL) X return (ENXIO); X X /* X * Initialize the instance. Note that the instance (=softc) does X * not necessarily match the hardware specific softc. We can't do X * anything about it now, because we may not attach to the device. X * Hardware drivers cannot use any of the class specific fields X * while probing. X */ X kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class); X sc->sc_dev = dev; X if (device_get_desc(dev) == NULL) X device_set_desc(dev, uartlirc_getname(sc->sc_class)); X X /* X * Allocate the register resource. We assume that all UARTs have X * a single register window in either I/O port space or memory X * mapped I/O space. Any UART that needs multiple windows will X * consequently not be supported by this driver as-is. We try I/O X * port space first because that's the common case. X */ X sc->sc_rrid = rid; X sc->sc_rtype = SYS_RES_IOPORT; X sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, X 0, ~0, uartlirc_getrange(sc->sc_class), RF_ACTIVE); X if (sc->sc_rres == NULL) { X sc->sc_rrid = rid; X sc->sc_rtype = SYS_RES_MEMORY; X sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, X &sc->sc_rrid, 0, ~0, uartlirc_getrange(sc->sc_class), X RF_ACTIVE); X if (sc->sc_rres == NULL) X return (ENXIO); X } X X /* X * Fill in the bus access structure and compare this device with X * a possible console device and/or a debug port. We set the flags X * in the softc so that the hardware dependent probe can adjust X * accordingly. In general, you don't want to permanently disrupt X * console I/O. X */ X sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); X sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); X sc->sc_bas.chan = chan; X sc->sc_bas.regshft = regshft; X sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk; X X SLIST_FOREACH(sysdev, &uartlirc_sysdevs, next) { X if (chan == sysdev->bas.chan && X uartlirc_cpu_eqres(&sc->sc_bas, &sysdev->bas)) { X /* XXX check if ops matches class. */ X sc->sc_sysdev = sysdev; X sysdev->bas.rclk = sc->sc_bas.rclk; X } X } X X error = UARTLIRC_PROBE(sc); X bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); X /* X * XXX use BUS_PROBE_VENDOR so uartlirc.ko loaded via loader X * overrides in-kernel uart(4) driver. X */ X return ((error) ? error : BUS_PROBE_VENDOR); X} X Xint Xuartlirc_bus_attach(device_t dev) X{ X struct uartlirc_softc *sc, *sc0; X const char *sep; X int error; X X /* X * The sc_class field defines the type of UART we're going to work X * with and thus the size of the softc. Replace the generic softc X * with one that matches the UART now that we're certain we handle X * the device. X */ X sc0 = device_get_softc(dev); X if (sc0->sc_class->size > sizeof(*sc)) { X sc = malloc(sc0->sc_class->size, M_UARTLIRC, M_WAITOK|M_ZERO); X bcopy(sc0, sc, sizeof(*sc)); X device_set_softc(dev, sc); X } else X sc = sc0; X X /* X * Protect ourselves against interrupts while we're not completely X * finished attaching and initializing. We don't expect interrupts X * until after UARTLIRC_ATTACH() though. X */ X sc->sc_leaving = 1; X X mtx_init(&sc->sc_hwmtx_s, "uartlirc_hwmtx", NULL, MTX_SPIN); X if (sc->sc_hwmtx == NULL) X sc->sc_hwmtx = &sc->sc_hwmtx_s; X X /* X * Re-allocate. We expect that the softc contains the information X * collected by uartlirc_bus_probe() intact. X */ X sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, X 0, ~0, uartlirc_getrange(sc->sc_class), RF_ACTIVE); X if (sc->sc_rres == NULL) { X mtx_destroy(&sc->sc_hwmtx_s); X return (ENXIO); X } X sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); X sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); X X sc->sc_irid = 0; X sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, X RF_ACTIVE | RF_SHAREABLE); X if (sc->sc_ires != NULL) { X error = bus_setup_intr(dev, X sc->sc_ires, INTR_TYPE_TTY, X uartlirc_intr, NULL, sc, &sc->sc_icookie); X if (error) X error = bus_setup_intr(dev, X sc->sc_ires, INTR_TYPE_TTY | INTR_MPSAFE, X NULL, (driver_intr_t *)uartlirc_intr, sc, &sc->sc_icookie); X else X sc->sc_fastintr = 1; X X if (error) { X device_printf(dev, "could not activate interrupt\n"); X bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, X sc->sc_ires); X sc->sc_ires = NULL; X } X } X if (sc->sc_ires == NULL) { X /* No interrupt resource. Force polled mode. */ X sc->sc_polled = 1; X callout_init(&sc->sc_timer, 1); X } X X sc->sc_rxbufsz = 384; X sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), X M_UARTLIRC, M_WAITOK); X sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf), X M_UARTLIRC, M_WAITOK); X X error = UARTLIRC_ATTACH(sc); X if (error) X goto fail; X X if (sc->sc_hwiflow || sc->sc_hwoflow) { X sep = ""; X device_print_prettyname(dev); X if (sc->sc_hwiflow) { X printf("%sRTS iflow", sep); X sep = ", "; X } X if (sc->sc_hwoflow) { X printf("%sCTS oflow", sep); X sep = ", "; X } X printf("\n"); X } X X if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { X sep = ""; X device_print_prettyname(dev); X if (sc->sc_fastintr) { X printf("%sfast interrupt", sep); X sep = ", "; X } X if (sc->sc_polled) { X printf("%spolled mode", sep); X sep = ", "; X } X printf("\n"); X } X X if (sc->sc_sysdev != NULL) { X if (sc->sc_sysdev->baudrate == 0) { X if (UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_BAUD, X (intptr_t)&sc->sc_sysdev->baudrate) != 0) X sc->sc_sysdev->baudrate = -1; X } X switch (sc->sc_sysdev->type) { X case UARTLIRC_DEV_CONSOLE: X device_printf(dev, "console"); X break; X case UARTLIRC_DEV_DBGPORT: X device_printf(dev, "debug port"); X break; X case UARTLIRC_DEV_KEYBOARD: X device_printf(dev, "keyboard"); X break; X default: X device_printf(dev, "unknown system device"); X break; X } X printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate, X "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits, X sc->sc_sysdev->stopbits); X } X X sc->sc_pps.ppscap = PPS_CAPTUREBOTH; X pps_init(&sc->sc_pps); X X error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) X ? (*sc->sc_sysdev->attach)(sc) : uartlirc_tty_attach(sc); X if (error) X goto fail; X X if (sc->sc_sysdev != NULL) X sc->sc_sysdev->hwmtx = sc->sc_hwmtx; X X sc->sc_leaving = 0; X uartlirc_intr(sc); X return (0); X X fail: X free(sc->sc_txbuf, M_UARTLIRC); X free(sc->sc_rxbuf, M_UARTLIRC); X X if (sc->sc_ires != NULL) { X bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); X bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, X sc->sc_ires); X } X bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); X X mtx_destroy(&sc->sc_hwmtx_s); X X return (error); X} X Xint Xuartlirc_bus_detach(device_t dev) X{ X struct uartlirc_softc *sc; X X sc = device_get_softc(dev); X X sc->sc_leaving = 1; X X if (sc->sc_sysdev != NULL) X sc->sc_sysdev->hwmtx = NULL; X X UARTLIRC_DETACH(sc); X X if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL) X (*sc->sc_sysdev->detach)(sc); X else X uartlirc_tty_detach(sc); X X free(sc->sc_txbuf, M_UARTLIRC); X free(sc->sc_rxbuf, M_UARTLIRC); X X if (sc->sc_ires != NULL) { X bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); X bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, X sc->sc_ires); X } X bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); X X mtx_destroy(&sc->sc_hwmtx_s); X X if (sc->sc_class->size > sizeof(*sc)) { X device_set_softc(dev, NULL); X free(sc, M_UARTLIRC); X } else X device_set_softc(dev, NULL); X X return (0); X} 89a7092e214918cc121a565dc3e7a273 echo x - uartlirc/uartlirc_cpu.h sed 's/^X//' >uartlirc/uartlirc_cpu.h << 'd74b12af89ef76259335d50175a143ea' X/*- X * Copyright (c) 2003, 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X * X * $FreeBSD: src/sys/dev/uart/uartlirc_cpu.h,v 1.12.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X */ X X#ifndef _DEV_UARTLIRC_CPU_H_ X#define _DEV_UARTLIRC_CPU_H_ X X#include X#include X#include X X/* X * Low-level operations for use by console and/or debug port support. X */ Xstruct uartlirc_ops { X int (*probe)(struct uartlirc_bas *); X void (*init)(struct uartlirc_bas *, int, int, int, int); X void (*term)(struct uartlirc_bas *); X void (*putc)(struct uartlirc_bas *, int); X int (*rxready)(struct uartlirc_bas *); X int (*getc)(struct uartlirc_bas *, struct mtx *); X}; X Xextern bus_space_tag_t uartlirc_bus_space_io; Xextern bus_space_tag_t uartlirc_bus_space_mem; X X/* X * Console and debug port device info. X */ Xstruct uartlirc_softc; Xstruct uartlirc_devinfo { X SLIST_ENTRY(uartlirc_devinfo) next; X struct uartlirc_ops *ops; X struct uartlirc_bas bas; X int baudrate; X int databits; X int stopbits; X int parity; X int type; X#define UARTLIRC_DEV_CONSOLE 0 X#define UARTLIRC_DEV_DBGPORT 1 X#define UARTLIRC_DEV_KEYBOARD 2 X int (*attach)(struct uartlirc_softc*); X int (*detach)(struct uartlirc_softc*); X void *cookie; /* Type dependent use. */ X struct mtx *hwmtx; X}; X Xint uartlirc_cpu_eqres(struct uartlirc_bas *, struct uartlirc_bas *); Xint uartlirc_cpu_getdev(int, struct uartlirc_devinfo *); X Xint uartlirc_getenv(int, struct uartlirc_devinfo *, struct uartlirc_class *); Xconst char *uartlirc_getname(struct uartlirc_class *); Xstruct uartlirc_ops *uartlirc_getops(struct uartlirc_class *); Xint uartlirc_getrange(struct uartlirc_class *); X Xvoid uartlirc_add_sysdev(struct uartlirc_devinfo *); X X/* X * Operations for low-level access to the UART. Primarily for use X * by console and debug port logic. X */ X Xstatic __inline void Xuartlirc_lock(struct mtx *hwmtx) X{ X if (!kdb_active && hwmtx != NULL) X mtx_lock_spin(hwmtx); X} X Xstatic __inline void Xuartlirc_unlock(struct mtx *hwmtx) X{ X if (!kdb_active && hwmtx != NULL) X mtx_unlock_spin(hwmtx); X} X Xstatic __inline int Xuartlirc_probe(struct uartlirc_devinfo *di) X{ X int res; X X uartlirc_lock(di->hwmtx); X res = di->ops->probe(&di->bas); X uartlirc_unlock(di->hwmtx); X return (res); X} X Xstatic __inline void Xuartlirc_init(struct uartlirc_devinfo *di) X{ X uartlirc_lock(di->hwmtx); X di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits, X di->parity); X uartlirc_unlock(di->hwmtx); X} X Xstatic __inline void Xuartlirc_term(struct uartlirc_devinfo *di) X{ X uartlirc_lock(di->hwmtx); X di->ops->term(&di->bas); X uartlirc_unlock(di->hwmtx); X} X Xstatic __inline void Xuartlirc_putc(struct uartlirc_devinfo *di, int c) X{ X uartlirc_lock(di->hwmtx); X di->ops->putc(&di->bas, c); X uartlirc_unlock(di->hwmtx); X} X Xstatic __inline int Xuartlirc_rxready(struct uartlirc_devinfo *di) X{ X int res; X X uartlirc_lock(di->hwmtx); X res = di->ops->rxready(&di->bas); X uartlirc_unlock(di->hwmtx); X return (res); X} X Xstatic __inline int Xuartlirc_poll(struct uartlirc_devinfo *di) X{ X int res; X X uartlirc_lock(di->hwmtx); X if (di->ops->rxready(&di->bas)) X res = di->ops->getc(&di->bas, NULL); X else X res = -1; X uartlirc_unlock(di->hwmtx); X return (res); X} X Xstatic __inline int Xuartlirc_getc(struct uartlirc_devinfo *di) X{ X X return (di->ops->getc(&di->bas, di->hwmtx)); X} X X#endif /* _DEV_UARTLIRC_CPU_H_ */ d74b12af89ef76259335d50175a143ea echo x - uartlirc/uartlirc_cpu_amd64.c sed 's/^X//' >uartlirc/uartlirc_cpu_amd64.c << '9227db9e448b4893a5581906d7f0abe5' X/*- X * Copyright (c) 2003, 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_amd64.c,v 1.13.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X X#if __FreeBSD_version >= 900000 Xbus_space_tag_t uartlirc_bus_space_io = X86_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = X86_BUS_SPACE_MEM; X#else Xbus_space_tag_t uartlirc_bus_space_io = AMD64_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = AMD64_BUS_SPACE_MEM; X#endif X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X struct uartlirc_class *class; X unsigned int i, ivar; X X class = &uartlirc_ns8250_class; X if (class == NULL) X return (ENXIO); X X /* Check the environment. */ X if (uartlirc_getenv(devtype, di, class) == 0) X return (0); X X /* X * Scan the hints. We only try units 0 to 3 (inclusive). This X * covers the ISA legacy where 4 UARTs had their resources X * predefined. X */ X for (i = 0; i < 4; i++) { X if (resource_int_value("uartlirc", i, "flags", &ivar)) X continue; X if (devtype == UARTLIRC_DEV_CONSOLE && !UARTLIRC_FLAGS_CONSOLE(ivar)) X continue; X if (devtype == UARTLIRC_DEV_DBGPORT && !UARTLIRC_FLAGS_DBGPORT(ivar)) X continue; X /* X * We have a possible device. Make sure it's enabled and X * that we have an I/O port. X */ X if (resource_int_value("uartlirc", i, "disabled", &ivar) == 0 && X ivar != 0) X continue; X if (resource_int_value("uartlirc", i, "port", &ivar) != 0 || X ivar == 0) X continue; X /* X * Got it. Fill in the instance and return it. We only have X * ns8250 and successors on i386. X */ X di->ops = uartlirc_getops(class); X di->bas.chan = 0; X di->bas.bst = uartlirc_bus_space_io; X if (bus_space_map(di->bas.bst, ivar, uartlirc_getrange(class), 0, X &di->bas.bsh) != 0) X continue; X di->bas.regshft = 0; X di->bas.rclk = 0; X if (resource_int_value("uartlirc", i, "baud", &ivar) != 0) X ivar = 0; X di->baudrate = ivar; X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X return (0); X } X X return (ENXIO); X} 9227db9e448b4893a5581906d7f0abe5 echo x - uartlirc/uartlirc_cpu_i386.c sed 's/^X//' >uartlirc/uartlirc_cpu_i386.c << '015e00feed4d0a133b98417ff80de080' X/*- X * Copyright (c) 2003, 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_i386.c,v 1.13.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X X#if __FreeBSD_version >= 900000 Xbus_space_tag_t uartlirc_bus_space_io = X86_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = X86_BUS_SPACE_MEM; X#else Xbus_space_tag_t uartlirc_bus_space_io = I386_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = I386_BUS_SPACE_MEM; X#endif X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X struct uartlirc_class *class; X unsigned int i, ivar; X X class = &uartlirc_ns8250_class; X if (class == NULL) X return (ENXIO); X X /* Check the environment. */ X if (uartlirc_getenv(devtype, di, class) == 0) X return (0); X X /* X * Scan the hints. We only try units 0 to 3 (inclusive). This X * covers the ISA legacy where 4 UARTs had their resources X * predefined. X */ X for (i = 0; i < 4; i++) { X if (resource_int_value("uartlirc", i, "flags", &ivar)) X continue; X if (devtype == UARTLIRC_DEV_CONSOLE && !UARTLIRC_FLAGS_CONSOLE(ivar)) X continue; X if (devtype == UARTLIRC_DEV_DBGPORT && !UARTLIRC_FLAGS_DBGPORT(ivar)) X continue; X /* X * We have a possible device. Make sure it's enabled and X * that we have an I/O port. X */ X if (resource_int_value("uartlirc", i, "disabled", &ivar) == 0 && X ivar != 0) X continue; X if (resource_int_value("uartlirc", i, "port", &ivar) != 0 || X ivar == 0) X continue; X /* X * Got it. Fill in the instance and return it. We only have X * ns8250 and successors on i386. X */ X di->ops = uartlirc_getops(class); X di->bas.chan = 0; X di->bas.bst = uartlirc_bus_space_io; X if (bus_space_map(di->bas.bst, ivar, uartlirc_getrange(class), 0, X &di->bas.bsh) != 0) X continue; X di->bas.regshft = 0; X di->bas.rclk = 0; X if (resource_int_value("uartlirc", i, "baud", &ivar) != 0) X ivar = 0; X di->baudrate = ivar; X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X return (0); X } X X return (ENXIO); X} 015e00feed4d0a133b98417ff80de080 echo x - uartlirc/uartlirc_cpu_ia64.c sed 's/^X//' >uartlirc/uartlirc_cpu_ia64.c << 'd8447a3f367a5154642a42f4e5b4946c' X/*- X * Copyright (c) 2003, 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_ia64.c,v 1.13.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X X#include X#include X#include X#include X X#include "uart.h" X#include "uartlirc_cpu.h" X Xbus_space_tag_t uartlirc_bus_space_io = IA64_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = IA64_BUS_SPACE_MEM; X Xstatic int dig64_to_uartlirc_parity[] = { X UARTLIRC_PARITY_NONE, UARTLIRC_PARITY_NONE, UARTLIRC_PARITY_EVEN, X UARTLIRC_PARITY_ODD, UARTLIRC_PARITY_MARK, UARTLIRC_PARITY_SPACE X}; X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X struct dig64_hcdp_table *tbl; X struct dig64_hcdp_entry *ent; X struct uartlirc_class *class; X bus_addr_t addr; X uint64_t hcdp; X unsigned int i; X X class = &uartlirc_ns8250_class; X if (class == NULL) X return (ENXIO); X X /* X * Use the DIG64 HCDP table if present. X */ X hcdp = ia64_get_hcdp(); X if (hcdp != 0) { X tbl = (void*)IA64_PHYS_TO_RR7(hcdp); X for (i = 0; i < tbl->entries; i++) { X ent = tbl->entry + i; X X if (devtype == UARTLIRC_DEV_CONSOLE && X ent->type != DIG64_HCDP_CONSOLE) X continue; X X if (devtype == UARTLIRC_DEV_DBGPORT && X ent->type != DIG64_HCDP_DBGPORT) X continue; X X addr = ent->address.addr_high; X addr = (addr << 32) + ent->address.addr_low; X di->ops = uartlirc_getops(class); X di->bas.chan = 0; X di->bas.bst = (ent->address.addr_space == 0) X ? uartlirc_bus_space_mem : uartlirc_bus_space_io; X if (bus_space_map(di->bas.bst, addr, X uartlirc_getrange(class), 0, &di->bas.bsh) != 0) X continue; X di->bas.regshft = 0; X di->bas.rclk = ent->pclock << 4; X /* We don't deal with 64-bit baud rates. */ X di->baudrate = ent->baud_low; X di->databits = ent->databits; X di->stopbits = ent->stopbits; X di->parity = (ent->parity >= 6) ? UARTLIRC_PARITY_NONE X : dig64_to_uartlirc_parity[ent->parity]; X return (0); X } X X /* FALLTHROUGH */ X } X X /* Check the environment. */ X return (uartlirc_getenv(devtype, di, class)); X} d8447a3f367a5154642a42f4e5b4946c echo x - uartlirc/uartlirc_cpu_pc98.c sed 's/^X//' >uartlirc/uartlirc_cpu_pc98.c << 'f2034d6884751f9ac24b947ed689d88c' X/*- X * Copyright (c) 2008 TAKAHASHI Yoshihiro X * Copyright (c) 2003 M. Warner Losh, Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_pc98.c,v 1.20.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X X#if __FreeBSD_version >= 900000 Xbus_space_tag_t uartlirc_bus_space_io = X86_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = X86_BUS_SPACE_MEM; X#else Xbus_space_tag_t uartlirc_bus_space_io = I386_BUS_SPACE_IO; Xbus_space_tag_t uartlirc_bus_space_mem = I386_BUS_SPACE_MEM; X#endif X Xstatic struct { X u_long iobase; X struct uartlirc_class *class; X} uartlirc_pc98_devs[] = { X { 0x238, &uartlirc_ns8250_class }, X { 0, NULL } X}; X Xstruct uartlirc_class * Xuartlirc_pc98_getdev(u_long port) X{ X int i; X X for (i = 0; uartlirc_pc98_devs[i].iobase; i++) { X if (port == uartlirc_pc98_devs[i].iobase) X return (uartlirc_pc98_devs[i].class); X } X return (NULL); X} X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X if (bus_space_compare(b1->bst, b1->bsh, b2->bst, b2->bsh) == 0) X return (1); X X return (0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X struct uartlirc_class *class; X unsigned int i, ivar; X X class = &uartlirc_ns8250_class; X if (class == NULL) X return (ENXIO); X X /* Check the environment. */ X if (uartlirc_getenv(devtype, di, class) == 0) X return (0); X X /* X * There is a serial port on all pc98 hardware. It is 8251 or X * an enhance version of that. Some pc98 have the second serial X * port which is 16550A compatible. X */ X for (i = 0; i < 2; i++) { X if (resource_int_value("uartlirc", i, "flags", &ivar)) X continue; X if (devtype == UARTLIRC_DEV_CONSOLE && !UARTLIRC_FLAGS_CONSOLE(ivar)) X continue; X if (devtype == UARTLIRC_DEV_DBGPORT && !UARTLIRC_FLAGS_DBGPORT(ivar)) X continue; X /* X * We have a possible device. Make sure it's enabled and X * that we have an I/O port. X */ X if (resource_int_value("uartlirc", i, "disabled", &ivar) == 0 && X ivar != 0) X continue; X if (resource_int_value("uartlirc", i, "port", &ivar) != 0 || X ivar == 0) X continue; X X class = uartlirc_pc98_getdev(ivar); X if (class == NULL) X continue; X X di->ops = uartlirc_getops(class); X di->bas.chan = 0; X di->bas.bst = uartlirc_bus_space_io; X if (bus_space_map(di->bas.bst, ivar, uartlirc_getrange(class), 0, X &di->bas.bsh) != 0) X continue; X di->bas.regshft = 0; X di->bas.rclk = 0; X if (resource_int_value("uartlirc", i, "baud", &ivar) != 0) X ivar = 0; X di->baudrate = ivar; X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X return (0); X } X X return (ENXIO); X} f2034d6884751f9ac24b947ed689d88c echo x - uartlirc/uartlirc_cpu_powerpc.c sed 's/^X//' >uartlirc/uartlirc_cpu_powerpc.c << '4516250a672ab8b04c863f567e2a81b8' X/*- X * Copyright (c) 2006 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_powerpc.c,v 1.9.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X X#include X#include X X#include X#include "uart.h" X#include "uartlirc_cpu.h" X Xbus_space_tag_t uartlirc_bus_space_io = &bs_le_tag; Xbus_space_tag_t uartlirc_bus_space_mem = &bs_le_tag; X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0); X} X Xstatic int Xofw_get_uartlirc_console(phandle_t opts, phandle_t *result, const char *inputdev, X const char *outputdev) X{ X char buf[64]; X phandle_t input; X X if (OF_getprop(opts, inputdev, buf, sizeof(buf)) == -1) X return (ENXIO); X input = OF_finddevice(buf); X if (input == -1) X return (ENXIO); X if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1) X return (ENXIO); X if (OF_finddevice(buf) != input) X return (ENXIO); X X *result = input; X return (0); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X char buf[64]; X struct uartlirc_class *class; X phandle_t input, opts; X int error; X X class = &uartlirc_z8530_class; X if (class == NULL) X return (ENXIO); X X if ((opts = OF_finddevice("/options")) == -1) X return (ENXIO); X switch (devtype) { X case UARTLIRC_DEV_CONSOLE: X if (ofw_get_uartlirc_console(opts, &input, "input-device", X "output-device")) { X /* X * At least some G5 Xserves require that we X * probe input-device-1 as well X */ X X if (ofw_get_uartlirc_console(opts, &input, "input-device-1", X "output-device-1")) X return (ENXIO); X } X break; X case UARTLIRC_DEV_DBGPORT: X if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf))) X return (ENXIO); X input = OF_finddevice(buf); X if (input == -1) X return (ENXIO); X break; X default: X return (EINVAL); X } X X if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) X return (ENXIO); X if (strcmp(buf, "serial") != 0) X return (ENXIO); X if (OF_getprop(input, "name", buf, sizeof(buf)) == -1) X return (ENXIO); X X if (strcmp(buf, "ch-a") == 0) { X class = &uartlirc_z8530_class; X di->bas.regshft = 4; X di->bas.chan = 1; X } else if (strcmp(buf,"serial") == 0) { X class = &uartlirc_ns8250_class; X di->bas.regshft = 0; X di->bas.chan = 0; X } else X return (ENXIO); X X error = OF_decode_addr(input, 0, &di->bas.bst, &di->bas.bsh); X if (error) X return (error); X X di->ops = uartlirc_getops(class); X X if (OF_getprop(input, "clock-frequency", &di->bas.rclk, X sizeof(di->bas.rclk)) == -1) X di->bas.rclk = 230400; X if (OF_getprop(input, "current-speed", &di->baudrate, X sizeof(di->baudrate)) == -1) X di->baudrate = 0; X X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X return (0); X} 4516250a672ab8b04c863f567e2a81b8 echo x - uartlirc/uartlirc_cpu_sparc64.c sed 's/^X//' >uartlirc/uartlirc_cpu_sparc64.c << 'a1cbe10122b95b46e9b3d6520fe24959' X/*- X * Copyright (c) 2003, 2004 Marcel Moolenaar X * Copyright (c) 2004 - 2006 Marius Strobl X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_cpu_sparc64.c,v 1.26.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X X#include X#include X X#include X#include X X#include "uart.h" X#include "uartlirc_cpu.h" X Xbus_space_tag_t uartlirc_bus_space_io; Xbus_space_tag_t uartlirc_bus_space_mem; X Xstatic struct bus_space_tag bst_store[3]; X X/* X * Determine which channel of a SCC a device referenced by a full device X * path or as an alias is (in the latter case we try to look up the device X * path via the /aliases node). X * Only the device paths of devices which are used for TTYs really allow X * to do this as they look like these (taken from /aliases nodes): X * ttya: '/central/fhc/zs@0,902000:a' X * ttyc: '/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a' X * Additionally, for device paths of SCCs which are connected to a RSC X * (Remote System Control) device we can hardcode the appropriate channel. X * Such device paths look like these: X * rsc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' X * ttyc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' X */ Xstatic int Xuartlirc_cpu_channel(char *dev) X{ X char alias[64]; X phandle_t aliases; X int len; X const char *p; X X strcpy(alias, dev); X if ((aliases = OF_finddevice("/aliases")) != -1) X (void)OF_getprop(aliases, dev, alias, sizeof(alias)); X len = strlen(alias); X if ((p = strrchr(alias, ':')) == NULL) X return (0); X p++; X if (p - alias == len - 1 && (*p == 'a' || *p == 'b')) X return (*p - 'a' + 1); X if (strcmp(p, "ssp") == 0) X return (1); X return (0); X} X Xint Xuartlirc_cpu_eqres(struct uartlirc_bas *b1, struct uartlirc_bas *b2) X{ X X return ((b1->bsh == b2->bsh) ? 1 : 0); X} X X/* X * Get the package handle of the UART that is selected as the console, if X * the console is an UART of course. Note that we enforce that both input X * and output are selected. X * Note that the currently active console (i.e. /chosen/stdout and X * /chosen/stdin) may not be the same as the device selected in the X * environment (ie /options/output-device and /options/input-device) because X * keyboard and screen were selected but the keyboard was unplugged or the X * user has changed the environment. In the latter case I would assume that X * the user expects that FreeBSD uses the new console setting. X * For weirder configurations, use ofw_console(4). X */ Xstatic phandle_t Xuartlirc_cpu_getdev_console(phandle_t options, char *dev, size_t devsz) X{ X char buf[sizeof("serial")]; X ihandle_t inst; X phandle_t chosen, input, output; X X if (OF_getprop(options, "input-device", dev, devsz) == -1) X return (-1); X input = OF_finddevice(dev); X if (OF_getprop(options, "output-device", dev, devsz) == -1) X return (-1); X output = OF_finddevice(dev); X if (input == -1 || output == -1 || X OF_getproplen(input, "keyboard") >= 0) { X if ((chosen = OF_finddevice("/chosen")) == -1) X return (-1); X if (OF_getprop(chosen, "stdin", &inst, sizeof(inst)) == -1) X return (-1); X if ((input = OF_instance_to_package(inst)) == -1) X return (-1); X if (OF_getprop(chosen, "stdout", &inst, sizeof(inst)) == -1) X return (-1); X if ((output = OF_instance_to_package(inst)) == -1) X return (-1); X snprintf(dev, devsz, "ttya"); X } X if (input != output) X return (-1); X if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) X return (-1); X if (strcmp(buf, "serial") != 0) X return (-1); X /* For a Serengeti console device point to the bootbus controller. */ X if (OF_getprop(input, "name", buf, sizeof(buf)) > 0 && X !strcmp(buf, "sgcn")) { X if ((chosen = OF_finddevice("/chosen")) == -1) X return (-1); X if (OF_getprop(chosen, "iosram", &input, sizeof(input)) == -1) X return (-1); X } X return (input); X} X X/* X * Get the package handle of the UART that's selected as the debug port. X * Since there's no place for this in the OF, we use the kernel environment X * variable "hw.uart.dbgport". Note however that the variable is not a X * list of attributes. It's single device name or alias, as known by X * the OF. X */ Xstatic phandle_t Xuartlirc_cpu_getdev_dbgport(char *dev, size_t devsz) X{ X char buf[sizeof("serial")]; X phandle_t input; X X if (!getenv_string("hw.uart.dbgport", dev, devsz)) X return (-1); X if ((input = OF_finddevice(dev)) == -1) X return (-1); X if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) X return (-1); X if (strcmp(buf, "serial") != 0) X return (-1); X return (input); X} X X/* X * Get the package handle of the UART that is selected as the keyboard port, X * if it's actually used to connect the keyboard according to the OF. I.e. X * this will return the UART used to connect the keyboard regardless whether X * it's stdin or not, however not in case the user or the OF gave preference X * to e.g. a PS/2 keyboard by setting /aliases/keyboard accordingly. X */ Xstatic phandle_t Xuartlirc_cpu_getdev_keyboard(char *dev, size_t devsz) X{ X char buf[sizeof("serial")]; X phandle_t input; X X if ((input = OF_finddevice("keyboard")) == -1) X return (-1); X if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) X return (-1); X if (strcmp(buf, "serial") != 0) X return (-1); X if (OF_getprop(input, "name", dev, devsz) == -1) X return (-1); X /* X * So far this also matched PS/2 keyboard nodes so make sure it's X * one of the SCCs/UARTs known to be used to connect keyboards. X */ X if (strcmp(dev, "su") && strcmp(dev, "su_pnp") && strcmp(dev, "zs")) X return (-1); X return (input); X} X Xint Xuartlirc_cpu_getdev(int devtype, struct uartlirc_devinfo *di) X{ X char buf[32], compat[32], dev[64]; X struct uartlirc_class *class; X phandle_t input, options; X bus_addr_t addr; X int baud, bits, error, range, space, stop; X char flag, par; X X if ((options = OF_finddevice("/options")) == -1) X return (ENXIO); X switch (devtype) { X case UARTLIRC_DEV_CONSOLE: X input = uartlirc_cpu_getdev_console(options, dev, sizeof(dev)); X break; X case UARTLIRC_DEV_DBGPORT: X input = uartlirc_cpu_getdev_dbgport(dev, sizeof(dev)); X break; X case UARTLIRC_DEV_KEYBOARD: X input = uartlirc_cpu_getdev_keyboard(dev, sizeof(dev)); X break; X default: X input = -1; X break; X } X if (input == -1) X return (ENXIO); X error = OF_decode_addr(input, 0, &space, &addr); X if (error) X return (error); X X /* Get the device class. */ X if (OF_getprop(input, "name", buf, sizeof(buf)) == -1) X return (ENXIO); X if (OF_getprop(input, "compatible", compat, sizeof(compat)) == -1) X compat[0] = '\0'; X di->bas.regshft = 0; X di->bas.rclk = 0; X class = NULL; X if (!strcmp(buf, "se") || !strcmp(buf, "FJSV,se") || X !strcmp(compat, "sab82532")) { X class = &uartlirc_sab82532_class; X /* SAB82532 are only known to be used for TTYs. */ X if ((di->bas.chan = uartlirc_cpu_channel(dev)) == 0) X return (ENXIO); X addr += uartlirc_getrange(class) * (di->bas.chan - 1); X } else if (!strcmp(buf, "zs")) { X class = &uartlirc_z8530_class; X if ((di->bas.chan = uartlirc_cpu_channel(dev)) == 0) { X /* X * There's no way to determine from OF which X * channel has the keyboard. Should always be X * on channel 1 however. X */ X if (devtype == UARTLIRC_DEV_KEYBOARD) X di->bas.chan = 1; X else X return (ENXIO); X } X di->bas.regshft = 1; X range = uartlirc_getrange(class) << di->bas.regshft; X addr += range - range * (di->bas.chan - 1); X } else if (!strcmp(buf, "lom-console") || !strcmp(buf, "su") || X !strcmp(buf, "su_pnp") || !strcmp(compat, "rsc-console") || X !strcmp(compat, "su") || !strcmp(compat, "su16550") || X !strcmp(compat, "su16552")) { X class = &uartlirc_ns8250_class; X di->bas.chan = 0; X } else if (!strcmp(compat, "sgsbbc")) { X class = &uartlirc_sbbc_class; X di->bas.chan = 0; X } X if (class == NULL) X return (ENXIO); X X /* Fill in the device info. */ X di->ops = uartlirc_getops(class); X di->bas.bst = &bst_store[devtype]; X di->bas.bsh = sparc64_fake_bustag(space, addr, di->bas.bst); X X /* Get the line settings. */ X if (devtype == UARTLIRC_DEV_KEYBOARD) X di->baudrate = 1200; X else if (!strcmp(compat, "rsc-console")) X di->baudrate = 115200; X else X di->baudrate = 9600; X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X snprintf(buf, sizeof(buf), "%s-mode", dev); X if (OF_getprop(options, buf, buf, sizeof(buf)) == -1 && X OF_getprop(input, "ssp-console-modes", buf, sizeof(buf)) == -1) X return (0); X if (sscanf(buf, "%d,%d,%c,%d,%c", &baud, &bits, &par, &stop, &flag) X != 5) X return (0); X di->baudrate = baud; X di->databits = bits; X di->stopbits = stop; X di->parity = (par == 'n') ? UARTLIRC_PARITY_NONE : X (par == 'o') ? UARTLIRC_PARITY_ODD : UARTLIRC_PARITY_EVEN; X return (0); X} a1cbe10122b95b46e9b3d6520fe24959 echo x - uartlirc/uartlirc_dbg.c sed 's/^X//' >uartlirc/uartlirc_dbg.c << '087762ff448f3171fd9aa7cce93c483d' X/*- X * Copyright (c) 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_dbg.c,v 1.3.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X Xstatic gdb_probe_f uartlirc_dbg_probe; Xstatic gdb_init_f uartlirc_dbg_init; Xstatic gdb_term_f uartlirc_dbg_term; Xstatic gdb_getc_f uartlirc_dbg_getc; Xstatic gdb_putc_f uartlirc_dbg_putc; X XGDB_DBGPORT(uartlirc, uartlirc_dbg_probe, uartlirc_dbg_init, uartlirc_dbg_term, X uartlirc_dbg_getc, uartlirc_dbg_putc); X Xstatic struct uartlirc_devinfo uartlirc_dbgport; X Xstatic int Xuartlirc_dbg_probe(void) X{ X X if (uartlirc_cpu_getdev(UARTLIRC_DEV_DBGPORT, &uartlirc_dbgport)) X return (-1); X X if (uartlirc_probe(&uartlirc_dbgport)) X return (-1); X X return (0); X} X Xstatic void Xuartlirc_dbg_init(void) X{ X X uartlirc_dbgport.type = UARTLIRC_DEV_DBGPORT; X uartlirc_add_sysdev(&uartlirc_dbgport); X uartlirc_init(&uartlirc_dbgport); X} X Xstatic void Xuartlirc_dbg_term(void) X{ X X uartlirc_term(&uartlirc_dbgport); X} X Xstatic void Xuartlirc_dbg_putc(int c) X{ X X uartlirc_putc(&uartlirc_dbgport, c); X} X Xstatic int Xuartlirc_dbg_getc(void) X{ X X return (uartlirc_poll(&uartlirc_dbgport)); X} 087762ff448f3171fd9aa7cce93c483d echo x - uartlirc/uartlirc_dev_ns8250.c sed 's/^X//' >uartlirc/uartlirc_dev_ns8250.c << '5210da5292a9e1b8f2f52ae6e4ee2dc7' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_dev_ns8250.c,v 1.33.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X#include "uartlirc_bus.h" X X#include X X#include "uartlirc_if.h" X X#define DEFAULT_RCLK 1843200 X X/* X * Clear pending interrupts. THRE is cleared by reading IIR. Data X * that may have been received gets lost here. X */ Xstatic void Xns8250_clrint(struct uartlirc_bas *bas) X{ X uint8_t iir, lsr; X X iir = uartlirc_getreg(bas, REG_IIR); X while ((iir & IIR_NOPEND) == 0) { X iir &= IIR_IMASK; X if (iir == IIR_RLS) { X lsr = uartlirc_getreg(bas, REG_LSR); X if (lsr & (LSR_BI|LSR_FE|LSR_PE)) X (void)uartlirc_getreg(bas, REG_DATA); X } else if (iir == IIR_RXRDY || iir == IIR_RXTOUT) X (void)uartlirc_getreg(bas, REG_DATA); X else if (iir == IIR_MLSC) X (void)uartlirc_getreg(bas, REG_MSR); X uartlirc_barrier(bas); X iir = uartlirc_getreg(bas, REG_IIR); X } X} X Xstatic int Xns8250_delay(struct uartlirc_bas *bas) X{ X int divisor; X u_char lcr; X X lcr = uartlirc_getreg(bas, REG_LCR); X uartlirc_setreg(bas, REG_LCR, lcr | LCR_DLAB); X uartlirc_barrier(bas); X divisor = uartlirc_getreg(bas, REG_DLL) | (uartlirc_getreg(bas, REG_DLH) << 8); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X X /* 1/10th the time to transmit 1 character (estimate). */ X if (divisor <= 134) X return (16000000 * divisor / bas->rclk); X return (16000 * divisor / (bas->rclk / 1000)); X} X Xstatic int Xns8250_divisor(int rclk, int baudrate) X{ X int actual_baud, divisor; X int error; X X if (baudrate == 0) X return (0); X X divisor = (rclk / (baudrate << 3) + 1) >> 1; X if (divisor == 0 || divisor >= 65536) X return (0); X actual_baud = rclk / (divisor << 4); X X /* 10 times error in percent: */ X error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1; X X /* 3.0% maximum error tolerance: */ X if (error < -30 || error > 30) X return (0); X X return (divisor); X} X Xstatic int Xns8250_drain(struct uartlirc_bas *bas, int what) X{ X int delay, limit; X X delay = ns8250_delay(bas); X X if (what & UARTLIRC_DRAIN_TRANSMITTER) { X /* X * Pick an arbitrary high limit to avoid getting stuck in X * an infinite loop when the hardware is broken. Make the X * limit high enough to handle large FIFOs. X */ X limit = 10*1024; X while ((uartlirc_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) X DELAY(delay); X if (limit == 0) { X /* printf("ns8250: transmitter appears stuck... "); */ X return (EIO); X } X } X X if (what & UARTLIRC_DRAIN_RECEIVER) { X /* X * Pick an arbitrary high limit to avoid getting stuck in X * an infinite loop when the hardware is broken. Make the X * limit high enough to handle large FIFOs and integrated X * UARTs. The HP rx2600 for example has 3 UARTs on the X * management board that tend to get a lot of data send X * to it when the UART is first activated. X */ X limit=10*4096; X while ((uartlirc_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { X (void)uartlirc_getreg(bas, REG_DATA); X uartlirc_barrier(bas); X DELAY(delay << 2); X } X if (limit == 0) { X /* printf("ns8250: receiver appears broken... "); */ X return (EIO); X } X } X X return (0); X} X X/* X * We can only flush UARTs with FIFOs. UARTs without FIFOs should be X * drained. WARNING: this function clobbers the FIFO setting! X */ Xstatic void Xns8250_flush(struct uartlirc_bas *bas, int what) X{ X uint8_t fcr; X X fcr = FCR_ENABLE; X if (what & UARTLIRC_FLUSH_TRANSMITTER) X fcr |= FCR_XMT_RST; X if (what & UARTLIRC_FLUSH_RECEIVER) X fcr |= FCR_RCV_RST; X uartlirc_setreg(bas, REG_FCR, fcr); X uartlirc_barrier(bas); X} X Xstatic int Xns8250_param(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X int divisor; X uint8_t lcr; X X lcr = 0; X if (databits >= 8) X lcr |= LCR_8BITS; X else if (databits == 7) X lcr |= LCR_7BITS; X else if (databits == 6) X lcr |= LCR_6BITS; X else X lcr |= LCR_5BITS; X if (stopbits > 1) X lcr |= LCR_STOPB; X lcr |= parity << 3; X X /* Set baudrate. */ X if (baudrate > 0) { X divisor = ns8250_divisor(bas->rclk, baudrate); X if (divisor == 0) X return (EINVAL); X uartlirc_setreg(bas, REG_LCR, lcr | LCR_DLAB); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_DLL, divisor & 0xff); X uartlirc_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); X uartlirc_barrier(bas); X } X X /* Set LCR and clear DLAB. */ X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X return (0); X} X X/* X * Low-level UART interface. X */ Xstatic int ns8250_probe(struct uartlirc_bas *bas); Xstatic void ns8250_init(struct uartlirc_bas *bas, int, int, int, int); Xstatic void ns8250_term(struct uartlirc_bas *bas); Xstatic void ns8250_putc(struct uartlirc_bas *bas, int); Xstatic int ns8250_rxready(struct uartlirc_bas *bas); Xstatic int ns8250_getc(struct uartlirc_bas *bas, struct mtx *); X Xstatic struct uartlirc_ops uartlirc_ns8250_ops = { X .probe = ns8250_probe, X .init = ns8250_init, X .term = ns8250_term, X .putc = ns8250_putc, X .rxready = ns8250_rxready, X .getc = ns8250_getc, X}; X Xstatic int Xns8250_probe(struct uartlirc_bas *bas) X{ X u_char val; X X /* Check known 0 bits that don't depend on DLAB. */ X val = uartlirc_getreg(bas, REG_IIR); X if (val & 0x30) X return (ENXIO); X /* X * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699 X * chip, but otherwise doesn't seem to have a function. In X * other words, uart(4) works regardless. Ignore that bit so X * the probe succeeds. X */ X val = uartlirc_getreg(bas, REG_MCR); X if (val & 0xa0) X return (ENXIO); X X return (0); X} X Xstatic void Xns8250_init(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X u_char ier; X X if (bas->rclk == 0) X bas->rclk = DEFAULT_RCLK; X ns8250_param(bas, baudrate, databits, stopbits, parity); X X /* Disable all interrupt sources. */ X /* X * We use 0xe0 instead of 0xf0 as the mask because the XScale PXA X * UARTs split the receive time-out interrupt bit out separately as X * 0x10. This gets handled by ier_mask and ier_rxbits below. X */ X ier = uartlirc_getreg(bas, REG_IER) & 0xe0; X uartlirc_setreg(bas, REG_IER, ier); X uartlirc_barrier(bas); X X /* Disable the FIFO (if present). */ X uartlirc_setreg(bas, REG_FCR, 0); X uartlirc_barrier(bas); X X /* Set RTS & DTR. */ X uartlirc_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); X uartlirc_barrier(bas); X X ns8250_clrint(bas); X} X Xstatic void Xns8250_term(struct uartlirc_bas *bas) X{ X X /* Clear RTS & DTR. */ X uartlirc_setreg(bas, REG_MCR, MCR_IE); X uartlirc_barrier(bas); X} X Xstatic void Xns8250_putc(struct uartlirc_bas *bas, int c) X{ X int limit; X X limit = 250000; X while ((uartlirc_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit) X DELAY(4); X uartlirc_setreg(bas, REG_DATA, c); X uartlirc_barrier(bas); X limit = 250000; X while ((uartlirc_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) X DELAY(4); X} X Xstatic int Xns8250_rxready(struct uartlirc_bas *bas) X{ X X return ((uartlirc_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0); X} X Xstatic int Xns8250_getc(struct uartlirc_bas *bas, struct mtx *hwmtx) X{ X int c; X X uartlirc_lock(hwmtx); X X while ((uartlirc_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) { X uartlirc_unlock(hwmtx); X DELAY(4); X uartlirc_lock(hwmtx); X } X X c = uartlirc_getreg(bas, REG_DATA); X X uartlirc_unlock(hwmtx); X X return (c); X} X X/* X * High-level UART interface. X */ Xstruct ns8250_softc { X struct uartlirc_softc base; X uint8_t fcr; X uint8_t ier; X uint8_t mcr; X X uint8_t ier_mask; X uint8_t ier_rxbits; X}; X Xstatic int ns8250_bus_attach(struct uartlirc_softc *); Xstatic int ns8250_bus_detach(struct uartlirc_softc *); Xstatic int ns8250_bus_flush(struct uartlirc_softc *, int); Xstatic int ns8250_bus_getsig(struct uartlirc_softc *); Xstatic int ns8250_bus_ioctl(struct uartlirc_softc *, int, intptr_t); Xstatic int ns8250_bus_ipend(struct uartlirc_softc *); Xstatic int ns8250_bus_param(struct uartlirc_softc *, int, int, int, int); Xstatic int ns8250_bus_probe(struct uartlirc_softc *); Xstatic int ns8250_bus_receive(struct uartlirc_softc *); Xstatic int ns8250_bus_setsig(struct uartlirc_softc *, int); Xstatic int ns8250_bus_transmit(struct uartlirc_softc *); X Xstatic kobj_method_t ns8250_methods[] = { X KOBJMETHOD(uartlirc_attach, ns8250_bus_attach), X KOBJMETHOD(uartlirc_detach, ns8250_bus_detach), X KOBJMETHOD(uartlirc_flush, ns8250_bus_flush), X KOBJMETHOD(uartlirc_getsig, ns8250_bus_getsig), X KOBJMETHOD(uartlirc_ioctl, ns8250_bus_ioctl), X KOBJMETHOD(uartlirc_ipend, ns8250_bus_ipend), X KOBJMETHOD(uartlirc_param, ns8250_bus_param), X KOBJMETHOD(uartlirc_probe, ns8250_bus_probe), X KOBJMETHOD(uartlirc_receive, ns8250_bus_receive), X KOBJMETHOD(uartlirc_setsig, ns8250_bus_setsig), X KOBJMETHOD(uartlirc_transmit, ns8250_bus_transmit), X { 0, 0 } X}; X Xstruct uartlirc_class uartlirc_ns8250_class = { X "ns8250", X ns8250_methods, X sizeof(struct ns8250_softc), X .uc_ops = &uartlirc_ns8250_ops, X .uc_range = 8, X .uc_rclk = DEFAULT_RCLK X}; X X#define SIGCHG(c, i, s, d) \ X if (c) { \ X i |= (i & s) ? s : s | d; \ X } else { \ X i = (i & s) ? (i & ~s) | d : i; \ X } X Xstatic int Xns8250_bus_attach(struct uartlirc_softc *sc) X{ X struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; X struct uartlirc_bas *bas; X unsigned int ivar; X X bas = &sc->sc_bas; X X ns8250->mcr = uartlirc_getreg(bas, REG_MCR); X ns8250->fcr = FCR_ENABLE; X if (!resource_int_value("uartlirc", device_get_unit(sc->sc_dev), "flags", X &ivar)) { X if (UARTLIRC_FLAGS_FCR_RX_LOW(ivar)) X ns8250->fcr |= FCR_RX_LOW; X else if (UARTLIRC_FLAGS_FCR_RX_MEDL(ivar)) X ns8250->fcr |= FCR_RX_MEDL; X else if (UARTLIRC_FLAGS_FCR_RX_HIGH(ivar)) X ns8250->fcr |= FCR_RX_HIGH; X else X ns8250->fcr |= FCR_RX_MEDH; X } else X ns8250->fcr |= FCR_RX_MEDH; X X /* Get IER mask */ X ivar = 0xf0; X resource_int_value("uartlirc", device_get_unit(sc->sc_dev), "ier_mask", X &ivar); X ns8250->ier_mask = (uint8_t)(ivar & 0xff); X X /* Get IER RX interrupt bits */ X ivar = IER_EMSC | IER_ERLS | IER_ERXRDY; X resource_int_value("uartlirc", device_get_unit(sc->sc_dev), "ier_rxbits", X &ivar); X ns8250->ier_rxbits = (uint8_t)(ivar & 0xff); X X uartlirc_setreg(bas, REG_FCR, ns8250->fcr); X uartlirc_barrier(bas); X ns8250_bus_flush(sc, UARTLIRC_FLUSH_RECEIVER|UARTLIRC_FLUSH_TRANSMITTER); X X if (ns8250->mcr & MCR_DTR) X sc->sc_hwsig |= SER_DTR; X if (ns8250->mcr & MCR_RTS) X sc->sc_hwsig |= SER_RTS; X ns8250_bus_getsig(sc); X X ns8250_clrint(bas); X ns8250->ier = uartlirc_getreg(bas, REG_IER) & ns8250->ier_mask; X ns8250->ier |= ns8250->ier_rxbits; X uartlirc_setreg(bas, REG_IER, ns8250->ier); X uartlirc_barrier(bas); X X return (0); X} X Xstatic int Xns8250_bus_detach(struct uartlirc_softc *sc) X{ X struct ns8250_softc *ns8250; X struct uartlirc_bas *bas; X u_char ier; X X ns8250 = (struct ns8250_softc *)sc; X bas = &sc->sc_bas; X ier = uartlirc_getreg(bas, REG_IER) & ns8250->ier_mask; X uartlirc_setreg(bas, REG_IER, ier); X uartlirc_barrier(bas); X ns8250_clrint(bas); X return (0); X} X Xstatic int Xns8250_bus_flush(struct uartlirc_softc *sc, int what) X{ X struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; X struct uartlirc_bas *bas; X int error; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X if (sc->sc_rxfifosz > 1) { X ns8250_flush(bas, what); X uartlirc_setreg(bas, REG_FCR, ns8250->fcr); X uartlirc_barrier(bas); X error = 0; X } else X error = ns8250_drain(bas, what); X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xns8250_bus_getsig(struct uartlirc_softc *sc) X{ X uint32_t new, old, sig; X uint8_t msr; X X do { X old = sc->sc_hwsig; X sig = old; X uartlirc_lock(sc->sc_hwmtx); X msr = uartlirc_getreg(&sc->sc_bas, REG_MSR); X uartlirc_unlock(sc->sc_hwmtx); X SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); X SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); X SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); X SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); X new = sig & ~SER_MASK_DELTA; X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X return (sig); X} X Xstatic int Xns8250_bus_ioctl(struct uartlirc_softc *sc, int request, intptr_t data) X{ X struct uartlirc_bas *bas; X int baudrate, divisor, error; X uint8_t efr, lcr; X X bas = &sc->sc_bas; X error = 0; X uartlirc_lock(sc->sc_hwmtx); X switch (request) { X case UARTLIRC_IOCTL_BREAK: X lcr = uartlirc_getreg(bas, REG_LCR); X if (data) X lcr |= LCR_SBREAK; X else X lcr &= ~LCR_SBREAK; X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_IFLOW: X lcr = uartlirc_getreg(bas, REG_LCR); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, 0xbf); X uartlirc_barrier(bas); X efr = uartlirc_getreg(bas, REG_EFR); X if (data) X efr |= EFR_RTS; X else X efr &= ~EFR_RTS; X uartlirc_setreg(bas, REG_EFR, efr); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_OFLOW: X lcr = uartlirc_getreg(bas, REG_LCR); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, 0xbf); X uartlirc_barrier(bas); X efr = uartlirc_getreg(bas, REG_EFR); X if (data) X efr |= EFR_CTS; X else X efr &= ~EFR_CTS; X uartlirc_setreg(bas, REG_EFR, efr); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_BAUD: X lcr = uartlirc_getreg(bas, REG_LCR); X uartlirc_setreg(bas, REG_LCR, lcr | LCR_DLAB); X uartlirc_barrier(bas); X divisor = uartlirc_getreg(bas, REG_DLL) | X (uartlirc_getreg(bas, REG_DLH) << 8); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_LCR, lcr); X uartlirc_barrier(bas); X baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; X if (baudrate > 0) X *(int*)data = baudrate; X else X error = ENXIO; X break; X default: X error = EINVAL; X break; X } X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xns8250_bus_ipend(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X struct ns8250_softc *ns8250; X int ipend; X uint8_t iir, lsr; X X ns8250 = (struct ns8250_softc *)sc; X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X iir = uartlirc_getreg(bas, REG_IIR); X if (iir & IIR_NOPEND) { X uartlirc_unlock(sc->sc_hwmtx); X return (0); X } X ipend = 0; X if (iir & IIR_RXRDY) { X lsr = uartlirc_getreg(bas, REG_LSR); X if (lsr & LSR_OE) X ipend |= SER_INT_OVERRUN; X if (lsr & LSR_BI) X ipend |= SER_INT_BREAK; X if (lsr & LSR_RXRDY) X ipend |= SER_INT_RXREADY; X } else { X if (iir & IIR_TXRDY) { X ipend |= SER_INT_TXIDLE; X uartlirc_setreg(bas, REG_IER, ns8250->ier); X } else X ipend |= SER_INT_SIGCHG; X } X if (ipend == 0) X ns8250_clrint(bas); X uartlirc_unlock(sc->sc_hwmtx); X return (ipend); X} X Xstatic int Xns8250_bus_param(struct uartlirc_softc *sc, int baudrate, int databits, X int stopbits, int parity) X{ X struct uartlirc_bas *bas; X int error; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X error = ns8250_param(bas, baudrate, databits, stopbits, parity); X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xns8250_bus_probe(struct uartlirc_softc *sc) X{ X struct ns8250_softc *ns8250; X struct uartlirc_bas *bas; X int count, delay, error, limit; X uint8_t lsr, mcr, ier; X X ns8250 = (struct ns8250_softc *)sc; X bas = &sc->sc_bas; X X error = ns8250_probe(bas); X if (error) X return (error); X X mcr = MCR_IE; X if (sc->sc_sysdev == NULL) { X /* By using ns8250_init() we also set DTR and RTS. */ X ns8250_init(bas, 115200, 8, 1, UARTLIRC_PARITY_NONE); X } else X mcr |= MCR_DTR | MCR_RTS; X X error = ns8250_drain(bas, UARTLIRC_DRAIN_TRANSMITTER); X if (error) X return (error); X X /* X * Set loopback mode. This avoids having garbage on the wire and X * also allows us send and receive data. We set DTR and RTS to X * avoid the possibility that automatic flow-control prevents X * any data from being sent. X */ X uartlirc_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_IE | MCR_DTR | MCR_RTS); X uartlirc_barrier(bas); X X /* X * Enable FIFOs. And check that the UART has them. If not, we're X * done. Since this is the first time we enable the FIFOs, we reset X * them. X */ X uartlirc_setreg(bas, REG_FCR, FCR_ENABLE); X uartlirc_barrier(bas); X if (!(uartlirc_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) { X /* X * NS16450 or INS8250. We don't bother to differentiate X * between them. They're too old to be interesting. X */ X uartlirc_setreg(bas, REG_MCR, mcr); X uartlirc_barrier(bas); X sc->sc_rxfifosz = sc->sc_txfifosz = 1; X device_set_desc(sc->sc_dev, "8250 or 16450 or compatible"); X return (0); X } X X uartlirc_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST); X uartlirc_barrier(bas); X X count = 0; X delay = ns8250_delay(bas); X X /* We have FIFOs. Drain the transmitter and receiver. */ X error = ns8250_drain(bas, UARTLIRC_DRAIN_RECEIVER|UARTLIRC_DRAIN_TRANSMITTER); X if (error) { X uartlirc_setreg(bas, REG_MCR, mcr); X uartlirc_setreg(bas, REG_FCR, 0); X uartlirc_barrier(bas); X goto describe; X } X X /* X * We should have a sufficiently clean "pipe" to determine the X * size of the FIFOs. We send as much characters as is reasonable X * and wait for the overflow bit in the LSR register to be X * asserted, counting the characters as we send them. Based on X * that count we know the FIFO size. X */ X do { X uartlirc_setreg(bas, REG_DATA, 0); X uartlirc_barrier(bas); X count++; X X limit = 30; X lsr = 0; X /* X * LSR bits are cleared upon read, so we must accumulate X * them to be able to test LSR_OE below. X */ X while (((lsr |= uartlirc_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 && X --limit) X DELAY(delay); X if (limit == 0) { X ier = uartlirc_getreg(bas, REG_IER) & ns8250->ier_mask; X uartlirc_setreg(bas, REG_IER, ier); X uartlirc_setreg(bas, REG_MCR, mcr); X uartlirc_setreg(bas, REG_FCR, 0); X uartlirc_barrier(bas); X count = 0; X goto describe; X } X } while ((lsr & LSR_OE) == 0 && count < 130); X count--; X X uartlirc_setreg(bas, REG_MCR, mcr); X X /* Reset FIFOs. */ X ns8250_flush(bas, UARTLIRC_FLUSH_RECEIVER|UARTLIRC_FLUSH_TRANSMITTER); X X describe: X if (count >= 14 && count <= 16) { X sc->sc_rxfifosz = 16; X device_set_desc(sc->sc_dev, "16550 or compatible"); X } else if (count >= 28 && count <= 32) { X sc->sc_rxfifosz = 32; X device_set_desc(sc->sc_dev, "16650 or compatible"); X } else if (count >= 56 && count <= 64) { X sc->sc_rxfifosz = 64; X device_set_desc(sc->sc_dev, "16750 or compatible"); X } else if (count >= 112 && count <= 128) { X sc->sc_rxfifosz = 128; X device_set_desc(sc->sc_dev, "16950 or compatible"); X } else { X sc->sc_rxfifosz = 16; X device_set_desc(sc->sc_dev, X "Non-standard ns8250 class UART with FIFOs"); X } X X /* X * Force the Tx FIFO size to 16 bytes for now. We don't program the X * Tx trigger. Also, we assume that all data has been sent when the X * interrupt happens. X */ X sc->sc_txfifosz = 16; X X#if 0 X /* X * XXX there are some issues related to hardware flow control and X * it's likely that uart(4) is the cause. This basicly needs more X * investigation, but we avoid using for hardware flow control X * until then. X */ X /* 16650s or higher have automatic flow control. */ X if (sc->sc_rxfifosz > 16) { X sc->sc_hwiflow = 1; X sc->sc_hwoflow = 1; X } X#endif X X return (0); X} X Xstatic int Xns8250_bus_receive(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int xc; X uint8_t lsr; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X lsr = uartlirc_getreg(bas, REG_LSR); X while (lsr & LSR_RXRDY) { X if (uartlirc_rx_full(sc)) { X sc->sc_rxbuf[sc->sc_rxput] = UARTLIRC_STAT_OVERRUN; X break; X } X xc = uartlirc_getreg(bas, REG_DATA); X if (lsr & LSR_FE) X xc |= UARTLIRC_STAT_FRAMERR; X if (lsr & LSR_PE) X xc |= UARTLIRC_STAT_PARERR; X uartlirc_rx_put(sc, xc); X lsr = uartlirc_getreg(bas, REG_LSR); X } X /* Discard everything left in the Rx FIFO. */ X while (lsr & LSR_RXRDY) { X (void)uartlirc_getreg(bas, REG_DATA); X uartlirc_barrier(bas); X lsr = uartlirc_getreg(bas, REG_LSR); X } X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xns8250_bus_setsig(struct uartlirc_softc *sc, int sig) X{ X struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; X struct uartlirc_bas *bas; X uint32_t new, old; X X bas = &sc->sc_bas; X do { X old = sc->sc_hwsig; X new = old; X if (sig & SER_DDTR) { X SIGCHG(sig & SER_DTR, new, SER_DTR, X SER_DDTR); X } X if (sig & SER_DRTS) { X SIGCHG(sig & SER_RTS, new, SER_RTS, X SER_DRTS); X } X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X uartlirc_lock(sc->sc_hwmtx); X ns8250->mcr &= ~(MCR_DTR|MCR_RTS); X if (new & SER_DTR) X ns8250->mcr |= MCR_DTR; X if (new & SER_RTS) X ns8250->mcr |= MCR_RTS; X uartlirc_setreg(bas, REG_MCR, ns8250->mcr); X uartlirc_barrier(bas); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xns8250_bus_transmit(struct uartlirc_softc *sc) X{ X struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; X struct uartlirc_bas *bas; X int i; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X while ((uartlirc_getreg(bas, REG_LSR) & LSR_THRE) == 0) X ; X uartlirc_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); X uartlirc_barrier(bas); X for (i = 0; i < sc->sc_txdatasz; i++) { X uartlirc_setreg(bas, REG_DATA, sc->sc_txbuf[i]); X uartlirc_barrier(bas); X } X sc->sc_txbusy = 1; X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} 5210da5292a9e1b8f2f52ae6e4ee2dc7 echo x - uartlirc/uartlirc_dev_quicc.c sed 's/^X//' >uartlirc/uartlirc_dev_quicc.c << '7f210a1411ebb5b465a1609735bcb80b' X/*- X * Copyright (c) 2006 Juniper Networks X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_dev_quicc.c,v 1.2.4.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X#include "uartlirc_bus.h" X X#include "uartlirc_if.h" X X#define DEFAULT_RCLK ((266000000 * 2) / 16) X X#define quicc_read2(bas, reg) \ X bus_space_read_2((bas)->bst, (bas)->bsh, reg) X#define quicc_read4(bas, reg) \ X bus_space_read_4((bas)->bst, (bas)->bsh, reg) X X#define quicc_write2(bas, reg, val) \ X bus_space_write_2((bas)->bst, (bas)->bsh, reg, val) X#define quicc_write4(bas, reg, val) \ X bus_space_write_4((bas)->bst, (bas)->bsh, reg, val) X Xstatic int Xquicc_divisor(int rclk, int baudrate) X{ X int act_baud, divisor, error; X X if (baudrate == 0) X return (-1); X X divisor = rclk / baudrate / 16; X if (divisor > 4096) X divisor = ((divisor >> 3) - 2) | 1; X else if (divisor >= 0) X divisor = (divisor - 1) << 1; X if (divisor < 0 || divisor >= 8192) X return (-1); X act_baud = rclk / (((divisor >> 1) + 1) << ((divisor & 1) ? 8 : 4)); X X /* 10 times error in percent: */ X error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1; X X /* 3.0% maximum error tolerance: */ X if (error < -30 || error > 30) X return (-1); X X return (divisor); X} X Xstatic int Xquicc_param(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X int divisor; X uint16_t psmr; X X if (baudrate > 0) { X divisor = quicc_divisor(bas->rclk, baudrate); X if (divisor == -1) X return (EINVAL); X quicc_write4(bas, QUICC_REG_BRG(bas->chan - 1), X divisor | 0x10000); X } X X psmr = 0; X switch (databits) { X case 5: psmr |= 0x0000; break; X case 6: psmr |= 0x1000; break; X case 7: psmr |= 0x2000; break; X case 8: psmr |= 0x3000; break; X default: return (EINVAL); X } X switch (stopbits) { X case 1: psmr |= 0x0000; break; X case 2: psmr |= 0x4000; break; X default: return (EINVAL); X } X switch (parity) { X case UARTLIRC_PARITY_EVEN: psmr |= 0x1a; break; X case UARTLIRC_PARITY_MARK: psmr |= 0x1f; break; X case UARTLIRC_PARITY_NONE: psmr |= 0x00; break; X case UARTLIRC_PARITY_ODD: psmr |= 0x10; break; X case UARTLIRC_PARITY_SPACE: psmr |= 0x15; break; X default: return (EINVAL); X } X quicc_write2(bas, QUICC_REG_SCC_PSMR(bas->chan - 1), psmr); X return (0); X} X Xstatic void Xquicc_setup(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X X if (bas->rclk == 0) X bas->rclk = DEFAULT_RCLK; X X /* X * GSMR_L = 0x00028034 X * GSMR_H = 0x00000020 X */ X quicc_param(bas, baudrate, databits, stopbits, parity); X X quicc_write2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1), ~0); X quicc_write2(bas, QUICC_REG_SCC_SCCM(bas->chan - 1), 0x0027); X} X X/* X * Low-level UART interface. X */ Xstatic int quicc_probe(struct uartlirc_bas *bas); Xstatic void quicc_init(struct uartlirc_bas *bas, int, int, int, int); Xstatic void quicc_term(struct uartlirc_bas *bas); Xstatic void quicc_putc(struct uartlirc_bas *bas, int); Xstatic int quicc_rxready(struct uartlirc_bas *bas); Xstatic int quicc_getc(struct uartlirc_bas *bas, struct mtx *); X Xstatic struct uartlirc_ops uartlirc_quicc_ops = { X .probe = quicc_probe, X .init = quicc_init, X .term = quicc_term, X .putc = quicc_putc, X .rxready = quicc_rxready, X .getc = quicc_getc, X}; X Xstatic int Xquicc_probe(struct uartlirc_bas *bas) X{ X X return (0); X} X Xstatic void Xquicc_init(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X X quicc_setup(bas, baudrate, databits, stopbits, parity); X} X Xstatic void Xquicc_term(struct uartlirc_bas *bas) X{ X} X Xstatic void Xquicc_putc(struct uartlirc_bas *bas, int c) X{ X int unit; X uint16_t toseq; X X unit = bas->chan - 1; X while (quicc_read2(bas, QUICC_PRAM_SCC_UART_TOSEQ(unit)) & 0x2000) X DELAY(10); X X toseq = 0x2000 | (c & 0xff); X quicc_write2(bas, QUICC_PRAM_SCC_UART_TOSEQ(unit), toseq); X} X Xstatic int Xquicc_rxready(struct uartlirc_bas *bas) X{ X uint16_t rb; X X rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); X return ((quicc_read2(bas, rb) & 0x8000) ? 0 : 1); X} X Xstatic int Xquicc_getc(struct uartlirc_bas *bas, struct mtx *hwmtx) X{ X volatile char *buf; X int c; X uint16_t rb, sc; X X uartlirc_lock(hwmtx); X X rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); X X while ((sc = quicc_read2(bas, rb)) & 0x8000) { X uartlirc_unlock(hwmtx); X DELAY(4); X uartlirc_lock(hwmtx); X } X X buf = (void *)(uintptr_t)quicc_read4(bas, rb + 4); X c = *buf; X quicc_write2(bas, rb, sc | 0x8000); X X uartlirc_unlock(hwmtx); X X return (c); X} X X/* X * High-level UART interface. X */ Xstruct quicc_softc { X struct uartlirc_softc base; X}; X Xstatic int quicc_bus_attach(struct uartlirc_softc *); Xstatic int quicc_bus_detach(struct uartlirc_softc *); Xstatic int quicc_bus_flush(struct uartlirc_softc *, int); Xstatic int quicc_bus_getsig(struct uartlirc_softc *); Xstatic int quicc_bus_ioctl(struct uartlirc_softc *, int, intptr_t); Xstatic int quicc_bus_ipend(struct uartlirc_softc *); Xstatic int quicc_bus_param(struct uartlirc_softc *, int, int, int, int); Xstatic int quicc_bus_probe(struct uartlirc_softc *); Xstatic int quicc_bus_receive(struct uartlirc_softc *); Xstatic int quicc_bus_setsig(struct uartlirc_softc *, int); Xstatic int quicc_bus_transmit(struct uartlirc_softc *); X Xstatic kobj_method_t quicc_methods[] = { X KOBJMETHOD(uartlirc_attach, quicc_bus_attach), X KOBJMETHOD(uartlirc_detach, quicc_bus_detach), X KOBJMETHOD(uartlirc_flush, quicc_bus_flush), X KOBJMETHOD(uartlirc_getsig, quicc_bus_getsig), X KOBJMETHOD(uartlirc_ioctl, quicc_bus_ioctl), X KOBJMETHOD(uartlirc_ipend, quicc_bus_ipend), X KOBJMETHOD(uartlirc_param, quicc_bus_param), X KOBJMETHOD(uartlirc_probe, quicc_bus_probe), X KOBJMETHOD(uartlirc_receive, quicc_bus_receive), X KOBJMETHOD(uartlirc_setsig, quicc_bus_setsig), X KOBJMETHOD(uartlirc_transmit, quicc_bus_transmit), X { 0, 0 } X}; X Xstruct uartlirc_class uartlirc_quicc_class = { X "quicc", X quicc_methods, X sizeof(struct quicc_softc), X .uc_ops = &uartlirc_quicc_ops, X .uc_range = 2, X .uc_rclk = DEFAULT_RCLK X}; X X#define SIGCHG(c, i, s, d) \ X if (c) { \ X i |= (i & s) ? s : s | d; \ X } else { \ X i = (i & s) ? (i & ~s) | d : i; \ X } X Xstatic int Xquicc_bus_attach(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X struct uartlirc_devinfo *di; X uint16_t st, rb; X X bas = &sc->sc_bas; X if (sc->sc_sysdev != NULL) { X di = sc->sc_sysdev; X quicc_param(bas, di->baudrate, di->databits, di->stopbits, X di->parity); X } else { X quicc_setup(bas, 9600, 8, 1, UARTLIRC_PARITY_NONE); X } X X sc->sc_rxfifosz = 1; X sc->sc_txfifosz = 1; X X /* Enable interrupts on the receive buffer. */ X rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); X st = quicc_read2(bas, rb); X quicc_write2(bas, rb, st | 0x9000); X X (void)quicc_bus_getsig(sc); X X return (0); X} X Xstatic int Xquicc_bus_detach(struct uartlirc_softc *sc) X{ X X return (0); X} X Xstatic int Xquicc_bus_flush(struct uartlirc_softc *sc, int what) X{ X X return (0); X} X Xstatic int Xquicc_bus_getsig(struct uartlirc_softc *sc) X{ X uint32_t new, old, sig; X uint32_t dummy; X X do { X old = sc->sc_hwsig; X sig = old; X uartlirc_lock(sc->sc_hwmtx); X /* XXX SIGNALS */ X dummy = 0; X uartlirc_unlock(sc->sc_hwmtx); X SIGCHG(dummy, sig, SER_CTS, SER_DCTS); X SIGCHG(dummy, sig, SER_DCD, SER_DDCD); X SIGCHG(dummy, sig, SER_DSR, SER_DDSR); X new = sig & ~SER_MASK_DELTA; X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X return (sig); X} X Xstatic int Xquicc_bus_ioctl(struct uartlirc_softc *sc, int request, intptr_t data) X{ X struct uartlirc_bas *bas; X uint32_t brg; X int baudrate, error; X X bas = &sc->sc_bas; X error = 0; X uartlirc_lock(sc->sc_hwmtx); X switch (request) { X case UARTLIRC_IOCTL_BREAK: X break; X case UARTLIRC_IOCTL_BAUD: X brg = quicc_read4(bas, QUICC_REG_BRG(bas->chan - 1)) & 0x1fff; X brg = (brg & 1) ? (brg + 1) << 3 : (brg + 2) >> 1; X baudrate = bas->rclk / (brg * 16); X *(int*)data = baudrate; X break; X default: X error = EINVAL; X break; X } X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xquicc_bus_ipend(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int ipend; X uint16_t scce; X X bas = &sc->sc_bas; X ipend = 0; X X uartlirc_lock(sc->sc_hwmtx); X scce = quicc_read2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1)); X quicc_write2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1), ~0); X uartlirc_unlock(sc->sc_hwmtx); X if (scce & 0x0001) X ipend |= SER_INT_RXREADY; X if (scce & 0x0002) X ipend |= SER_INT_TXIDLE; X if (scce & 0x0004) X ipend |= SER_INT_OVERRUN; X if (scce & 0x0020) X ipend |= SER_INT_BREAK; X /* XXX SIGNALS */ X return (ipend); X} X Xstatic int Xquicc_bus_param(struct uartlirc_softc *sc, int baudrate, int databits, X int stopbits, int parity) X{ X int error; X X uartlirc_lock(sc->sc_hwmtx); X error = quicc_param(&sc->sc_bas, baudrate, databits, stopbits, X parity); X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xquicc_bus_probe(struct uartlirc_softc *sc) X{ X char buf[80]; X int error; X X error = quicc_probe(&sc->sc_bas); X if (error) X return (error); X X snprintf(buf, sizeof(buf), "quicc, channel %d", sc->sc_bas.chan); X device_set_desc_copy(sc->sc_dev, buf); X return (0); X} X Xstatic int Xquicc_bus_receive(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X volatile char *buf; X uint16_t st, rb; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); X st = quicc_read2(bas, rb); X buf = (void *)(uintptr_t)quicc_read4(bas, rb + 4); X uartlirc_rx_put(sc, *buf); X quicc_write2(bas, rb, st | 0x9000); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xquicc_bus_setsig(struct uartlirc_softc *sc, int sig) X{ X struct uartlirc_bas *bas; X uint32_t new, old; X X bas = &sc->sc_bas; X do { X old = sc->sc_hwsig; X new = old; X if (sig & SER_DDTR) { X SIGCHG(sig & SER_DTR, new, SER_DTR, X SER_DDTR); X } X if (sig & SER_DRTS) { X SIGCHG(sig & SER_RTS, new, SER_RTS, X SER_DRTS); X } X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X X uartlirc_lock(sc->sc_hwmtx); X /* XXX SIGNALS */ X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xquicc_bus_transmit(struct uartlirc_softc *sc) X{ X volatile char *buf; X struct uartlirc_bas *bas; X uint16_t st, tb; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X tb = quicc_read2(bas, QUICC_PRAM_SCC_TBASE(bas->chan - 1)); X st = quicc_read2(bas, tb); X buf = (void *)(uintptr_t)quicc_read4(bas, tb + 4); X *buf = sc->sc_txbuf[0]; X quicc_write2(bas, tb + 2, 1); X quicc_write2(bas, tb, st | 0x9000); X sc->sc_txbusy = 1; X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} 7f210a1411ebb5b465a1609735bcb80b echo x - uartlirc/uartlirc_dev_sab82532.c sed 's/^X//' >uartlirc/uartlirc_dev_sab82532.c << 'c7a2be52f77178009819512afaaa6209' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_dev_sab82532.c,v 1.16.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X#include "uartlirc_bus.h" X X#include X X#include "uartlirc_if.h" X X#define DEFAULT_RCLK 29491200 X X/* X * NOTE: To allow us to read the baudrate divisor from the chip, we X * copy the value written to the write-only BGR register to an unused X * read-write register. We use TCR for that. X */ X Xstatic int Xsab82532_delay(struct uartlirc_bas *bas) X{ X int divisor, m, n; X uint8_t bgr, ccr2; X X bgr = uartlirc_getreg(bas, SAB_TCR); X ccr2 = uartlirc_getreg(bas, SAB_CCR2); X n = (bgr & 0x3f) + 1; X m = (bgr >> 6) | ((ccr2 >> 4) & 0xC); X divisor = n * (1<rclk); X} X Xstatic int Xsab82532_divisor(int rclk, int baudrate) X{ X int act_baud, act_div, divisor; X int error, m, n; X X if (baudrate == 0) X return (0); X X divisor = (rclk / (baudrate << 3) + 1) >> 1; X if (divisor < 2 || divisor >= 1048576) X return (0); X X /* Find the best (N+1,M) pair. */ X for (m = 1; m < 15; m++) { X n = divisor / (1< 63) X continue; X act_div = n * (1<> 1; X X /* 3.0% maximum error tolerance: */ X if (error < -30 || error > 30) X continue; X X /* Got it. */ X return ((n - 1) | (m << 6)); X } X X return (0); X} X Xstatic void Xsab82532_flush(struct uartlirc_bas *bas, int what) X{ X X if (what & UARTLIRC_FLUSH_TRANSMITTER) { X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_XRES); X uartlirc_barrier(bas); X } X if (what & UARTLIRC_FLUSH_RECEIVER) { X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_RRES); X uartlirc_barrier(bas); X } X} X Xstatic int Xsab82532_param(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X int divisor; X uint8_t ccr2, dafo; X X if (databits >= 8) X dafo = SAB_DAFO_CHL_CS8; X else if (databits == 7) X dafo = SAB_DAFO_CHL_CS7; X else if (databits == 6) X dafo = SAB_DAFO_CHL_CS6; X else X dafo = SAB_DAFO_CHL_CS5; X if (stopbits > 1) X dafo |= SAB_DAFO_STOP; X switch (parity) { X case UARTLIRC_PARITY_EVEN: dafo |= SAB_DAFO_PAR_EVEN; break; X case UARTLIRC_PARITY_MARK: dafo |= SAB_DAFO_PAR_MARK; break; X case UARTLIRC_PARITY_NONE: dafo |= SAB_DAFO_PAR_NONE; break; X case UARTLIRC_PARITY_ODD: dafo |= SAB_DAFO_PAR_ODD; break; X case UARTLIRC_PARITY_SPACE: dafo |= SAB_DAFO_PAR_SPACE; break; X default: return (EINVAL); X } X X /* Set baudrate. */ X if (baudrate > 0) { X divisor = sab82532_divisor(bas->rclk, baudrate); X if (divisor == 0) X return (EINVAL); X uartlirc_setreg(bas, SAB_BGR, divisor & 0xff); X uartlirc_barrier(bas); X /* Allow reading the (n-1,m) tuple from the chip. */ X uartlirc_setreg(bas, SAB_TCR, divisor & 0xff); X uartlirc_barrier(bas); X ccr2 = uartlirc_getreg(bas, SAB_CCR2); X ccr2 &= ~(SAB_CCR2_BR9 | SAB_CCR2_BR8); X ccr2 |= (divisor >> 2) & (SAB_CCR2_BR9 | SAB_CCR2_BR8); X uartlirc_setreg(bas, SAB_CCR2, ccr2); X uartlirc_barrier(bas); X } X X uartlirc_setreg(bas, SAB_DAFO, dafo); X uartlirc_barrier(bas); X return (0); X} X X/* X * Low-level UART interface. X */ Xstatic int sab82532_probe(struct uartlirc_bas *bas); Xstatic void sab82532_init(struct uartlirc_bas *bas, int, int, int, int); Xstatic void sab82532_term(struct uartlirc_bas *bas); Xstatic void sab82532_putc(struct uartlirc_bas *bas, int); Xstatic int sab82532_rxready(struct uartlirc_bas *bas); Xstatic int sab82532_getc(struct uartlirc_bas *bas, struct mtx *); X Xstatic struct uartlirc_ops uartlirc_sab82532_ops = { X .probe = sab82532_probe, X .init = sab82532_init, X .term = sab82532_term, X .putc = sab82532_putc, X .rxready = sab82532_rxready, X .getc = sab82532_getc, X}; X Xstatic int Xsab82532_probe(struct uartlirc_bas *bas) X{ X X return (0); X} X Xstatic void Xsab82532_init(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X uint8_t ccr0, pvr; X X if (bas->rclk == 0) X bas->rclk = DEFAULT_RCLK; X X /* X * Set all pins, except the DTR pins (pin 1 and 2) to be inputs. X * Pin 4 is magical, meaning that I don't know what it does, but X * it too has to be set to output. X */ X uartlirc_setreg(bas, SAB_PCR, X ~(SAB_PVR_DTR_A|SAB_PVR_DTR_B|SAB_PVR_MAGIC)); X uartlirc_barrier(bas); X /* Disable port interrupts. */ X uartlirc_setreg(bas, SAB_PIM, 0xff); X uartlirc_barrier(bas); X /* Interrupts are active low. */ X uartlirc_setreg(bas, SAB_IPC, SAB_IPC_ICPL); X uartlirc_barrier(bas); X /* Set DTR. */ X pvr = uartlirc_getreg(bas, SAB_PVR); X switch (bas->chan) { X case 1: X pvr &= ~SAB_PVR_DTR_A; X break; X case 2: X pvr &= ~SAB_PVR_DTR_B; X break; X } X uartlirc_setreg(bas, SAB_PVR, pvr | SAB_PVR_MAGIC); X uartlirc_barrier(bas); X X /* power down */ X uartlirc_setreg(bas, SAB_CCR0, 0); X uartlirc_barrier(bas); X X /* set basic configuration */ X ccr0 = SAB_CCR0_MCE|SAB_CCR0_SC_NRZ|SAB_CCR0_SM_ASYNC; X uartlirc_setreg(bas, SAB_CCR0, ccr0); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_CCR1, SAB_CCR1_ODS|SAB_CCR1_BCR|SAB_CCR1_CM_7); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_CCR2, SAB_CCR2_BDF|SAB_CCR2_SSEL|SAB_CCR2_TOE); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_CCR3, 0); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_CCR4, SAB_CCR4_MCK4|SAB_CCR4_EBRG|SAB_CCR4_ICD); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_MODE, SAB_MODE_FCTS|SAB_MODE_RTS|SAB_MODE_RAC); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_RFC, SAB_RFC_DPS|SAB_RFC_RFDF| X SAB_RFC_RFTH_32CHAR); X uartlirc_barrier(bas); X X sab82532_param(bas, baudrate, databits, stopbits, parity); X X /* Clear interrupts. */ X uartlirc_setreg(bas, SAB_IMR0, (unsigned char)~SAB_IMR0_TCD); X uartlirc_setreg(bas, SAB_IMR1, 0xff); X uartlirc_barrier(bas); X uartlirc_getreg(bas, SAB_ISR0); X uartlirc_getreg(bas, SAB_ISR1); X uartlirc_barrier(bas); X X sab82532_flush(bas, UARTLIRC_FLUSH_TRANSMITTER|UARTLIRC_FLUSH_RECEIVER); X X /* Power up. */ X uartlirc_setreg(bas, SAB_CCR0, ccr0|SAB_CCR0_PU); X uartlirc_barrier(bas); X} X Xstatic void Xsab82532_term(struct uartlirc_bas *bas) X{ X uint8_t pvr; X X pvr = uartlirc_getreg(bas, SAB_PVR); X switch (bas->chan) { X case 1: X pvr |= SAB_PVR_DTR_A; X break; X case 2: X pvr |= SAB_PVR_DTR_B; X break; X } X uartlirc_setreg(bas, SAB_PVR, pvr); X uartlirc_barrier(bas); X} X Xstatic void Xsab82532_putc(struct uartlirc_bas *bas, int c) X{ X int delay, limit; X X /* 1/10th the time to transmit 1 character (estimate). */ X delay = sab82532_delay(bas); X X limit = 20; X while ((uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit) X DELAY(delay); X uartlirc_setreg(bas, SAB_TIC, c); X limit = 20; X while ((uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_TEC) && --limit) X DELAY(delay); X} X Xstatic int Xsab82532_rxready(struct uartlirc_bas *bas) X{ X X return ((uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) != 0 ? 1 : 0); X} X Xstatic int Xsab82532_getc(struct uartlirc_bas *bas, struct mtx *hwmtx) X{ X int c, delay; X X uartlirc_lock(hwmtx); X X /* 1/10th the time to transmit 1 character (estimate). */ X delay = sab82532_delay(bas); X X while (!(uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)) { X uartlirc_unlock(hwmtx); X DELAY(delay); X uartlirc_lock(hwmtx); X } X X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); X uartlirc_barrier(bas); X X while (!(uartlirc_getreg(bas, SAB_ISR0) & SAB_ISR0_TCD)) X DELAY(delay); X X c = uartlirc_getreg(bas, SAB_RFIFO); X uartlirc_barrier(bas); X X /* Blow away everything left in the FIFO... */ X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); X uartlirc_barrier(bas); X X uartlirc_unlock(hwmtx); X X return (c); X} X X/* X * High-level UART interface. X */ Xstruct sab82532_softc { X struct uartlirc_softc base; X}; X Xstatic int sab82532_bus_attach(struct uartlirc_softc *); Xstatic int sab82532_bus_detach(struct uartlirc_softc *); Xstatic int sab82532_bus_flush(struct uartlirc_softc *, int); Xstatic int sab82532_bus_getsig(struct uartlirc_softc *); Xstatic int sab82532_bus_ioctl(struct uartlirc_softc *, int, intptr_t); Xstatic int sab82532_bus_ipend(struct uartlirc_softc *); Xstatic int sab82532_bus_param(struct uartlirc_softc *, int, int, int, int); Xstatic int sab82532_bus_probe(struct uartlirc_softc *); Xstatic int sab82532_bus_receive(struct uartlirc_softc *); Xstatic int sab82532_bus_setsig(struct uartlirc_softc *, int); Xstatic int sab82532_bus_transmit(struct uartlirc_softc *); X Xstatic kobj_method_t sab82532_methods[] = { X KOBJMETHOD(uartlirc_attach, sab82532_bus_attach), X KOBJMETHOD(uartlirc_detach, sab82532_bus_detach), X KOBJMETHOD(uartlirc_flush, sab82532_bus_flush), X KOBJMETHOD(uartlirc_getsig, sab82532_bus_getsig), X KOBJMETHOD(uartlirc_ioctl, sab82532_bus_ioctl), X KOBJMETHOD(uartlirc_ipend, sab82532_bus_ipend), X KOBJMETHOD(uartlirc_param, sab82532_bus_param), X KOBJMETHOD(uartlirc_probe, sab82532_bus_probe), X KOBJMETHOD(uartlirc_receive, sab82532_bus_receive), X KOBJMETHOD(uartlirc_setsig, sab82532_bus_setsig), X KOBJMETHOD(uartlirc_transmit, sab82532_bus_transmit), X { 0, 0 } X}; X Xstruct uartlirc_class uartlirc_sab82532_class = { X "sab82532", X sab82532_methods, X sizeof(struct sab82532_softc), X .uc_ops = &uartlirc_sab82532_ops, X .uc_range = 64, X .uc_rclk = DEFAULT_RCLK X}; X X#define SIGCHG(c, i, s, d) \ X if (c) { \ X i |= (i & s) ? s : s | d; \ X } else { \ X i = (i & s) ? (i & ~s) | d : i; \ X } X Xstatic int Xsab82532_bus_attach(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X uint8_t imr0, imr1; X X bas = &sc->sc_bas; X if (sc->sc_sysdev == NULL) X sab82532_init(bas, 9600, 8, 1, UARTLIRC_PARITY_NONE); X X sc->sc_rxfifosz = 32; X sc->sc_txfifosz = 32; X X imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO| X SAB_IMR0_RPF; X uartlirc_setreg(bas, SAB_IMR0, 0xff & ~imr0); X imr1 = SAB_IMR1_BRKT|SAB_IMR1_ALLS|SAB_IMR1_CSC; X uartlirc_setreg(bas, SAB_IMR1, 0xff & ~imr1); X uartlirc_barrier(bas); X X if (sc->sc_sysdev == NULL) X sab82532_bus_setsig(sc, SER_DDTR|SER_DRTS); X (void)sab82532_bus_getsig(sc); X return (0); X} X Xstatic int Xsab82532_bus_detach(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X X bas = &sc->sc_bas; X uartlirc_setreg(bas, SAB_IMR0, 0xff); X uartlirc_setreg(bas, SAB_IMR1, 0xff); X uartlirc_barrier(bas); X uartlirc_getreg(bas, SAB_ISR0); X uartlirc_getreg(bas, SAB_ISR1); X uartlirc_barrier(bas); X uartlirc_setreg(bas, SAB_CCR0, 0); X uartlirc_barrier(bas); X return (0); X} X Xstatic int Xsab82532_bus_flush(struct uartlirc_softc *sc, int what) X{ X X uartlirc_lock(sc->sc_hwmtx); X sab82532_flush(&sc->sc_bas, what); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xsab82532_bus_getsig(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X uint32_t new, old, sig; X uint8_t pvr, star, vstr; X X bas = &sc->sc_bas; X do { X old = sc->sc_hwsig; X sig = old; X uartlirc_lock(sc->sc_hwmtx); X star = uartlirc_getreg(bas, SAB_STAR); X SIGCHG(star & SAB_STAR_CTS, sig, SER_CTS, SER_DCTS); X vstr = uartlirc_getreg(bas, SAB_VSTR); X SIGCHG(vstr & SAB_VSTR_CD, sig, SER_DCD, SER_DDCD); X pvr = ~uartlirc_getreg(bas, SAB_PVR); X switch (bas->chan) { X case 1: X pvr &= SAB_PVR_DSR_A; X break; X case 2: X pvr &= SAB_PVR_DSR_B; X break; X } X SIGCHG(pvr, sig, SER_DSR, SER_DDSR); X uartlirc_unlock(sc->sc_hwmtx); X new = sig & ~SER_MASK_DELTA; X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X return (sig); X} X Xstatic int Xsab82532_bus_ioctl(struct uartlirc_softc *sc, int request, intptr_t data) X{ X struct uartlirc_bas *bas; X uint8_t dafo, mode; X int error; X X bas = &sc->sc_bas; X error = 0; X uartlirc_lock(sc->sc_hwmtx); X switch (request) { X case UARTLIRC_IOCTL_BREAK: X dafo = uartlirc_getreg(bas, SAB_DAFO); X if (data) X dafo |= SAB_DAFO_XBRK; X else X dafo &= ~SAB_DAFO_XBRK; X uartlirc_setreg(bas, SAB_DAFO, dafo); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_IFLOW: X mode = uartlirc_getreg(bas, SAB_MODE); X if (data) { X mode &= ~SAB_MODE_RTS; X mode |= SAB_MODE_FRTS; X } else { X mode |= SAB_MODE_RTS; X mode &= ~SAB_MODE_FRTS; X } X uartlirc_setreg(bas, SAB_MODE, mode); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_OFLOW: X mode = uartlirc_getreg(bas, SAB_MODE); X if (data) X mode &= ~SAB_MODE_FCTS; X else X mode |= SAB_MODE_FCTS; X uartlirc_setreg(bas, SAB_MODE, mode); X uartlirc_barrier(bas); X break; X default: X error = EINVAL; X break; X } X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xsab82532_bus_ipend(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int ipend; X uint8_t isr0, isr1; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X isr0 = uartlirc_getreg(bas, SAB_ISR0); X isr1 = uartlirc_getreg(bas, SAB_ISR1); X uartlirc_barrier(bas); X if (isr0 & SAB_ISR0_TIME) { X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD); X uartlirc_barrier(bas); X } X uartlirc_unlock(sc->sc_hwmtx); X X ipend = 0; X if (isr1 & SAB_ISR1_BRKT) X ipend |= SER_INT_BREAK; X if (isr0 & SAB_ISR0_RFO) X ipend |= SER_INT_OVERRUN; X if (isr0 & (SAB_ISR0_TCD|SAB_ISR0_RPF)) X ipend |= SER_INT_RXREADY; X if ((isr0 & SAB_ISR0_CDSC) || (isr1 & SAB_ISR1_CSC)) X ipend |= SER_INT_SIGCHG; X if (isr1 & SAB_ISR1_ALLS) X ipend |= SER_INT_TXIDLE; X X return (ipend); X} X Xstatic int Xsab82532_bus_param(struct uartlirc_softc *sc, int baudrate, int databits, X int stopbits, int parity) X{ X struct uartlirc_bas *bas; X int error; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X error = sab82532_param(bas, baudrate, databits, stopbits, parity); X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xsab82532_bus_probe(struct uartlirc_softc *sc) X{ X char buf[80]; X const char *vstr; X int error; X char ch; X X error = sab82532_probe(&sc->sc_bas); X if (error) X return (error); X X ch = sc->sc_bas.chan - 1 + 'A'; X X switch (uartlirc_getreg(&sc->sc_bas, SAB_VSTR) & SAB_VSTR_VMASK) { X case SAB_VSTR_V_1: X vstr = "v1"; X break; X case SAB_VSTR_V_2: X vstr = "v2"; X break; X case SAB_VSTR_V_32: X vstr = "v3.2"; X sc->sc_hwiflow = 0; /* CTS doesn't work with RFC:RFDF. */ X sc->sc_hwoflow = 1; X break; X default: X vstr = "v4?"; X break; X } X X snprintf(buf, sizeof(buf), "SAB 82532 %s, channel %c", vstr, ch); X device_set_desc_copy(sc->sc_dev, buf); X return (0); X} X Xstatic int Xsab82532_bus_receive(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int i, rbcl, xc; X uint8_t s; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X if (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) { X rbcl = uartlirc_getreg(bas, SAB_RBCL) & 31; X if (rbcl == 0) X rbcl = 32; X for (i = 0; i < rbcl; i += 2) { X if (uartlirc_rx_full(sc)) { X sc->sc_rxbuf[sc->sc_rxput] = UARTLIRC_STAT_OVERRUN; X break; X } X xc = uartlirc_getreg(bas, SAB_RFIFO); X s = uartlirc_getreg(bas, SAB_RFIFO + 1); X if (s & SAB_RSTAT_FE) X xc |= UARTLIRC_STAT_FRAMERR; X if (s & SAB_RSTAT_PE) X xc |= UARTLIRC_STAT_PARERR; X uartlirc_rx_put(sc, xc); X } X } X X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_RMC); X uartlirc_barrier(bas); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xsab82532_bus_setsig(struct uartlirc_softc *sc, int sig) X{ X struct uartlirc_bas *bas; X uint32_t new, old; X uint8_t mode, pvr; X X bas = &sc->sc_bas; X do { X old = sc->sc_hwsig; X new = old; X if (sig & SER_DDTR) { X SIGCHG(sig & SER_DTR, new, SER_DTR, X SER_DDTR); X } X if (sig & SER_DRTS) { X SIGCHG(sig & SER_RTS, new, SER_RTS, X SER_DRTS); X } X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X X uartlirc_lock(sc->sc_hwmtx); X /* Set DTR pin. */ X pvr = uartlirc_getreg(bas, SAB_PVR); X switch (bas->chan) { X case 1: X if (new & SER_DTR) X pvr &= ~SAB_PVR_DTR_A; X else X pvr |= SAB_PVR_DTR_A; X break; X case 2: X if (new & SER_DTR) X pvr &= ~SAB_PVR_DTR_B; X else X pvr |= SAB_PVR_DTR_B; X break; X } X uartlirc_setreg(bas, SAB_PVR, pvr); X X /* Set RTS pin. */ X mode = uartlirc_getreg(bas, SAB_MODE); X if (new & SER_RTS) X mode &= ~SAB_MODE_FRTS; X else X mode |= SAB_MODE_FRTS; X uartlirc_setreg(bas, SAB_MODE, mode); X uartlirc_barrier(bas); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xsab82532_bus_transmit(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int i; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X while (!(uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_XFW)) X ; X for (i = 0; i < sc->sc_txdatasz; i++) X uartlirc_setreg(bas, SAB_XFIFO + i, sc->sc_txbuf[i]); X uartlirc_barrier(bas); X while (uartlirc_getreg(bas, SAB_STAR) & SAB_STAR_CEC) X ; X uartlirc_setreg(bas, SAB_CMDR, SAB_CMDR_XF); X sc->sc_txbusy = 1; X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} c7a2be52f77178009819512afaaa6209 echo x - uartlirc/uartlirc_dev_z8530.c sed 's/^X//' >uartlirc/uartlirc_dev_z8530.c << '525f4a1c43f1258d814d4102fb292caa' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_dev_z8530.c,v 1.22.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X#include "uartlirc_bus.h" X X#include X X#include "uartlirc_if.h" X X#define DEFAULT_RCLK 307200 X X/* Hack! */ X#ifdef __powerpc__ X#define UARTLIRC_PCLK 0 X#else X#define UARTLIRC_PCLK MCB2_PCLK X#endif X X/* Multiplexed I/O. */ Xstatic __inline void Xuartlirc_setmreg(struct uartlirc_bas *bas, int reg, int val) X{ X X uartlirc_setreg(bas, REG_CTRL, reg); X uartlirc_barrier(bas); X uartlirc_setreg(bas, REG_CTRL, val); X} X Xstatic __inline uint8_t Xuartlirc_getmreg(struct uartlirc_bas *bas, int reg) X{ X X uartlirc_setreg(bas, REG_CTRL, reg); X uartlirc_barrier(bas); X return (uartlirc_getreg(bas, REG_CTRL)); X} X Xstatic int Xz8530_divisor(int rclk, int baudrate) X{ X int act_baud, divisor, error; X X if (baudrate == 0) X return (-1); X X divisor = (rclk + baudrate) / (baudrate << 1) - 2; X if (divisor < 0 || divisor >= 65536) X return (-1); X act_baud = rclk / 2 / (divisor + 2); X X /* 10 times error in percent: */ X error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1; X X /* 3.0% maximum error tolerance: */ X if (error < -30 || error > 30) X return (-1); X X return (divisor); X} X Xstatic int Xz8530_param(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity, uint8_t *tpcp) X{ X int divisor; X uint8_t mpm, rpc, tpc; X X rpc = RPC_RXE; X mpm = MPM_CM16; X tpc = TPC_TXE | (*tpcp & (TPC_DTR | TPC_RTS)); X X if (databits >= 8) { X rpc |= RPC_RB8; X tpc |= TPC_TB8; X } else if (databits == 7) { X rpc |= RPC_RB7; X tpc |= TPC_TB7; X } else if (databits == 6) { X rpc |= RPC_RB6; X tpc |= TPC_TB6; X } else { X rpc |= RPC_RB5; X tpc |= TPC_TB5; X } X mpm |= (stopbits > 1) ? MPM_SB2 : MPM_SB1; X switch (parity) { X case UARTLIRC_PARITY_EVEN: mpm |= MPM_PE | MPM_EVEN; break; X case UARTLIRC_PARITY_NONE: break; X case UARTLIRC_PARITY_ODD: mpm |= MPM_PE; break; X default: return (EINVAL); X } X X if (baudrate > 0) { X divisor = z8530_divisor(bas->rclk, baudrate); X if (divisor == -1) X return (EINVAL); X } else X divisor = -1; X X uartlirc_setmreg(bas, WR_MCB2, UARTLIRC_PCLK); X uartlirc_barrier(bas); X X if (divisor >= 0) { X uartlirc_setmreg(bas, WR_TCL, divisor & 0xff); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_TCH, (divisor >> 8) & 0xff); X uartlirc_barrier(bas); X } X X uartlirc_setmreg(bas, WR_RPC, rpc); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_MPM, mpm); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_TPC, tpc); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_MCB2, UARTLIRC_PCLK | MCB2_BRGE); X uartlirc_barrier(bas); X *tpcp = tpc; X return (0); X} X Xstatic int Xz8530_setup(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X uint8_t tpc; X X if (bas->rclk == 0) X bas->rclk = DEFAULT_RCLK; X X /* Assume we don't need to perform a full hardware reset. */ X switch (bas->chan) { X case 1: X uartlirc_setmreg(bas, WR_MIC, MIC_NV | MIC_CRA); X break; X case 2: X uartlirc_setmreg(bas, WR_MIC, MIC_NV | MIC_CRB); X break; X } X uartlirc_barrier(bas); X /* Set clock sources. */ X uartlirc_setmreg(bas, WR_CMC, CMC_RC_BRG | CMC_TC_BRG); X uartlirc_setmreg(bas, WR_MCB2, UARTLIRC_PCLK); X uartlirc_barrier(bas); X /* Set data encoding. */ X uartlirc_setmreg(bas, WR_MCB1, MCB1_NRZ); X uartlirc_barrier(bas); X X tpc = TPC_DTR | TPC_RTS; X z8530_param(bas, baudrate, databits, stopbits, parity, &tpc); X return (int)tpc; X} X X/* X * Low-level UART interface. X */ Xstatic int z8530_probe(struct uartlirc_bas *bas); Xstatic void z8530_init(struct uartlirc_bas *bas, int, int, int, int); Xstatic void z8530_term(struct uartlirc_bas *bas); Xstatic void z8530_putc(struct uartlirc_bas *bas, int); Xstatic int z8530_rxready(struct uartlirc_bas *bas); Xstatic int z8530_getc(struct uartlirc_bas *bas, struct mtx *); X Xstatic struct uartlirc_ops uartlirc_z8530_ops = { X .probe = z8530_probe, X .init = z8530_init, X .term = z8530_term, X .putc = z8530_putc, X .rxready = z8530_rxready, X .getc = z8530_getc, X}; X Xstatic int Xz8530_probe(struct uartlirc_bas *bas) X{ X X return (0); X} X Xstatic void Xz8530_init(struct uartlirc_bas *bas, int baudrate, int databits, int stopbits, X int parity) X{ X X z8530_setup(bas, baudrate, databits, stopbits, parity); X} X Xstatic void Xz8530_term(struct uartlirc_bas *bas) X{ X} X Xstatic void Xz8530_putc(struct uartlirc_bas *bas, int c) X{ X X while (!(uartlirc_getreg(bas, REG_CTRL) & BES_TXE)) X ; X uartlirc_setreg(bas, REG_DATA, c); X uartlirc_barrier(bas); X} X Xstatic int Xz8530_rxready(struct uartlirc_bas *bas) X{ X X return ((uartlirc_getreg(bas, REG_CTRL) & BES_RXA) != 0 ? 1 : 0); X} X Xstatic int Xz8530_getc(struct uartlirc_bas *bas, struct mtx *hwmtx) X{ X int c; X X uartlirc_lock(hwmtx); X X while (!(uartlirc_getreg(bas, REG_CTRL) & BES_RXA)) { X uartlirc_unlock(hwmtx); X DELAY(10); X uartlirc_lock(hwmtx); X } X X c = uartlirc_getreg(bas, REG_DATA); X X uartlirc_unlock(hwmtx); X X return (c); X} X X/* X * High-level UART interface. X */ Xstruct z8530_softc { X struct uartlirc_softc base; X uint8_t tpc; X uint8_t txidle; X}; X Xstatic int z8530_bus_attach(struct uartlirc_softc *); Xstatic int z8530_bus_detach(struct uartlirc_softc *); Xstatic int z8530_bus_flush(struct uartlirc_softc *, int); Xstatic int z8530_bus_getsig(struct uartlirc_softc *); Xstatic int z8530_bus_ioctl(struct uartlirc_softc *, int, intptr_t); Xstatic int z8530_bus_ipend(struct uartlirc_softc *); Xstatic int z8530_bus_param(struct uartlirc_softc *, int, int, int, int); Xstatic int z8530_bus_probe(struct uartlirc_softc *); Xstatic int z8530_bus_receive(struct uartlirc_softc *); Xstatic int z8530_bus_setsig(struct uartlirc_softc *, int); Xstatic int z8530_bus_transmit(struct uartlirc_softc *); X Xstatic kobj_method_t z8530_methods[] = { X KOBJMETHOD(uartlirc_attach, z8530_bus_attach), X KOBJMETHOD(uartlirc_detach, z8530_bus_detach), X KOBJMETHOD(uartlirc_flush, z8530_bus_flush), X KOBJMETHOD(uartlirc_getsig, z8530_bus_getsig), X KOBJMETHOD(uartlirc_ioctl, z8530_bus_ioctl), X KOBJMETHOD(uartlirc_ipend, z8530_bus_ipend), X KOBJMETHOD(uartlirc_param, z8530_bus_param), X KOBJMETHOD(uartlirc_probe, z8530_bus_probe), X KOBJMETHOD(uartlirc_receive, z8530_bus_receive), X KOBJMETHOD(uartlirc_setsig, z8530_bus_setsig), X KOBJMETHOD(uartlirc_transmit, z8530_bus_transmit), X { 0, 0 } X}; X Xstruct uartlirc_class uartlirc_z8530_class = { X "z8530", X z8530_methods, X sizeof(struct z8530_softc), X .uc_ops = &uartlirc_z8530_ops, X .uc_range = 2, X .uc_rclk = DEFAULT_RCLK X}; X X#define SIGCHG(c, i, s, d) \ X if (c) { \ X i |= (i & s) ? s : s | d; \ X } else { \ X i = (i & s) ? (i & ~s) | d : i; \ X } X Xstatic int Xz8530_bus_attach(struct uartlirc_softc *sc) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X struct uartlirc_bas *bas; X struct uartlirc_devinfo *di; X X bas = &sc->sc_bas; X if (sc->sc_sysdev != NULL) { X di = sc->sc_sysdev; X z8530->tpc = TPC_DTR|TPC_RTS; X z8530_param(bas, di->baudrate, di->databits, di->stopbits, X di->parity, &z8530->tpc); X } else { X z8530->tpc = z8530_setup(bas, 9600, 8, 1, UARTLIRC_PARITY_NONE); X z8530->tpc &= ~(TPC_DTR|TPC_RTS); X } X z8530->txidle = 1; /* Report SER_INT_TXIDLE. */ X X sc->sc_rxfifosz = 3; X sc->sc_txfifosz = 1; X X (void)z8530_bus_getsig(sc); X X uartlirc_setmreg(bas, WR_IC, IC_BRK | IC_CTS | IC_DCD); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_IV, 0); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_TPC, z8530->tpc); X uartlirc_barrier(bas); X uartlirc_setmreg(bas, WR_MIC, MIC_NV | MIC_MIE); X uartlirc_barrier(bas); X return (0); X} X Xstatic int Xz8530_bus_detach(struct uartlirc_softc *sc) X{ X X return (0); X} X Xstatic int Xz8530_bus_flush(struct uartlirc_softc *sc, int what) X{ X X return (0); X} X Xstatic int Xz8530_bus_getsig(struct uartlirc_softc *sc) X{ X uint32_t new, old, sig; X uint8_t bes; X X do { X old = sc->sc_hwsig; X sig = old; X uartlirc_lock(sc->sc_hwmtx); X bes = uartlirc_getmreg(&sc->sc_bas, RR_BES); X uartlirc_unlock(sc->sc_hwmtx); X SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS); X SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD); X SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR); X new = sig & ~SER_MASK_DELTA; X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X return (sig); X} X Xstatic int Xz8530_bus_ioctl(struct uartlirc_softc *sc, int request, intptr_t data) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X struct uartlirc_bas *bas; X int baudrate, divisor, error; X X bas = &sc->sc_bas; X error = 0; X uartlirc_lock(sc->sc_hwmtx); X switch (request) { X case UARTLIRC_IOCTL_BREAK: X if (data) X z8530->tpc |= TPC_BRK; X else X z8530->tpc &= ~TPC_BRK; X uartlirc_setmreg(bas, WR_TPC, z8530->tpc); X uartlirc_barrier(bas); X break; X case UARTLIRC_IOCTL_BAUD: X divisor = uartlirc_getmreg(bas, RR_TCH); X divisor = (divisor << 8) | uartlirc_getmreg(bas, RR_TCL); X baudrate = bas->rclk / 2 / (divisor + 2); X *(int*)data = baudrate; X break; X default: X error = EINVAL; X break; X } X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xz8530_bus_ipend(struct uartlirc_softc *sc) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X struct uartlirc_bas *bas; X int ipend; X uint32_t sig; X uint8_t bes, ip, iv, src; X X bas = &sc->sc_bas; X ipend = 0; X X uartlirc_lock(sc->sc_hwmtx); X switch (bas->chan) { X case 1: X ip = uartlirc_getmreg(bas, RR_IP); X break; X case 2: /* XXX hack!!! */ X iv = uartlirc_getmreg(bas, RR_IV) & 0x0E; X switch (iv) { X case IV_TEB: ip = IP_TIA; break; X case IV_XSB: ip = IP_SIA; break; X case IV_RAB: ip = IP_RIA; break; X default: ip = 0; break; X } X break; X default: X ip = 0; X break; X } X X if (ip & IP_RIA) X ipend |= SER_INT_RXREADY; X X if (ip & IP_TIA) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTTXI); X uartlirc_barrier(bas); X if (z8530->txidle) { X ipend |= SER_INT_TXIDLE; X z8530->txidle = 0; /* Mask SER_INT_TXIDLE. */ X } X } X X if (ip & IP_SIA) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTXSI); X uartlirc_barrier(bas); X bes = uartlirc_getmreg(bas, RR_BES); X if (bes & BES_BRK) X ipend |= SER_INT_BREAK; X sig = sc->sc_hwsig; X SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS); X SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD); X SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR); X if (sig & SER_MASK_DELTA) X ipend |= SER_INT_SIGCHG; X src = uartlirc_getmreg(bas, RR_SRC); X if (src & SRC_OVR) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTERR); X uartlirc_barrier(bas); X ipend |= SER_INT_OVERRUN; X } X } X X if (ipend) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTIUS); X uartlirc_barrier(bas); X } X X uartlirc_unlock(sc->sc_hwmtx); X X return (ipend); X} X Xstatic int Xz8530_bus_param(struct uartlirc_softc *sc, int baudrate, int databits, X int stopbits, int parity) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X int error; X X uartlirc_lock(sc->sc_hwmtx); X error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity, X &z8530->tpc); X uartlirc_unlock(sc->sc_hwmtx); X return (error); X} X Xstatic int Xz8530_bus_probe(struct uartlirc_softc *sc) X{ X char buf[80]; X int error; X char ch; X X error = z8530_probe(&sc->sc_bas); X if (error) X return (error); X X ch = sc->sc_bas.chan - 1 + 'A'; X X snprintf(buf, sizeof(buf), "z8530, channel %c", ch); X device_set_desc_copy(sc->sc_dev, buf); X return (0); X} X Xstatic int Xz8530_bus_receive(struct uartlirc_softc *sc) X{ X struct uartlirc_bas *bas; X int xc; X uint8_t bes, src; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X bes = uartlirc_getmreg(bas, RR_BES); X while (bes & BES_RXA) { X if (uartlirc_rx_full(sc)) { X sc->sc_rxbuf[sc->sc_rxput] = UARTLIRC_STAT_OVERRUN; X break; X } X xc = uartlirc_getreg(bas, REG_DATA); X uartlirc_barrier(bas); X src = uartlirc_getmreg(bas, RR_SRC); X if (src & SRC_FE) X xc |= UARTLIRC_STAT_FRAMERR; X if (src & SRC_PE) X xc |= UARTLIRC_STAT_PARERR; X if (src & SRC_OVR) X xc |= UARTLIRC_STAT_OVERRUN; X uartlirc_rx_put(sc, xc); X if (src & (SRC_FE | SRC_PE | SRC_OVR)) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTERR); X uartlirc_barrier(bas); X } X bes = uartlirc_getmreg(bas, RR_BES); X } X /* Discard everything left in the Rx FIFO. */ X while (bes & BES_RXA) { X (void)uartlirc_getreg(bas, REG_DATA); X uartlirc_barrier(bas); X src = uartlirc_getmreg(bas, RR_SRC); X if (src & (SRC_FE | SRC_PE | SRC_OVR)) { X uartlirc_setreg(bas, REG_CTRL, CR_RSTERR); X uartlirc_barrier(bas); X } X bes = uartlirc_getmreg(bas, RR_BES); X } X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xz8530_bus_setsig(struct uartlirc_softc *sc, int sig) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X struct uartlirc_bas *bas; X uint32_t new, old; X X bas = &sc->sc_bas; X do { X old = sc->sc_hwsig; X new = old; X if (sig & SER_DDTR) { X SIGCHG(sig & SER_DTR, new, SER_DTR, X SER_DDTR); X } X if (sig & SER_DRTS) { X SIGCHG(sig & SER_RTS, new, SER_RTS, X SER_DRTS); X } X } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); X X uartlirc_lock(sc->sc_hwmtx); X if (new & SER_DTR) X z8530->tpc |= TPC_DTR; X else X z8530->tpc &= ~TPC_DTR; X if (new & SER_RTS) X z8530->tpc |= TPC_RTS; X else X z8530->tpc &= ~TPC_RTS; X uartlirc_setmreg(bas, WR_TPC, z8530->tpc); X uartlirc_barrier(bas); X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} X Xstatic int Xz8530_bus_transmit(struct uartlirc_softc *sc) X{ X struct z8530_softc *z8530 = (struct z8530_softc*)sc; X struct uartlirc_bas *bas; X X bas = &sc->sc_bas; X uartlirc_lock(sc->sc_hwmtx); X while (!(uartlirc_getmreg(bas, RR_BES) & BES_TXE)) X ; X uartlirc_setreg(bas, REG_DATA, sc->sc_txbuf[0]); X uartlirc_barrier(bas); X sc->sc_txbusy = 1; X z8530->txidle = 1; /* Report SER_INT_TXIDLE again. */ X uartlirc_unlock(sc->sc_hwmtx); X return (0); X} 525f4a1c43f1258d814d4102fb292caa echo x - uartlirc/uartlirc_if.m sed 's/^X//' >uartlirc/uartlirc_if.m << '26e82b275c356085382b13dc0bd8a824' X#- X# Copyright (c) 2003 Marcel Moolenaar X# All rights reserved. X# X# Redistribution and use in source and binary forms, with or without X# modification, are permitted provided that the following conditions X# are met: X# X# 1. Redistributions of source code must retain the above copyright X# notice, this list of conditions and the following disclaimer. X# 2. Redistributions in binary form must reproduce the above copyright X# notice, this list of conditions and the following disclaimer in the X# documentation and/or other materials provided with the distribution. X# X# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X# X# $FreeBSD: src/sys/dev/uart/uartlirc_if.m,v 1.3.28.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X X#include X#include X#include X#include X#include X#include X#include "uartlirc.h" X#include "uartlirc_bus.h" X X# The UART hardware interface. The core UART code is hardware independent. X# The details of the hardware are abstracted by the UART hardware interface. X XINTERFACE uartlirc; X X# attach() - attach hardware. X# This method is called when the device is being attached. All resources X# have been allocated. The transmit and receive buffers exist, but no X# high-level (ie tty) initialization has been done yet. X# The intend of this method is to setup the hardware for normal operation. XMETHOD int attach { X struct uartlirc_softc *this; X}; X X# detach() - detach hardware. X# This method is called when a device is being detached from its bus. It X# is the first action performed, so even the high-level (ie tty) interface X# is still operational. X# The intend of this method is to disable the hardware. XMETHOD int detach { X struct uartlirc_softc *this; X}; X X# flush() - flush FIFOs. X# This method is called to flush the transmitter and/or the receiver as X# specified by the what argument. Characters are expected to be lost. XMETHOD int flush { X struct uartlirc_softc *this; X int what; X}; X X# getsig() - get line and modem signals. X# This method retrieves the DTE and DCE signals and their corresponding X# delta bits. The delta bits include those corresponding to DTE signals X# when they were changed by a call to setsig. The delta bits maintained X# by the hardware driver are cleared as a side-effect. A second call to X# this function will not have any delta bits set, unless there was a X# change in the signals in the mean time. XMETHOD int getsig { X struct uartlirc_softc *this; X}; X X# ioctl() - get or set miscellaneous parameters. X# This method is the bitbucket method. It can (and will) be used when there's X# something we need to set or get for which a new method is overkill. It's X# used for example to set HW or SW flow-control. XMETHOD int ioctl { X struct uartlirc_softc *this; X int request; X intptr_t data; X}; X X# ipend() - query UART for pending interrupts. X# When an interrupt is signalled, the handler will call this method to find X# out which of the interrupt sources needs attention. The handler will use X# this information to dispatch service routines that deal with each of the X# interrupt sources. An advantage of this approach is that it allows multi- X# port drivers (like puc(4)) to query multiple devices concurrently and X# service them on an interrupt priority basis. If the hardware cannot provide X# the information reliably, it is free to service the interrupt and return 0, X# meaning that no attention is required. XMETHOD int ipend { X struct uartlirc_softc *this; X} X X# param() - set communication parameters. X# This method is called to change the communication parameters. XMETHOD int param { X struct uartlirc_softc *this; X int baudrate; X int databits; X int stopbits; X int parity; X}; X X# probe() - detect hardware. X# This method is called as part of the bus probe to make sure the X# hardware exists. This function should also set the device description X# to something that represents the hardware. XMETHOD int probe { X struct uartlirc_softc *this; X}; X X# receive() - move data from the receive FIFO to the receive buffer. X# This method is called to move received data to the receive buffer and X# additionally should make sure the receive interrupt should be cleared. XMETHOD int receive { X struct uartlirc_softc *this; X}; X X# setsig() - set line and modem signals. X# This method allows changing DTE signals. The DTE delta bits indicate which X# signals are to be changed and the DTE bits themselves indicate whether to X# set or clear the signals. A subsequent call to getsig will return with the X# DTE delta bits set of those DTE signals that did change by this method. XMETHOD int setsig { X struct uartlirc_softc *this; X int sig; X}; X X# transmit() - move data from the transmit buffer to the transmit FIFO. X# This method is responsible for writing the Tx buffer to the UART and X# additionally should make sure that a transmit interrupt is generated X# when transmission is complete. XMETHOD int transmit { X struct uartlirc_softc *this; X}; 26e82b275c356085382b13dc0bd8a824 echo x - uartlirc/uartlirc_kbd_sun.c sed 's/^X//' >uartlirc/uartlirc_kbd_sun.c << '4908e0d6267bd05fb1aeab96b2aa36ea' X/*- X * Copyright (c) 2003 Jake Burkholder. X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_kbd_sun.c,v 1.14.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include "opt_compat.h" X#include "opt_kbd.h" X#include "opt_sunkbd.h" X X#if (defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP)) || \ X !defined(SUNKBD_EMULATE_ATKBD) X#define KBD_DFLT_KEYMAP X#endif X X#include X#include X#include X#include X#include X#include X#include X X#include X X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X X#include "uartlirc_kbd_sun.h" X#if !defined(SUNKBD_EMULATE_ATKBD) X#include "uartlirc_kbd_sun_tables.h" X#endif X X#if defined(SUNKBD_EMULATE_ATKBD) && defined(SUNKBD_DFLT_KEYMAP) X#include "sunkbdmap.h" X#endif X#include "uartlirc_if.h" X X#define SUNKBD_DRIVER_NAME "sunkbd" X X#define TODO printf("%s: unimplemented", __func__) X Xstruct sunkbd_softc { X keyboard_t sc_kbd; X struct uartlirc_softc *sc_uartlirc; X struct uartlirc_devinfo *sc_sysdev; X X struct callout sc_repeat_callout; X int sc_repeat_key; X X int sc_accents; X int sc_composed_char; X int sc_flags; X#define KPCOMPOSE (1 << 0) X int sc_mode; X int sc_polling; X int sc_repeating; X int sc_state; X X#if defined(SUNKBD_EMULATE_ATKBD) X int sc_buffered_char[2]; X#endif X}; X Xstatic int sunkbd_configure(int flags); Xstatic int sunkbd_probe_keyboard(struct uartlirc_devinfo *di); X Xstatic int sunkbd_probe(int unit, void *arg, int flags); Xstatic int sunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags); Xstatic int sunkbd_term(keyboard_t *kbd); Xstatic int sunkbd_intr(keyboard_t *kbd, void *arg); Xstatic int sunkbd_test_if(keyboard_t *kbd); Xstatic int sunkbd_enable(keyboard_t *kbd); Xstatic int sunkbd_disable(keyboard_t *kbd); Xstatic int sunkbd_read(keyboard_t *kbd, int wait); Xstatic int sunkbd_check(keyboard_t *kbd); Xstatic u_int sunkbd_read_char(keyboard_t *kbd, int wait); Xstatic int sunkbd_check_char(keyboard_t *kbd); Xstatic int sunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data); Xstatic int sunkbd_lock(keyboard_t *kbd, int lock); Xstatic void sunkbd_clear_state(keyboard_t *kbd); Xstatic int sunkbd_get_state(keyboard_t *kbd, void *buf, size_t len); Xstatic int sunkbd_set_state(keyboard_t *kbd, void *buf, size_t len); Xstatic int sunkbd_poll_mode(keyboard_t *kbd, int on); Xstatic void sunkbd_diag(keyboard_t *kbd, int level); X Xstatic void sunkbd_repeat(void *v); X#if defined(SUNKBD_EMULATE_ATKBD) Xstatic int keycode2scancode(int keycode, int shift, int up); X#endif X Xstatic keyboard_switch_t sunkbdsw = { X sunkbd_probe, X sunkbd_init, X sunkbd_term, X sunkbd_intr, X sunkbd_test_if, X sunkbd_enable, X sunkbd_disable, X sunkbd_read, X sunkbd_check, X sunkbd_read_char, X sunkbd_check_char, X sunkbd_ioctl, X sunkbd_lock, X sunkbd_clear_state, X sunkbd_get_state, X sunkbd_set_state, X genkbd_get_fkeystr, X sunkbd_poll_mode, X sunkbd_diag X}; X XKEYBOARD_DRIVER(sunkbd, sunkbdsw, sunkbd_configure); X Xstatic struct sunkbd_softc sunkbd_softc; Xstatic struct uartlirc_devinfo uartlirc_keyboard; X X#if defined(SUNKBD_EMULATE_ATKBD) X X#define SCAN_PRESS 0x000 X#define SCAN_RELEASE 0x080 X#define SCAN_PREFIX_E0 0x100 X#define SCAN_PREFIX_E1 0x200 X#define SCAN_PREFIX_CTL 0x400 X#define SCAN_PREFIX_SHIFT 0x800 X#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \ X SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT) X X#define NOTR 0x0 /* no translation */ X Xstatic const uint8_t sunkbd_trtab[] = { X NOTR, 0x6d, 0x78, 0x6e, 0x79, 0x3b, 0x3c, 0x44, /* 0x00 - 0x07 */ X 0x3d, 0x57, 0x3e, 0x58, 0x3f, 0x5d, 0x40, NOTR, /* 0x08 - 0x0f */ X 0x41, 0x42, 0x43, 0x38, 0x5f, 0x68, 0x5c, 0x46, /* 0x10 - 0x17 */ X 0x61, 0x6f, 0x70, 0x64, 0x62, 0x01, 0x02, 0x03, /* 0x18 - 0x1f */ X 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, /* 0x20 - 0x27 */ X 0x0c, 0x0d, 0x29, 0x0e, 0x66, 0x77, 0x5b, 0x37, /* 0x28 - 0x2f */ X 0x7a, 0x71, 0x53, 0x74, 0x5e, 0x0f, 0x10, 0x11, /* 0x30 - 0x37 */ X 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, /* 0x38 - 0x3f */ X 0x1a, 0x1b, 0x67, 0x6b, 0x47, 0x48, 0x49, 0x4a, /* 0x40 - 0x47 */ X 0x73, 0x72, 0x63, NOTR, 0x1d, 0x1e, 0x1f, 0x20, /* 0x48 - 0x4f */ X 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 0x50 - 0x57 */ X 0x2b, 0x1c, 0x59, 0x4b, 0x4c, 0x4d, 0x52, 0x75, /* 0x58 - 0x5f */ X 0x60, 0x76, 0x45, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x60 - 0x67 */ X 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, NOTR, /* 0x68 - 0x6f */ X 0x4f, 0x50, 0x51, NOTR, NOTR, NOTR, 0x6c, 0x3a, /* 0x70 - 0x77 */ X 0x69, 0x39, 0x6a, 0x65, 0x56, 0x4e, NOTR, NOTR /* 0x78 - 0x7f */ X}; X X#endif X Xstatic int Xsunkbd_probe_keyboard(struct uartlirc_devinfo *di) X{ X int c, id, ltries, tries; X X for (tries = 5; tries != 0; tries--) { X uartlirc_putc(di, SKBD_CMD_RESET); X for (ltries = 1000; ltries != 0; ltries--) { X if (uartlirc_poll(di) == SKBD_RSP_RESET) X break; X DELAY(1000); X } X if (ltries == 0) X continue; X id = -1; X for (ltries = 1000; ltries != 0; ltries--) { X switch (c = uartlirc_poll(di)) { X case -1: X break; X case SKBD_RSP_IDLE: X return (id); X default: X id = c; X } X DELAY(1000); X } X } X return (-1); X} X Xstatic int sunkbd_attach(struct uartlirc_softc *sc); Xstatic void sunkbd_uartlirc_intr(void *arg); X Xstatic int Xsunkbd_configure(int flags) X{ X struct sunkbd_softc *sc; X X /* X * We are only prepared to be used for the high-level console X * when the keyboard is both configured and attached. X */ X if (!(flags & KB_CONF_PROBE_ONLY)) { X if (KBD_IS_INITIALIZED(&sunkbd_softc.sc_kbd)) X goto found; X else X return (0); X } X X if (uartlirc_cpu_getdev(UARTLIRC_DEV_KEYBOARD, &uartlirc_keyboard)) X return (0); X if (uartlirc_probe(&uartlirc_keyboard)) X return (0); X uartlirc_init(&uartlirc_keyboard); X X uartlirc_keyboard.type = UARTLIRC_DEV_KEYBOARD; X uartlirc_keyboard.attach = sunkbd_attach; X uartlirc_add_sysdev(&uartlirc_keyboard); X X if (sunkbd_probe_keyboard(&uartlirc_keyboard) != KB_SUN4) X return (0); X X sc = &sunkbd_softc; X callout_init(&sc->sc_repeat_callout, 0); X sunkbd_clear_state(&sc->sc_kbd); X X#if defined(SUNKBD_EMULATE_ATKBD) X kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_101, 0, 0, 0, 0); X kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab, X sizeof(fkey_tab) / sizeof(fkey_tab[0])); X#else X kbd_init_struct(&sc->sc_kbd, SUNKBD_DRIVER_NAME, KB_OTHER, 0, 0, 0, 0); X kbd_set_maps(&sc->sc_kbd, &keymap_sun_us_unix_kbd, X &accentmap_sun_us_unix_kbd, fkey_tab, X sizeof(fkey_tab) / sizeof(fkey_tab[0])); X#endif X sc->sc_mode = K_XLATE; X kbd_register(&sc->sc_kbd); X X sc->sc_sysdev = &uartlirc_keyboard; X X found: X /* Return number of found keyboards. */ X return (1); X} X Xstatic int Xsunkbd_attach(struct uartlirc_softc *sc) X{ X X /* X * Don't attach if we didn't probe the keyboard. Note that X * the UART is still marked as a system device in that case. X */ X if (sunkbd_softc.sc_sysdev == NULL) { X device_printf(sc->sc_dev, "keyboard not present\n"); X return (0); X } X X if (sc->sc_sysdev != NULL) { X sunkbd_softc.sc_uartlirc = sc; X X#ifdef KBD_INSTALL_CDEV X kbd_attach(&sunkbd_softc.sc_kbd); X#endif X sunkbd_enable(&sunkbd_softc.sc_kbd); X X swi_add(&tty_intr_event, uartlirc_driver_name, sunkbd_uartlirc_intr, X &sunkbd_softc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); X X sc->sc_opened = 1; X KBD_INIT_DONE(&sunkbd_softc.sc_kbd); X } X X return (0); X} X Xstatic void Xsunkbd_uartlirc_intr(void *arg) X{ X struct sunkbd_softc *sc = arg; X int pend; X X if (sc->sc_uartlirc->sc_leaving) X return; X X pend = atomic_readandclear_32(&sc->sc_uartlirc->sc_ttypend); X if (!(pend & SER_INT_MASK)) X return; X X if (pend & SER_INT_RXREADY) { X if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { X sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, X KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); X } X } X} X Xstatic int Xsunkbd_probe(int unit, void *arg, int flags) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_term(keyboard_t *kbd) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_intr(keyboard_t *kbd, void *arg) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_test_if(keyboard_t *kbd) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_enable(keyboard_t *kbd) X{ X X KBD_ACTIVATE(kbd); X return (0); X} X Xstatic int Xsunkbd_disable(keyboard_t *kbd) X{ X X KBD_DEACTIVATE(kbd); X return (0); X} X Xstatic int Xsunkbd_read(keyboard_t *kbd, int wait) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_check(keyboard_t *kbd) X{ X struct sunkbd_softc *sc; X X if (!KBD_IS_ACTIVE(kbd)) X return (FALSE); X X sc = (struct sunkbd_softc *)kbd; X X#if defined(SUNKBD_EMULATE_ATKBD) X if (sc->sc_buffered_char[0]) X return (TRUE); X#endif X X if (sc->sc_repeating) X return (TRUE); X X if (sc->sc_uartlirc != NULL && !uartlirc_rx_empty(sc->sc_uartlirc)) X return (TRUE); X X if (sc->sc_polling != 0 && sc->sc_sysdev != NULL && X uartlirc_rxready(sc->sc_sysdev)) X return (TRUE); X X return (FALSE); X} X Xstatic u_int Xsunkbd_read_char(keyboard_t *kbd, int wait) X{ X struct sunkbd_softc *sc; X int key, release, repeated, suncode; X X sc = (struct sunkbd_softc *)kbd; X X#if defined(SUNKBD_EMULATE_ATKBD) X if (sc->sc_mode == K_RAW && sc->sc_buffered_char[0]) { X key = sc->sc_buffered_char[0]; X if (key & SCAN_PREFIX) { X sc->sc_buffered_char[0] = key & ~SCAN_PREFIX; X return ((key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1); X } else { X sc->sc_buffered_char[0] = sc->sc_buffered_char[1]; X sc->sc_buffered_char[1] = 0; X return (key); X } X } X#endif X X repeated = 0; X if (sc->sc_repeating) { X repeated = 1; X sc->sc_repeating = 0; X callout_reset(&sc->sc_repeat_callout, hz / 10, X sunkbd_repeat, sc); X suncode = sc->sc_repeat_key; X goto process_code; X } X X for (;;) { X next_code: X if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) { X key = sc->sc_composed_char; X sc->sc_composed_char = 0; X if (key > UCHAR_MAX) X return (ERRKEY); X return (key); X } X X if (sc->sc_uartlirc != NULL && !uartlirc_rx_empty(sc->sc_uartlirc)) { X suncode = uartlirc_rx_get(sc->sc_uartlirc); X } else if (sc->sc_polling != 0 && sc->sc_sysdev != NULL) { X if (wait) X suncode = uartlirc_getc(sc->sc_sysdev); X else if ((suncode = uartlirc_poll(sc->sc_sysdev)) == -1) X return (NOKEY); X } else { X return (NOKEY); X } X X switch (suncode) { X case SKBD_RSP_IDLE: X break; X default: X process_code: X ++kbd->kb_count; X key = SKBD_KEY_CHAR(suncode); X release = suncode & SKBD_KEY_RELEASE; X if (!repeated) { X if (release == 0) { X callout_reset(&sc->sc_repeat_callout, X hz / 2, sunkbd_repeat, sc); X sc->sc_repeat_key = suncode; X } else if (sc->sc_repeat_key == key) { X callout_stop(&sc->sc_repeat_callout); X sc->sc_repeat_key = -1; X } X } X X#if defined(SUNKBD_EMULATE_ATKBD) X key = sunkbd_trtab[key]; X if (key == NOTR) X return (NOKEY); X X if (!repeated) { X switch (key) { X case 0x1d: /* ctrl */ X if (release != 0) X sc->sc_flags &= ~CTLS; X else X sc->sc_flags |= CTLS; X break; X case 0x2a: /* left shift */ X case 0x36: /* right shift */ X if (release != 0) X sc->sc_flags &= ~SHIFTS; X else X sc->sc_flags |= SHIFTS; X break; X case 0x38: /* alt */ X case 0x5d: /* altgr */ X if (release != 0) X sc->sc_flags &= ~ALTS; X else X sc->sc_flags |= ALTS; X break; X } X } X if (sc->sc_mode == K_RAW) { X key = keycode2scancode(key, sc->sc_flags, X release); X if (key & SCAN_PREFIX) { X if (key & SCAN_PREFIX_CTL) { X sc->sc_buffered_char[0] = X 0x1d | (key & SCAN_RELEASE); X sc->sc_buffered_char[1] = X key & ~SCAN_PREFIX; X } else if (key & SCAN_PREFIX_SHIFT) { X sc->sc_buffered_char[0] = X 0x2a | (key & SCAN_RELEASE); X sc->sc_buffered_char[1] = X key & ~SCAN_PREFIX_SHIFT; X } else { X sc->sc_buffered_char[0] = X key & ~SCAN_PREFIX; X sc->sc_buffered_char[1] = 0; X } X return ((key & SCAN_PREFIX_E0) ? X 0xe0 : 0xe1); X } X return (key); X } X switch (key) { X case 0x5c: /* print screen */ X if (sc->sc_flags & ALTS) X key = 0x54; /* sysrq */ X break; X case 0x68: /* pause/break */ X if (sc->sc_flags & CTLS) X key = 0x6c; /* break */ X break; X } X X if (sc->sc_mode == K_CODE) X return (key | release); X#else X if (sc->sc_mode == K_RAW || sc->sc_mode == K_CODE) X return (suncode); X#endif X X#if defined(SUNKBD_EMULATE_ATKBD) X if (key == 0x38) { /* left alt (KP compose key) */ X#else X if (key == 0x13) { /* left alt (KP compose key) */ X#endif X if (release != 0) { X if (sc->sc_flags & KPCOMPOSE) { X sc->sc_flags &= ~KPCOMPOSE; X if (sc->sc_composed_char > X UCHAR_MAX) X sc->sc_composed_char = X 0; X } X } else { X if (!(sc->sc_flags & KPCOMPOSE)) { X sc->sc_flags |= KPCOMPOSE; X sc->sc_composed_char = 0; X } X } X } X if (sc->sc_flags & KPCOMPOSE) { X switch (suncode) { X case 0x44: /* KP 7 */ X case 0x45: /* KP 8 */ X case 0x46: /* KP 9 */ X sc->sc_composed_char *= 10; X sc->sc_composed_char += suncode - 0x3d; X if (sc->sc_composed_char > UCHAR_MAX) X return (ERRKEY); X goto next_code; X case 0x5b: /* KP 4 */ X case 0x5c: /* KP 5 */ X case 0x5d: /* KP 6 */ X sc->sc_composed_char *= 10; X sc->sc_composed_char += suncode - 0x58; X if (sc->sc_composed_char > UCHAR_MAX) X return (ERRKEY); X goto next_code; X case 0x70: /* KP 1 */ X case 0x71: /* KP 2 */ X case 0x72: /* KP 3 */ X sc->sc_composed_char *= 10; X sc->sc_composed_char += suncode - 0x6f; X if (sc->sc_composed_char > UCHAR_MAX) X return (ERRKEY); X goto next_code; X case 0x5e: /* KP 0 */ X sc->sc_composed_char *= 10; X if (sc->sc_composed_char > UCHAR_MAX) X return (ERRKEY); X goto next_code; X X case 0x44 | SKBD_KEY_RELEASE: /* KP 7 */ X case 0x45 | SKBD_KEY_RELEASE: /* KP 8 */ X case 0x46 | SKBD_KEY_RELEASE: /* KP 9 */ X case 0x5b | SKBD_KEY_RELEASE: /* KP 4 */ X case 0x5c | SKBD_KEY_RELEASE: /* KP 5 */ X case 0x5d | SKBD_KEY_RELEASE: /* KP 6 */ X case 0x70 | SKBD_KEY_RELEASE: /* KP 1 */ X case 0x71 | SKBD_KEY_RELEASE: /* KP 2 */ X case 0x72 | SKBD_KEY_RELEASE: /* KP 3 */ X case 0x5e | SKBD_KEY_RELEASE: /* KP 0 */ X goto next_code; X default: X if (sc->sc_composed_char > 0) { X sc->sc_flags &= ~KPCOMPOSE; X sc->sc_composed_char = 0; X return (ERRKEY); X } X } X } X X key = genkbd_keyaction(kbd, key, release, X &sc->sc_state, &sc->sc_accents); X if (key != NOKEY || repeated) X return (key); X } X } X return (0); X} X Xstatic int Xsunkbd_check_char(keyboard_t *kbd) X{ X struct sunkbd_softc *sc; X X if (!KBD_IS_ACTIVE(kbd)) X return (FALSE); X X sc = (struct sunkbd_softc *)kbd; X if (!(sc->sc_flags & KPCOMPOSE) && (sc->sc_composed_char > 0)) X return (TRUE); X X return (sunkbd_check(kbd)); X} X Xstatic int Xsunkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data) X{ X struct sunkbd_softc *sc; X int c, error; X#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) X int ival; X#endif X X sc = (struct sunkbd_softc *)kbd; X error = 0; X switch (cmd) { X case KDGKBMODE: X *(int *)data = sc->sc_mode; X break; X#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) X case _IO('K', 7): X ival = IOCPARM_IVAL(data); X data = (caddr_t)&ival; X /* FALLTHROUGH */ X#endif X case KDSKBMODE: X switch (*(int *)data) { X case K_XLATE: X if (sc->sc_mode != K_XLATE) { X /* make lock key state and LED state match */ X sc->sc_state &= ~LOCK_MASK; X sc->sc_state |= KBD_LED_VAL(kbd); X } X /* FALLTHROUGH */ X case K_RAW: X case K_CODE: X if (sc->sc_mode != *(int *)data) { X sunkbd_clear_state(kbd); X sc->sc_mode = *(int *)data; X } X break; X default: X error = EINVAL; X break; X } X break; X case KDGETLED: X *(int *)data = KBD_LED_VAL(kbd); X break; X#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) X case _IO('K', 66): X ival = IOCPARM_IVAL(data); X data = (caddr_t)&ival; X /* FALLTHROUGH */ X#endif X case KDSETLED: X if (*(int *)data & ~LOCK_MASK) { X error = EINVAL; X break; X } X if (sc->sc_sysdev == NULL) X break; X c = 0; X if (*(int *)data & CLKED) X c |= SKBD_LED_CAPSLOCK; X if (*(int *)data & NLKED) X c |= SKBD_LED_NUMLOCK; X if (*(int *)data & SLKED) X c |= SKBD_LED_SCROLLLOCK; X uartlirc_lock(sc->sc_sysdev->hwmtx); X sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED); X sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, c); X uartlirc_unlock(sc->sc_sysdev->hwmtx); X KBD_LED_VAL(kbd) = *(int *)data; X break; X case KDGKBSTATE: X *(int *)data = sc->sc_state & LOCK_MASK; X break; X#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) X case _IO('K', 20): X ival = IOCPARM_IVAL(data); X data = (caddr_t)&ival; X /* FALLTHROUGH */ X#endif X case KDSKBSTATE: X if (*(int *)data & ~LOCK_MASK) { X error = EINVAL; X break; X } X sc->sc_state &= ~LOCK_MASK; X sc->sc_state |= *(int *)data; X /* set LEDs and quit */ X return (sunkbd_ioctl(kbd, KDSETLED, data)); X case KDSETREPEAT: X case KDSETRAD: X break; X case PIO_KEYMAP: X case OPIO_KEYMAP: X case PIO_KEYMAPENT: X case PIO_DEADKEYMAP: X default: X return (genkbd_commonioctl(kbd, cmd, data)); X } X return (error); X} X Xstatic int Xsunkbd_lock(keyboard_t *kbd, int lock) X{ X X TODO; X return (0); X} X Xstatic void Xsunkbd_clear_state(keyboard_t *kbd) X{ X struct sunkbd_softc *sc; X X sc = (struct sunkbd_softc *)kbd; X sc->sc_repeat_key = -1; X sc->sc_accents = 0; X sc->sc_composed_char = 0; X sc->sc_flags = 0; X sc->sc_polling = 0; X sc->sc_repeating = 0; X sc->sc_state &= LOCK_MASK; /* Preserve locking key state. */ X X#if defined(SUNKBD_EMULATE_ATKBD) X sc->sc_buffered_char[0] = 0; X sc->sc_buffered_char[1] = 0; X#endif X} X Xstatic int Xsunkbd_get_state(keyboard_t *kbd, void *buf, size_t len) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_set_state(keyboard_t *kbd, void *buf, size_t len) X{ X X TODO; X return (0); X} X Xstatic int Xsunkbd_poll_mode(keyboard_t *kbd, int on) X{ X struct sunkbd_softc *sc; X X sc = (struct sunkbd_softc *)kbd; X if (on) X sc->sc_polling++; X else X sc->sc_polling--; X return (0); X} X Xstatic void Xsunkbd_diag(keyboard_t *kbd, int level) X{ X X TODO; X} X Xstatic void Xsunkbd_repeat(void *v) X{ X struct sunkbd_softc *sc = v; X X if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { X if (sc->sc_repeat_key != -1) { X sc->sc_repeating = 1; X sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, X KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); X } X } X} X X#if defined(SUNKBD_EMULATE_ATKBD) Xstatic int Xkeycode2scancode(int keycode, int shift, int up) X{ X static const int scan[] = { X /* KP enter, right ctrl, KP divide */ X 0x1c , 0x1d , 0x35 , X /* print screen */ X 0x37 | SCAN_PREFIX_SHIFT, X /* right alt, home, up, page up, left, right, end */ X 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f, X /* down, page down, insert, delete */ X 0x50, 0x51, 0x52, 0x53, X /* pause/break (see also below) */ X 0x46, X /* X * MS: left window, right window, menu X * also Sun: left meta, right meta, compose X */ X 0x5b, 0x5c, 0x5d, X /* Sun type 6 USB */ X /* help, stop, again, props, undo, front, copy */ X 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, X /* open, paste, find, cut, audiomute, audiolower, audioraise */ X 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e, X /* power */ X 0x20 X }; X int scancode; X X scancode = keycode; X if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0]))) X scancode = scan[keycode - 89] | SCAN_PREFIX_E0; X /* pause/break */ X if ((keycode == 104) && !(shift & CTLS)) X scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL; X if (shift & SHIFTS) X scancode &= ~SCAN_PREFIX_SHIFT; X return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS)); X} X#endif 4908e0d6267bd05fb1aeab96b2aa36ea echo x - uartlirc/uartlirc_kbd_sun.h sed 's/^X//' >uartlirc/uartlirc_kbd_sun.h << '2e9614c5879e222347627ad5af917375' X/*- X * Copyright (c) 2002 Jason L. Wright (jason@thought.net) X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by Jason L. Wright X * 4. The name of the author may not be used to endorse or promote products X * derived from this software without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE X * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, X * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES X * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR X * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, X * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN X * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE X * POSSIBILITY OF SUCH DAMAGE. X * X * Effort sponsored in part by the Defense Advanced Research Projects X * Agency (DARPA) and Air Force Research Laboratory, Air Force X * Materiel Command, USAF, under agreement number F30602-01-2-0537. X * X * $FreeBSD: src/sys/dev/uart/uartlirc_kbd_sun.h,v 1.3.16.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X */ X X/* keyboard commands (host->kbd) */ X#define SKBD_CMD_RESET 0x01 X#define SKBD_CMD_BELLON 0x02 X#define SKBD_CMD_BELLOFF 0x03 X#define SKBD_CMD_CLICKON 0x0a X#define SKBD_CMD_CLICKOFF 0x0b X#define SKBD_CMD_SETLED 0x0e X#define SKBD_CMD_LAYOUT 0x0f X X/* keyboard responses (kbd->host) */ X#define SKBD_RSP_RESET_OK 0x04 /* normal reset status for type 4/5/6 */ X#define SKBD_RSP_IDLE 0x7f /* no keys down */ X#define SKBD_RSP_LAYOUT 0xfe /* layout follows */ X#define SKBD_RSP_RESET 0xff /* reset status follows */ X X#define SKBD_LED_NUMLOCK 0x01 X#define SKBD_LED_COMPOSE 0x02 X#define SKBD_LED_SCROLLLOCK 0x04 X#define SKBD_LED_CAPSLOCK 0x08 X X#define SKBD_STATE_RESET 0 X#define SKBD_STATE_LAYOUT 1 X#define SKBD_STATE_GETKEY 2 X X/* keyboard types */ X#define KB_SUN2 2 /* type 2 keyboard */ X#define KB_SUN3 3 /* type 3 keyboard */ X#define KB_SUN4 4 /* type 4/5/6 keyboard */ X X#define SKBD_KEY_RELEASE 0x80 X#define SKBD_KEY_CHAR(c) ((c) & 0x7f) 2e9614c5879e222347627ad5af917375 echo x - uartlirc/uartlirc_kbd_sun_tables.h sed 's/^X//' >uartlirc/uartlirc_kbd_sun_tables.h << 'ae314254f8bc308e656e22f7d5a529b4' X/* X * Automatically generated from sun.us.unix.kbd. X * DO NOT EDIT! X * X * $FreeBSD: src/sys/dev/uart/uartlirc_kbd_sun_tables.h,v 1.1.38.1.2.1 2011/11/11 04:20:22 kensmith Exp $ X */ Xstatic keymap_t keymap_sun_us_unix_kbd = { 0x80, { X/* alt X * scan cntrl alt alt cntrl X * code base shift cntrl shift alt shift cntrl shift spcl flgs X * --------------------------------------------------------------------------- X */ X/*00*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*01*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*02*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*03*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*04*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*05*/{{ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11),}, 0xFF,0x00 }, X/*06*/{{ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12),}, 0xFF,0x00 }, X/*07*/{{ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10),}, 0xFF,0x00 }, X/*08*/{{ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13),}, 0xFF,0x00 }, X/*09*/{{ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11),}, 0xFF,0x00 }, X/*0a*/{{ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14),}, 0xFF,0x00 }, X/*0b*/{{ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12),}, 0xFF,0x00 }, X/*0c*/{{ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15),}, 0xFF,0x00 }, X/*0d*/{{ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, }, 0xFF,0x00 }, X/*0e*/{{ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16),}, 0xFF,0x00 }, X/*0f*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*10*/{{ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7),}, 0xFF,0x00 }, X/*11*/{{ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8),}, 0xFF,0x00 }, X/*12*/{{ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9),}, 0xFF,0x00 }, X/*13*/{{ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, }, 0xFF,0x00 }, X/*14*/{{ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50),}, 0xFF,0x00 }, X/*15*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*16*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*17*/{{ SLK, SPSC, SLK, SPSC, SUSP, NOP, SUSP, NOP, }, 0xFF,0x00 }, X/*18*/{{ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53),}, 0xFF,0x00 }, X/*19*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*1a*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*1b*/{{ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58),}, 0xFF,0x00 }, X/*1c*/{{ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55),}, 0xFF,0x00 }, X/*1d*/{{ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, }, 0x02,0x00 }, X/*1e*/{{ '1', '!', NOP, NOP, '1', '!', NOP, NOP, }, 0x33,0x00 }, X/*1f*/{{ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, }, 0x00,0x00 }, X/*20*/{{ '3', '#', NOP, NOP, '3', '#', NOP, NOP, }, 0x33,0x00 }, X/*21*/{{ '4', '$', NOP, NOP, '4', '$', NOP, NOP, }, 0x33,0x00 }, X/*22*/{{ '5', '%', NOP, NOP, '5', '%', NOP, NOP, }, 0x33,0x00 }, X/*23*/{{ '6', '^', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, }, 0x00,0x00 }, X/*24*/{{ '7', '&', NOP, NOP, '7', '&', NOP, NOP, }, 0x33,0x00 }, X/*25*/{{ '8', '*', NOP, NOP, '8', '*', NOP, NOP, }, 0x33,0x00 }, X/*26*/{{ '9', '(', NOP, NOP, '9', '(', NOP, NOP, }, 0x33,0x00 }, X/*27*/{{ '0', ')', NOP, NOP, '0', ')', NOP, NOP, }, 0x33,0x00 }, X/*28*/{{ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, }, 0x00,0x00 }, X/*29*/{{ '=', '+', NOP, NOP, '=', '+', NOP, NOP, }, 0x33,0x00 }, X/*2a*/{{ '`', '~', NOP, NOP, '`', '~', DBG, NOP, }, 0x33,0x00 }, X/*2b*/{{ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, }, 0x00,0x00 }, X/*2c*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*2d*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*2e*/{{ '/', '/', '/', '/', '/', '/', '/', '/', }, 0x00,0x02 }, X/*2f*/{{ '*', '*', '*', '*', '*', '*', '*', '*', }, 0x00,0x00 }, X/*30*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*31*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*32*/{{ 0x08, '.', '.', '.', '.', '.', RBT, RBT, }, 0x03,0x02 }, X/*33*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*34*/{{ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49),}, 0xFF,0x00 }, X/*35*/{{ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, }, 0x77,0x00 }, X/*36*/{{ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, }, 0x00,0x01 }, X/*37*/{{ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, }, 0x00,0x01 }, X/*38*/{{ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, }, 0x00,0x01 }, X/*39*/{{ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, }, 0x00,0x01 }, X/*3a*/{{ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, }, 0x00,0x01 }, X/*3b*/{{ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, }, 0x00,0x01 }, X/*3c*/{{ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, }, 0x00,0x01 }, X/*3d*/{{ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, }, 0x00,0x01 }, X/*3e*/{{ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, }, 0x00,0x01 }, X/*3f*/{{ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, }, 0x00,0x01 }, X/*40*/{{ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, }, 0x00,0x00 }, X/*41*/{{ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, }, 0x00,0x00 }, X/*42*/{{ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, }, 0x00,0x00 }, X/*43*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*44*/{{ F(49), '7', '7', '7', '7', '7', '7', '7', }, 0x80,0x02 }, X/*45*/{{ F(50), '8', '8', '8', '8', '8', '8', '8', }, 0x80,0x02 }, X/*46*/{{ F(51), '9', '9', '9', '9', '9', '9', '9', }, 0x80,0x02 }, X/*47*/{{ F(52), '-', '-', '-', '-', '-', '-', '-', }, 0x80,0x02 }, X/*48*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*49*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*4a*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*4b*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*4c*/{{ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, }, 0xFF,0x00 }, X/*4d*/{{ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, }, 0x00,0x01 }, X/*4e*/{{ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, }, 0x00,0x01 }, X/*4f*/{{ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, }, 0x00,0x01 }, X/*50*/{{ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, }, 0x00,0x01 }, X/*51*/{{ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, }, 0x00,0x01 }, X/*52*/{{ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, }, 0x00,0x01 }, X/*53*/{{ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, }, 0x00,0x01 }, X/*54*/{{ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, }, 0x00,0x01 }, X/*55*/{{ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, }, 0x00,0x01 }, X/*56*/{{ ';', ':', NOP, NOP, ';', ':', NOP, NOP, }, 0x33,0x00 }, X/*57*/{{ '\'', '"', NOP, NOP, '\'', '"', NOP, NOP, }, 0x33,0x00 }, X/*58*/{{ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, }, 0x00,0x00 }, X/*59*/{{ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, }, 0x00,0x00 }, X/*5a*/{{ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, }, 0x00,0x00 }, X/*5b*/{{ F(53), '4', '4', '4', '4', '4', '4', '4', }, 0x80,0x02 }, X/*5c*/{{ F(54), '5', '5', '5', '5', '5', '5', '5', }, 0x80,0x02 }, X/*5d*/{{ F(55), '6', '6', '6', '6', '6', '6', '6', }, 0x80,0x02 }, X/*5e*/{{ F(60), '0', '0', '0', '0', '0', '0', '0', }, 0x80,0x02 }, X/*5f*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*60*/{{ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51),}, 0xFF,0x00 }, X/*61*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*62*/{{ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, }, 0xFF,0x00 }, X/*63*/{{ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, }, 0xFF,0x00 }, X/*64*/{{ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, }, 0x00,0x01 }, X/*65*/{{ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, }, 0x00,0x01 }, X/*66*/{{ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, }, 0x00,0x01 }, X/*67*/{{ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, }, 0x00,0x01 }, X/*68*/{{ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, }, 0x00,0x01 }, X/*69*/{{ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, }, 0x00,0x01 }, X/*6a*/{{ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, }, 0x00,0x01 }, X/*6b*/{{ ',', '<', NOP, NOP, ',', '<', NOP, NOP, }, 0x33,0x00 }, X/*6c*/{{ '.', '>', NOP, NOP, '.', '>', NOP, NOP, }, 0x33,0x00 }, X/*6d*/{{ '/', '?', NOP, NOP, '/', '?', NOP, NOP, }, 0x33,0x00 }, X/*6e*/{{ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, }, 0xFF,0x00 }, X/*6f*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*70*/{{ F(57), '1', '1', '1', '1', '1', '1', '1', }, 0x80,0x02 }, X/*71*/{{ F(58), '2', '2', '2', '2', '2', '2', '2', }, 0x80,0x02 }, X/*72*/{{ F(59), '3', '3', '3', '3', '3', '3', '3', }, 0x80,0x02 }, X/*73*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*74*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*75*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*76*/{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, 0x00,0x00 }, X/*77*/{{ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, }, 0xFF,0x00 }, X/*78*/{{ META, META, META, META, META, META, META, META, }, 0xFF,0x00 }, X/*79*/{{ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', }, 0x02,0x00 }, X/*7a*/{{ META, META, META, META, META, META, META, META, }, 0xFF,0x00 }, X/*7b*/{{ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59),}, 0xFF,0x00 }, X/*7c*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*7d*/{{ F(56), '+', '+', '+', '+', '+', '+', '+', }, 0x80,0x02 }, X/*7e*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X/*7f*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, X} }; X Xstatic accentmap_t accentmap_sun_us_unix_kbd = { 0 }; X ae314254f8bc308e656e22f7d5a529b4 echo x - uartlirc/uartlirc_lircdev.c sed 's/^X//' >uartlirc/uartlirc_lircdev.c << 'c6a3aae7fdadf6a930fe412fa56724cd' X/*- X * Copyright (c) 2012 Juergen Lock X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X#include "uartlirc_lircdev.h" X X#include "uartlirc_if.h" X X#include "lirc.h" X X#define UARTLIRC_LIRCOPEN 1 X Xint uartlirc_allowopenboth; X XSYSCTL_INT(_debug, OID_AUTO, uartlirc_allowopenboth, CTLFLAG_RW, X &uartlirc_allowopenboth, 0, "uartlirc allow open both"); X Xstatic int Xuartlirc_lircdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) X{ X struct uartlirc_softc *sc = dev->si_drv1; X struct buf_ring *br; X X if (sc == NULL) X return (ENXIO); X X if (sc->sc_lircstate || (!uartlirc_allowopenboth && sc->sc_opened)) X return (EBUSY); X X sc->sc_lirc_lastevent = 0; X X /* flush receiver fifo */ X /* XXX locking - is critical_enter() enough? */ X br = sc->sc_lirc_rcv_fifo; X X critical_enter(); X br->br_prod_head = br->br_cons_head = 0; X br->br_prod_tail = br->br_cons_tail = 0; X critical_exit(); X X /* raise RTS to power the IR receiver */ X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_IFLOW, 1); X UARTLIRC_SETSIG(sc, SER_DTR | SER_DDTR | SER_DRTS | SER_RTS); X X sc->sc_lircstate = UARTLIRC_LIRCOPEN; X return (0); X} X Xstatic int Xuartlirc_lircdev_close(struct cdev *dev, int fflag, int devtype, struct thread *td) X{ X struct uartlirc_softc *sc = dev->si_drv1; X X if (sc == NULL || !sc->sc_lircstate) X return 0; X X sc->sc_lircstate = 0; X X wakeup(&sc->sc_lircstate); X selwakeup(&sc->sc_lirc_rsel); X return 0; X} X Xstatic int Xuartlirc_lircdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) X{ X uint32_t *arg = (uint32_t *)data; X X switch (cmd) { X case LIRC_GET_FEATURES: X *arg = LIRC_CAN_REC_MODE2; X return (0); X default: X return ENOTTY; X } X} X Xstatic int Xuartlirc_lircdev_read(struct cdev *dev, struct uio *uio, int ioflag) X{ X struct uartlirc_softc *sc = dev->si_drv1; X X int error = 0, num = 0; X void *entry; X uint32_t data; X X mtx_lock(&sc->sc_lirc_lock); X while (uio->uio_resid) { X if (uio->uio_resid % sizeof(data)) X return EINVAL; X X while ((entry = buf_ring_dequeue_sc(sc->sc_lirc_rcv_fifo)) == NULL) { X if (!num) { X if (ioflag & O_NONBLOCK) { X error = EWOULDBLOCK; X goto end_read; X } X error = msleep(&sc->sc_lircstate, &sc->sc_lirc_lock, PCATCH | PDROP, "rdlirc", 0); X if (error == EINTR) X goto end_read2; X if (sc != dev->si_drv1) X error = ENXIO; X if (error) X goto end_read2; X mtx_lock(&sc->sc_lirc_lock); X } else { X goto end_read; X } X } X data = (uint32_t)(size_t)entry; X error = uiomove(&data, sizeof(data), uio); X if (error) X goto end_read; X ++num; X } X Xend_read: X mtx_unlock(&sc->sc_lirc_lock); Xend_read2: X return error; X} X Xstatic int Xuartlirc_lircdev_poll(struct cdev *dev, int events, struct thread *td) X{ X struct uartlirc_softc *sc = dev->si_drv1; X X if (!sc->sc_lircstate) X return POLLHUP; X X if (events & (POLLIN | POLLRDNORM)) { X if (buf_ring_peek(sc->sc_lirc_rcv_fifo)) X return events & (POLLIN | POLLRDNORM); X else X selrecord(td, &sc->sc_lirc_rsel); X } X return 0; X} X Xstatic void Xuartlirc_lircevent(struct uartlirc_softc *sc, uint32_t val); X Xstatic void Xuartlirc_lircevent(struct uartlirc_softc *sc, uint32_t val) X{ X#if 0 X if (LIRC_MODE2(val) == LIRC_MODE2(sc->sc_lirc_lastevent)) X /* XXX we were too slow */ X return; X#endif X if (buf_ring_enqueue(sc->sc_lirc_rcv_fifo, (void *)(size_t)val) != 0) X return; X sc->sc_lirc_lastevent = val; X wakeup(&sc->sc_lircstate); X selwakeup(&sc->sc_lirc_rsel); X} X Xvoid Xuartlirc_lircdev_sig(void *arg, int sig) X{ X struct uartlirc_softc *sc = arg; X X if (!sc->sc_lircstate) X return; X X if (sig & SER_DDCD) { X struct timeval oldtv = sc->sc_lirc_rcv_time, delta; X X microtime(&sc->sc_lirc_rcv_time); X delta = sc->sc_lirc_rcv_time; X timevalsub(&delta, &oldtv); X if (delta.tv_sec) X delta.tv_usec = (suseconds_t) 1.e6; X if ((sig ^ sc->sc_lirc_sigxor) & SER_DCD) { X /* pulse */ X uartlirc_lircevent(sc, LIRC_PULSE(delta.tv_usec)); X } else { X /* space */ X uartlirc_lircevent(sc, LIRC_SPACE(delta.tv_usec)); X } X } X} X Xstatic struct cdevsw uartlirc_lircdev_cdevsw = { X .d_version = D_VERSION, X .d_open = uartlirc_lircdev_open, X .d_close = uartlirc_lircdev_close, X .d_ioctl = uartlirc_lircdev_ioctl, X .d_read = uartlirc_lircdev_read, X .d_poll = uartlirc_lircdev_poll, X}; X Xint Xuartlirc_lircdev_attach(struct uartlirc_softc *sc) X{ X int unit; X X unit = device_get_unit(sc->sc_dev); X X int ivar = 1; X resource_int_value("uartlirc", device_get_unit(sc->sc_dev), X "activelowflag", &ivar); X if (ivar) X sc->sc_lirc_sigxor = 0; X else X sc->sc_lirc_sigxor = -1; X X mtx_init(&sc->sc_lirc_rcv_fifo_lock, "lirc rcv fifo", NULL, MTX_SPIN|MTX_DUPOK); X mtx_init(&sc->sc_lirc_lock, "lirc lock", NULL, MTX_DUPOK); X sc->sc_lirc_rcv_fifo = buf_ring_alloc((1 << 15), M_DEVBUF, M_WAITOK, &sc->sc_lirc_rcv_fifo_lock); X X sc->sc_lirc_cdev = make_dev(&uartlirc_lircdev_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "lirc%d", unit); X sc->sc_lirc_cdev->si_drv1 = sc; X X return (0); X} X Xint Xuartlirc_lircdev_detach(struct uartlirc_softc *sc) X{ X sc->sc_lirc_cdev->si_drv1 = NULL; X wakeup(&sc->sc_lircstate); X selwakeup(&sc->sc_lirc_rsel); X destroy_dev(sc->sc_lirc_cdev); X buf_ring_free(sc->sc_lirc_rcv_fifo, M_DEVBUF); X mtx_destroy(&sc->sc_lirc_rcv_fifo_lock); X X return (0); X} c6a3aae7fdadf6a930fe412fa56724cd echo x - uartlirc/uartlirc_lircdev.h sed 's/^X//' >uartlirc/uartlirc_lircdev.h << '2f3e780350a7b12241bc3b7d7c410e2a' Xvoid uartlirc_lircdev_sig(void *arg, int sig); Xint uartlirc_lircdev_attach(struct uartlirc_softc *sc); Xint uartlirc_lircdev_detach(struct uartlirc_softc *sc); X Xextern int uartlirc_allowopenboth; 2f3e780350a7b12241bc3b7d7c410e2a echo x - uartlirc/uartlirc_subr.c sed 's/^X//' >uartlirc/uartlirc_subr.c << 'd31d92ff392cd3a216fea6f5190d0b37' X/*- X * Copyright (c) 2004 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_subr.c,v 1.7.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X X#include X#include X X#include "uartlirc.h" X#include "uartlirc_cpu.h" X X#define UARTLIRC_TAG_BR 0 X#define UARTLIRC_TAG_CH 1 X#define UARTLIRC_TAG_DB 2 X#define UARTLIRC_TAG_DT 3 X#define UARTLIRC_TAG_IO 4 X#define UARTLIRC_TAG_MM 5 X#define UARTLIRC_TAG_PA 6 X#define UARTLIRC_TAG_RS 7 X#define UARTLIRC_TAG_SB 8 X#define UARTLIRC_TAG_XO 9 X Xstatic struct uartlirc_class *uartlirc_classes[] = { X &uartlirc_ns8250_class, X &uartlirc_sab82532_class, X &uartlirc_z8530_class, X}; Xstatic size_t uartlirc_nclasses = sizeof(uartlirc_classes) / sizeof(uartlirc_classes[0]); X Xstatic bus_addr_t Xuartlirc_parse_addr(const char **p) X{ X return (strtoul(*p, (char**)(uintptr_t)p, 0)); X} X Xstatic struct uartlirc_class * Xuartlirc_parse_class(struct uartlirc_class *class, const char **p) X{ X struct uartlirc_class *uc; X const char *nm; X size_t len; X u_int i; X X for (i = 0; i < uartlirc_nclasses; i++) { X uc = uartlirc_classes[i]; X nm = uartlirc_getname(uc); X if (nm == NULL || *nm == '\0') X continue; X len = strlen(nm); X if (strncmp(nm, *p, len) == 0) { X *p += len; X return (uc); X } X } X return (class); X} X Xstatic long Xuartlirc_parse_long(const char **p) X{ X return (strtol(*p, (char**)(uintptr_t)p, 0)); X} X Xstatic int Xuartlirc_parse_parity(const char **p) X{ X if (!strncmp(*p, "even", 4)) { X *p += 4; X return UARTLIRC_PARITY_EVEN; X } X if (!strncmp(*p, "mark", 4)) { X *p += 4; X return UARTLIRC_PARITY_MARK; X } X if (!strncmp(*p, "none", 4)) { X *p += 4; X return UARTLIRC_PARITY_NONE; X } X if (!strncmp(*p, "odd", 3)) { X *p += 3; X return UARTLIRC_PARITY_ODD; X } X if (!strncmp(*p, "space", 5)) { X *p += 5; X return UARTLIRC_PARITY_SPACE; X } X return (-1); X} X Xstatic int Xuartlirc_parse_tag(const char **p) X{ X int tag; X X if ((*p)[0] == 'b' && (*p)[1] == 'r') { X tag = UARTLIRC_TAG_BR; X goto out; X } X if ((*p)[0] == 'c' && (*p)[1] == 'h') { X tag = UARTLIRC_TAG_CH; X goto out; X } X if ((*p)[0] == 'd' && (*p)[1] == 'b') { X tag = UARTLIRC_TAG_DB; X goto out; X } X if ((*p)[0] == 'd' && (*p)[1] == 't') { X tag = UARTLIRC_TAG_DT; X goto out; X } X if ((*p)[0] == 'i' && (*p)[1] == 'o') { X tag = UARTLIRC_TAG_IO; X goto out; X } X if ((*p)[0] == 'm' && (*p)[1] == 'm') { X tag = UARTLIRC_TAG_MM; X goto out; X } X if ((*p)[0] == 'p' && (*p)[1] == 'a') { X tag = UARTLIRC_TAG_PA; X goto out; X } X if ((*p)[0] == 'r' && (*p)[1] == 's') { X tag = UARTLIRC_TAG_RS; X goto out; X } X if ((*p)[0] == 's' && (*p)[1] == 'b') { X tag = UARTLIRC_TAG_SB; X goto out; X } X if ((*p)[0] == 'x' && (*p)[1] == 'o') { X tag = UARTLIRC_TAG_XO; X goto out; X } X return (-1); X Xout: X *p += 2; X if ((*p)[0] != ':') X return (-1); X (*p)++; X return (tag); X} X X/* X * Parse a device specification. The specification is a list of attributes X * separated by commas. Each attribute is a tag-value pair with the tag and X * value separated by a colon. Supported tags are: X * X * br = Baudrate X * ch = Channel X * db = Data bits X * dt = Device type X * io = I/O port address X * mm = Memory mapped I/O address X * pa = Parity X * rs = Register shift X * sb = Stopbits X * xo = Device clock (xtal oscillator) X * X * The io and mm tags are mutually exclusive. X */ X Xint Xuartlirc_getenv(int devtype, struct uartlirc_devinfo *di, struct uartlirc_class *class) X{ X const char *spec; X bus_addr_t addr = ~0U; X int error; X X /* X * All uartlirc_class references are weak. Make sure the default X * device class has been compiled-in. X */ X if (class == NULL) X return (ENXIO); X X /* X * Check the environment variables "hw.uart.console" and X * "hw.uart.dbgport". These variables, when present, specify X * which UART port is to be used as serial console or debug X * port (resp). X */ X if (devtype == UARTLIRC_DEV_CONSOLE) X spec = getenv("hw.uart.console"); X else if (devtype == UARTLIRC_DEV_DBGPORT) X spec = getenv("hw.uart.dbgport"); X else X spec = NULL; X if (spec == NULL) X return (ENXIO); X X /* Set defaults. */ X di->bas.chan = 0; X di->bas.regshft = 0; X di->bas.rclk = 0; X di->baudrate = 0; X di->databits = 8; X di->stopbits = 1; X di->parity = UARTLIRC_PARITY_NONE; X X /* Parse the attributes. */ X while (1) { X switch (uartlirc_parse_tag(&spec)) { X case UARTLIRC_TAG_BR: X di->baudrate = uartlirc_parse_long(&spec); X break; X case UARTLIRC_TAG_CH: X di->bas.chan = uartlirc_parse_long(&spec); X break; X case UARTLIRC_TAG_DB: X di->databits = uartlirc_parse_long(&spec); X break; X case UARTLIRC_TAG_DT: X class = uartlirc_parse_class(class, &spec); X break; X case UARTLIRC_TAG_IO: X di->bas.bst = uartlirc_bus_space_io; X addr = uartlirc_parse_addr(&spec); X break; X case UARTLIRC_TAG_MM: X di->bas.bst = uartlirc_bus_space_mem; X addr = uartlirc_parse_addr(&spec); X break; X case UARTLIRC_TAG_PA: X di->parity = uartlirc_parse_parity(&spec); X break; X case UARTLIRC_TAG_RS: X di->bas.regshft = uartlirc_parse_long(&spec); X break; X case UARTLIRC_TAG_SB: X di->stopbits = uartlirc_parse_long(&spec); X break; X case UARTLIRC_TAG_XO: X di->bas.rclk = uartlirc_parse_long(&spec); X break; X default: X return (EINVAL); X } X if (*spec == '\0') X break; X if (*spec != ',') X return (EINVAL); X spec++; X } X X /* X * If we still have an invalid address, the specification must be X * missing an I/O port or memory address. We don't like that. X */ X if (addr == ~0U) X return (EINVAL); X X /* X * Accept only the well-known baudrates. Any invalid baudrate X * is silently replaced with a 0-valued baudrate. The 0 baudrate X * has special meaning. It means that we're not supposed to X * program the baudrate and simply communicate with whatever X * speed the hardware is currently programmed for. X */ X if (di->baudrate >= 19200) { X if (di->baudrate % 19200) X di->baudrate = 0; X } else if (di->baudrate >= 1200) { X if (di->baudrate % 1200) X di->baudrate = 0; X } else if (di->baudrate > 0) { X if (di->baudrate % 75) X di->baudrate = 0; X } else X di->baudrate = 0; X X /* Set the ops and create a bus space handle. */ X di->ops = uartlirc_getops(class); X error = bus_space_map(di->bas.bst, addr, uartlirc_getrange(class), 0, X &di->bas.bsh); X return (error); X} d31d92ff392cd3a216fea6f5190d0b37 echo x - uartlirc/uartlirc_tty.c sed 's/^X//' >uartlirc/uartlirc_tty.c << '1b5f12be791eca8f3d27314d9ba1c6bc' X/*- X * Copyright (c) 2003 Marcel Moolenaar X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X */ X X#include X__FBSDID("$FreeBSD: src/sys/dev/uart/uartlirc_tty.c,v 1.36.2.1.2.1 2011/11/11 04:20:22 kensmith Exp $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include "uartlirc.h" X#include "uartlirc_bus.h" X#include "uartlirc_cpu.h" X#include "uartlirc_lircdev.h" X X#include "uartlirc_if.h" X Xstatic cn_probe_t uartlirc_cnprobe; Xstatic cn_init_t uartlirc_cninit; Xstatic cn_term_t uartlirc_cnterm; Xstatic cn_getc_t uartlirc_cngetc; Xstatic cn_putc_t uartlirc_cnputc; X#if __FreeBSD_version >= 1000000 Xstatic cn_grab_t uartlirc_cngrab; Xstatic cn_ungrab_t uartlirc_cnungrab; X#endif X XCONSOLE_DRIVER(uartlirc); X Xstatic struct uartlirc_devinfo uartlirc_console; X Xstatic void Xuartlirc_cnprobe(struct consdev *cp) X{ X X cp->cn_pri = CN_DEAD; X X KASSERT(uartlirc_console.cookie == NULL, ("foo")); X X if (uartlirc_cpu_getdev(UARTLIRC_DEV_CONSOLE, &uartlirc_console)) X return; X X if (uartlirc_probe(&uartlirc_console)) X return; X X strlcpy(cp->cn_name, uartlirc_driver_name, sizeof(cp->cn_name)); X cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL; X cp->cn_arg = &uartlirc_console; X} X Xstatic void Xuartlirc_cninit(struct consdev *cp) X{ X struct uartlirc_devinfo *di; X X /* X * Yedi trick: we need to be able to define cn_dev before we go X * single- or multi-user. The problem is that we don't know at X * this time what the device will be. Hence, we need to link from X * the uartlirc_devinfo to the consdev that corresponds to it so that X * we can define cn_dev in uartlirc_bus_attach() when we find the X * device during bus enumeration. That's when we'll know what the X * the unit number will be. X */ X di = cp->cn_arg; X KASSERT(di->cookie == NULL, ("foo")); X di->cookie = cp; X di->type = UARTLIRC_DEV_CONSOLE; X uartlirc_add_sysdev(di); X uartlirc_init(di); X} X Xstatic void Xuartlirc_cnterm(struct consdev *cp) X{ X X uartlirc_term(cp->cn_arg); X} X X#if __FreeBSD_version >= 1000000 Xstatic void Xuartlirc_cngrab(struct consdev *cp) X{ X} X Xstatic void Xuartlirc_cnungrab(struct consdev *cp) X{ X} X#endif X Xstatic void Xuartlirc_cnputc(struct consdev *cp, int c) X{ X X uartlirc_putc(cp->cn_arg, c); X} X Xstatic int Xuartlirc_cngetc(struct consdev *cp) X{ X X return (uartlirc_poll(cp->cn_arg)); X} X Xstatic int Xuartlirc_tty_open(struct tty *tp) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X X if (sc == NULL || sc->sc_leaving) X return (ENXIO); X X if (!uartlirc_allowopenboth && sc->sc_lircstate) X return (EBUSY); X X sc->sc_opened = 1; X return (0); X} X Xstatic void Xuartlirc_tty_close(struct tty *tp) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X if (sc == NULL || sc->sc_leaving || !sc->sc_opened) X return; X X if (sc->sc_hwiflow) X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_IFLOW, 0); X if (sc->sc_hwoflow) X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_OFLOW, 0); X if (sc->sc_sysdev == NULL) X UARTLIRC_SETSIG(sc, SER_DDTR | SER_DRTS); X X wakeup(sc); X sc->sc_opened = 0; X return; X} X Xstatic void Xuartlirc_tty_outwakeup(struct tty *tp) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X if (sc == NULL || sc->sc_leaving) X return; X X if (sc->sc_txbusy) X return; X X /* X * Respect RTS/CTS (output) flow control if enabled and not already X * handled by hardware. X */ X if ((tp->t_termios.c_cflag & CCTS_OFLOW) && !sc->sc_hwoflow && X !(sc->sc_hwsig & SER_CTS)) X return; X X sc->sc_txdatasz = ttydisc_getc(tp, sc->sc_txbuf, sc->sc_txfifosz); X if (sc->sc_txdatasz != 0) X UARTLIRC_TRANSMIT(sc); X} X Xstatic void Xuartlirc_tty_inwakeup(struct tty *tp) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X if (sc == NULL || sc->sc_leaving) X return; X X if (sc->sc_isquelch) { X if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) X UARTLIRC_SETSIG(sc, SER_DRTS|SER_RTS); X sc->sc_isquelch = 0; X uartlirc_sched_softih(sc, SER_INT_RXREADY); X } X} X Xstatic int Xuartlirc_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X X switch (cmd) { X case TIOCSBRK: X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_BREAK, 1); X return (0); X case TIOCCBRK: X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_BREAK, 0); X return (0); X default: X return pps_ioctl(cmd, data, &sc->sc_pps); X } X} X Xstatic int Xuartlirc_tty_param(struct tty *tp, struct termios *t) X{ X struct uartlirc_softc *sc; X int databits, parity, stopbits; X X sc = tty_softc(tp); X if (sc == NULL || sc->sc_leaving) X return (ENODEV); X if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0) X return (EINVAL); X /* Fixate certain parameters for system devices. */ X if (sc->sc_sysdev != NULL) { X t->c_ispeed = t->c_ospeed = sc->sc_sysdev->baudrate; X t->c_cflag |= CLOCAL; X t->c_cflag &= ~HUPCL; X } X if (t->c_ospeed == 0) { X UARTLIRC_SETSIG(sc, SER_DDTR | SER_DRTS); X return (0); X } X switch (t->c_cflag & CSIZE) { X case CS5: databits = 5; break; X case CS6: databits = 6; break; X case CS7: databits = 7; break; X default: databits = 8; break; X } X stopbits = (t->c_cflag & CSTOPB) ? 2 : 1; X if (t->c_cflag & PARENB) X parity = (t->c_cflag & PARODD) ? UARTLIRC_PARITY_ODD X : UARTLIRC_PARITY_EVEN; X else X parity = UARTLIRC_PARITY_NONE; X if (UARTLIRC_PARAM(sc, t->c_ospeed, databits, stopbits, parity) != 0) X return (EINVAL); X UARTLIRC_SETSIG(sc, SER_DDTR | SER_DTR); X /* Set input flow control state. */ X if (!sc->sc_hwiflow) { X if ((t->c_cflag & CRTS_IFLOW) && sc->sc_isquelch) X UARTLIRC_SETSIG(sc, SER_DRTS); X else X UARTLIRC_SETSIG(sc, SER_DRTS | SER_RTS); X } else X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW)); X /* Set output flow control state. */ X if (sc->sc_hwoflow) X UARTLIRC_IOCTL(sc, UARTLIRC_IOCTL_OFLOW, (t->c_cflag & CCTS_OFLOW)); X X return (0); X} X Xstatic int Xuartlirc_tty_modem(struct tty *tp, int biton, int bitoff) X{ X struct uartlirc_softc *sc; X X sc = tty_softc(tp); X if (biton != 0 || bitoff != 0) X UARTLIRC_SETSIG(sc, SER_DELTA(bitoff|biton) | biton); X return (sc->sc_hwsig); X} X Xvoid Xuartlirc_tty_intr(void *arg) X{ X struct uartlirc_softc *sc = arg; X struct tty *tp; X int c, err = 0, pend, sig, xc; X X if (sc->sc_leaving) X return; X X pend = atomic_readandclear_32(&sc->sc_ttypend); X if (!(pend & SER_INT_MASK)) X return; X X tp = sc->sc_u.u_tty.tp; X tty_lock(tp); X X if (pend & SER_INT_RXREADY) { X while (!uartlirc_rx_empty(sc) && !sc->sc_isquelch) { X xc = uartlirc_rx_peek(sc); X c = xc & 0xff; X if (xc & UARTLIRC_STAT_FRAMERR) X err |= TRE_FRAMING; X if (xc & UARTLIRC_STAT_OVERRUN) X err |= TRE_OVERRUN; X if (xc & UARTLIRC_STAT_PARERR) X err |= TRE_PARITY; X if (ttydisc_rint(tp, c, err) != 0) { X sc->sc_isquelch = 1; X if ((tp->t_termios.c_cflag & CRTS_IFLOW) && X !sc->sc_hwiflow) X UARTLIRC_SETSIG(sc, SER_DRTS); X } else X uartlirc_rx_next(sc); X } X } X X if (pend & SER_INT_BREAK) X ttydisc_rint(tp, 0, TRE_BREAK); X X if (pend & SER_INT_SIGCHG) { X sig = pend & SER_INT_SIGMASK; X if (sig & SER_DDCD) X ttydisc_modem(tp, sig & SER_DCD); X if (sig & SER_DCTS) X uartlirc_tty_outwakeup(tp); X } X X if (pend & SER_INT_TXIDLE) X uartlirc_tty_outwakeup(tp); X ttydisc_rint_done(tp); X tty_unlock(tp); X} X Xstatic void Xuartlirc_tty_free(void *arg) X{ X X /* X * XXX: uart(4) could reuse the device unit number before it is X * being freed by the TTY layer. We should use this hook to free X * the device unit number, but unfortunately newbus does not X * seem to support such a construct. X */ X} X Xstatic struct ttydevsw uartlirc_tty_class = { X .tsw_flags = TF_INITLOCK|TF_CALLOUT, X .tsw_open = uartlirc_tty_open, X .tsw_close = uartlirc_tty_close, X .tsw_outwakeup = uartlirc_tty_outwakeup, X .tsw_inwakeup = uartlirc_tty_inwakeup, X .tsw_ioctl = uartlirc_tty_ioctl, X .tsw_param = uartlirc_tty_param, X .tsw_modem = uartlirc_tty_modem, X .tsw_free = uartlirc_tty_free, X}; X Xint Xuartlirc_tty_attach(struct uartlirc_softc *sc) X{ X struct tty *tp; X int unit; X X sc->sc_u.u_tty.tp = tp = tty_alloc(&uartlirc_tty_class, sc); X X unit = device_get_unit(sc->sc_dev); X X if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UARTLIRC_DEV_CONSOLE) { X sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name, X "ttyu%r", unit); X tty_init_console(tp, 0); X } X X swi_add(&tty_intr_event, uartlirc_driver_name, uartlirc_tty_intr, sc, SWI_TTY, X INTR_TYPE_TTY, &sc->sc_softih); X X /* XXX if flags & LIRC? */ X uartlirc_lircdev_attach(sc); X X tty_makedev(tp, NULL, "u%r", unit); X X return (0); X} X Xint Xuartlirc_tty_detach(struct uartlirc_softc *sc) X{ X struct tty *tp; X X /* XXX if flags & LIRC? */ X uartlirc_lircdev_detach(sc); X X tp = sc->sc_u.u_tty.tp; X X tty_lock(tp); X swi_remove(sc->sc_softih); X tty_rel_gone(tp); X X return (0); X} 1b5f12be791eca8f3d27314d9ba1c6bc exit