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