1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_CONSKBD_H
28#define	_SYS_CONSKBD_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <sys/types.h>
33#include <sys/stream.h>
34#include <sys/consdev.h>
35#include <sys/kbd.h>
36#include <sys/kbtrans.h>
37
38#ifdef	__cplusplus
39extern "C" {
40#endif
41
42/*
43 * Lower Queue State:
44 *
45 * Every physical keyboard has a corresponding STREAMS queue. We call this
46 * queue lower queue. To describe this kind of queue, we define a structure
47 * (refer conskbd_lower_queue_t). Every lower queue has a state, transform
48 * of the state describes the process from a keyborad attached to system to
49 * the keyboard is plumbed into conskbd or rejected.
50 *  Rule:
51 *
52 * 1) LQS_UNINITIALIZED 	--->	LQS_KIOCTYPE_ACK_PENDING;
53 * 	send a KIOCTYPE to lower queue, and then wait response;
54 *
55 * 2) LQS_KIOCTYPE_ACK_PENDING	--->	LQS_INITIALIZED_LEGACY;
56 * 	receive nak to KIOCTYPE, the corresponding keyboard can not
57 * 	multiplexed with other keyboards. so the conskbd is bypassed,
58 * 	only one keyboard is supported.
59 *
60 * 3) LQS_KIOCTYPE_ACK_PENDING	--->	LQS_KIOCTRANS_ACK_PENDING;
61 *	receive ack to KIOCTYPE, and send KIOCTRANS to lower queue,
62 *
63 * 4) LQS_KIOCTRANS_ACK_PENDING	--->	LQS_KIOCLAYOUT_ACK_PENDING;
64 * 	receive ack to KIOCTRANS, and send KIOCLAYOUT to lower queue
65 *
66 * 5) LQS_KIOCTRANS_ACK_PENDING --->	Destroy
67 * 	receive nak to KIOCTRANS, it is a fatal error so that this
68 * 	keyboard is not avilable. destroy the lower queue struct.
69 *
70 * 6) LQS_KIOCLAYOUT_ACK_PENDING --->	LQS_KIOCSLED_ACK_PENDING;
71 * 	receive ack/nak to KIOCLAYOUT, and send KIOCSLED/KIOCGLED to
72 *	lower queue.
73 *
74 * 7) LQS_KIOCSLED_ACK_PENDING	--->	LQS_INITIALIZED
75 * 	receive ack/nak, the keyboard is linked under conskbd, multiplexed
76 * 	with other keyboards.
77 *
78 * 8) when lower queue is in the state of LQS_INITIALIZED_LEGACY or
79 *    LQS_INITIALIZED, no state transform occures unless the lower
80 *    queue is destroyed.
81 */
82enum conskbd_lqs_state {
83	LQS_UNINITIALIZED = 0,
84	LQS_KIOCTYPE_ACK_PENDING = 1,	/* waiting ACK for KIOCTYPE */
85	LQS_KIOCTRANS_ACK_PENDING = 2, /* waiting ACK for KIOCTRANS */
86	LQS_KIOCLAYOUT_ACK_PENDING = 3, /* waiting ACK for KIOCLAYOUT */
87	LQS_KIOCSLED_ACK_PENDING = 4, /* waiting ACK for KIOCSLED/KIOCGLED */
88	LQS_INITIALIZED_LEGACY = 5, /* only one lower legacy keyboard */
89	LQS_INITIALIZED = 6 /* virtual keyboard initialized */
90};
91
92struct conskbd_state;
93struct conskbd_lower_queue;
94
95/*
96 * state of lower queue.
97 */
98typedef struct conskbd_lower_queue	conskbd_lower_queue_t;
99struct conskbd_lower_queue {
100
101	conskbd_lower_queue_t	*lqs_next;
102
103	queue_t		*lqs_queue; /* streams queue of lower driver */
104
105	queue_t		*lqs_pending_queue; /* queue of pending message from */
106	mblk_t		*lqs_pending_plink; /* pending I_PLINK message */
107
108	/* state of lower queue */
109	enum conskbd_lqs_state		lqs_state;
110
111	/* polled I/O interface structure of lower keyboard driver */
112	struct cons_polledio	*lqs_polledio;
113
114	/* key status (key-down/key-up) of each key */
115	enum keystate	lqs_key_state[KBTRANS_KEYNUMS_MAX];
116};
117
118/*
119 * Pending message structure.
120 *
121 * Note:
122 *     When conskbd receives message from its upper module, it has to
123 * clone the message and send a copy to each of its lower queues. The
124 * conskbd_pending_msg structure is used to track the process of handling
125 * this kind of messages.
126 */
127typedef struct conskbd_pending_msg	conskbd_pending_msg_t;
128struct conskbd_pending_msg {
129
130	conskbd_pending_msg_t	*kpm_next;
131
132	/* the upper queue from which request message is sent out */
133	queue_t	*kpm_upper_queue;
134
135	mblk_t	*kpm_req_msg;	/* the message block from upper */
136
137	/* message ID and Command Code of the message pointed by kpm_req_msg */
138	uint_t	kpm_req_id;
139	int	kpm_req_cmd;
140
141	/* number of request message's copies sent down to lower queues */
142	int	kpm_req_nums;
143
144	/* number of responses to request message received from lower queues */
145	int	kpm_resp_nums;
146
147	mblk_t	*kpm_resp_list;	/* chain of responses from lower */
148
149	kmutex_t kpm_lock;	/* lock for this structure */
150};
151
152/*
153 * software state structure for virtual keyboard
154 */
155struct conskbd_state {
156
157	/* kbtrans of virtual keyboard */
158	struct kbtrans		*conskbd_kbtrans;
159
160	/* polled I/O interface structure of virutal keyboard */
161	struct cons_polledio	conskbd_polledio;
162
163	/* chain of lower physical keyboard queues */
164	conskbd_lower_queue_t	*conskbd_lqueue_list;
165
166	/* the number of lower physical keyboard queues */
167	int	conskbd_lqueue_nums;
168
169	int	conskbd_layout;	 /* layout of virtual keyboard */
170	int	conskbd_led_state; /* LED state of virtual keyboard */
171
172	boolean_t	conskbd_directio; /* upstream directory */
173	boolean_t	conskbd_bypassed; /* is virtual keyboard disabled ? */
174};
175typedef struct conskbd_state	conskbd_state_t;
176
177#ifdef	__cplusplus
178}
179#endif
180
181#endif	/* _SYS_CONSKBD_H */
182