summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/pcmcia/sys/cis.h
blob: d1a42630b82c1ea77b3aca604b78f1f22a3bc871 (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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
 * 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 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _CIS_H
#define	_CIS_H

/*
 * This is the Card Services Card Information Structure (CIS) interpreter
 *	header file.  CIS information in this file is based on the
 *	Release 2.01 PCMCIA standard.
 */


#ifdef	__cplusplus
extern "C" {
#endif


#if defined(DEBUG)
#define	CIS_DEBUG
#endif


/*
 * The CIS interpreter has a single entry point with a bunch of function
 *	id numbers.
 */
#define	CISP_CIS_SETUP		0x01	/* setup CS address in CIS */
#define	CISP_CIS_LIST_CREATE	0x02	/* create the CIS linked list */
#define	CISP_CIS_LIST_DESTROY	0x03	/* destroy the CIS linked list */
#define	CISP_CIS_GET_LTUPLE	0x04	/* get a tuple */
#define	CISP_CIS_PARSE_TUPLE	0x05	/* parse a tuple */
#define	CISP_CIS_CONV_DEVSPEED	0x06	/* convert devspeed to nS and back */
#define	CISP_CIS_CONV_DEVSIZE	0x07	/* convert device size */

/*
 * Make the  calls to CardServices look like function calls.
 */
#define	CIS_CARD_SERVICES	(*cis_card_services)

/*
 * define the tuples that we recognize
 *
 * Layer 1 - Basic Compatability TUples
 */
#define	CISTPL_NULL		0x000	/* null tuple - ignore */
#define	CISTPL_DEVICE		0x001	/* device information */
#define	CISTPL_LONGLINK_CB	0x002	/* longlink to next tuple chain */
#define	CISTPL_CONFIG_CB	0x004	/* configuration tuple */
#define	CISTPL_CFTABLE_ENTRY_CB	0x005	/* configuration table entry */
#define	CISTPL_LONGLINK_MFC	0x006	/* multi-function tuple */
#define	CISTPL_BAR		0x007	/* Base Address Register definition */
#define	CISTPL_CHECKSUM		0x010	/* checksum control */
#define	CISTPL_LONGLINK_A	0x011	/* long-link to AM */
#define	CISTPL_LONGLINK_C	0x012	/* long-link to CM */
#define	CISTPL_LINKTARGET	0x013	/* link-target control */
#define	CISTPL_NO_LINK		0x014	/* no-link control */
#define	CISTPL_VERS_1		0x015	/* level 1 version information */
#define	CISTPL_ALTSTR		0x016	/* alternate language string */
#define	CISTPL_DEVICE_A		0x017	/* AM device information */
#define	CISTPL_JEDEC_C		0x018	/* JEDEC programming info for CM */
#define	CISTPL_JEDEC_A		0x019	/* JEDEC programming info for AM */
#define	CISTPL_CONFIG		0x01a	/* configuration */
#define	CISTPL_CFTABLE_ENTRY	0x01b	/* configuration-table-entry */
#define	CISTPL_DEVICE_OC	0x01c	/* other op conditions CM device info */
#define	CISTPL_DEVICE_OA	0x01d	/* other op conditions AM device info */
#define	CISTPL_DEVICEGEO	0x01e	/* Common Memory device geometry */
#define	CISTPL_DEVICEGEO_A	0x01f	/* Attribute Memory device geometry */
#define	CISTPL_MANFID		0x020	/* manufacturer identification */
#define	CISTPL_FUNCID		0x021	/* function identification */
#define	CISTPL_FUNCE		0x022	/* function extension */

/*
 * Layer 2 - Data Recording Format Tuples
 */
#define	CISTPL_SWIL		0x023	/* software interleave */
#define	CISTPL_VERS_2		0x040	/* level 2 version information */
#define	CISTPL_FORMAT		0x041	/* Common Memory recording format */
#define	CISTPL_GEOMETRY		0x042	/* geometry */
#define	CISTPL_BYTEORDER	0x043	/* byte order */
#define	CISTPL_DATE		0x044	/* card initialization date */
#define	CISTPL_BATTERY		0x045	/* battery replacement date */
#define	CISTPL_FORMAT_A		0x047	/* Attribute Memory recording format */

/*
 * Layer 3 - Data Organization Tuples
 */
#define	CISTPL_ORG		0x046	/* organization */

/*
 * Layer 4 - System Specific Standard Tuples
 */
#define	CISTPL_VEND_SPEC_80	0x080	/* vendor-specific 0x80 */
#define	CISTPL_VEND_SPEC_81	0x081	/* vendor-specific 0x81 */
#define	CISTPL_VEND_SPEC_82	0x082	/* vendor-specific 0x82 */
#define	CISTPL_VEND_SPEC_83	0x083	/* vendor-specific 0x83 */
#define	CISTPL_VEND_SPEC_84	0x084	/* vendor-specific 0x84 */
#define	CISTPL_VEND_SPEC_85	0x085	/* vendor-specific 0x85 */
#define	CISTPL_VEND_SPEC_86	0x086	/* vendor-specific 0x86 */
#define	CISTPL_VEND_SPEC_87	0x087	/* vendor-specific 0x87 */
#define	CISTPL_VEND_SPEC_88	0x088	/* vendor-specific 0x88 */
#define	CISTPL_VEND_SPEC_89	0x089	/* vendor-specific 0x89 */
#define	CISTPL_VEND_SPEC_8a	0x08a	/* vendor-specific 0x8a */
#define	CISTPL_VEND_SPEC_8b	0x08b	/* vendor-specific 0x8b */
#define	CISTPL_VEND_SPEC_8c	0x08c	/* vendor-specific 0x8c */
#define	CISTPL_VEND_SPEC_8d	0x08d	/* vendor-specific 0x8d */
#define	CISTPL_VEND_SPEC_8e	0x08e	/* vendor-specific 0x8e */
#define	CISTPL_VEND_SPEC_8f	0x08f	/* vendor-specific 0x8f */
#define	CISTPL_SPCL		0x090	/* special-purpose tuple */
#define	CISTPL_END		0x0ff	/* end-of-list tuple */

/*
 * Macro to check if tuple is a vendor-specific tuple.
 */
#define	CISTPL_VENDSPEC_START	CISTPL_VEND_SPEC_80
#define	CISTPL_VENDSPEC_END	CISTPL_VEND_SPEC_8f
#define	CISTPL_IS_VENDOR_SPECIFIC(td)	(((td) >= CISTPL_VENDSPEC_START) &&   \
						((td) <= CISTPL_VENDSPEC_END))

/*
 * The GetFirstTuple and GetNextTuple Card Services function calls use
 *	the DesiredTuple member of the tuple_t structure to determine
 *	while tuple type to return; since the CIS parser doesn't ever
 *	return CISTPL_END tuples, we can never ask for those tuples,
 *	so we overload this tuple code to mean that we want the
 *	first (or next) tuple in the chain.
 * XXX - If we ever do return CISTPL_END tuples, we'll have to
 *	re-think this.
 */
#define	RETURN_FIRST_TUPLE	0x0ff	/* return first/next tuple */
#define	RETURN_NEXT_TUPLE	0x0ff	/* return first/next tuple */

/*
 * types for data in CIS and pointers into PC card's CIS space
 *
 * The "size" member is used by the NEXT_CIS_ADDR macro so that
 *	we don't run past the end of the mapped CIS address space.
 */
typedef uchar_t cisdata_t;

typedef struct cisptr_t {
    acc_handle_t	handle;	/* access handle of CIS space */
    uint32_t		size;	/* size of mapped area */
    uint32_t		offset;	/* byte offset into CIS space */
	/* see flag definitions for cistpl_t structure */
    uint32_t		flags;
} cisptr_t;

/*
 * This is the maximum length that the data portion of a tuple can be.
 *	We have to use this since the brain-damaged 2.01 PCMCIA spec
 *	specifies that you can end a CIS chain by putting a CISTPL_END
 *	in the link field of the last VALID tuple.
 */
#define	CIS_MAX_TUPLE_DATA_LEN	254

/*
 * This is the maximum size of the string used to describe the name
 *	of the tuple.
 */
#define	CIS_MAX_TUPLE_NAME_LEN	40

/*
 * CIS_MAX_FUNCTIONS defines the maximum number of functions that can
 *	exist on a card.
 */
#define	CIS_MAX_FUNCTIONS	8	/* max number of functions per card */

/*
 * Macros to manipulate addresses and data in various CIS spaces
 *
 * NEXT_CIS_ADDR(cisptr_t *) increments the offset to point to the
 *	next data element in the CIS, based on what space the CIS
 *	we are reading resides in.  If the resulting address would
 *	be past the end of the mapped-in area, we return NULL,
 *	otherwise the adjusted offset value is returned. Note that
 *	this only works if the "size" member specifies the maximum
 *	mapped in window size and an "offset" member value of zero
 *	refers to the first byte of the window.
 *
 * GET_CIS_DATA(ptr) returns the data byte at the current CIS location.
 *
 * GET_CIS_ADDR(tp,ptr) returns the virtual address that was saved by a
 *	call to STORE_CIS_ADDR.
 *
 * BAD_CIS_ADDR is a flag that should be returned by callers of NEXT_CIS_ADDR
 *	if that macro returns NULL.  Note that this flag shares the same bit
 *	field definitions as the tuple handler flags defined in cis_handlers.h
 *	so check that file if you make any changes to these flags.
 * XXX - not the best distribution of flags, I'm afraid
 */
#define	NEXT_CIS_ADDR(ptr)	\
			(((ptr->flags&CISTPLF_AM_SPACE)?(ptr->offset += 2): \
				(ptr->offset++)),	\
				((ptr->offset > ptr->size)?(0):ptr->offset))
#define	GET_CIS_DATA(ptr)	csx_Get8(ptr->handle, ptr->offset)
#define	GET_CIS_ADDR(tp)	((cisdata_t *)(uintptr_t)(tp)->offset)
#define	BAD_CIS_ADDR	0x080000000 /* read past end of mapped CIS error */

/*
 * CIS_MEM_ALLOC(len) is used to allocate memory for our local linked
 *	CIS list; we use a macro so that the same code can be used in
 *	the kernel as well as in user space
 *
 * CIS_MEM_FREE(ptr) - same comment as CIS_MEM_ALLOC
 */
#if !defined(_KERNEL)
#ifdef	CISMALLOC_DEBUG
#define	CIS_MEM_ALLOC(len)		cis_malloc((uint32_t)len)
#define	CIS_MEM_FREE(ptr)		cis_free(ptr)
#else
#define	CIS_MEM_ALLOC(len)		malloc((uint32_t)len)
#define	CIS_MEM_FREE(ptr)		free(ptr)
#endif	/* CISMALLOC_DEBUG */
#else
#define	CIS_MEM_ALLOC(len)		cis_malloc((uint32_t)len)
#define	CIS_MEM_FREE(ptr)		cis_free(ptr)
#endif

typedef struct cis_u_malloc_tag_t {
	caddr_t		addr;
	uint32_t	len;
} cis_u_malloc_tag_t;

/*
 * We keep the tuples in a locally-maintained linked list.  This allows
 *	us to return the tuple information at any time to a client for
 *	those cards that make their CIS inaccessible once the card is
 *	configured.
 */
typedef struct cistpl_t {
	cisdata_t	type;	/* type of tuple */
	cisdata_t	len;	/* length of tuple data */
	cisdata_t	*data;	/* data in tuple */
	union {
		cisdata_t	*byte;	/* read pointer for GET_BYTE macros */
		uint16_t	*sword;
	}		read;
	uint32_t	flags;	/* misc flags */
	uint32_t	offset;	/* CIS address offset of start of tuple */
	struct cistpl_t	*prev;	/* back pointer */
	struct cistpl_t	*next;	/* forward pointer */
} cistpl_t;

/*
 * Flags that are used in the cistpl_t and cisptr_t linked lists
 */
#define	CISTPLF_NOERROR		0x000000000 /* no error return from handler */
#define	CISTPLF_UNKNOWN		0x000000001 /* unknown tuple */
#define	CISTPLF_REGS		0x000000002 /* tuple contains registers */
#define	CISTPLF_COPYOK		0x000000004 /* OK to copy tuple data */
#define	CISTPLF_VALID		0x000000008 /* tuple is valid */
#define	CISTPLF_GLOBAL_CIS	0x000000010 /* tuple from global CIS */
#define	CISTPLF_MF_CIS		0x000000020 /* tuple from MF CIS chain */
#define	CISTPLF_FROM_AM		0x000000040 /* tuple read from AM space */
#define	CISTPLF_FROM_CM		0x000000080 /* tuple read from CM space */
#define	CISTPLF_IGNORE_TUPLE	0x000000100 /* ignore this tuple */
#define	CISTPLF_VENDOR_SPECIFIC	0x000000200 /* vnedor-specific tuple */
#define	CISTPLF_LINK_INVALID	0x001000000 /* tuple link is invalid */
#define	CISTPLF_PARAMS_INVALID	0x002000000 /* tuple body is invalid */
#define	CISTPLF_AM_SPACE	0x010000000 /* this tuple is in AM space */
#define	CISTPLF_CM_SPACE	0x020000000 /* this tuple is in CM space */
#define	CISTPLF_LM_SPACE	0x040000000 /* this tuple is in local memory */
#define	CISTPLF_MEM_ERR		0x080000000 /* GET_BYTE macros memory error */

/*
 * Some convienience macros
 */
#define	CISTPLF_SPACE_MASK	(CISTPLF_AM_SPACE | CISTPLF_CM_SPACE |	\
							CISTPLF_LM_SPACE)
