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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _CIS_H
  27 #define _CIS_H
  28 
  29 #pragma ident   "%Z%%M% %I%     %E% SMI"
  30 
  31 /*
  32  * This is the Card Services Card Information Structure (CIS) interpreter
  33  *      header file.  CIS information in this file is based on the
  34  *      Release 2.01 PCMCIA standard.
  35  */
  36 
  37 
  38 #ifdef  __cplusplus
  39 extern "C" {
  40 #endif
  41 
  42 
  43 #if defined(DEBUG)
  44 #define CIS_DEBUG
  45 #endif
  46 
  47 
  48 /*
  49  * The CIS interpreter has a single entry point with a bunch of function
  50  *      id numbers.
  51  */
  52 #define CISP_CIS_SETUP          0x01    /* setup CS address in CIS */
  53 #define CISP_CIS_LIST_CREATE    0x02    /* create the CIS linked list */
  54 #define CISP_CIS_LIST_DESTROY   0x03    /* destroy the CIS linked list */
  55 #define CISP_CIS_GET_LTUPLE     0x04    /* get a tuple */
  56 #define CISP_CIS_PARSE_TUPLE    0x05    /* parse a tuple */
  57 #define CISP_CIS_CONV_DEVSPEED  0x06    /* convert devspeed to nS and back */
  58 #define CISP_CIS_CONV_DEVSIZE   0x07    /* convert device size */
  59 
  60 /*
  61  * Make the  calls to CardServices look like function calls.
  62  */
  63 #define CIS_CARD_SERVICES       (*cis_card_services)
  64 
  65 /*
  66  * define the tuples that we recognize
  67  *
  68  * Layer 1 - Basic Compatability TUples
  69  */
  70 #define CISTPL_NULL             0x000   /* null tuple - ignore */
  71 #define CISTPL_DEVICE           0x001   /* device information */
  72 #define CISTPL_LONGLINK_CB      0x002   /* longlink to next tuple chain */
  73 #define CISTPL_CONFIG_CB        0x004   /* configuration tuple */
  74 #define CISTPL_CFTABLE_ENTRY_CB 0x005   /* configuration table entry */
  75 #define CISTPL_LONGLINK_MFC     0x006   /* multi-function tuple */
  76 #define CISTPL_BAR              0x007   /* Base Address Register definition */
  77 #define CISTPL_CHECKSUM         0x010   /* checksum control */
  78 #define CISTPL_LONGLINK_A       0x011   /* long-link to AM */
  79 #define CISTPL_LONGLINK_C       0x012   /* long-link to CM */
  80 #define CISTPL_LINKTARGET       0x013   /* link-target control */
  81 #define CISTPL_NO_LINK          0x014   /* no-link control */
  82 #define CISTPL_VERS_1           0x015   /* level 1 version information */
  83 #define CISTPL_ALTSTR           0x016   /* alternate language string */
  84 #define CISTPL_DEVICE_A         0x017   /* AM device information */
  85 #define CISTPL_JEDEC_C          0x018   /* JEDEC programming info for CM */
  86 #define CISTPL_JEDEC_A          0x019   /* JEDEC programming info for AM */
  87 #define CISTPL_CONFIG           0x01a   /* configuration */
  88 #define CISTPL_CFTABLE_ENTRY    0x01b   /* configuration-table-entry */
  89 #define CISTPL_DEVICE_OC        0x01c   /* other op conditions CM device info */
  90 #define CISTPL_DEVICE_OA        0x01d   /* other op conditions AM device info */
  91 #define CISTPL_DEVICEGEO        0x01e   /* Common Memory device geometry */
  92 #define CISTPL_DEVICEGEO_A      0x01f   /* Attribute Memory device geometry */
  93 #define CISTPL_MANFID           0x020   /* manufacturer identification */
  94 #define CISTPL_FUNCID           0x021   /* function identification */
  95 #define CISTPL_FUNCE            0x022   /* function extension */
  96 
  97 /*
  98  * Layer 2 - Data Recording Format Tuples
  99  */
 100 #define CISTPL_SWIL             0x023   /* software interleave */
 101 #define CISTPL_VERS_2           0x040   /* level 2 version information */
 102 #define CISTPL_FORMAT           0x041   /* Common Memory recording format */
 103 #define CISTPL_GEOMETRY         0x042   /* geometry */
 104 #define CISTPL_BYTEORDER        0x043   /* byte order */
 105 #define CISTPL_DATE             0x044   /* card initialization date */
 106 #define CISTPL_BATTERY          0x045   /* battery replacement date */
 107 #define CISTPL_FORMAT_A         0x047   /* Attribute Memory recording format */
 108 
 109 /*
 110  * Layer 3 - Data Organization Tuples
 111  */
 112 #define CISTPL_ORG              0x046   /* organization */
 113 
 114 /*
 115  * Layer 4 - System Specific Standard Tuples
 116  */
 117 #define CISTPL_VEND_SPEC_80     0x080   /* vendor-specific 0x80 */
 118 #define CISTPL_VEND_SPEC_81     0x081   /* vendor-specific 0x81 */
 119 #define CISTPL_VEND_SPEC_82     0x082   /* vendor-specific 0x82 */
 120 #define CISTPL_VEND_SPEC_83     0x083   /* vendor-specific 0x83 */
 121 #define CISTPL_VEND_SPEC_84     0x084   /* vendor-specific 0x84 */
 122 #define CISTPL_VEND_SPEC_85     0x085   /* vendor-specific 0x85 */
 123 #define CISTPL_VEND_SPEC_86     0x086   /* vendor-specific 0x86 */
 124 #define CISTPL_VEND_SPEC_87     0x087   /* vendor-specific 0x87 */
 125 #define CISTPL_VEND_SPEC_88     0x088   /* vendor-specific 0x88 */
 126 #define CISTPL_VEND_SPEC_89     0x089   /* vendor-specific 0x89 */
 127 #define CISTPL_VEND_SPEC_8a     0x08a   /* vendor-specific 0x8a */
 128 #define CISTPL_VEND_SPEC_8b     0x08b   /* vendor-specific 0x8b */
 129 #define CISTPL_VEND_SPEC_8c     0x08c   /* vendor-specific 0x8c */
 130 #define CISTPL_VEND_SPEC_8d     0x08d   /* vendor-specific 0x8d */
 131 #define CISTPL_VEND_SPEC_8e     0x08e   /* vendor-specific 0x8e */
 132 #define CISTPL_VEND_SPEC_8f     0x08f   /* vendor-specific 0x8f */
 133 #define CISTPL_SPCL             0x090   /* special-purpose tuple */
 134 #define CISTPL_END              0x0ff   /* end-of-list tuple */
 135 
 136 /*
 137  * Macro to check if tuple is a vendor-specific tuple.
 138  */
 139 #define CISTPL_VENDSPEC_START   CISTPL_VEND_SPEC_80
 140 #define CISTPL_VENDSPEC_END     CISTPL_VEND_SPEC_8f
 141 #define CISTPL_IS_VENDOR_SPECIFIC(td)   (((td) >= CISTPL_VENDSPEC_START) &&   \
 142                                                 ((td) <= CISTPL_VENDSPEC_END))
 143 
 144 /*
 145  * The GetFirstTuple and GetNextTuple Card Services function calls use
 146  *      the DesiredTuple member of the tuple_t structure to determine
 147  *      while tuple type to return; since the CIS parser doesn't ever
 148  *      return CISTPL_END tuples, we can never ask for those tuples,
 149  *      so we overload this tuple code to mean that we want the
 150  *      first (or next) tuple in the chain.
 151  * XXX - If we ever do return CISTPL_END tuples, we'll have to
 152  *      re-think this.
 153  */
 154 #define RETURN_FIRST_TUPLE      0x0ff   /* return first/next tuple */
 155 #define RETURN_NEXT_TUPLE       0x0ff   /* return first/next tuple */
 156 
 157 /*
 158  * types for data in CIS and pointers into PC card's CIS space
 159  *
 160  * The "size" member is used by the NEXT_CIS_ADDR macro so that
 161  *      we don't run past the end of the mapped CIS address space.
 162  */
 163 typedef uchar_t cisdata_t;
 164 
 165 typedef struct cisptr_t {
 166     acc_handle_t        handle; /* access handle of CIS space */
 167     uint32_t            size;   /* size of mapped area */
 168     uint32_t            offset; /* byte offset into CIS space */
 169         /* see flag definitions for cistpl_t structure */
 170     uint32_t            flags;
 171 } cisptr_t;
 172 
 173 /*
 174  * This is the maximum length that the data portion of a tuple can be.
 175  *      We have to use this since the brain-damaged 2.01 PCMCIA spec
 176  *      specifies that you can end a CIS chain by putting a CISTPL_END
 177  *      in the link field of the last VALID tuple.
 178  */
 179 #define CIS_MAX_TUPLE_DATA_LEN  254
 180 
 181 /*
 182  * This is the maximum size of the string used to describe the name
 183  *      of the tuple.
 184  */
 185 #define CIS_MAX_TUPLE_NAME_LEN  40
 186 
 187 /*
 188  * CIS_MAX_FUNCTIONS defines the maximum number of functions that can
 189  *      exist on a card.
 190  */
 191 #define CIS_MAX_FUNCTIONS       8       /* max number of functions per card */
 192 
 193 /*
 194  * Macros to manipulate addresses and data in various CIS spaces
 195  *
 196  * NEXT_CIS_ADDR(cisptr_t *) increments the offset to point to the
 197  *      next data element in the CIS, based on what space the CIS
 198  *      we are reading resides in.  If the resulting address would
 199  *      be past the end of the mapped-in area, we return NULL,
 200  *      otherwise the adjusted offset value is returned. Note that
 201  *      this only works if the "size" member specifies the maximum
 202  *      mapped in window size and an "offset" member value of zero
 203  *      refers to the first byte of the window.
 204  *
 205  * GET_CIS_DATA(ptr) returns the data byte at the current CIS location.
 206  *
 207  * GET_CIS_ADDR(tp,ptr) returns the virtual address that was saved by a
 208  *      call to STORE_CIS_ADDR.
 209  *
 210  * BAD_CIS_ADDR is a flag that should be returned by callers of NEXT_CIS_ADDR
 211  *      if that macro returns NULL.  Note that this flag shares the same bit
 212  *      field definitions as the tuple handler flags defined in cis_handlers.h
 213  *      so check that file if you make any changes to these flags.
 214  * XXX - not the best distribution of flags, I'm afraid
 215  */
 216 #define NEXT_CIS_ADDR(ptr)      \
 217                         (((ptr->flags&CISTPLF_AM_SPACE)?(ptr->offset += 2): \
 218                                 (ptr->offset++)),    \
 219                                 ((ptr->offset > ptr->size)?(NULL):ptr->offset))
 220 #define GET_CIS_DATA(ptr)       csx_Get8(ptr->handle, ptr->offset)
 221 #define GET_CIS_ADDR(tp)        ((cisdata_t *)(uintptr_t)(tp)->offset)
 222 #define BAD_CIS_ADDR    0x080000000 /* read past end of mapped CIS error */
 223 
 224 /*
 225  * CIS_MEM_ALLOC(len) is used to allocate memory for our local linked
 226  *      CIS list; we use a macro so that the same code can be used in
 227  *      the kernel as well as in user space
 228  *
 229  * CIS_MEM_FREE(ptr) - same comment as CIS_MEM_ALLOC
 230  */
 231 #if !defined(_KERNEL)
 232 #ifdef  CISMALLOC_DEBUG
 233 #define CIS_MEM_ALLOC(len)              cis_malloc((uint32_t)len)
 234 #define CIS_MEM_FREE(ptr)               cis_free(ptr)
 235 #else
 236 #define CIS_MEM_ALLOC(len)              malloc((uint32_t)len)
 237 #define CIS_MEM_FREE(ptr)               free(ptr)
 238 #endif  /* CISMALLOC_DEBUG */
 239 #else
 240 #define CIS_MEM_ALLOC(len)              cis_malloc((uint32_t)len)
 241 #define CIS_MEM_FREE(ptr)               cis_free(ptr)
 242 #endif
 243 
 244 typedef struct cis_u_malloc_tag_t {
 245         caddr_t         addr;
 246         uint32_t        len;
 247 } cis_u_malloc_tag_t;
 248 
 249 /*
 250  * We keep the tuples in a locally-maintained linked list.  This allows
 251  *      us to return the tuple information at any time to a client for
 252  *      those cards that make their CIS inaccessible once the card is
 253  *      configured.
 254  */
 255 typedef struct cistpl_t {
 256         cisdata_t       type;   /* type of tuple */
 257         cisdata_t       len;    /* length of tuple data */
 258         cisdata_t       *data;  /* data in tuple */
 259         union {
 260                 cisdata_t       *byte;  /* read pointer for GET_BYTE macros */
 261                 uint16_t        *sword;
 262         }               read;
 263         uint32_t        flags;  /* misc flags */
 264         uint32_t        offset; /* CIS address offset of start of tuple */
 265         struct cistpl_t *prev;  /* back pointer */
 266         struct cistpl_t *next;  /* forward pointer */
 267 } cistpl_t;
 268 
 269 /*
 270  * Flags that are used in the cistpl_t and cisptr_t linked lists
 271  */
 272 #define CISTPLF_NOERROR         0x000000000 /* no error return from handler */
 273 #define CISTPLF_UNKNOWN         0x000000001 /* unknown tuple */
 274 #define CISTPLF_REGS            0x000000002 /* tuple contains registers */
 275 #define CISTPLF_COPYOK          0x000000004 /* OK to copy tuple data */
 276 #define CISTPLF_VALID           0x000000008 /* tuple is valid */
 277 #define CISTPLF_GLOBAL_CIS      0x000000010 /* tuple from global CIS */
 278 #define CISTPLF_MF_CIS          0x000000020 /* tuple from MF CIS chain */
 279 #define CISTPLF_FROM_AM         0x000000040 /* tuple read from AM space */
 280 #define CISTPLF_FROM_CM         0x000000080 /* tuple read from CM space */
 281 #define CISTPLF_IGNORE_TUPLE    0x000000100 /* ignore this tuple */
 282 #define CISTPLF_VENDOR_SPECIFIC 0x000000200 /* vnedor-specific tuple */
 283 #define CISTPLF_LINK_INVALID    0x001000000 /* tuple link is invalid */
 284 #define CISTPLF_PARAMS_INVALID  0x002000000 /* tuple body is invalid */
 285 #define CISTPLF_AM_SPACE        0x010000000 /* this tuple is in AM space */
 286 #define CISTPLF_CM_SPACE        0x020000000 /* this tuple is in CM space */
 287 #define CISTPLF_LM_SPACE        0x040000000 /* this tuple is in local memory */
 288 #define CISTPLF_MEM_ERR         0x080000000 /* GET_BYTE macros memory error */
 289 
 290 /*
 291  * Some convienience macros
 292  */
 293 #define CISTPLF_SPACE_MASK      (CISTPLF_AM_SPACE | CISTPLF_CM_SPACE |  \
 294                                                         CISTPLF_LM_SPACE)
 295 #define CISTPLF_FROM_MASK       (CISTPLF_FROM_AM | CISTPLF_FROM_CM)
 296 
 297 /*
 298  * Values used internally on calls to cis_get_ltuple.
 299  *
 300  * The GET_XXX_LTUPLEF and FIND_XXX_XXX values are mutually exclusive,
 301  *      i.e. cis_get_ltuple can only do one of these operations per call.
 302  *
 303  * The other flags are bit flags and they share the flags parameter.
 304  *
 305  *    CIS_GET_LTUPLE_IGNORE - return tuples with CISTPLF_IGNORE_TUPLE
 306  *                              set in cistpl_t->flags
 307  */
 308 #define GET_FIRST_LTUPLEF       0x000000001 /* return first tuple in list */
 309 #define GET_LAST_LTUPLEF        0x000000002 /* return last tuple in list */
 310 #define FIND_LTUPLE_FWDF        0x000000003 /* find tuple, fwd search from tp */
 311 #define FIND_LTUPLE_BACKF       0x000000004 /* find tuple, backward from tp */
 312 #define FIND_NEXT_LTUPLEF       0x000000005 /* find tuple, fwd from tp+1 */
 313 #define FIND_PREV_LTUPLEF       0x000000006 /* find tuple, backward from tp-1 */
 314 #define GET_NEXT_LTUPLEF        0x000000007 /* return next tuple in list */
 315 #define GET_PREV_LTUPLEF        0x000000008 /* return prev tuple in list */
 316 #define CIS_GET_LTUPLE_OPMASK   0x00000ffff /* mask for operation values */
 317 #define CIS_GET_LTUPLE_IGNORE   0x000010000 /* return ignored tuples */
 318 
 319 /*
 320  * macros for getting various data types out of a tuple
 321  * Note that due to the modem tuple using a few big-endian values,
 322  * we have to support both big and little endian macros
 323  *
 324  * Common Memory Specific macros - these will also work for tuples in
 325  *      local memory
 326  */
 327 #define GET_CM_BYTE(tp) (((size_t)(tp)->len >= \
 328                                 ((uintptr_t)(tp)->read.byte - \
 329                                         (uintptr_t)(tp)->data)) ? \
 330                          *(tp)->read.byte++ : ((tp)->flags |= CISTPLF_MEM_ERR))
 331 #define GET_CM_LEN(tp)  ((size_t)(tp)->len - \
 332                                 ((uintptr_t)(tp)->read.byte - \
 333                                 (uintptr_t)(tp)->data))
 334 
 335 /* Attribute Memory Specific macros */
 336 #define GET_AM_BYTE(tp) (((size_t)(tp)->len >= \
 337                                 (((uintptr_t)(tp)->read.byte - \
 338                                         (uintptr_t)(tp)->data))>>1) ? \
 339                          *(cisdata_t *)(tp)->read.sword++ : \
 340                                 ((tp)->flags |= CISTPLF_MEM_ERR))
 341 #define GET_AM_LEN(tp)  ((size_t)(tp)->len - (((uintptr_t)(tp)->read.byte - \
 342                                 (uintptr_t)(tp)->data) >> 1))
 343 
 344 /* generic macros */
 345 #define RESET_TP(tp)    (tp)->read.byte = (tp)->data
 346 #define LOOK_BYTE(tp)   *(tp)->read.byte
 347 #define GET_BYTE_ADDR(tp) (tp)->read.byte
 348 
 349 #define GET_BYTE(tp)    (((tp)->flags & CISTPLF_AM_SPACE) ? \
 350                                 GET_AM_BYTE(tp) : GET_CM_BYTE(tp))
 351 #define GET_SHORT(tp)           cis_get_short(tp)
 352 #define GET_BE_SHORT(tp)        cis_get_be_short(tp)
 353 #define GET_INT24(tp)           cis_get_int24(tp)
 354 #define GET_LONG(tp)            cis_get_long(tp)
 355 #define GET_LEN(tp)     (((tp)->flags & CISTPLF_AM_SPACE) ? \
 356                                 GET_AM_LEN(tp) : GET_CM_LEN(tp))
 357 
 358 /*
 359  * cistpl_ignore_list_t - this structure describes tuples in the global
 360  *                              CIS list that we want to ignore if they
 361  *                              also show up in a function-specific CIS.
 362  */
 363 typedef struct cistpl_ignore_list_t {
 364         cisdata_t       type;
 365 } cistpl_ignore_list_t;
 366 
 367 #ifdef  __cplusplus
 368 }
 369 #endif
 370 
 371 #endif  /* _CIS_H */