code:
/* $OpenBSD: dsdt.h,v 1.64 2015/06/13 21:41:42 guenther Exp $ */
/*
 * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __DEV_ACPI_DSDT_H__
#define __DEV_ACPI_DSDT_H__

struct aml_scope {
	struct acpi_softc	*sc;
	uint8_t			*pos;
	uint8_t			*start;
	uint8_t			*end;
	struct aml_node		*node;
	struct aml_scope	*parent;
	struct aml_value	*locals;
	struct aml_value	*args;
	struct aml_value	*retv;
	int			type;
	int			depth;
};

struct aml_opcode {
	u_int32_t		opcode;
	const char		*mnem;
	const char		*args;
};

const char		*aml_eisaid(u_int32_t);
const char		*aml_mnem(int, uint8_t *);
int64_t			aml_val2int(struct aml_value *);
struct aml_node		*aml_searchname(struct aml_node *, const void *);
struct aml_node		*aml_searchrel(struct aml_node *, const void *);

struct aml_value	*aml_getstack(struct aml_scope *, int);
struct aml_value	*aml_allocvalue(int, int64_t, const void *);
void			aml_freevalue(struct aml_value *);
void			aml_notify(struct aml_node *, int);
void			aml_showvalue(struct aml_value *, int);
void			aml_walkroot(void);
void			aml_walktree(struct aml_node *);

int			aml_find_node(struct aml_node *, const char *,
			    int (*)(struct aml_node *, void *), void *);
int			acpi_parse_aml(struct acpi_softc *, u_int8_t *,
			    u_int32_t);
void			aml_register_notify(struct aml_node *, const char *,
			    int (*)(struct aml_node *, int, void *), void *,
			    int);

int			aml_evalnode(struct acpi_softc *, struct aml_node *,
			    int, struct aml_value *, struct aml_value *);
int			aml_node_setval(struct acpi_softc *, struct aml_node *,
			    int64_t);
int			aml_evalname(struct acpi_softc *, struct aml_node *,
			    const char *, int, struct aml_value *,
			    struct aml_value *);
int			aml_evalinteger(struct acpi_softc *, struct aml_node *,
                            const char *, int, struct aml_value *, int64_t *);

void			aml_create_defaultobjects(void);

const char		*aml_nodename(struct aml_node *);

#define SRT_IRQ2		0x22
#define SRT_IRQ3		0x23
#define SRT_DMA			0x2A
#define SRT_STARTDEP0		0x30
#define SRT_STARTDEP1		0x31
#define SRT_ENDDEP		0x38
#define SRT_IOPORT		0x47
#define SRT_FIXEDPORT		0x4B
#define SRT_ENDTAG		0x78

#define SR_IRQ			0x04
#define SR_DMA			0x05
#define SR_STARTDEP		0x06
#define SR_ENDDEP		0x07
#define SR_IOPORT		0x08
#define SR_FIXEDPORT		0x09
#define SR_ENDTAG		0x0F
/* byte zero of small resources combines the tag above a length [1..7] */
#define	SR_TAG(tag,len)		((tag << 3) + (len))

#define LR_24BIT		0x81
#define LR_GENREGISTER		0x82
#define LR_32BIT		0x85
#define LR_32BITFIXED		0x86
#define LR_DWORD		0x87
#define LR_WORD			0x88
#define LR_EXTIRQ		0x89
#define LR_QWORD		0x8A

#define __amlflagbit(v,s,l)
union acpi_resource {
	struct {
		uint8_t  typecode;
		uint16_t length;
	}  __packed hdr;

	/* Small resource structures
	 * format of typecode is: tttttlll, t = type, l = length
	 */
	struct {
		uint8_t  typecode;
		uint16_t irq_mask;
		uint8_t  irq_flags;
#define SR_IRQ_SHR		(1L << 4)
#define SR_IRQ_POLARITY		(1L << 3)
#define SR_IRQ_MODE		(1L << 0)
	}  __packed sr_irq;
	struct {
		uint8_t  typecode;
		uint8_t  channel;
		uint8_t  flags;
#define SR_DMA_TYP_MASK		0x3
#define SR_DMA_TYP_SHIFT 	5
#define SR_DMA_BM		(1L << 2)
#define SR_DMA_SIZE_MASK	0x3
#define SR_DMA_SIZE_SHIFT	0
	}  __packed sr_dma;
	struct {
		uint8_t  typecode;
		uint8_t  flags;
#define SR_IOPORT_DEC		(1L << 0)
		uint16_t _min;
		uint16_t _max;
		uint8_t  _aln;
		uint8_t  _len;
	}  __packed sr_ioport;
	struct {
		uint8_t  typecode;
		uint16_t _bas;
		uint8_t  _len;
	}  __packed sr_fioport;

	/* Large resource structures */
	struct {
		uint8_t  typecode;
		uint16_t length;
		uint8_t  _info;
		uint16_t _min;
		uint16_t _max;
		uint16_t _aln;
		uint16_t _len;
	}  __packed lr_m24;
	struct {
		uint8_t  typecode;
		uint16_t length;
		uint8_t  _info;
		uint32_t _min;
		uint32_t _max;
		uint32_t _aln;
		uint32_t _len;
	}  __packed lr_m32;
	struct {
		uint8_t  typecode;
		uint16_t length;
		uint8_t  flags;
#define LR_EXTIRQ_SHR		(1L << 3)
#define LR_EXTIRQ_POLARITY	(1L << 2)
#define LR_EXTIRQ_MODE		(1L << 1)
		uint8_t  irq_count;
		uint32_t irq[1];
	} __packed lr_extirq;
	struct {
		uint8_t		typecode;
		uint16_t	length;
		uint8_t		type;
		uint8_t		flags;
		uint8_t		tflags;
		uint16_t	_gra;
		uint16_t	_min;
		uint16_t	_max;
		uint16_t	_tra;
		uint16_t	_len;
		uint8_t		src_index;
		char		src[1];
	} __packed lr_word;
	struct {
		uint8_t		typecode;
		uint16_t	length;
		uint8_t		type;
		uint8_t		flags;
		uint8_t		tflags;
		uint32_t	_gra;
		uint32_t	_min;
		uint32_t	_max;
		uint32_t	_tra;
		uint32_t	_len;
		uint8_t		src_index;
		char		src[1];
	} __packed lr_dword;
	struct {
		uint8_t		typecode;
		uint16_t	length;
		uint8_t		type;
		uint8_t		flags;
		uint8_t		tflags;
		uint64_t	_gra;
		uint64_t	_min;
		uint64_t	_max;
		uint64_t	_tra;
		uint64_t	_len;
		uint8_t		src_index;
		char		src[1];
	} __packed lr_qword;
	uint8_t		pad[64];
} __packed;

#define AML_CRSTYPE(x)	((x)->hdr.typecode & 0x80 ? \
			    (x)->hdr.typecode : (x)->hdr.typecode >> 3)
#define AML_CRSLEN(x)	((x)->hdr.typecode & 0x80 ? \
			    3+(x)->hdr.length : 1+((x)->hdr.typecode & 0x7))

int			aml_print_resource(union acpi_resource *, void *);
int			aml_parse_resource(struct aml_value *,
			    int (*)(union acpi_resource *, void *), void *);

#define ACPI_E_NOERROR   0x00
#define ACPI_E_BADVALUE  0x01

#define AML_MAX_ARG	 7
#define AML_MAX_LOCAL	 8

#define AML_WALK_PRE 0x00
#define AML_WALK_POST 0x01

void			aml_walknodes(struct aml_node *, int,
			    int (*)(struct aml_node *, void *), void *);

void			aml_postparse(void);

void			aml_hashopcodes(void);

void			aml_foreachpkg(struct aml_value *, int,
			    void (*fn)(struct aml_value *, void *), void *);

const char		*aml_val_to_string(const struct aml_value *);

void			aml_disasm(struct aml_scope *scope, int lvl,
			    void (*dbprintf)(void *, const char *, ...),
			    void *arg);
int			aml_getpci(struct aml_node *, int64_t *);
int			aml_evalhid(struct aml_node *, struct aml_value *);

int			acpi_walkmem(int, const char *);

#define aml_get8(p)    *(uint8_t *)(p)
#define aml_get16(p)   *(uint16_t *)(p)
#define aml_get32(p)   *(uint32_t *)(p)
#define aml_get64(p)   *(uint64_t *)(p)

union amlpci_t {
	uint64_t addr;
	struct {
		uint16_t reg;
		uint16_t fun;
		uint16_t dev;
		uint16_t bus;
	};
};
int			aml_rdpciaddr(struct aml_node *pcidev,
			    union amlpci_t *);

#ifndef SMALL_KERNEL
void			acpi_getdevlist(struct acpi_devlist_head *,
			    struct aml_node *, struct aml_value *, int);
#endif
void			aml_notify_dev(const char *, int);

void			acpi_freedevlist(struct acpi_devlist_head *);

void			acpi_glk_enter(void);
void			acpi_glk_leave(void);

#endif /* __DEV_ACPI_DSDT_H__ */

license: unknown


code:
#	$OpenBSD: files.acpi,v 1.27 2013/11/06 10:40:36 mpi Exp $
#
# Config file and device description for machine-independent ACPI code.
# Included by ports that need it.

define	acpi {}
device	acpi
attach	acpi at bios
file	dev/acpi/acpi.c			acpi needs-flag
file	dev/acpi/acpiutil.c		acpi
file	dev/acpi/dsdt.c			acpi
file	dev/acpi/acpidebug.c		acpi & ddb

# ACPI timer
device	acpitimer
attach	acpitimer at acpi
file	dev/acpi/acpitimer.c		acpitimer

# AC device
device	acpiac
attach	acpiac at acpi
file	dev/acpi/acpiac.c		acpiac

# battery device
device	acpibat
attach	acpibat at acpi
file	dev/acpi/acpibat.c		acpibat

# button device
device	acpibtn
attach	acpibtn at acpi
file	dev/acpi/acpibtn.c		acpibtn

# cpu device
device	acpicpu
attach	acpicpu at acpi
file	dev/acpi/acpicpu.c		acpicpu needs-flag

# High Precision Event Timer
device	acpihpet
attach	acpihpet at acpi
file	dev/acpi/acpihpet.c		acpihpet

# Embedded Controller
device	acpiec
attach	acpiec at acpi
file	dev/acpi/acpiec.c		acpiec

# Thermal Zone
device	acpitz
attach	acpitz at acpi
file	dev/acpi/acpitz.c		acpitz

# Multiple APIC Description Table
device	acpimadt
attach	acpimadt at acpi
file	dev/acpi/acpimadt.c		acpimadt

# Memory Mapped Configuration Space Address Description Table
device	acpimcfg
attach	acpimcfg at acpi
file	dev/acpi/acpimcfg.c		acpimcfg

# PCI Routing Table
device	acpiprt
attach	acpiprt at acpi
file	dev/acpi/acpiprt.c		acpiprt needs-flag

# Docking station
device	acpidock
attach	acpidock at acpi
file	dev/acpi/acpidock.c		acpidock

# ASUS ACPI Hotkeys
device	acpiasus
attach	acpiasus at acpi
file	dev/acpi/acpiasus.c		acpiasus

# IBM/Lenovo ThinkPad support
device	acpithinkpad
attach	acpithinkpad at acpi
file	dev/acpi/acpithinkpad.c		acpithinkpad