#define	CISTPLF_FROM_MASK	(CISTPLF_FROM_AM | CISTPLF_FROM_CM)

/*
 * Values used internally on calls to cis_get_ltuple.
 *
 * The GET_XXX_LTUPLEF and FIND_XXX_XXX values are mutually exclusive,
 *	i.e. cis_get_ltuple can only do one of these operations per call.
 *
 * The other flags are bit flags and they share the flags parameter.
 *
 *    CIS_GET_LTUPLE_IGNORE - return tuples with CISTPLF_IGNORE_TUPLE
 *				set in cistpl_t->flags
 */
#define	GET_FIRST_LTUPLEF	0x000000001 /* return first tuple in list */
#define	GET_LAST_LTUPLEF	0x000000002 /* return last tuple in list */
#define	FIND_LTUPLE_FWDF	0x000000003 /* find tuple, fwd search from tp */
#define	FIND_LTUPLE_BACKF	0x000000004 /* find tuple, backward from tp */
#define	FIND_NEXT_LTUPLEF	0x000000005 /* find tuple, fwd from tp+1 */
#define	FIND_PREV_LTUPLEF	0x000000006 /* find tuple, backward from tp-1 */
#define	GET_NEXT_LTUPLEF	0x000000007 /* return next tuple in list */
#define	GET_PREV_LTUPLEF	0x000000008 /* return prev tuple in list */
#define	CIS_GET_LTUPLE_OPMASK	0x00000ffff /* mask for operation values */
#define	CIS_GET_LTUPLE_IGNORE	0x000010000 /* return ignored tuples */

