Home | History | Annotate | Download | only in sys
      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