# Toshiba support
device	acpitoshiba
attach	acpitoshiba at acpi
file	dev/acpi/acpitoshiba.c		acpitoshiba

# Sony support
device	acpisony
attach	acpisony at acpi
file	dev/acpi/acpisony.c		acpisony

# ACPI video
define	acpivideo {}
device	acpivideo
attach	acpivideo at acpi
file	dev/acpi/acpivideo.c		acpivideo

# ACPI vout
device	acpivout
attach	acpivout at acpivideo
file	dev/acpi/acpivout.c		acpivout

# ACPI pwrres
device	acpipwrres
attach	acpipwrres at acpi
file	dev/acpi/acpipwrres.c		acpipwrres needs-flag

# ASUSTeK AI Booster ATK0110
device	aibs
attach	aibs at acpi
file	dev/acpi/atk0110.c		aibs


code: src/sys/dev/adb

path: sys/dev/adb/CVS/Repository


code:
/*	$OpenBSD: adb.h,v 1.5 2011/06/16 10:44:33 mpi Exp $	*/
/*	$NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $	*/

/*-
 * Copyright (C) 1993, 1994	Allen K. Briggs, Chris P. Caputo,
 *			Michael L. Finch, Bradley A. Grantham, and
 *			Lawrence A. Kesteloot
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the Alice Group.
 * 4. The names of the Alice Group or any of its members may not be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ADB_H_
#define _ADB_H_

#ifdef _KERNEL

/*
 * Arguments used to attach a device to the Apple Desktop Bus
 */
struct adb_attach_args {
	const char	*name;		/* adb_device_name if real adb device */
	int		 origaddr;
	int		 adbaddr;
	int		 handler_id;
};

extern const char adb_device_name[];

#define	ADB_CMDADDR(cmd)	((u_int8_t)(cmd & 0xf0) >> 4)
#define	ADBFLUSH(dev)		((((u_int8_t)dev & 0x0f) << 4) | 0x01)
#define	ADBLISTEN(dev, reg)	((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg)
#define	ADBTALK(dev, reg)	((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg)

/* an ADB event */
typedef struct adb_event_s {
	int byte_count;			/* number of bytes */
	unsigned char bytes[8];		/* bytes from register 0 */
} adb_event_t;

	/* Interesting default addresses */
#define	ADBADDR_SECURE	1		/* Security dongles */
#define ADBADDR_MAP	2		/* Mapped devices (keyboards/pads) */
#define ADBADDR_REL	3		/* Relative positioning devices
					   (mice, trackballs/pads) */
#define ADBADDR_ABS	4		/* Absolute positioning devices
					   (graphics tablets) */
#define ADBADDR_DATATX	5
#define ADBADDR_RSRVD	6		/* Reserved by Apple */
#define ADBADDR_MISC	7		/* Miscellaneous appliances */
#define ADBADDR_DONGLE	ADBADDR_SECURE
#define ADBADDR_KBD	ADBADDR_MAP
#define ADBADDR_MS	ADBADDR_REL
#define ADBADDR_TABLET	ADBADDR_ABS
#define ADBADDR_MODEM	ADBADDR_DATATX

	/* Interesting keyboard handler IDs */
#define ADB_STDKBD	1
#define ADB_EXTKBD	2
#define ADB_ISOKBD	4
#define ADB_EXTISOKBD	5
#define ADB_KBDII	8
#define ADB_ISOKBDII	9
#define ADB_PBKBD	12
#define ADB_PBISOKBD	13
#define ADB_ADJKPD	14
#define ADB_ADJKBD	16
#define ADB_ADJISOKBD	17
#define ADB_ADJJAPKBD	18
#define ADB_PBEXTISOKBD	20
#define ADB_PBEXTJAPKBD	21
#define ADB_JPKBDII	22
#define ADB_PBEXTKBD	24
#define ADB_DESIGNKBD	27	/* XXX Needs to be verified XXX */
#define ADB_PBJPKBD	30
#define ADB_PBG4KBD	195
#define ADB_IBITISOKBD	196
#define ADB_PBG3JPKBD	201

	/* Interesting mouse handler IDs */
#define ADBMS_100DPI	1
#define ADBMS_200DPI	2
#define ADBMS_MSA3	3	/* Mouse Systems A3 Mouse */
#define ADBMS_EXTENDED	4	/* Extended mouse protocol */
#define ADBMS_USPEED	0x2f	/* MicroSpeed mouse */
#define ADBMS_UCONTOUR	0x66	/* Contour mouse */
#define ADBMS_TURBO	50	/* Kensington Turbo Mouse */

	/* Interesting tablet handler ID */
#define ADB_ARTPAD	58	/* WACOM ArtPad II tablet */

	/* Interesting miscellaneous handler ID */
#define ADB_POWERKEY	34	/* Sophisticated Circuits PowerKey */
				/* (intelligent power tap) */

extern int	adb_polling;
#ifdef ADB_DEBUG
extern int	adb_debug;
#endif

/* ADB Manager */

typedef caddr_t Ptr;

typedef struct {
	Ptr siServiceRtPtr;
	Ptr siDataAreaAddr;
} ADBSetInfoBlock;

typedef struct {
	unsigned char	devType;
	unsigned char	origADBAddr;
	Ptr		dbServiceRtPtr;
	Ptr		dbDataAreaAddr;
} ADBDataBlock;

int	adbprint(void *, const char *);
int	adb_op_sync(Ptr, short);
int	set_adb_info(ADBSetInfoBlock *, int);

#endif	/* _KERNEL */

#endif /* _ADB_H_ */


code:
/*	$OpenBSD: adb_subr.c,v 1.4 2013/03/09 11:33:24 mpi Exp $	*/
/*	$NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $	*/

/*-
 * Copyright (C) 1994	Bradley A. Grantham
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <dev/adb/adb.h>

struct cfdriver adb_cd = {
	NULL, "adb", DV_DULL
};

const char adb_device_name[] = "adb_device";

int
adbprint(void *args, const char *name)
{
	struct adb_attach_args *aa_args = (struct adb_attach_args *)args;
	int rv = UNCONF;

	if (name) {	/* no configured device matched */
		rv = UNSUPP; /* most ADB device types are unsupported */

		/* print out what kind of ADB device we have found */
		switch(aa_args->origaddr) {
#ifdef ADBVERBOSE
		case ADBADDR_SECURE:
			printf("security dongle (%d)", aa_args->handler_id);
			break;
#endif
		case ADBADDR_MAP:
			printf("mapped device (%d)", aa_args->handler_id);
			rv = UNCONF;
			break;
		case ADBADDR_REL:
			printf("relative positioning device (%d)",
			    aa_args->handler_id);
			rv = UNCONF;
			break;
#ifdef ADBVERBOSE
		case ADBADDR_ABS:
			switch (aa_args->handler_id) {
			case ADB_ARTPAD:
				printf("WACOM ArtPad II");
				break;
			default:
				printf("absolute positioning device (%d)",
				    aa_args->handler_id);
				break;
			}
			break;
		case ADBADDR_DATATX:
			printf("data transfer device (modem?) (%d)",
			    aa_args->handler_id);
			break;
		case ADBADDR_MISC:
			switch (aa_args->handler_id) {
			case ADB_POWERKEY:
				printf("Sophisticated Circuits PowerKey");
				break;
			default:
				printf("misc. device (remote control?) (%d)",
				    aa_args->handler_id);
				break;
			}
			break;
#endif /* ADBVERBOSE */
		default:
			printf("unknown type %d device, (handler %d)",
			    aa_args->origaddr, aa_args->handler_id);
			break;
		}
		printf(" at %s", name);
	}

	printf(" addr %d", aa_args->adbaddr);

	return (rv);
}


code:
/*	$OpenBSD: akbd.c,v 1.14 2014/01/26 17:48:08 miod Exp $	*/
/*	$NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $	*/

/*
 * Copyright (C) 1998	Colin Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Colin Wood.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/timeout.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/systm.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>

#include <machine/autoconf.h>
#include <machine/cpu.h>

#include <dev/adb/adb.h>
#include <dev/adb/akbdmap.h>
#include <dev/adb/akbdvar.h>
#include <dev/adb/keyboard.h>

/*
 * Function declarations.
 */
int	akbdmatch(struct device *, void *, void *);
void	akbdattach(struct device *, struct device *, void *);

/* Driver definition. */
struct cfattach akbd_ca = {
	sizeof(struct akbd_softc), akbdmatch, akbdattach
};
struct cfdriver akbd_cd = {
	NULL, "akbd", DV_DULL
};

int	akbd_enable(void *, int);
void	akbd_set_leds(void *, int);
int	akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);

struct wskbd_accessops akbd_accessops = {
	akbd_enable,
	akbd_set_leds,
	akbd_ioctl,
};

struct wskbd_mapdata akbd_keymapdata = {
	akbd_keydesctab,
#ifdef AKBD_LAYOUT
	AKBD_LAYOUT,
#else
	KB_US | KB_DEFAULT,
#endif
};

void	akbd_adbcomplete(caddr_t, caddr_t, int);
void	akbd_capslockwrapper(struct akbd_softc *, int);
void	akbd_input(struct akbd_softc *, int);
void	akbd_processevent(struct akbd_softc *, adb_event_t *);
#ifdef notyet
u_char	getleds(int);
int	setleds(struct akbd_softc *, u_char);
void	blinkleds(struct akbd_softc *);
#endif

int
akbdmatch(struct device *parent, void *vcf, void *aux)
{
	struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;

	if (strcmp(aa_args->name, adb_device_name) != 0)
		return (0);

	if (aa_args->origaddr == ADBADDR_KBD)
		return (1);
	else
		return (0);
}

