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