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
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.
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]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
34 #pragma ident "%Z%%M% %I% %E% SMI"
44 #include <sys/modctl.h>
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 */
52 #define _VERSION(major, minor) ((major)<<16|(minor))
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"
64 * private interface between nexus and adapter specific driver
65 * This is only an "ops" type structure
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
)();
91 * magic number and version information to identify
92 * variant of the PCMCIA nexus.
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"
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.
105 struct pcmcia_adapter_nexus_private
{
109 ddi_iblock_cookie_t
*an_iblock
; /* high priority handler cookies */
110 ddi_idevice_cookie_t
*an_idev
;
114 typedef struct pcmcia_adapter_nexus_private anp_t
;
123 * shared interrupts are handled by the
124 * nexus going through the list
126 typedef struct inthandler
{
127 struct inthandler
*next
;
128 struct inthandler
*prev
;
130 uint32_t (*intr
)(caddr_t
, caddr_t
);
137 ddi_softintr_t softid
;
138 ddi_iblock_cookie_t iblk_cookie
;
139 ddi_idevice_cookie_t idev_cookie
;
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
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 */
159 void *ppd_handle
; /* client handle */
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 */
168 * macros to make indirect functions easier
169 * and shorter (makes cstyle happier)
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)
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,\
183 #define GET_CONFIG(f, dip, conf) INQUIRE_ADAPTER(f, dip, conf)
184 #define INQUIRE_SOCKET(f, dip, sock) (*(f)->pcif_inquire_socket)(dip, \
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)
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
)();
203 #define PCCS_MAGIC 0x50434353
204 #define PCCS_VERSION _VERSION(2, 1)
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 */
212 * per adapter structure
213 * this structure defines everything necessary for the
214 * the nexus to interact with the adapter specific driver
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
;
225 ddi_iblock_cookie_t
*pca_iblock
;
226 ddi_idevice_cookie_t
*pca_idev
;
230 int pca_first_socket
;
232 char pca_name
[MODMAXNAMELEN
];
233 uint32_t pca_avail_intr
;
234 inthandler_t pca_int_handlers
;
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 */
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 */
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
;
262 } pcmcia_logical_window_t
;
264 #define PCS_ENABLED 0x0002 /* window is enabled */
267 * management interface hook
269 #define EM_EVENTSIZE 4
271 struct pcmcia_mif
*mif_next
;
272 void (*mif_function
)();
274 uchar_t mif_events
[EM_EVENTSIZE
]; /* events registered for */
277 #define PR_WORDSIZE 8 /* bits in word */
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))
289 typedef uchar_t socket_enum_t
[PCMCIA_MAX_SOCKETS
/PR_WORDSIZE
];
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.
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
301 #define PR_MAX_IOADDR 0xffffffff
302 #define PR_MAX_MEMADDR 0xffffffff
303 #define PR_MAX_INTERRUPTS 0xff
307 * structures and definitions used in the private interface
322 #define PCC_PARALLEL 3
323 #define PCC_FIXED_DISK 4
328 * device information structure information
329 * this is what is used for initial construction of a device node
332 struct pcm_device_info
{
339 char pd_bind_name
[MODMAXNAMELEN
];
340 char pd_vers1_name
[MODMAXNAMELEN
*4];
341 char pd_generic_name
[MODMAXNAMELEN
];
344 #define PCM_GET_SOCKET(socknum) ((socknum) & 0x1F)
345 #define PCM_GET_FUNCTION(socknum) (((socknum) >> 5) & 0x7)
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"
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
367 struct pcm_device_node
{
368 struct pcm_device_node
*pd_next
;
369 dev_info_t
*pd_dip
; /* proto device info */
372 int pd_devtype
; /* from device tuple */
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 */
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
392 #define PCM_MAX_R2_MEM 0x3ffffff
394 #define PCMDEV_PREFIX "PC,"
395 #define PCMDEV_NAMEPREF "pccard"
398 #define PCM_PROP_DEVICE "device"
399 #define PCM_PROP_FUNCID "funcid"
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"
406 /* basic device types */
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
418 struct string_to_int
{
424 * PCMCIA nexus/adapter specific ioctl commands
427 #define PCIOC ('P' << 8)
428 /* SS is temporary until design done */
429 #define PC_SS_CMD(cmd) (PCIOC|(cmd))
431 /* stuff that used to be in obpdefs.h but no longer */
432 #define PCM_DEVICETYPE "device_type"
435 * new regspec and other 1275 stuff
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)
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))
461 #define PC_REG_PHYS_HI(n, p, t, c, s, f, r) (uint32_t)( \
463 PC_REG_PREFETCH(p) | \
467 PC_REG_FUNCTION(f) | \
470 #define PC_REG_TYPE_CARDBUS 0
471 #define PC_REG_TYPE_16BIT 1
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
479 * internal properties and other prop_op defines
482 #define PCMCIA_PROP_UNKNOWN 0x10000 /* pass to DDI decode */
483 #define PCMCIA_PROP_CIS 0x20000 /* need to get the tuple */
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 */
500 #endif /* _PCMCIA_H */