void
akbdattach(struct device *parent, struct device *self, void *aux)
{
	ADBSetInfoBlock adbinfo;
	struct akbd_softc *sc = (struct akbd_softc *)self;
	struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
	int error, kbd_done;
	short cmd;
	u_char buffer[9];
	struct wskbddev_attach_args a;
	static int akbd_console_initted;
	int wskbd_eligible = 1;

	sc->origaddr = aa_args->origaddr;
	sc->adbaddr = aa_args->adbaddr;
	sc->handler_id = aa_args->handler_id;

	sc->sc_leds = (u_int8_t)0x00;	/* initially off */
	sc->sc_caps = 0;
	sc->sc_iso = 0;

	adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete;
	adbinfo.siDataAreaAddr = (caddr_t)sc;

	printf(": ");
	switch (sc->handler_id) {
	case ADB_STDKBD:
		printf("standard keyboard\n");
		break;
	case ADB_ISOKBD:
		printf("standard keyboard (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	case ADB_EXTKBD:
		cmd = ADBTALK(sc->adbaddr, 1);
		kbd_done =
		    (adb_op_sync((Ptr)buffer, cmd) == 0);

		/* Ignore Logitech MouseMan/Trackman pseudo keyboard */
		if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
			printf("Mouseman (non-EMP) pseudo keyboard\n");
			adbinfo.siServiceRtPtr = (Ptr)0;
			adbinfo.siDataAreaAddr = (Ptr)0;
			wskbd_eligible = 0;
		} else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
			printf("Trackman (non-EMP) pseudo keyboard\n");
			adbinfo.siServiceRtPtr = (Ptr)0;
			adbinfo.siDataAreaAddr = (Ptr)0;
			wskbd_eligible = 0;
		} else {
			printf("extended keyboard\n");
#ifdef notyet
			blinkleds(sc);
#endif
		}
		break;
	case ADB_EXTISOKBD:
		printf("extended keyboard (ISO layout)\n");
		sc->sc_iso = 1;
#ifdef notyet
		blinkleds(sc);
#endif
		break;
	case ADB_KBDII:
		printf("keyboard II\n");
		break;
	case ADB_ISOKBDII:
		printf("keyboard II (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	case ADB_PBKBD:
		printf("PowerBook keyboard\n");
		break;
	case ADB_PBISOKBD:
		printf("PowerBook keyboard (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	case ADB_ADJKPD:
		printf("adjustable keypad\n");
		wskbd_eligible = 0;
		break;
	case ADB_ADJKBD:
		printf("adjustable keyboard\n");
		break;
	case ADB_ADJISOKBD:
		printf("adjustable keyboard (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	case ADB_ADJJAPKBD:
		printf("adjustable keyboard (Japanese layout)\n");
		break;
	case ADB_PBEXTISOKBD:
		printf("PowerBook extended keyboard (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	case ADB_PBEXTJAPKBD:
		printf("PowerBook extended keyboard (Japanese layout)\n");
		break;
	case ADB_JPKBDII:
		printf("keyboard II (Japanese layout)\n");
		break;
	case ADB_PBEXTKBD:
		printf("PowerBook extended keyboard\n");
		break;
	case ADB_DESIGNKBD:
		printf("extended keyboard\n");
#ifdef notyet
		blinkleds(sc);
#endif
		break;
	case ADB_PBJPKBD:
		printf("PowerBook keyboard (Japanese layout)\n");
		break;
	case ADB_PBG3JPKBD:
		printf("PowerBook G3 keyboard (Japanese layout)\n");
		break;
	case ADB_PBG4KBD:
		printf("PowerBook G4 keyboard (Inverted T)\n");
		break;
	case ADB_IBITISOKBD:
		printf("iBook keyboard with inverted T (ISO layout)\n");
		sc->sc_iso = 1;
		break;
	default:
		printf("mapped device (%d)\n", sc->handler_id);
#if 0
		wskbd_eligible = 0;
#endif
		break;
	}
	error = set_adb_info(&adbinfo, sc->adbaddr);
#ifdef ADB_DEBUG
	if (adb_debug)
		printf("akbd: returned %d from set_adb_info\n", error);
#endif

	if (akbd_is_console() && wskbd_eligible)
		a.console = (++akbd_console_initted == 1);
	else
		a.console = 0;
	a.keymap = &akbd_keymapdata;
	a.accessops = &akbd_accessops;
	a.accesscookie = sc;

	sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
}

/*
 * Handle putting the keyboard data received from the ADB into
 * an ADB event record.
 */
void
akbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
{
	adb_event_t event;
	struct akbd_softc *sc;
	int adbaddr;
#ifdef ADB_DEBUG
	int i;

	if (adb_debug)
		printf("adb: transaction completion\n");
#endif

	adbaddr = ADB_CMDADDR(adb_command);
	sc = (struct akbd_softc *)data_area;

	event.byte_count = buffer[0];
	memcpy(event.bytes, buffer + 1, event.byte_count);

#ifdef ADB_DEBUG
	if (adb_debug) {
		printf("akbd: from %d at %d (org %d) %d:", adbaddr,
		    sc->handler_id, sc->origaddr, buffer[0]);
		for (i = 1; i <= buffer[0]; i++)
			printf(" %x", buffer[i]);
		printf("\n");
	}
#endif

	if (sc->sc_wskbddev != NULL)
		akbd_processevent(sc, &event);
}

#ifdef notyet
/*
 * Get the actual hardware LED state and convert it to softc format.
 */
u_char
getleds(int addr)
{
	short cmd;
	u_char buffer[9], leds;

	leds = 0x00;	/* all off */
	buffer[0] = 0;

	cmd = ADBTALK(addr, 2);
	if (adb_op_sync((Ptr)buffer, cmd) == 0 &&
	    buffer[0] > 0)
		leds = ~(buffer[2]) & 0x07;

	return (leds);
}

/*
 * Set the keyboard LED's.
 *
 * Automatically translates from ioctl/softc format to the
 * actual keyboard register format
 */
int
setleds(struct akbd_softc *sc, u_char leds)
{
	int addr;
	short cmd;
	u_char buffer[9];

	addr = sc->adbaddr;
	buffer[0] = 0;

	cmd = ADBTALK(addr, 2);
	if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
		return (EIO);

	leds = ~leds & 0x07;
	buffer[2] &= 0xf8;
	buffer[2] |= leds;

	cmd = ADBLISTEN(addr, 2);
	adb_op_sync((Ptr)buffer, cmd);

	/* talk R2 */
	cmd = ADBTALK(addr, 2);
	if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
		return (EIO);

	if ((buffer[2] & 0xf8) != leds)
		return (EIO);
	else
		return (0);
}

/*
 * Toggle all of the LED's on and off, just for show.
 */
void
blinkleds(struct akbd_softc *sc)
{
	u_char origleds;

	origleds = getleds(sc->adbaddr);
	setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK);
	delay(400000);
	setleds(sc, origleds);

	if (origleds & LED_NUMLOCK)
		sc->sc_leds |= WSKBD_LED_NUM;
	if (origleds & LED_CAPSLOCK)
		sc->sc_leds |= WSKBD_LED_CAPS;
	if (origleds & LED_SCROLL_LOCK)
		sc->sc_leds |= WSKBD_LED_SCROLL;
}
#endif

int
akbd_enable(void *v, int on)
{
	return 0;
}

void
akbd_set_leds(void *v, int on)
{
#ifdef notyet
	struct akbd_softc *sc = v;
	int leds;

	if (sc->sc_extended) {
		if (sc->sc_leds == on)
			return;

		leds = 0;
		if (on & WSKBD_LED_NUM)
			leds |= LED_NUMLOCK;
		if (on & WSKBD_LED_CAPS)
			leds |= LED_CAPSLOCK;
		if (on & WSKBD_LED_SCROLL)
			leds |= LED_SCROLL_LOCK;

		setleds(sc, leds);
	}
#endif
}

int
akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct akbd_softc *sc = v;

	switch (cmd) {

	case WSKBDIO_GTYPE:
		*(int *)data = WSKBD_TYPE_ADB;
		return 0;
	case WSKBDIO_SETLEDS:
		akbd_set_leds(v, *(int *)data);
		return 0;
	case WSKBDIO_GETLEDS:
		*(int *)data = sc->sc_leds;
		return 0;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	case WSKBDIO_SETMODE:
		sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
		return (0);
#endif
	default:
		return (-1);
	}
}

/*
 * The ``caps lock'' key is special: since on earlier keyboards, the physical
 * key stays down when pressed, we will get a notification of the key press,
 * but not of the key release. Then, when it is pressed again, we will not get
 * a notification of the key press, but will see the key release.
 *
 * This is not exactly true. We see the missing release and press events both
 * as the release of the power (reset) key.
 *
 * To avoid confusing them with real power key presses, we maintain two
 * states for the caps lock key: logically down (from wscons' point of view),
 * and ``physically'' down (from the adb messages point of view), to ignore
 * the power key. But since one may press the power key while the caps lock
 * is held down, we also have to remember the state of the power key... this
 * is quite messy.
 */

/*
 * Values for caps lock state machine
 */
#define	CL_DOWN_ADB	0x01
#define	CL_DOWN_LOGICAL	0x02
#define	CL_DOWN_RESET	0x04

/*
 * Given a keyboard ADB event, decode the keycodes and pass them to wskbd.
 */
void
akbd_processevent(struct akbd_softc *sc, adb_event_t *event)
{
	switch (event->byte_count) {
	case 1:
		akbd_capslockwrapper(sc, event->bytes[0]);
		break;
	case 2:
		/*
		 * The reset (or power) key sends 0x7f7f on press and
		 * 0xffff on release, and we ignore it.
		 */
		if (event->bytes[0] == event->bytes[1] &&
		    ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
			if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
				SET(sc->sc_caps, CL_DOWN_RESET);
			else {
				if (ISSET(sc->sc_caps, CL_DOWN_RESET))
					CLR(sc->sc_caps, CL_DOWN_RESET);
				else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
					akbd_input(sc, ISSET(sc->sc_caps,
					    CL_DOWN_LOGICAL) ?
					      ADBK_KEYDOWN(ADBK_CAPSLOCK) :
					      ADBK_KEYUP(ADBK_CAPSLOCK));
					sc->sc_caps ^= CL_DOWN_LOGICAL;
				}
			}
		} else {
			akbd_capslockwrapper(sc, event->bytes[0]);
			akbd_capslockwrapper(sc, event->bytes[1]);
		}
		break;
	default:
#ifdef DIAGNOSTIC
		printf("%s: unexpected message length %d\n",
		    sc->sc_dev.dv_xname, event->byte_count);
#endif
		break;
	}

}

void
akbd_capslockwrapper(struct akbd_softc *sc, int key)
{
	if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
		sc->sc_caps ^= CL_DOWN_ADB;

	if (key != 0xff)
		akbd_input(sc, key);
}

static inline int
akbd_iso_swap(int keycode)
{
	switch (keycode) {
	case 10:
		return (50);
	case 50:
		return (10);
	default:
		return (keycode);
	}
}

int adb_polledkey;
void
akbd_input(struct akbd_softc *sc, int key)
{
	int press, val;
	int type;

	press = ADBK_PRESS(key);
	val = ADBK_KEYVAL(key);

	if (sc->sc_iso)
		val = akbd_iso_swap(val);

	type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;

	if (adb_polling) {
		adb_polledkey = key;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	} else if (sc->sc_rawkbd) {
		char cbuf[2];
		int c, j, s;

		j = 0;

		c = keyboard[val];
		if (c == 0) {
			return; /* XXX */
		}
		if (c & 0x80)
			cbuf[j++] = 0xe0;
		cbuf[j] = c & 0x7f;
		if (type == WSCONS_EVENT_KEY_UP)
			cbuf[j] |= 0x80;
		j++;
		s = spltty();
		wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
		splx(s);
#endif
	} else {
		wskbd_input(sc->sc_wskbddev, type, val);
	}
}


code:
/*	$OpenBSD: akbdmap.h,v 1.10 2014/09/06 10:18:34 mpi Exp $ */
/*	$NetBSD: akbdmap.h,v 1.7 2005/05/05 22:29:41 abs Exp $	*/

