summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/usb/clients/hid/hidvar.h
blob: 61ac49800a5fc5d07f0f5ddfba6e9966b413edeb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Copyright 2017 Joyent, Inc.
 */

#ifndef _SYS_USB_HIDVAR_H
#define	_SYS_USB_HIDVAR_H


#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/usb/usba/usbai_private.h>
#include <sys/usb/usba/usba_ugen.h>

/*
 * HID : This header file contains the internal structures
 * and variable definitions used in hid driver.
 */

/*
 * HID USB device state management :
 *
 *	ONLINE-----1--->SUSPENDED----2---->ONLINE
 *	  |
 *	  +-----3--->DISCONNECTED----4----->ONLINE
 *	  |
 *	  +-----7--->POWERED DOWN----8----->POWER CHANGE---9--->ONLINE
 *						|
 *						+---3--->DISCONNECTED
 *
 *	POWERED DOWN----1--->SUSPENDED------2----->POWERED DOWN
 *	  |		      |     ^
 *	  |		      5     |
 *	  |		      |     6
 *	  |		      v     |
 *	  +---------3----->DISCONNECTED-------4----->POWERED DOWN
 *
 *	1 = CPR SUSPEND
 *	2 = CPR RESUME (with original device)
 *	3 = Device Unplug
 *	4 = Original Device Plugged in
 *	5 = CPR RESUME (with device disconnected or with a wrong device)
 *	6 = CPR SUSPEND on a disconnected device
 *	7 = Device idles for time T & transitions to low power state
 *	8 = Remote wakeup by device OR Application kicking off IO to device
 *          This results in a Transistion state till PM calls the power
 *	    entry point to raise the power level of the device
 *	9 = Device entry point called to raise power level of the device
 *
 */


/* Boot Interface Subclass for HID devices */
#define	BOOT_INTERFACE		0x01

/* Boot protocol values for keyboard and mouse */
#define	KEYBOARD_PROTOCOL	0x01		/* legacy keyboard */
#define	MOUSE_PROTOCOL		0x02		/* legacy mouse */
#define	NONE_PROTOCOL		0
/*
 * If the hid descriptor is not valid, the following values are
 * used.
 */
#define	USBKPSZ			8	/* keyboard packet size */
#define	USBMSSZ			3	/* mouse packet size */
#define	USB_KB_HID_DESCR_LENGTH 0x3f	/* keyboard Report descr length */
#define	USB_MS_HID_DESCR_LENGTH 0x32	/* mouse Report descr length */

/*
 * Flags for the default pipe.
 */
#define	HID_DEFAULT_PIPE_BUSY	0x01

/*
 * Hid interrupt pipe states. Interrupt pipe
 * can be in only one of these states :
 *
 *	open--1-->data_transferring--1-->open
 *	 |
 *	 |----2---->closed
 *
 *	1 = interrupt pipe callback
 *	2 = hid_close
 */
#define	HID_INTERRUPT_PIPE_CLOSED 0x00 /* Int. pipe is closed */
#define	HID_INTERRUPT_PIPE_OPEN	0x01 /* Int. pipe is opened */

/* HID mctl processing return codes */
#define	HID_SUCCESS	0	/* mctl processed successfully */
#define	HID_INPROGRESS	1	/* mctl queued/deferred for execution */
#define	HID_ENQUEUE	2	/* mctl queued/deferred for execution */
#define	HID_FAILURE	-1	/* mctl processing failed */

/* Data is being sent up */
#define	HID_INTERRUPT_PIPE_DATA_TRANSFERRING	0x03

/* Attach/detach states */
#define	HID_LOCK_INIT		0x01	/* Initial attach state */
#define	HID_MINOR_NODES		0x02	/* Set after minor node is created */

/* HID Protocol Requests */
#define	SET_IDLE		0x0a	/* bRequest value to set idle request */
#define	DURATION		(0<<8)	/* no. of repeat reports (HID 7.2.4) */
#define	SET_PROTOCOL		0x0b	/* bRequest value for boot protocol */

/* Hid PM scheme */
typedef enum {
	HID_PM_ACTIVITY,	/* device is power managed by idleness */
	HID_PM_OPEN_CLOSE,	/* device is busy on open, idle on close */
	HID_PM_APPLICATION	/* device is power managed by application */
} hid_pm_scheme_t;

typedef struct hid_power {

	void			*hid_state;	/* points back to hid_state */

	int			hid_pm_busy;	/* device busy accounting */

	hid_pm_scheme_t		hid_pm_strategy;	/* device PM */

	uint8_t			hid_wakeup_enabled;

	/* this is the bit mask of the power states that device has */
	uint8_t			hid_pwr_states;

	/* wakeup and power transistion capabilites of an interface */
	uint8_t			hid_pm_capabilities;

	/* flag to indicate if driver is about to raise power level */
	boolean_t		hid_raise_power;

	/* current power level the device is in */
	uint8_t			hid_current_power;

	/* mblk indicating that the device has powered up */
	mblk_t			*hid_pm_pwrup;
} hid_power_t;

_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_power_t::hid_state))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_power_t::hid_pm_strategy))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_power_t::hid_wakeup_enabled))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_power_t::hid_pwr_states))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_power_t::hid_pm_capabilities))


