xref: /illumos-gate/usr/src/uts/common/sys/pcmcia.h (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * PCMCIA nexus
29  */
30 
31 #ifndef _PCMCIA_H
32 #define	_PCMCIA_H
33 
34 #pragma ident	"%Z%%M%	%I%	%E% SMI"
35 
36 #ifdef	__cplusplus
37 extern "C" {
38 #endif
39 
40 #if defined(DEBUG)
41 #define	PCMCIA_DEBUG
42 #endif
43 
44 #include <sys/modctl.h>
45 
46 #define	PCMCIA_MAX_ADAPTERS	8 /* maximum distinct adapters */
47 #define	PCMCIA_MAX_SOCKETS	64 /* maximum distinct sockets */
48 #define	PCMCIA_MAX_WIN_ADAPT	40
49 #define	PCMCIA_MAX_WINDOWS	(PCMCIA_MAX_ADAPTERS*PCMCIA_MAX_WIN_ADAPT)
50 #define	PCMCIA_MAX_POWER	16 /* maximum power table entries */
51 
52 #define	_VERSION(major, minor)	((major)<<16|(minor))
53 
54 /*
55  * DDI/Nexus stuff
56  */
57 
58 #define	PCMCIA_NEXUS_NAME	"pcmcia"
59 #define	PCMCIA_ADAPTER_NODE	"ddi_pcmcia:adapter"
60 #define	PCMCIA_SOCKET_NODE	"ddi_pcmcia:socket"
61 #define	PCMCIA_PCCARD_NODE	"ddi_pcmcia:pccard"
62 
63 /*
64  * private interface between nexus and adapter specific driver
65  * This is only an "ops" type structure
66  */
67 
68 typedef struct pcmcia_if {
69 	uint32_t  pcif_magic;	/* magic number to verify correct scructure */
70 	uint32_t  pcif_version;
71 	int	(*pcif_set_callback)();
72 	int	(*pcif_get_adapter)();
73 	int	(*pcif_get_page)();
74 	int	(*pcif_get_socket)();
75 	int	(*pcif_get_status)();
76 	int	(*pcif_get_window)();
77 	int	(*pcif_inquire_adapter)();
78 	int	(*pcif_inquire_socket)();
79 	int	(*pcif_inquire_window)();
80 	int	(*pcif_reset_socket)();
81 	int	(*pcif_set_page)();
82 	int	(*pcif_set_window)();
83 	int	(*pcif_set_socket)();
84 	int	(*pcif_set_interrupt)();
85 	int	(*pcif_clr_interrupt)();
86 	int	(*pcic_init_dev)();
87 	uint32_t  (*pcic_get_tstamp)();
88 } pcmcia_if_t;
89 
90 /*
91  * magic number and version information to identify
92  * variant of the PCMCIA nexus.
93  */
94 #define	PCIF_MAGIC 0x50434946
95 #define	PCIF_VERSION	_VERSION(0, 1)
96 #define	PCIF_MIN_VERSION _VERSION(0, 1)
97 #define	DEFAULT_CS_NAME	"cs"
98 
99 /*
100  * all adapter drivers use a commonly defined structure for
101  * their private data.  This structure must be filled in
102  * and set.  The an_private member is for the driver writer's
103  * use and is not looked at by the nexus.
104  */
105 struct pcmcia_adapter_nexus_private {
106 	dev_info_t	*an_dip;
107 	pcmcia_if_t	*an_if;
108 	void		*an_private;
109 	ddi_iblock_cookie_t *an_iblock;	/* high priority handler cookies */
110 	ddi_idevice_cookie_t *an_idev;
111 	uint32_t	an_ipl;
112 };
113 
114 typedef struct pcmcia_adapter_nexus_private anp_t;
115 
116 struct pcm_regs {
117 	uint32_t phys_hi;
118 	uint32_t phys_lo;
119 	uint32_t phys_len;
120 };
121 
122 /*
123  * shared interrupts are handled by the
124  * nexus going through the list
125  */
126 typedef struct inthandler {
127 	struct inthandler	*next;
128 	struct inthandler	*prev;
129 	int			flags;
130 	uint32_t		(*intr)(caddr_t, caddr_t);
131 	unsigned		handler_id;
132 	void			*arg1;
133 	void			*arg2;
134 	unsigned		socket;
135 	unsigned		irq;
136 	unsigned		priority;
137 	ddi_softintr_t		softid;
138 	ddi_iblock_cookie_t	iblk_cookie;
139 	ddi_idevice_cookie_t	idev_cookie;
140 } inthandler_t;
141 
142 /*
143  * parent private data area
144  *	not using the old style but will adapt on request
145  *	this allows better framework handling and 1275 compliance
146  */
147 
148 struct pcmcia_parent_private {
149 	int	ppd_nreg;	/* number of regs */
150 	struct	pcm_regs *ppd_reg; /* array of regs in parsed form */
151 	int	ppd_intr;	/* number intrspecs (always 0 or 1) */
152 	struct	intrspec *ppd_intrspec;
153 	void	*pcm_dummy[3];	/* fill for prtconf -v */
154 	struct	pcm_regs *ppd_assigned; /* array of regs in parsed form */
155 	short	ppd_socket;	/* socket number of this instance */
156 	short	ppd_function;	/* function number */
157 	int	ppd_active;	/* is PC Card in a socket and active */
158 	uint32_t  ppd_flags;
159 	void	*ppd_handle; /* client handle */
160 };
161 
162 #define	PPD_CARD_MULTI		0x0001 /* card is multifunction card */
163 #define	PPD_CARD_CARDBUS	0x0002 /* card is CardBus type */
164 #define	PPD_CB_BUSMASTER	0x0004 /* card bus card is busmaster */
165 #define	PPD_SUSPENDED		0x0008 /* this device was pm suspended */
166 
167 /*
168  * macros to make indirect functions easier
169  * and shorter (makes cstyle happier)
170  */
171 
172 #define	GET_SOCKET_STATUS(f, dip, sock, stat)\
173 			(*(f)->pcif_get_socket_status)(dip, sock, stat)
174 #define	SET_CALLBACK(f, dip, callback, sock)\
175 			(*(f)->pcif_set_callback)(dip, callback, sock)
176 
177 #define	GET_ADAPTER(f, dip, conf) (*(f)->pcif_get_adapter) (dip, conf)
178 #define	GET_SOCKET(f, dip, sock) (*(f)->pcif_get_socket)(dip, sock)
179 #define	GET_STATUS(f, dip, status) (*(f)->pcif_get_status)(dip, status)
180 #define	GET_WINDOW(f, dip, window) (*(f)->pcif_get_window)(dip, window)
181 #define	INQUIRE_ADAPTER(f, dip, inquire) (*(f)->pcif_inquire_adapter)(dip,\
182 						inquire)
183 #define	GET_CONFIG(f, dip, conf) INQUIRE_ADAPTER(f, dip, conf)
184 #define	INQUIRE_SOCKET(f, dip, sock) (*(f)->pcif_inquire_socket)(dip, \
185 						sock)
186 #define	GET_PAGE(f, dip, page) (*(f)->pcif_get_page)(dip, page)
187 #define	INQUIRE_WINDOW(f, dip, window) (*(f)->pcif_inquire_window)(dip, window)
188 #define	RESET_SOCKET(f, dip, socket, mode) \
189 			(*(f)->pcif_reset_socket)(dip, socket, mode)
190 #define	SET_PAGE(f, dip, page) (*(f)->pcif_set_page)(dip, page)
191 #define	SET_WINDOW(f, dip, window) (*(f)->pcif_set_window)(dip, window)
192 #define	SET_SOCKET(f, dip, socket) (*(f)->pcif_set_socket)(dip, socket)
193 #define	SET_IRQ(f, dip, handler) (*(f)->pcif_set_interrupt)(dip, handler)
194 #define	CLEAR_IRQ(f, dip, handler) (*(f)->pcif_clr_interrupt)(dip, handler)
195 
196 typedef struct pcmcia_cs {
197 	uint32_t   pccs_magic;	/* magic number of verify correct structure */
198 	uint32_t   pccs_version;
199 	int   (*pccs_callback)();
200 	int   (*pccs_getconfig)();
201 } pcmcia_cs_t;
202 
203 #define	PCCS_MAGIC	0x50434353
204 #define	PCCS_VERSION	_VERSION(2, 1)
205 
206 /* properties used by the nexus for setup */
207 #define	ADAPT_PROP	"adapters"	/* property used to find adapter list */
208 #define	CS_PROP		"card-services"	/* property specifying Card Services */
209 #define	DEF_DRV_PROP	"default-driver" /* default driver to load if no CIS */
210 
211 /*
212  * per adapter structure
213  * this structure defines everything necessary for the
214  * the nexus to interact with the adapter specific driver
215  */
216 
217 struct pcmcia_adapter {
218 	int		pca_module;	/* adapter major number */
219 	int		pca_unit;	/* adapter minor number */
220 	int		pca_number;	/* canonical adapter number */
221 	struct dev_ops	*pca_ops;
222 	dev_info_t	*pca_dip;
223 	pcmcia_if_t	*pca_if;
224 	void		*pca_power;
225 	ddi_iblock_cookie_t *pca_iblock;
226 	ddi_idevice_cookie_t *pca_idev;
227 	kmutex_t	*pca_mutex;
228 	int		pca_numpower;
229 	int		pca_numsockets;
230 	int		pca_first_socket;
231 	uint32_t	pca_flags;
232 	char		pca_name[MODMAXNAMELEN];
233 	uint32_t	pca_avail_intr;
234 	inthandler_t	pca_int_handlers;
235 };
236 
237 #define	PCA_RES_NEED_IRQ	0x0001 /* needs IRQ allocation */
238 #define	PCA_RES_NEED_IO		0x0002 /* needs I/O allocation */
239 #define	PCA_RES_NEED_MEM	0x0004 /* needs memory allocation */
240 #define	PCA_RES_CONSTRAINT	0x0008 /* resource constraints defined */
241 #define	PCA_IRQ_SMI_SHARE	0x0010 /* SMI and child share */
242 #define	PCA_IRQ_SHAREABLE	0x0020 /* all interrupts sharable */
243 #define	PCA_IRQ_ISA		0x0040 /* ISA style (host) interrupts */
244 
245 /* These flags are for open/close -- hot-plug support in future */
246 #define	PCMCIA_MAX_FUNCTIONS	8
247 #define	PCS_CARD_PRESENT	0x0001 /* card in socket */
248 #define	PCS_MULTI_FUNCTION	0x0002 /* indicates dip is multifunction */
249 #define	PCS_SOCKET_ADDED	0x0004 /* CS knows about the socket */
250 #define	PCS_COOKIES_VALID	0x0008 /* iblk and idev valid */
251 #define	PCS_IRQ_ENABLED		0x0010 /* IRQ has been enabled */
252 #define	PCS_SUSPENDED		0x0020 /* PM SUSPEND was done */
253 
254 typedef struct pcmcia_logical_window {
255 	int			lw_window; /* window number */
256 	int			lw_socket; /* logical socket number assigned */
257 	struct pcmcia_adapter	*lw_adapter;
258 	pcmcia_if_t		*lw_if;
259 	uint32_t		lw_status;
260 	baseaddr_t		lw_base;
261 	int			lw_len;
262 } pcmcia_logical_window_t;
263 
264 #define	PCS_ENABLED		0x0002 /* window is enabled */
265 
266 /*
267  * management interface hook
268  */
269 #define	EM_EVENTSIZE	4
270 struct pcmcia_mif {
271 	struct pcmcia_mif *mif_next;
272 	void		(*mif_function)();
273 	uint32_t	  mif_id;
274 	uchar_t		  mif_events[EM_EVENTSIZE]; /* events registered for */
275 };
276 
277 #define	PR_WORDSIZE	8	/* bits in word */
278 #define	PR_MASK		0x7
279 #define	PR_GET(map, bit)	(((uchar_t *)(map))[(bit)/PR_WORDSIZE] &\
280 					(1 << ((bit) & PR_MASK)))
281 #define	PR_SET(map, bit)	(((uchar_t *)(map))[(bit)/PR_WORDSIZE] |=\
282 					(1 << ((bit) & PR_MASK)))
283 #define	PR_CLEAR(map, bit)	(((uchar_t *)(map))[(bit)/PR_WORDSIZE] &=\
284 					~(1 << ((bit) & PR_MASK)))
285 #define	PR_ADDR(map, bit)	(((uchar_t *)(map)) + ((bit)/PR_WORDSIZE))
286 #define	PR_ZERO(map)		bzero((caddr_t)map, sizeof (map))
287 
288 /* socket bit map */
289 typedef uchar_t socket_enum_t[PCMCIA_MAX_SOCKETS/PR_WORDSIZE];
290 
291 /*
292  * Max resoruce limits - all of these have to be power-of-2 aligned
293  *	and the PR_MAX_IO_LEN and PR_MAX_MEM_LEN values must be at
294  *	least 64 or the allocators will panic.
295  */
296 #define	PR_MAX_IO_LEN		1024	/* bytes of IO space */
297 #define	PR_MAX_IO_RANGES	4
298 #define	PR_MAX_MEM_LEN		1024 /* pages or 4M bytes */
299 #define	PR_MAX_MEM_RANGES	32
300 
301 #define	PR_MAX_IOADDR		0xffffffff
302 #define	PR_MAX_MEMADDR		0xffffffff
303 #define	PR_MAX_INTERRUPTS	0xff
304 
305 
306 /*
307  * structures and definitions used in the private interface
308  */
309 
310 /* general values */
311 #define	PC_SUCCESS	1
312 #define	PC_FAILURE	0
313 
314 /* set_mem() */
315 #define	PC_MEM_AM	0
316 #define	PC_MEM_CM	1
317 
318 /* device classes */
319 #define	PCC_MULTI	0
320 #define	PCC_MEMORY	1
321 #define	PCC_SERIAL	2
322 #define	PCC_PARALLEL	3
323 #define	PCC_FIXED_DISK	4
324 #define	PCC_VIDEO	5
325 #define	PCC_LAN		6
326 
327 /*
328  * device information structure information
329  * this is what is used for initial construction of a device node
330  */
331 
332 struct pcm_device_info {
333 	int		pd_socket;
334 	int		pd_function;
335 	int		pd_type;
336 	uint32_t	pd_handle;
337 	uint32_t	pd_tuples;
338 	uint32_t	pd_flags;
339 	char		pd_bind_name[MODMAXNAMELEN];
340 	char		pd_vers1_name[MODMAXNAMELEN*4];
341 	char		pd_generic_name[MODMAXNAMELEN];
342 };
343 
344 #define	PCM_GET_SOCKET(socknum)		((socknum) & 0x1F)
345 #define	PCM_GET_FUNCTION(socknum)	(((socknum) >> 5) & 0x7)
346 
347 #define	PCM_DEFAULT_NODEID		(-1)
348 #define	PCM_DEV_MODEL	"model"
349 #define	PCM_DEV_ACTIVE	"card-active"
350 #define	PCM_DEV_SOCKET	"socket"
351 #define	PCM_DEV_R2TYPE	"16bitcard"
352 #define	PCM_DEV_CARDBUS	"cardbus"
353 
354 typedef
355 struct init_dev {
356 	int	socket;
357 } init_dev_t;
358 
359 /*
360  * device descriptions
361  * used to determine what driver to associate with a PC Card
362  * so that automatic creation of device information trees can
363  * be supported.
364  */
365 
366 typedef
367 struct pcm_device_node {
368 	struct pcm_device_node *pd_next;
369 	dev_info_t *pd_dip;	/* proto device info */
370 	char	pd_name[16];
371 	int	pd_flags;
372 	int	pd_devtype;	/* from device tuple */
373 	int	pd_funcid;
374 	int	pd_manfid;
375 	int	pd_manmask;
376 } pcm_dev_node_t;
377 
378 #define	PCMD_DEVTYPE	0x0001	/* match device type */
379 #define	PCMD_FUNCID	0x0002	/* match function ID */
380 #define	PCMD_MANFID	0x0004	/* match manufacturer ID */
381 #define	PCMD_FUNCE	0x0008	/* match function extension */
382 #define	PCMD_VERS1	0x0010	/* match VERSION_1 string(s) */
383 #define	PCMD_JEDEC	0x0020	/* JEDEC ID */
384 
385 #define	PCM_NAME_1275		0x0001
386 #define	PCM_NAME_VERS1		0x0002
387 #define	PCM_NAME_GENERIC	0x0004
388 #define	PCM_NO_CONFIG		0x0008
389 #define	PCM_OTHER_NOCIS		0x0100
390 #define	PCM_MULTI_FUNCTION	0x0200
391 
392 #define	PCM_MAX_R2_MEM		0x3ffffff
393 
394 #define	PCMDEV_PREFIX	"PC,"
395 #define	PCMDEV_NAMEPREF "pccard"
396 
397 /* property names */
398 #define	PCM_PROP_DEVICE	"device"
399 #define	PCM_PROP_FUNCID "funcid"
400 
401 /* 1275 specific properties */
402 #define	PCM_1275_NUMWIN		"#windows"
403 #define	PCM_1275_NUMSOCK	"#sockets"
404 #define	PCM_1275_SCIC		"status-change-int_caps"
405 
406 /* basic device types */
407 
408 #define	PCM_TYPE_MULTI		0
409 #define	PCM_TYPE_MEMORY		1
410 #define	PCM_TYPE_SERIAL		2
411 #define	PCM_TYPE_PARALLEL	3
412 #define	PCM_TYPE_FIXED		4
413 #define	PCM_TYPE_VIDEO		5
414 #define	PCM_TYPE_LAN		6
415 
416 
417 typedef
418 struct string_to_int {
419 	char *sti_str;
420 	uint32_t sti_int;
421 } str_int_t;
422 
423 /*
424  * PCMCIA nexus/adapter specific ioctl commands
425  */
426 
427 #define	PCIOC	('P' << 8)
428 /* SS is temporary until design done */
429 #define	PC_SS_CMD(cmd)		(PCIOC|(cmd))
430 
431 /* stuff that used to be in obpdefs.h but no longer */
432 #define	PCM_DEVICETYPE	"device_type"
433 
434 /*
435  * new regspec and other 1275 stuff
436  */
437 #define	PC_REG_RELOC(x)		((((uint32_t)x) & 0x1) << 31)
438 #define	PC_REG_PREFETCH(x)	(((x) & 0x1) << 30)
439 #define	PC_REG_TYPE(x)		(((x) & 0x1) << 29)
440 #define	PC_REG_SPACE(x)		(((x) & 0x7) << 24)
441 #define	PC_REG_SOCKET(x)	(((x) & 0x1f) << 11)
442 #define	PC_REG_FUNCTION(x)	(((x) & 0x7) << 8)
443 #define	PC_REG_BASEREG(x)	((x) & 0xff)
444 /* solaris internal only */
445 #define	PC_REG_REFCNT(x)	(((x) & 0xFF) << 16)
446 
447 #define	PC_GET_REG_RELOC(x)	(((x) >> 31) & 1)
448 #define	PC_GET_REG_PREFETCH(x)	(((x) >> 30) & 1)
449 #define	PC_GET_REG_TYPE(x)	(((x) >> 29) & 1)
450 #define	PC_GET_REG_SPACE(x)	(((x) >> 24) & 7)
451 #define	PC_GET_REG_SOCKET(x)	(((x) >> 11) & 0x1f)
452 #define	PC_GET_REG_FUNCTION(x)	(((x) >> 8) & 0x7)
453 #define	PC_GET_REG_BASEREG(x)	((x) & 0xff)
454 /* solaris internal only */
455 #define	PC_GET_REG_REFCNT(x)	(((x) >> 16) & 0xFF)
456 #define	PC_INCR_REFCNT(x)	(((x) & 0xFF00FFFF) | \
457 				    PC_REG_REFCNT(PC_GET_REG_REFCNT(x) + 1))
458 #define	PC_DECR_REFCNT(x)	(((x) & 0xFF00FFFF) | \
459 				    PC_REG_REFCNT(PC_GET_REG_REFCNT(x) - 1))
460 
461 #define	PC_REG_PHYS_HI(n, p, t, c, s, f, r) (uint32_t)( \
462 			PC_REG_RELOC(n) | \
463 			PC_REG_PREFETCH(p) | \
464 			PC_REG_TYPE(t) | \
465 			PC_REG_SPACE(c) | \
466 			PC_REG_SOCKET(s) | \
467 			PC_REG_FUNCTION(f) | \
468 			PC_REG_BASEREG(r))
469 
470 #define	PC_REG_TYPE_CARDBUS	0
471 #define	PC_REG_TYPE_16BIT	1
472 
473 #define	PC_REG_SPACE_CONFIG	0x0
474 #define	PC_REG_SPACE_IO		0x1
475 #define	PC_REG_SPACE_MEMORY	0x2
476 #define	PC_REG_SPACE_ATTRIBUTE	0x4
477 
478 /*
479  * internal properties and other prop_op defines
480  */
481 
482 #define	PCMCIA_PROP_UNKNOWN	0x10000	/* pass to DDI decode */
483 #define	PCMCIA_PROP_CIS		0x20000	/* need to get the tuple */
484 
485 	/* specific known properties */
486 #define	PCMCIA_PROP_SOCKET	0 /* "socket" */
487 #define	PCMCIA_PROP_COMPAT	1 /* "compatible" */
488 #define	PCMCIA_PROP_DEFAULT_PM	2 /* power managment timestamp */
489 #define	PCMCIA_PROP_ACTIVE	3 /* card-active property */
490 #define	PCMCIA_PROP_R2TYPE	4 /* 16 bit card */
491 #define	PCMCIA_PROP_CARDBUS	5 /* card is cardbus */
492 #define	PCMCIA_PROP_OLDCS	6 /* old card services property */
493 #define	PCMCIA_PROP_REG		7 /* standard reg= property */
494 #define	PCMCIA_PROP_INTR	8 /* interrupts property */
495 
496 #ifdef	__cplusplus
497 }
498 #endif
499 
500 #endif	/* _PCMCIA_H */
501