/*-
 * Copyright (c) 1997 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Juergen Hannken-Illjes.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef WSDISPLAY_COMPAT_RAWKBD
#include <dev/wscons/wskbdraw.h>

unsigned char keyboard[128] = {
	RAWKEY_a,
	RAWKEY_s,
	RAWKEY_d,
	RAWKEY_f,
	RAWKEY_h,
	RAWKEY_g,
	RAWKEY_z,
	RAWKEY_x,
	RAWKEY_c,
	RAWKEY_v,
	RAWKEY_less,
	RAWKEY_b,
	RAWKEY_q,
	RAWKEY_w,
	RAWKEY_e,
	RAWKEY_r,
	RAWKEY_y,
	RAWKEY_t,
	RAWKEY_1,
	RAWKEY_2,
	RAWKEY_3,
	RAWKEY_4,
	RAWKEY_6,
	RAWKEY_5,
	RAWKEY_equal,
	RAWKEY_9,
	RAWKEY_7,
	RAWKEY_minus,
	RAWKEY_8,
	RAWKEY_0,
	RAWKEY_bracketright,
	RAWKEY_o,
	RAWKEY_u,
	RAWKEY_bracketleft,
	RAWKEY_i,
	RAWKEY_p,
	RAWKEY_Return,
	RAWKEY_l,
	RAWKEY_j,
	RAWKEY_apostrophe,
	RAWKEY_k,
	RAWKEY_semicolon,
	RAWKEY_backslash,
	RAWKEY_comma,
	RAWKEY_slash,
	RAWKEY_n,
	RAWKEY_m,
	RAWKEY_period,
	RAWKEY_Tab,
	RAWKEY_space,
	RAWKEY_grave,
	RAWKEY_BackSpace,
	RAWKEY_KP_Enter,
	RAWKEY_Escape,
	RAWKEY_Control_L,
	219,			/* Command -> Win */
	RAWKEY_Shift_L,
	RAWKEY_Caps_Lock,
	RAWKEY_Alt_L,		/* Option -> Alt */
	RAWKEY_Left,
	RAWKEY_Right,
	RAWKEY_Down,
	RAWKEY_Up,
	0, /* Fn */
	0,
	RAWKEY_KP_Delete,
	0,
	RAWKEY_KP_Multiply,
	0,
	RAWKEY_KP_Add,
	0,
	RAWKEY_Num_Lock,
	0,
	0,
	0,
	RAWKEY_KP_Divide,
	RAWKEY_KP_Enter,
	0,
	RAWKEY_KP_Subtract,
	0,
	0,
	RAWKEY_KP_Equal,
	RAWKEY_KP_Insert,
	RAWKEY_KP_End,
	RAWKEY_KP_Down,
	RAWKEY_KP_Next,
	RAWKEY_KP_Left,
	RAWKEY_KP_Begin,
	RAWKEY_KP_Right,
	RAWKEY_KP_Home,
	0,
	RAWKEY_KP_Up,
	RAWKEY_KP_Prior,
	0,
	0,
	RAWKEY_KP_Delete,
	RAWKEY_f5,
	RAWKEY_f6,
	RAWKEY_f7,
	RAWKEY_f3,
	RAWKEY_f8,
	RAWKEY_f9,
	0,
	RAWKEY_f11,
	0,
	RAWKEY_Print_Screen,
	RAWKEY_KP_Enter,
	RAWKEY_Hold_Screen,
	0,
	RAWKEY_f10,
	0,
	RAWKEY_f12,
	0,
	RAWKEY_Pause,
	RAWKEY_Insert,
	RAWKEY_Home,
	RAWKEY_Prior,
	RAWKEY_Delete,
	RAWKEY_f4,
	RAWKEY_End,
	RAWKEY_f2,
	RAWKEY_Next,
	RAWKEY_f1,
	0,
	0,
	0,
	0,
	0
};
#endif /* WSDISPLAY_COMPAT_RAWKBD */

/* XXX This list is incomplete. */

#define KC(n) KS_KEYCODE(n)

static const keysym_t akbd_keydesc_us[] = {
/*  pos      command		normal		shifted */
    KC(0),			KS_a,
    KC(1),			KS_s,
    KC(2),			KS_d,
    KC(3),			KS_f,
    KC(4),			KS_h,
    KC(5),			KS_g,
    KC(6),			KS_z,
    KC(7),			KS_x,
    KC(8),			KS_c,
    KC(9),			KS_v,

    KC(11),			KS_b,
    KC(12),			KS_q,
    KC(13),			KS_w,
    KC(14),			KS_e,
    KC(15),			KS_r,
    KC(16),			KS_y,
    KC(17),			KS_t,
    KC(18),			KS_1,		KS_exclam,
    KC(19),			KS_2,		KS_at,
    KC(20),			KS_3,		KS_numbersign,
    KC(21),			KS_4,		KS_dollar,
    KC(22),			KS_6,		KS_asciicircum,
    KC(23),			KS_5,		KS_percent,
    KC(24),			KS_equal,	KS_plus,
    KC(25),			KS_9,		KS_parenleft,
    KC(26),			KS_7,		KS_ampersand,
    KC(27),			KS_minus,	KS_underscore,
    KC(28),			KS_8,		KS_asterisk,
    KC(29),			KS_0,		KS_parenright,
    KC(30),			KS_bracketright, KS_braceright,
    KC(31),			KS_o,
    KC(32),			KS_u,
    KC(33),			KS_bracketleft,	KS_braceleft,
    KC(34),			KS_i,
    KC(35),			KS_p,
    KC(36),			KS_Return,
    KC(37),			KS_l,
    KC(38),			KS_j,
    KC(39),			KS_apostrophe,	KS_quotedbl,
    KC(40),			KS_k,
    KC(41),			KS_semicolon,	KS_colon,
    KC(42),			KS_backslash,	KS_bar,
    KC(43),			KS_comma,	KS_less,
    KC(44),			KS_slash,	KS_question,
    KC(45),			KS_n,
    KC(46),			KS_m,
    KC(47),			KS_period,	KS_greater,
    KC(48),			KS_Tab,
    KC(49),			KS_space,
    KC(50),			KS_grave,	KS_asciitilde,
    KC(51),  KS_Cmd_ResetEmul,	KS_Delete,
    KC(52),			KS_KP_Enter,
    KC(53),  KS_Cmd_Debugger,	KS_Escape,
    KC(54),	KS_Cmd1,	KS_Control_L,
    KC(55),	KS_Cmd2,	KS_Alt_L,	/* Command */
    KC(56),			KS_Shift_L,
    KC(57),			KS_Caps_Lock,
    KC(58),	KS_Cmd2,	KS_Alt_R,	/* Option */
    KC(59),			KS_Left,
    KC(60),			KS_Right,
    KC(61),			KS_Down,
    KC(62),			KS_Up,

    KC(65),			KS_KP_Decimal,
    KC(67),			KS_KP_Multiply,
    KC(69),			KS_KP_Add,
    KC(71),			KS_Num_Lock,	KS_Clear,
    KC(75),			KS_KP_Divide,
    KC(76),			KS_KP_Enter,
    KC(78),			KS_KP_Subtract,

    KC(81),			KS_KP_Equal,
    KC(82),			KS_KP_0,	KS_KP_Insert,
    KC(83),			KS_KP_1,	KS_KP_End,
    KC(84),			KS_KP_2,	KS_KP_Down,
    KC(85),			KS_KP_3,	KS_KP_Next,
    KC(86),			KS_KP_4,	KS_KP_Left,
    KC(87),			KS_KP_5,	KS_KP_Begin,
    KC(88),			KS_KP_6,	KS_KP_Right,
    KC(89),			KS_KP_7,	KS_KP_Home,

    KC(91),			KS_KP_8,	KS_KP_Up,
    KC(92),			KS_KP_9,	KS_KP_Prior,

    KC(95),			KS_KP_Decimal,	KS_KP_Delete,
    KC(96), KS_Cmd_Screen4,	KS_f5,
    KC(97), KS_Cmd_Screen5,	KS_f6,
    KC(98), KS_Cmd_Screen6,	KS_f7,
    KC(99), KS_Cmd_Screen2,	KS_f3,
    KC(100), KS_Cmd_Screen7,	KS_f8,

    KC(101), KS_Cmd_Screen8,	KS_f9,

    KC(103), KS_Cmd_Screen10,	KS_f11,

    KC(105),			KS_f13,		KS_Print_Screen,
    KC(106),			KS_KP_Enter,
    KC(107),			KS_f14,		KS_Hold_Screen,

    KC(109), KS_Cmd_Screen9,	KS_f10,

    KC(111), KS_Cmd_Screen11,	KS_f12,

    KC(113),			KS_f15,		KS_Pause,
    KC(114),			KS_Insert,
    KC(115),			KS_Home,
    KC(116), KS_Cmd_ScrollBack,	KS_Prior,
    KC(117), KS_Cmd_ResetEmul,	KS_Delete,
    KC(118), KS_Cmd_Screen3,	KS_f4,
    KC(119),			KS_End,
    KC(120), KS_Cmd_Screen1,	KS_f2,
    KC(121), KS_Cmd_ScrollFwd,	KS_Next,
    KC(122), KS_Cmd_Screen0,	KS_f1,

    KC(127),	KS_Cmd_Debugger,
};