/*
 * macros for getting various data types out of a tuple
 * Note that due to the modem tuple using a few big-endian values,
 * we have to support both big and little endian macros
 *
 * Common Memory Specific macros - these will also work for tuples in
 *	local memory
 */
#define	GET_CM_BYTE(tp)	(((size_t)(tp)->len >= \
				((uintptr_t)(tp)->read.byte - \
					(uintptr_t)(tp)->data)) ? \
			 *(tp)->read.byte++ : ((tp)->flags |= CISTPLF_MEM_ERR))
#define	GET_CM_LEN(tp)	((size_t)(tp)->len - \
				((uintptr_t)(tp)->read.byte - \
				(uintptr_t)(tp)->data))

/* Attribute Memory Specific macros */
#define	GET_AM_BYTE(tp)	(((size_t)(tp)->len >= \
				(((uintptr_t)(tp)->read.byte - \
					(uintptr_t)(tp)->data))>>1) ? \
			 *(cisdata_t *)(tp)->read.sword++ : \
				((tp)->flags |= CISTPLF_MEM_ERR))
#define	GET_AM_LEN(tp)	((size_t)(tp)->len - (((uintptr_t)(tp)->read.byte - \
				(uintptr_t)(tp)->data) >> 1))

/* generic macros */
#define	RESET_TP(tp)	(tp)->read.byte = (tp)->data
#define	LOOK_BYTE(tp)	*(tp)->read.byte
#define	GET_BYTE_ADDR(tp) (tp)->read.byte

#define	GET_BYTE(tp)	(((tp)->flags & CISTPLF_AM_SPACE) ? \
				GET_AM_BYTE(tp) : GET_CM_BYTE(tp))
#define	GET_SHORT(tp)		cis_get_short(tp)
#define	GET_BE_SHORT(tp)	cis_get_be_short(tp)
#define	GET_INT24(tp)		cis_get_int24(tp)
#define	GET_LONG(tp)		cis_get_long(tp)
#define	GET_LEN(tp)	(((tp)->flags & CISTPLF_AM_SPACE) ? \
				GET_AM_LEN(tp) : GET_CM_LEN(tp))

/*
 * cistpl_ignore_list_t - this structure describes tuples in the global
 *				CIS list that we want to ignore if they
 *				also show up in a function-specific CIS.
 */
typedef struct cistpl_ignore_list_t {
	cisdata_t	type;
} cistpl_ignore_list_t;

#ifdef	__cplusplus
}
#endif

#endif	/* _CIS_H */