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