static const keysym_t akbd_keydesc_fr[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(0),	KS_q,
    KC(1),	KS_s,		KS_S,		KS_Ograve,
    KC(4),	KS_h,		KS_H,		KS_Igrave,	KS_Icircumflex,
    KC(6),	KS_w,		KS_W,		KS_less,	KS_greater,
    KC(8),	KS_c,		KS_C,		KS_copyright,	KS_cent,
    KC(10),	KS_less,	KS_greater,
    KC(11),	KS_b,		KS_B,		KS_ssharp,
    KC(12),	KS_a,		KS_A,		KS_ae,		KS_AE,
    KC(13),	KS_z,		KS_Z,		KS_Acircumflex,	KS_Aring,
    KC(14),	KS_e,		KS_E,		KS_ecircumflex,	KS_Ecircumflex,
    KC(15),	KS_r,		KS_R,		KS_registered,	KS_comma,
    KC(16),	KS_y,		KS_Y,		KS_Uacute,
    KC(18),	KS_ampersand,	KS_1,		KS_voidSymbol,	KS_dead_acute,
    KC(19),	KS_eacute,	KS_2,		KS_ediaeresis,
    KC(20),	KS_quotedbl,	KS_3,
    KC(21),	KS_apostrophe,	KS_4,		KS_braceleft,	KS_bracketleft,
    KC(22),	KS_section,	KS_6,		KS_paragraph,	KS_aring,
    KC(23),	KS_parenleft,	KS_5,		KS_braceleft,	KS_bracketleft,
    KC(24),	KS_minus,	KS_underscore,	KS_braceright,
    KC(25),	KS_ccedilla,	KS_9,		KS_Ccedilla,	KS_Aacute,
    KC(26),	KS_egrave,	KS_7,		KS_guillemotleft,
						KS_guillemotright,
    KC(27),	KS_parenright,	KS_degree,	KS_braceright,	KS_bracketright,
    KC(28),	KS_exclam,	KS_8,		KS_exclamdown,	KS_Ucircumflex,
    KC(29),	KS_agrave,	KS_0,		KS_oslash,	KS_Ooblique,
    KC(30),	KS_dollar,	KS_asterisk,	KS_cent,	KS_yen,
    KC(33),	KS_dead_circumflex, KS_dead_diaeresis,
						KS_ocircumflex,	KS_Ocircumflex,
    KC(34),	KS_i,		KS_I,		KS_icircumflex, KS_idiaeresis,
    KC(37),	KS_l,		KS_L,		KS_notsign,	KS_bar,
    KC(38),	KS_j,		KS_J,		KS_Idiaeresis,	KS_Iacute,
    KC(39),	KS_ugrave,	KS_percent,	KS_Ugrave,
    KC(40),	KS_k,		KS_K,		KS_Egrave,	KS_Ediaeresis,
    KC(41),	KS_m,		KS_M,		KS_mu,		KS_Oacute,
    KC(42),	KS_dead_grave,	KS_sterling,	KS_at,		KS_numbersign,
    KC(43),	KS_semicolon,	KS_period,
    KC(44),	KS_equal,	KS_plus,	KS_voidSymbol,	KS_plusminus,
    KC(45),	KS_n,		KS_N,		KS_dead_tilde,
    KC(46),	KS_comma,	KS_question,	KS_voidSymbol,	KS_questiondown,
    KC(47),	KS_colon,	KS_slash,	KS_division,	KS_backslash,
    KC(50),	KS_at,		KS_numbersign,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_fr_nodead[] = {
    KC(18),	KS_ampersand,	KS_1,		KS_voidSymbol,	KS_acute,
    KC(33),	KS_asciicircum,	KS_diaeresis,	KS_ocircumflex,	KS_Ocircumflex,
    KC(42),	KS_grave,	KS_sterling,	KS_at,		KS_numbersign,
    KC(45),	KS_n,		KS_N,		KS_asciitilde,
};

static const keysym_t akbd_keydesc_jp[] = {
/*  pos      command		normal		shifted */
    KC(19),			KS_2,		KS_quotedbl,
    KC(22),			KS_6,		KS_ampersand,
    KC(24),			KS_asciicircum,	KS_asciitilde,
    KC(25),			KS_9,		KS_parenright,
    KC(26),			KS_7,		KS_apostrophe,
    KC(27),			KS_minus,	KS_equal,
    KC(28),			KS_8,		KS_parenleft,
    KC(29),			KS_0,
    KC(30),			KS_bracketleft, KS_braceleft,
    KC(33),			KS_at,		KS_grave,
    KC(39),			KS_colon,	KS_asterisk,

    KC(41),			KS_semicolon,	KS_plus,
    KC(42),			KS_bracketright,KS_braceright,
    KC(93),			KS_backslash,	KS_bar,
    KC(94),			KS_underscore,
};

static const keysym_t akbd_keydesc_uk[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(20),	KS_3,		KS_sterling,	KS_numbersign,
    KC(50),	KS_section,	KS_plusminus,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_sv[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(10),	KS_less,	KS_greater,	KS_bar,
    KC(19),	KS_2,		KS_quotedbl,	KS_at,
    KC(21),	KS_4,		KS_dollar,
    KC(22),	KS_6,		KS_ampersand,
    KC(24),	KS_dead_acute,	KS_dead_grave,
    KC(25),	KS_9,		KS_parenright,	KS_bracketright,
    KC(26),	KS_7,		KS_slash,	KS_braceleft,
    KC(27),	KS_plus,	KS_question,	KS_backslash,
    KC(28),	KS_8,		KS_parenleft,	KS_bracketleft,
    KC(29),	KS_0,		KS_equal,	KS_braceright,
    KC(30),	KS_dead_diaeresis,KS_dead_circumflex,KS_dead_tilde,
    KC(33),	KS_aring,
    KC(39),	KS_adiaeresis,
    KC(41),	KS_odiaeresis,
    KC(42),	KS_apostrophe,	KS_asterisk,
    KC(43),	KS_comma,	KS_semicolon,
    KC(44),	KS_minus,	KS_underscore,
    KC(47),	KS_period,	KS_colon,
    KC(50),	KS_section,	KS_degree,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_sv_nodead[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(24),	KS_apostrophe,	KS_grave,
    KC(30),	KS_diaeresis,	KS_asciicircum,	KS_asciitilde,
};

static const keysym_t akbd_keydesc_de[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(0),	KS_a,		KS_A,		KS_aring,	KS_Aring,
    KC(1),	KS_s,		KS_S,		KS_voidSymbol,	KS_Iacute,
    KC(3),	KS_f,		KS_F,		KS_voidSymbol,	KS_Idiaeresis,
    KC(4),	KS_h,		KS_H,		KS_ordfeminine,	KS_Oacute,
    KC(5),	KS_g,		KS_G,		KS_copyright,	KS_Igrave,
    KC(6),	KS_y,		KS_Y,		KS_yen,
    KC(7),	KS_x,		KS_X,		KS_voidSymbol,	KS_Ugrave,
    KC(8),	KS_c,		KS_C,		KS_ccedilla,	KS_Ccedilla,
    KC(10),	KS_less,	KS_greater,
    KC(12),	KS_q,		KS_Q,		KS_guillemotleft,KS_guillemotright,
    KC(15),	KS_r,		KS_R,		KS_registered,	KS_cedilla,
    KC(16),	KS_z,		KS_Z,
    KC(18),	KS_1,		KS_exclam,	KS_exclamdown,	KS_notsign,
    KC(19),	KS_2,		KS_quotedbl,
    KC(20),	KS_3,		KS_section,	KS_paragraph,	KS_numbersign,
    KC(21),	KS_4,		KS_dollar,	KS_cent,	KS_sterling,
    KC(22),	KS_6,		KS_ampersand,	KS_bracketright,KS_dead_circumflex,
    KC(23),	KS_5,		KS_percent,	KS_bracketleft,
    KC(24),	KS_dead_acute,	KS_dead_grave,	KS_apostrophe,
    KC(25),	KS_9,		KS_parenright,	KS_braceright,	KS_periodcentered,
    KC(26),	KS_7,		KS_slash,	KS_bar,		KS_backslash,
    KC(27),	KS_ssharp,	KS_question,	KS_questiondown,
    KC(28),	KS_8,		KS_parenleft,	KS_braceleft,
    KC(29),	KS_0,		KS_equal,	KS_voidSymbol,	KS_macron,
    KC(30),	KS_plus,	KS_asterisk,	KS_plusminus,
    KC(31),	KS_o,		KS_O,		KS_oslash,	KS_Ooblique,
    KC(32),	KS_u,		KS_U,		KS_dead_diaeresis,KS_Aacute,
    KC(33),	KS_udiaeresis,	KS_Udiaeresis,	KS_voidSymbol,	KS_degree,
    KC(34),	KS_i,		KS_I,		KS_voidSymbol,	KS_Ucircumflex,
    KC(37),	KS_l,		KS_L,		KS_at,
    KC(38),	KS_j,		KS_J,		KS_masculine,
    KC(39),	KS_adiaeresis,	KS_Adiaeresis,	KS_ae,		KS_AE,
    KC(41),	KS_odiaeresis,	KS_Odiaeresis,
    KC(42),	KS_numbersign,	KS_apostrophe,
    KC(43),	KS_comma,	KS_semicolon,
    KC(44),	KS_minus,	KS_underscore,
    KC(45),	KS_n,		KS_N,		KS_dead_tilde,
    KC(46),	KS_m,		KS_M,		KS_mu,
    KC(47),	KS_period,	KS_colon,
    KC(50),	KS_dead_circumflex,KS_degree,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_de_nodead[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(22),	KS_6,		KS_ampersand,	KS_bracketright,KS_asciicircum,
    KC(24),	KS_acute,	KS_grave,	KS_apostrophe,
    KC(32),	KS_u,		KS_U,		KS_diaeresis,	KS_Aacute,
    KC(45),	KS_n,		KS_N,		KS_asciitilde,
    KC(50),	KS_asciicircum, KS_degree,
};

static const keysym_t akbd_keydesc_sf[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(6),	KS_y,
    KC(10),	KS_less,	KS_greater,
    KC(16),	KS_z,
    KC(18),	KS_plus,	KS_1,
    KC(19),	KS_quotedbl,	KS_2,
    KC(20),	KS_asterisk,	KS_3,
    KC(21),	KS_ccedilla,	KS_4,		KS_Ccedilla,
    KC(22),	KS_ampersand,	KS_6,
    KC(23),	KS_percent,	KS_5,
    KC(24),	KS_dead_circumflex,KS_grave,
    KC(25),	KS_parenright,	KS_9,
    KC(26),	KS_slash,	KS_7,
    KC(27),	KS_apostrophe,	KS_question,
    KC(28),	KS_parenleft,	KS_8,
    KC(29),	KS_equal,	KS_0,
    KC(30),	KS_dead_diaeresis,KS_exclam,
    KC(33),	KS_egrave,	KS_udiaeresis,
    KC(39),	KS_agrave,	KS_adiaeresis,
    KC(41),	KS_eacute,	KS_odiaeresis,
    KC(42),	KS_dollar,	KS_sterling,
    KC(43),	KS_period,	KS_colon,
    KC(46),	KS_comma,	KS_semicolon,
    KC(47),	KS_minus,	KS_underscore,
    KC(50),	KS_paragraph,	KS_degree,
};

static const keysym_t akbd_keydesc_es[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(10),	KS_less,	KS_greater,
    KC(18),	KS_1,		KS_exclam,	KS_bar,
    KC(19),	KS_2,		KS_quotedbl,	KS_at,
    KC(20),	KS_3,		KS_periodcentered, KS_numbersign,
    KC(21),	KS_4,		KS_dollar,	KS_asciitilde,
    KC(22),	KS_6,		KS_ampersand,	KS_notsign,
    KC(23),	KS_5,		KS_percent,
    KC(24),	KS_exclamdown,	KS_questiondown,
    KC(25),	KS_9,		KS_parenright,
    KC(26),	KS_7,		KS_slash,
    KC(27),	KS_apostrophe,	KS_question,
    KC(28),	KS_8,		KS_parenleft,
    KC(29),	KS_0,		KS_equal,
    KC(30),	KS_plus,	KS_asterisk,	KS_bracketright,
    KC(33),	KS_dead_grave,	KS_dead_circumflex, KS_bracketleft,
    KC(39),	KS_dead_acute,	KS_dead_diaeresis, KS_braceleft,
    KC(41),	KS_ntilde,
    KC(42),	KS_ccedilla,	KS_Ccedilla,	KS_braceright,
    KC(43),	KS_comma,	KS_semicolon,
    KC(44),	KS_minus,	KS_underscore,
    KC(47),	KS_period,	KS_colon,
    KC(50),	KS_degree,	KS_ordfeminine,	KS_backslash,
    KC(58),	KS_Mode_switch, KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_pt[] = {
/*  pos         normal          shifted         altgr           shift-altgr */
    KC(7),	KS_x,		KS_X,		KS_guillemotleft, KS_guillemotright,
    KC(10),	KS_less,	KS_greater,
    KC(19),	KS_2,		KS_quotedbl,	KS_at,
    KC(20),	KS_3,		KS_numbersign,	KS_sterling,
    KC(22),	KS_6,		KS_ampersand,
    KC(24),	KS_plus,	KS_asterisk,
    KC(25),     KS_9,		KS_parenright,	KS_bracketright, KS_braceright,
    KC(26),	KS_7,		KS_slash,
    KC(27),	KS_apostrophe,	KS_question,
    KC(28),	KS_8,		KS_parenleft,	KS_bracketleft, KS_braceleft,
    KC(29),	KS_0,		KS_equal,
    KC(30),	KS_dead_acute,	KS_dead_grave,
    KC(33), 	KS_masculine,	KS_ordfeminine,
    KC(39),	KS_dead_tilde,	KS_dead_circumflex,
    KC(41),	KS_ccedilla,	KS_Ccedilla,
    KC(43),	KS_comma,	KS_semicolon,
    KC(44),	KS_minus,	KS_underscore,
    KC(47),	KS_period,	KS_colon,
    KC(50),	KS_section,	KS_plusminus,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_us_dvorak[] = {
/*  pos      command		normal		shifted */
    KC(1),			KS_o,
    KC(2),			KS_e,
    KC(3),			KS_u,
    KC(4),			KS_d,
    KC(5),			KS_i,
    KC(6),			KS_semicolon, KS_colon,
    KC(7),			KS_q,
    KC(8),			KS_j,
    KC(9),			KS_k,
    KC(11),			KS_x,
    KC(12),			KS_apostrophe, KS_quotedbl,
    KC(13),			KS_comma, KS_less,
    KC(14),			KS_period, KS_greater,
    KC(15),			KS_p,
    KC(16),			KS_f,
    KC(17),			KS_y,
    KC(24),			KS_bracketright, KS_braceright,
    KC(27),			KS_bracketleft,	KS_braceleft,
    KC(30),			KS_equal, KS_plus,
    KC(31),			KS_r,
    KC(32),			KS_g,
    KC(33),			KS_slash, KS_question,
    KC(34),			KS_c,
    KC(35),			KS_l,
    KC(37),			KS_n,
    KC(38),			KS_h,
    KC(39),			KS_minus, KS_underscore,
    KC(40),			KS_t,
    KC(41),			KS_s,
    KC(43),			KS_w,
    KC(44),			KS_z,
    KC(45),			KS_b,
    KC(47),			KS_v,
};

static const keysym_t akbd_keydesc_sg[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(0),	KS_a,		KS_A,		KS_aring,	KS_Aring,
    KC(1),	KS_s,		KS_S,		KS_ssharp,	KS_voidSymbol,
    KC(3),	KS_f,		KS_F,		KS_section,	KS_voidSymbol,
    KC(4),	KS_h,		KS_H,		KS_ordfeminine,	KS_periodcentered,
    KC(5),	KS_g,		KS_G,		KS_at,		KS_comma,
    KC(6),	KS_y,		KS_Y,		KS_yen,		KS_ydiaeresis,
    KC(7),	KS_x,		KS_X,		KS_voidSymbol,	KS_ydiaeresis,
    KC(8),	KS_c,		KS_C,		KS_copyright,
    KC(10),	KS_less,	KS_greater,
    KC(12),	KS_q,		KS_Q,
    KC(15),	KS_r,		KS_R,		KS_registered,	KS_Egrave,
    KC(16),	KS_z,		KS_Z,		KS_voidSymbol,	KS_Aacute,
    KC(18),	KS_1,		KS_plus,	KS_plusminus,	KS_onesuperior,
    KC(19),	KS_2,		KS_quotedbl,	KS_twosuperior,
    KC(20),	KS_3,		KS_asterisk,	KS_numbersign,	KS_threesuperior,
    KC(21),	KS_4,		KS_ccedilla,	KS_Ccedilla,
    KC(22),	KS_6,		KS_ampersand,	KS_bracketright,
    KC(23),	KS_5,		KS_percent,	KS_bracketleft,
    KC(24),	KS_dead_circumflex,KS_dead_grave,KS_dead_acute,	KS_asciitilde,
    KC(25),	KS_9,		KS_parenright,	KS_braceright,	KS_Ocircumflex,
    KC(26),	KS_7,		KS_slash,	KS_bar,		KS_backslash,
    KC(27),	KS_apostrophe,	KS_question,	KS_questiondown,
    KC(28),	KS_8,		KS_parenleft,	KS_braceleft,	KS_Ograve,
    KC(29),	KS_0,		KS_equal,	KS_voidSymbol,	KS_Uacute,
    KC(30),	KS_dead_diaeresis,KS_exclam,	KS_bracketright,
    KC(31),	KS_o,		KS_O,		KS_oslash,
    KC(32),	KS_u,		KS_U,		KS_degree,	KS_Ugrave,
    KC(33),	KS_udiaeresis,	KS_egrave,	KS_bracketleft,
    KC(34),	KS_i,		KS_I,		KS_exclamdown,
    KC(37),	KS_l,		KS_L,		KS_notsign,
    KC(38),	KS_j,		KS_J,		KS_masculine,
    KC(39),	KS_adiaeresis,	KS_agrave,	KS_ae,		KS_AE,
    KC(41),	KS_odiaeresis,	KS_eacute,	KS_cent,
    KC(42),	KS_dollar,	KS_sterling,	KS_paragraph,
    KC(43),	KS_comma,	KS_semicolon,	KS_guillemotleft,KS_guillemotright,
    KC(44),	KS_minus,	KS_underscore,
    KC(45),	KS_n,		KS_N,		KS_dead_tilde,
    KC(46),	KS_m,		KS_M,		KS_mu,
    KC(47),	KS_period,	KS_colon,	KS_voidSymbol,	KS_division,
    KC(50),	KS_section,	KS_degree,
    KC(58),	KS_Mode_switch,	KS_Multi_key,		/* Option */
};

static const keysym_t akbd_keydesc_sg_nodead[] = {
/*  pos		normal		shifted		altgr		shift-altgr */
    KC(24),	KS_asciicircum,	KS_grave,	KS_acute,	KS_asciitilde,
    KC(30),	KS_diaeresis,	KS_exclam,	KS_bracketright,KS_braceright,
    KC(45),	KS_n,		KS_N,		KS_asciitilde,
};

#define KBD_MAP(name, base, map) \
			{ name, base, sizeof(map)/sizeof(keysym_t), map }

const struct wscons_keydesc akbd_keydesctab[] = {
	KBD_MAP(KB_US,			0,	akbd_keydesc_us),
	KBD_MAP(KB_US | KB_DVORAK,	KB_US,	akbd_keydesc_us_dvorak),
	KBD_MAP(KB_DE,			KB_US,  akbd_keydesc_de),
	KBD_MAP(KB_DE | KB_NODEAD,	KB_DE,  akbd_keydesc_de_nodead),
	KBD_MAP(KB_ES,			KB_US,	akbd_keydesc_es),
	KBD_MAP(KB_FR,			KB_US,	akbd_keydesc_fr),
	KBD_MAP(KB_FR | KB_NODEAD,	KB_FR,	akbd_keydesc_fr_nodead),
	KBD_MAP(KB_JP,			KB_US,	akbd_keydesc_jp),
	KBD_MAP(KB_PT,                  KB_US,  akbd_keydesc_pt),
	KBD_MAP(KB_SF,			KB_US,  akbd_keydesc_sf),
	KBD_MAP(KB_SG,			KB_US,  akbd_keydesc_sg),
	KBD_MAP(KB_SG | KB_NODEAD,	KB_SG,  akbd_keydesc_sg_nodead),
	KBD_MAP(KB_SV,			KB_US,  akbd_keydesc_sv),
	KBD_MAP(KB_SV | KB_NODEAD,	KB_SV,  akbd_keydesc_sv_nodead),
	KBD_MAP(KB_UK,			KB_US,  akbd_keydesc_uk),
	{0, 0, 0, 0}
};

#undef KBD_MAP
#undef KC


code:
/*	$OpenBSD: akbdvar.h,v 1.4 2012/01/29 10:54:21 mpi Exp $	*/
/*	$NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $	*/

/*
 * Copyright (C) 1998	Colin Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Colin Wood.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ADB_AKBDVAR_H_
#define _ADB_AKBDVAR_H_

/*
 * State info, per keyboard instance.
 */
struct akbd_softc {
	struct	device	sc_dev;

	/* ADB info */
	int		origaddr;	/* ADB device type (ADBADDR_KBD) */
	int		adbaddr;	/* current ADB address */
	int		handler_id;	/* type of keyboard */

	u_int8_t	sc_leds;	/* current LED state */
	u_int8_t	sc_iso;

	int		sc_caps;	/* capslock key state */
	struct device	*sc_wskbddev;

#ifdef WSDISPLAY_COMPAT_RAWKBD
	int sc_rawkbd;
#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */
};

/* LED register bits, inverse of actual register value */
#define LED_NUMLOCK	0x1
#define LED_CAPSLOCK	0x2
#define LED_SCROLL_LOCK	0x4

int	akbd_cnattach(void);
int	akbd_is_console(void);

extern struct wskbd_mapdata akbd_keymapdata;
extern int adb_polledkey;

#endif /* _ADB_AKBDVAR_H_ */


code:
/*	$OpenBSD: ams.c,v 1.6 2011/06/15 21:32:05 miod Exp $	*/
/*	$NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $	*/

/*
 * Copyright (C) 1998	Colin Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Colin Wood.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>

#include <machine/autoconf.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsmousevar.h>

#include <dev/adb/adb.h>
#include <dev/adb/amsvar.h>

/*
 * Function declarations.
 */
int	amsmatch(struct device *, void *, void *);
void	amsattach(struct device *, struct device *, void *);

/* Driver definition. */
struct cfattach ams_ca = {
	sizeof(struct ams_softc), amsmatch, amsattach
};
/* Driver definition. */
struct cfdriver ams_cd = {
	NULL, "ams", DV_DULL
};

int	ams_enable(void *);
int	ams_ioctl(void *, u_long, caddr_t, int, struct proc *);
void	ams_disable(void *);

const struct wsmouse_accessops ams_accessops = {
	ams_enable,
	ams_ioctl,
	ams_disable,
};

void	ems_init(struct ams_softc *);
void	ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
void	ms_handoff(adb_event_t *event, struct ams_softc *);
void	ms_processevent(adb_event_t *event, struct ams_softc *);

int
amsmatch(struct device *parent, void *cf, void *aux)
{
	struct adb_attach_args *aa_args = aux;

	if (strcmp(aa_args->name, adb_device_name) != 0)
		return (0);

	if (aa_args->origaddr == ADBADDR_MS)
		return 1;
	else
		return 0;
}

void
amsattach(struct device *parent, struct device *self, void   *aux)
{
	ADBSetInfoBlock adbinfo;
	struct ams_softc *sc = (struct ams_softc *)self;
	struct adb_attach_args *aa_args = aux;
	int error;
	struct wsmousedev_attach_args a;

	sc->origaddr = aa_args->origaddr;
	sc->adbaddr = aa_args->adbaddr;
	sc->handler_id = aa_args->handler_id;

	sc->sc_class = MSCLASS_MOUSE;
	sc->sc_buttons = 1;
	sc->sc_res = 100;
	sc->sc_devid[0] = 0;
	sc->sc_devid[4] = 0;

	adbinfo.siServiceRtPtr = (Ptr)ms_adbcomplete;
	adbinfo.siDataAreaAddr = (caddr_t)sc;

	ems_init(sc);

	/* print out the type of mouse we have */
	printf(": ");
	switch (sc->handler_id) {
	case ADBMS_200DPI:
		sc->sc_res = 200;
		/* FALLTHROUGH */
	case ADBMS_100DPI:
		printf("%d-button, %d dpi mouse\n", sc->sc_buttons,
		    (int)(sc->sc_res));
		break;
	case ADBMS_MSA3:
		printf("Mouse Systems A3 mouse, %d-button, %d dpi\n",
		    sc->sc_buttons, (int)(sc->sc_res));
		break;
	case ADBMS_USPEED:
		printf("MicroSpeed mouse, default parameters\n");
		break;
	case ADBMS_UCONTOUR:
		printf("Contour mouse, default parameters\n");
		break;
	case ADBMS_TURBO:
		printf("Kensington Turbo Mouse\n");
		break;
	case ADBMS_EXTENDED:
		if (sc->sc_devid[0] == '\0') {
			printf("Logitech ");
			switch (sc->sc_class) {
			case MSCLASS_MOUSE:
				printf("MouseMan (non-EMP) mouse");
				break;
			case MSCLASS_TRACKBALL:
				printf("TrackMan (non-EMP) trackball");
				break;
			default:
				printf("non-EMP relative positioning device");
				break;
			}
			printf("\n");
		} else {
			printf("EMP ");
			switch (sc->sc_class) {
			case MSCLASS_TABLET:
				printf("tablet");
				break;
			case MSCLASS_MOUSE:
				printf("mouse");
				break;
			case MSCLASS_TRACKBALL:
				printf("trackball");
				break;
			case MSCLASS_TRACKPAD:
				printf("trackpad");
				break;
			default:
				printf("unknown device");
				break;
			}
			printf(" <%s> %d-button, %d dpi\n", sc->sc_devid,
			    sc->sc_buttons, (int)(sc->sc_res));
		}
		break;
	default:
		printf("relative positioning device (mouse?) (%d)\n",
			sc->handler_id);
		break;
	}
	error = set_adb_info(&adbinfo, sc->adbaddr);
#ifdef ADB_DEBUG
	if (adb_debug)
		printf("ams: returned %d from set_adb_info\n", error);
#endif

	a.accessops = &ams_accessops;
	a.accesscookie = sc;
	sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
}

/*
 * Initialize extended mouse support -- probes devices as described
 * in Inside Macintosh: Devices, Chapter 5 "ADB Manager".
 *
 * Extended Mouse Protocol is documented in TechNote HW1:
 * 	"ADB - The Untold Story:  Space Aliens Ate My Mouse"
 *
 * Supports: Extended Mouse Protocol, MicroSpeed Mouse Deluxe,
 * 	     Mouse Systems A^3 Mouse, Logitech non-EMP MouseMan
 */
void
ems_init(struct ams_softc *sc)
{
	int adbaddr;
	short cmd;
	u_char buffer[9];

	adbaddr = sc->adbaddr;
	if (sc->origaddr != ADBADDR_MS)
		return;
	if (sc->handler_id == ADBMS_USPEED ||
	    sc->handler_id == ADBMS_UCONTOUR) {
		/* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */
		cmd = ADBLISTEN(adbaddr, 1);

		/*
		 * To setup the MicroSpeed or the Contour, it appears
		 * that we can send the following command to the mouse
		 * and then expect data back in the form:
		 *  buffer[0] = 4 (bytes)
		 *  buffer[1], buffer[2] as std. mouse
		 *  buffer[3] = buffer[4] = 0xff when no buttons
		 *   are down.  When button N down, bit N is clear.
		 * buffer[4]'s locking mask enables a
		 * click to toggle the button down state--sort of
		 * like the "Easy Access" shift/control/etc. keys.
		 * buffer[3]'s alternative speed mask enables using
		 * different speed when the corr. button is down
		 */
		buffer[0] = 4;
		buffer[1] = 0x00;	/* Alternative speed */
		buffer[2] = 0x00;	/* speed = maximum */
		buffer[3] = 0x10;	/* enable extended protocol,
					 * lower bits = alt. speed mask
					 *            = 0000b
					 */
		buffer[4] = 0x07;	/* Locking mask = 0000b,
					 * enable buttons = 0111b
					 */
		adb_op_sync((Ptr)buffer, cmd);

		sc->sc_buttons = 3;
		sc->sc_res = 200;
		return;
	}
	if (sc->handler_id == ADBMS_TURBO) {
		/* Found Kensington Turbo Mouse */
		static u_char data1[] =
			{ 8, 0xe7, 0x8c, 0, 0, 0, 0xff, 0xff, 0x94 };
		static u_char data2[] =
			{ 8, 0xa5, 0x14, 0, 0, 0x69, 0xff, 0xff, 0x27 };

		buffer[0] = 0;
		adb_op_sync((Ptr)buffer, ADBFLUSH(adbaddr));

		adb_op_sync((Ptr)data1, ADBLISTEN(adbaddr, 2));

		buffer[0] = 0;
		adb_op_sync((Ptr)buffer, ADBFLUSH(adbaddr));

		adb_op_sync((Ptr)data2, ADBLISTEN(adbaddr, 2));
		return;
	}
	if ((sc->handler_id == ADBMS_100DPI) ||
	    (sc->handler_id == ADBMS_200DPI)) {
		/* found a mouse */
		cmd = ADBTALK(adbaddr, 3);
		if (adb_op_sync((Ptr)buffer, cmd)) {
#ifdef ADB_DEBUG
			if (adb_debug)
				printf("adb: ems_init timed out\n");
#endif
			return;
		}

		/* Attempt to initialize Extended Mouse Protocol */
		buffer[2] = 4; /* make handler ID 4 */
		cmd = ADBLISTEN(adbaddr, 3);
		if (adb_op_sync((Ptr)buffer, cmd)) {
#ifdef ADB_DEBUG
			if (adb_debug)
				printf("adb: ems_init timed out\n");
#endif
			return;
		}

		/*
		 * Check to see if successful, if not
		 * try to initialize it as other types
		 */
		cmd = ADBTALK(adbaddr, 3);
		if (adb_op_sync((Ptr)buffer, cmd) == 0 &&
		    buffer[2] == ADBMS_EXTENDED) {
			sc->handler_id = ADBMS_EXTENDED;
			cmd = ADBTALK(adbaddr, 1);
			if (adb_op_sync((Ptr)buffer, cmd)) {
#ifdef ADB_DEBUG
				if (adb_debug)
					printf("adb: ems_init timed out\n");
#endif
			} else if (buffer[0] == 8) {
				/* we have a true EMP device */
				sc->sc_class = buffer[7];
				sc->sc_buttons = buffer[8];
				sc->sc_res = (int)*(short *)&buffer[5];
				bcopy(&(buffer[1]), sc->sc_devid, 4);
			} else if (buffer[1] == 0x9a &&
			    ((buffer[2] == 0x20) || (buffer[2] == 0x21))) {
				/*
				 * Set up non-EMP Mouseman/Trackman to put
				 * button bits in 3rd byte instead of sending
				 * via pseudo keyboard device.
				 */
				cmd = ADBLISTEN(adbaddr, 1);
				buffer[0]=2;
				buffer[1]=0x00;
				buffer[2]=0x81;
				adb_op_sync((Ptr)buffer, cmd);

				cmd = ADBLISTEN(adbaddr, 1);
				buffer[0]=2;
				buffer[1]=0x01;
				buffer[2]=0x81;
				adb_op_sync((Ptr)buffer, cmd);

				cmd = ADBLISTEN(adbaddr, 1);
				buffer[0]=2;
				buffer[1]=0x02;
				buffer[2]=0x81;
				adb_op_sync((Ptr)buffer, cmd);

				cmd = ADBLISTEN(adbaddr, 1);
				buffer[0]=2;
				buffer[1]=0x03;
				buffer[2]=0x38;
				adb_op_sync((Ptr)buffer, cmd);

				sc->sc_buttons = 3;
				sc->sc_res = 400;
				if (buffer[2] == 0x21)
					sc->sc_class = MSCLASS_TRACKBALL;
				else
					sc->sc_class = MSCLASS_MOUSE;
			} else
				/* unknown device? */;
		} else {
			/* Attempt to initialize as an A3 mouse */
			buffer[2] = 0x03; /* make handler ID 3 */
			cmd = ADBLISTEN(adbaddr, 3);
			if (adb_op_sync((Ptr)buffer, cmd)) {
#ifdef ADB_DEBUG
				if (adb_debug)
					printf("adb: ems_init timed out\n");
#endif
				return;
			}

			/*
			 * Check to see if successful, if not
			 * try to initialize it as other types
			 */
			cmd = ADBTALK(adbaddr, 3);
			if (adb_op_sync((Ptr)buffer, cmd) == 0
			    && buffer[2] == ADBMS_MSA3) {
				sc->handler_id = ADBMS_MSA3;
				/* Initialize as above */
				cmd = ADBLISTEN(adbaddr, 2);
				/* listen 2 */
				buffer[0] = 3;
				buffer[1] = 0x00;
				/* Irrelevant, buffer has 0x77 */
				buffer[2] = 0x07;
				/*
				 * enable 3 button mode = 0111b,
				 * speed = normal
				 */
				adb_op_sync((Ptr)buffer, cmd);
				sc->sc_buttons = 3;
				sc->sc_res = 300;
			} else {
				/* No special support for this mouse */
			}
		}
	}
}

/*
 * Handle putting the mouse data received from the ADB into
 * an ADB event record.
 */
void
ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
{
	adb_event_t event;
	struct ams_softc *sc;
	int adbaddr;
#ifdef ADB_DEBUG
	int i;

	if (adb_debug)
		printf("adb: transaction completion\n");
#endif

	adbaddr = ADB_CMDADDR(adb_command);
	sc = (struct ams_softc *)data_area;

	if ((sc->handler_id == ADBMS_EXTENDED) && (sc->sc_devid[0] == 0)) {
		/* massage the data to look like EMP data */
		if ((buffer[3] & 0x04) == 0x04)
			buffer[1] &= 0x7f;
		else
			buffer[1] |= 0x80;
		if ((buffer[3] & 0x02) == 0x02)
			buffer[2] &= 0x7f;
		else
			buffer[2] |= 0x80;
		if ((buffer[3] & 0x01) == 0x01)
			buffer[3] = 0x00;
		else
			buffer[3] = 0x80;
	}

	event.byte_count = buffer[0];
	memcpy(event.bytes, buffer + 1, event.byte_count);

#ifdef ADB_DEBUG
	if (adb_debug) {
		printf("ams: from %d at %d (org %d) %d:", adbaddr,
		    sc->handler_id, sc->origaddr, buffer[0]);
		for (i = 1; i <= buffer[0]; i++)
			printf(" %x", buffer[i]);
		printf("\n");
	}
#endif

	ms_processevent(&event, sc);
}

/*
 * Given a mouse ADB event, record the button settings, calculate the
 * x- and y-axis motion, and handoff the event to the appropriate subsystem.
 */
void
ms_processevent(adb_event_t *event, struct ams_softc *sc)
{
	int i, button_bit, max_byte, mask;
	int dx, dy, buttons;

	buttons = 0;

	/*
	 * This should handle both plain ol' Apple mice and mice
	 * that claim to support the Extended Apple Mouse Protocol.
	 */
	max_byte = event->byte_count;
	button_bit = 1;
	switch (sc->handler_id) {
	case ADBMS_USPEED:
	case ADBMS_UCONTOUR:
		/* MicroSpeed mouse and Contour mouse */
		if (max_byte == 4)
			buttons = (~event->bytes[2]) & 0xff;
		else
			buttons = (event->bytes[0] & 0x80) ? 0 : 1;
		break;
	case ADBMS_MSA3:
		/* Mouse Systems A3 mouse */
		if (max_byte == 3)
			buttons = (~event->bytes[2]) & 0x07;
		else
			buttons = (event->bytes[0] & 0x80) ? 0 : 1;
		break;
	default:
		/* Classic Mouse Protocol (up to 2 buttons) */
		for (i = 0; i < 2; i++, button_bit <<= 1)
			/* 0 when button down */
			if (!(event->bytes[i] & 0x80))
				buttons |= button_bit;
			else
				buttons &= ~button_bit;
		/* Extended Protocol (up to 6 more buttons) */
		if (sc->sc_class == MSCLASS_MOUSE)
			for (mask = 0x80; i < max_byte;
			     i += (mask == 0x80), button_bit <<= 1) {
				/* 0 when button down */
				if (!(event->bytes[i] & mask))
					buttons |= button_bit;
				else
					buttons &= ~button_bit;
				mask = ((mask >> 4) & 0xf)
					| ((mask & 0xf) << 4);
			}
		break;
	}

	buttons |= sc->sc_mb;
	dx = ((signed int) (event->bytes[1] & 0x3f)) -
	    ((event->bytes[1] & 0x40) ? 64 : 0);
	dy = ((signed int) (event->bytes[0] & 0x3f)) -
	    ((event->bytes[0] & 0x40) ? 64 : 0);

	if (sc->sc_wsmousedev)
		wsmouse_input(sc->sc_wsmousedev, buttons, dx, -dy, 0, 0,
		    WSMOUSE_INPUT_DELTA);
}

int
ams_enable(void *v)
{
	return 0;
}

int
ams_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	switch (cmd) {
	case WSMOUSEIO_GTYPE:
		*(u_int *)data = WSMOUSE_TYPE_ADB;
		return (0);
	}

	return -1;
}

void
ams_disable(void *v)
{
}


code:
/*	$OpenBSD: amsvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $	*/
/*	$NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $	*/

/*
 * Copyright (C) 1998	Colin Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Colin Wood.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ADB_AMSVAR_H_
#define _ADB_AMSVAR_H_

/*
 * State info, per mouse instance.
 */
struct ams_softc {
	struct	device	sc_dev;

	/* ADB info */
	int		origaddr;	/* ADB device type (ADBADDR_MS) */
	int		adbaddr;	/* current ADB address */
	int		handler_id;	/* type of mouse */

	/* Extended Mouse Protocol info, faked for non-EMP mice */
	u_int8_t	sc_class;	/* mouse class (mouse, trackball) */
	u_int8_t	sc_buttons;	/* number of buttons */
	u_int32_t	sc_res;		/* mouse resolution (dpi) */
	char		sc_devid[5];	/* device identifier */

	int		sc_mb;		/* current button state */
	struct device	*sc_wsmousedev;
};

/* EMP device classes */
#define MSCLASS_TABLET		0
#define MSCLASS_MOUSE		1
#define MSCLASS_TRACKBALL	2
#define MSCLASS_TRACKPAD	3

#endif /* _ADB_AMSVAR_H_ */


code:
#	$OpenBSD: files.adb,v 1.2 2014/10/18 12:21:57 miod Exp $

file	dev/adb/adb_subr.c		adb

device	akbd: wskbddev
attach	akbd at adb
file	dev/adb/akbd.c			akbd needs-flag

device	ams: wsmousedev
attach	ams at adb
file	dev/adb/ams.c			ams


code:
/*	$OpenBSD: keyboard.h,v 1.5 2011/06/13 16:29:11 shadchin Exp $	*/
/*	$NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $	*/

/*-
 * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
 *			Michael L. Finch, Bradley A. Grantham, and
 *			Lawrence A. Kesteloot
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the Alice Group.
 * 4. The names of the Alice Group or any of its members may not be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define ADBK_CAPSLOCK	0x39
#define	ADBK_RESET	0x7f

#define ADBK_KEYVAL(key)	((key) & 0x7f)
#define ADBK_PRESS(key)		(((key) & 0x80) == 0)
#define ADBK_KEYDOWN(key)	(key)
#define ADBK_KEYUP(key)		((key) | 0x80)


code: src/sys/dev/ata

path: sys/dev/ata/CVS/Repository


code:
/*      $OpenBSD: ata.c,v 1.34 2015/03/14 03:38:47 jsg Exp $      */
/*      $NetBSD: ata.c,v 1.9 1999/04/15 09:41:09 bouyer Exp $      */
/*
 * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/syslog.h>
#include <sys/pool.h>

#include <machine/bus.h>

#include <dev/ata/atareg.h>
#include <dev/ata/atavar.h>
#include <dev/ic/wdcreg.h>

#define DEBUG_FUNCS  0x08
#define DEBUG_PROBE  0x10
#ifdef WDCDEBUG
extern int wdcdebug_mask; /* init'ed in wdc.c */
#define WDCDEBUG_PRINT(args, level) do {	\
	if ((wdcdebug_mask & (level)) != 0)	\
		printf args;			\
} while (0)
#else
#define WDCDEBUG_PRINT(args, level)
#endif

#define ATAPARAMS_SIZE 512

/* Get the disk's parameters */
int
ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
    struct ataparams *prms)
{
	char *tb;
	struct wdc_command wdc_c;
	int i;
	u_int16_t *p;
	int ret;

	WDCDEBUG_PRINT(("ata_get_params\n"), DEBUG_FUNCS);

	bzero(&wdc_c, sizeof(struct wdc_command));

	if (drvp->drive_flags & DRIVE_ATA) {
		wdc_c.r_command = WDCC_IDENTIFY;
		wdc_c.r_st_bmask = WDCS_DRDY;
		wdc_c.r_st_pmask = 0;
		wdc_c.timeout = 3000; /* 3s */
	} else if (drvp->drive_flags & DRIVE_ATAPI) {
		wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
		wdc_c.r_st_bmask = 0;
		wdc_c.r_st_pmask = 0;
		wdc_c.timeout = 10000; /* 10s */
	} else {
		WDCDEBUG_PRINT(("ata_get_params: no disks\n"),
		    DEBUG_FUNCS|DEBUG_PROBE);
		return CMD_ERR;
	}

	tb = dma_alloc(ATAPARAMS_SIZE, PR_NOWAIT | PR_ZERO);
	if (tb == NULL)
		return CMD_AGAIN;
	wdc_c.flags = AT_READ | flags;
	wdc_c.data = tb;
	wdc_c.bcount = ATAPARAMS_SIZE;

	if ((ret = wdc_exec_command(drvp, &wdc_c)) != WDC_COMPLETE) {
		WDCDEBUG_PRINT(("%s: wdc_exec_command failed: %d\n",
		    __func__, ret), DEBUG_PROBE);
		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_AGAIN;
	}

	if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
		WDCDEBUG_PRINT(("%s: IDENTIFY failed: 0x%x\n", __func__,
		    wdc_c.flags), DEBUG_PROBE);

		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_ERR;
	} else {
#if BYTE_ORDER == BIG_ENDIAN
		/* All the fields in the params structure are 16-bit
		   integers except for the ID strings which are char
		   strings.  The 16-bit integers are currently in
		   memory in little-endian, regardless of architecture.
		   So, they need to be swapped on big-endian architectures
		   before they are accessed through the ataparams structure.

		   The swaps below avoid touching the char strings.
		*/

		swap16_multi((u_int16_t *)tb, 10);
		swap16_multi((u_int16_t *)tb + 20, 3);
		swap16_multi((u_int16_t *)tb + 47, ATAPARAMS_SIZE / 2 - 47);
#endif
		/* Read in parameter block. */
		bcopy(tb, prms, sizeof(struct ataparams));

		/*
		 * Shuffle string byte order.
		 * ATAPI Mitsumi and NEC drives don't need this.
		 */
		if ((prms->atap_config & WDC_CFG_ATAPI_MASK) ==
		    WDC_CFG_ATAPI &&
		    ((prms->atap_model[0] == 'N' &&
			prms->atap_model[1] == 'E') ||
		     (prms->atap_model[0] == 'F' &&
			 prms->atap_model[1] == 'X'))) {
			dma_free(tb, ATAPARAMS_SIZE);
			return CMD_OK;
		}
		for (i = 0; i < sizeof(prms->atap_model); i += 2) {
			p = (u_short *)(prms->atap_model + i);
			*p = swap16(*p);
		}
		for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
			p = (u_short *)(prms->atap_serial + i);
			*p = swap16(*p);
		}
		for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
			p = (u_short *)(prms->atap_revision + i);
			*p = swap16(*p);
		}

		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_OK;
	}
}