typedef struct hid_state {
	dev_info_t		*hid_dip;	/* per-device info handle */
	kmutex_t		hid_mutex;	/* for general locking */
	int			hid_instance;	/* instance number */

	/* Attach/detach flags */
	int			hid_attach_flags;

	/* device state flag */
	int			hid_dev_state;

	/* outstanding requests on the default pipe */
	int			hid_default_pipe_req;

	hid_power_t		*hid_pm;	/* ptr to power struct */

	usb_client_dev_data_t	*hid_dev_data;	/* ptr to usb reg struct */

	usb_dev_descr_t		*hid_dev_descr;	/* device descriptor. */

	/* hid driver is attached to this interface */
	int			hid_interfaceno;

	usb_if_descr_t		hid_if_descr;		/* interface descr */
	usb_hid_descr_t		hid_hid_descr;		/* hid descriptor */
	usb_ep_xdescr_t		hid_ep_intr_xdescr;	/* ep extended desc */
	hidparser_handle_t	hid_report_descr;	/* report descr */

	usb_pipe_handle_t	hid_default_pipe;	/* default pipe */
	usb_pipe_handle_t	hid_interrupt_pipe;	/* intr pipe handle */

	int			hid_packet_size;	/* data packet size */

	/* Pipe policy for the interrupt pipe is saved here */
	usb_pipe_policy_t	hid_intr_pipe_policy;

	/*
	 * This field is only used if the device provides polled input
	 * This is state information for the usba layer.
	 */
	usb_console_info_t	hid_polled_console_info;

	/*
	 * This is the buffer that the raw characters are stored in.
	 * for polled mode.
	 */
	uchar_t			*hid_polled_raw_buf;

	/* handle for outputting messages */
	usb_log_handle_t	hid_log_handle;

	queue_t			*hid_internal_rq;
	queue_t			*hid_external_rq;
	/* which one of the above 2 streams gets the input */
	queue_t			*hid_inuse_rq;
	int			hid_internal_flag;	/* see below */
	int			hid_external_flag;	/* see below */

	usb_ugen_hdl_t		hid_ugen_hdl;		/* ugen support */
} hid_state_t;

/* warlock directives, stable data */
_NOTE(MUTEX_PROTECTS_DATA(hid_state_t::hid_mutex, hid_state_t))
_NOTE(MUTEX_PROTECTS_DATA(hid_state_t::hid_mutex, hid_power_t))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_dip))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_pm))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_dev_data))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_instance))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_interrupt_pipe))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_ep_intr_descr))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_default_pipe))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_log_handle))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_if_descr))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_dev_data))
_NOTE(DATA_READABLE_WITHOUT_LOCK(hid_state_t::hid_dev_descr))
_NOTE(SCHEME_PROTECTS_DATA("stable data", usb_ep_descr))


/*
 * The hid_polled_console_info field is a handle from usba.  The
 * handle is used when the kernel is in the single thread mode
 * so the field is tagged with this note.
 */
_NOTE(SCHEME_PROTECTS_DATA("unique per call",
				hid_state_t::hid_polled_console_info))

/*
 * structure for argument for callback routine for async
 * data transfer through default pipe.
 */
typedef struct hid_default_pipe_argument {
	/* Pointer to the write queue from which the message comes from */
	queue_t		*hid_default_pipe_arg_queue;

	/* Message to be sent up to the stream */
	struct iocblk	hid_default_pipe_arg_mctlmsg;

	/* Pointer to the original mblk_t received from hid_wput() */
	mblk_t		*hid_default_pipe_arg_mblk;

	/* Request that caused this callback to happen */
	uchar_t		hid_default_pipe_arg_bRequest;

} hid_default_pipe_arg_t;

/*
 * An instance of this structure is created per command down to the
 * device.  The control callback is not executed until the call is
 * made into usba, so there is no danger of a callback happening when
 * the fields of the structure are being set.
 */
_NOTE(SCHEME_PROTECTS_DATA("unique per call", hid_default_pipe_arg_t))

/*
 * An instance of this structure is created per command down to the
 * device.  The callback is not executed until the call is
 * made into usba, so there is no danger of a callback happening when
 * the fields of the structure are being set.
 */

/* Value for hid_[internal|external]_flag */
#define	HID_STREAMS_OPEN	0x00000001	/* Streams are open */
#define	HID_STREAMS_DISMANTLING	0x00000002	/* In hid_close() */

#define	HID_STREAMS_FLAG(q, hidp) ((q) == (hidp)->hid_internal_rq ? \
	(hidp)->hid_internal_flag : (hidp)->hid_external_flag)

#define	HID_IS_OPEN(hidp)	(((hidp)->hid_internal_flag == \
	HID_STREAMS_OPEN) || ((hidp)->hid_external_flag == HID_STREAMS_OPEN))

#define	HID_BAD_DESCR		0x01		/* Bad hid report descriptor */

#define	HID_MINOR_NAME_LEN	20	/* Max length of minor_name string */

/* hid_close will wait 60 secons for callbacks to be over */
#define	HID_CLOSE_WAIT_TIMEOUT	10

/* define a timeout for draining requests on the default control pipe */
#define	HID_DEFAULT_PIPE_DRAIN_TIMEOUT	5

/* To support PM on SUN mice of later revisions */
#define	HID_SUN_MOUSE_VENDOR_ID	0x0430
#define	HID_SUN_MOUSE_PROD_ID	0x0100
#define	HID_SUN_MOUSE_BCDDEVICE	0x0105	/* and later revisions */


/*
 * Debug message Masks
 */
#define	PRINT_MASK_ATTA		0x00000001
#define	PRINT_MASK_OPEN		0x00000002
#define	PRINT_MASK_CLOSE	0x00000004
#define	PRINT_MASK_EVENTS	0x00000008
#define	PRINT_MASK_PM		0x00000010
#define	PRINT_MASK_ALL		0xFFFFFFFF

/*
 * Define states local to hid driver
 */
#define	USB_DEV_HID_POWER_CHANGE 0x80

/* define for retrying control requests */
#define	HID_RETRY	10

#ifdef __cplusplus
}
#endif

#endif	/* _SYS_USB_HIDVAR_H */