int
ata_set_mode(struct ata_drive_datas *drvp, u_int8_t mode, u_int8_t flags)
{
	struct wdc_command wdc_c;

	WDCDEBUG_PRINT(("%s: mode=0x%x, flags=0x%x\n", __func__,
	    mode, flags), DEBUG_PROBE);

	bzero(&wdc_c, sizeof(struct wdc_command));

	wdc_c.r_command = SET_FEATURES;
	wdc_c.r_st_bmask = 0;
	wdc_c.r_st_pmask = 0;
	wdc_c.r_precomp = WDSF_SET_MODE;
	wdc_c.r_count = mode;
	wdc_c.flags = flags;
	wdc_c.timeout = 1000; /* 1s */
	if (wdc_exec_command(drvp, &wdc_c) != WDC_COMPLETE)
		return CMD_AGAIN;

	WDCDEBUG_PRINT(("%s: after wdc_exec_command() wdc_c.flags=0x%x\n",
	    __func__, wdc_c.flags), DEBUG_PROBE);

	if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
		return CMD_ERR;
	}
	return CMD_OK;
}

void
ata_dmaerr(struct ata_drive_datas *drvp)
{
	/*
	 * Downgrade decision: if we get NERRS_MAX in NXFER.
	 * We start with n_dmaerrs set to NERRS_MAX-1 so that the
	 * first error within the first NXFER ops will immediately trigger
	 * a downgrade.
	 * If we got an error and n_xfers is bigger than NXFER reset counters.
	 */
	drvp->n_dmaerrs++;
	if (drvp->n_dmaerrs >= NERRS_MAX && drvp->n_xfers <= NXFER) {
		wdc_downgrade_mode(drvp);
		drvp->n_dmaerrs = NERRS_MAX-1;
		drvp->n_xfers = 0;
		return;
	}
	if (drvp->n_xfers > NXFER) {
		drvp->n_dmaerrs = 1; /* just got an error */
		drvp->n_xfers = 1; /* restart counting from this error */
	}
}

void
ata_perror(struct ata_drive_datas *drvp, int errno, char *buf, size_t buf_len)
{
	static char *errstr0_3[] = {"address mark not found",
	    "track 0 not found", "aborted command", "media change requested",
	    "id not found", "media changed", "uncorrectable data error",
	    "bad block detected"};
	static char *errstr4_5[] = {"",
	    "no media/write protected", "aborted command",
	    "media change requested", "id not found", "media changed",
	    "uncorrectable data error", "interface CRC error"};
	char **errstr;
	int i;
	char *sep = "";
	size_t len = 0;

	if (drvp->ata_vers >= 4)
		errstr = errstr4_5;
	else
		errstr = errstr0_3;

	if (errno == 0) {
		snprintf(buf, buf_len, "error not notified");
	}

	for (i = 0; i < 8; i++) {
		if (errno & (1 << i)) {
			snprintf(buf + len, buf_len - len, "%s%s", sep,
			    errstr[i]);
			len = strlen(buf);
			sep = ", ";
		}
	}
}