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 /*
  23  * Copyright 2008-2013 Solarflare Communications Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _SYS_EFSYS_H
  28 #define _SYS_EFSYS_H
  29 
  30 #ifdef  __cplusplus
  31 extern "C" {
  32 #endif
  33 
  34 #include <sys/types.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/cpuvar.h>
  39 #include <sys/disp.h>
  40 #include <sys/sdt.h>
  41 #include <sys/kstat.h>
  42 #include <sys/crc32.h>
  43 #include <sys/note.h>
  44 #include <sys/byteorder.h>
  45 
  46 #define EFSYS_HAS_UINT64 1
  47 #define EFSYS_USE_UINT64 0
  48 #ifdef  _BIG_ENDIAN
  49 #define EFSYS_IS_BIG_ENDIAN 1
  50 #endif
  51 #ifdef  _LITTLE_ENDIAN
  52 #define EFSYS_IS_LITTLE_ENDIAN 1
  53 #endif
  54 #include "efx_types.h"
  55 
  56 #ifdef _USE_GLD_V3_SOL10
  57 #include "compat.h"
  58 #endif
  59 
  60 /* Modifiers used for DOS builds */
  61 #define __cs
  62 #define __far
  63 
  64 /* Modifiers used for Windows builds */
  65 #define __in
  66 #define __in_opt
  67 #define __in_ecount(_n)
  68 #define __in_ecount_opt(_n)
  69 #define __in_bcount(_n)
  70 #define __in_bcount_opt(_n)
  71 
  72 #define __out
  73 #define __out_opt
  74 #define __out_ecount(_n)
  75 #define __out_ecount_opt(_n)
  76 #define __out_bcount(_n)
  77 #define __out_bcount_opt(_n)
  78 
  79 #define __deref_out
  80 
  81 #define __inout
  82 #define __inout_opt
  83 #define __inout_ecount(_n)
  84 #define __inout_ecount_opt(_n)
  85 #define __inout_bcount(_n)
  86 #define __inout_bcount_opt(_n)
  87 #define __inout_bcount_full_opt(_n)
  88 
  89 #define __deref_out_bcount_opt(n)
  90 
  91 #define __checkReturn
  92 
  93 #define __drv_when(_p, _c)
  94 
  95 /* Code inclusion options */
  96 
  97 
  98 #define EFSYS_OPT_NAMES 1
  99 
 100 #define EFSYS_OPT_FALCON 1
 101 #define EFSYS_OPT_SIENA 1
 102 #if DEBUG
 103 #define EFSYS_OPT_CHECK_REG 1
 104 #else
 105 #define EFSYS_OPT_CHECK_REG 0
 106 #endif
 107 
 108 #define EFSYS_OPT_MCDI 1
 109 
 110 #define EFSYS_OPT_MAC_FALCON_GMAC 1
 111 #define EFSYS_OPT_MAC_FALCON_XMAC 1
 112 #define EFSYS_OPT_MAC_STATS 1
 113 
 114 #define EFSYS_OPT_LOOPBACK 1
 115 
 116 #define EFSYS_OPT_MON_NULL 1
 117 #define EFSYS_OPT_MON_LM87 1
 118 #define EFSYS_OPT_MON_MAX6647 1
 119 #define EFSYS_OPT_MON_SIENA 1
 120 #define EFSYS_OPT_MON_STATS 1
 121 
 122 #define EFSYS_OPT_PHY_NULL 1
 123 #define EFSYS_OPT_PHY_QT2022C2 1
 124 #define EFSYS_OPT_PHY_SFX7101 1
 125 #define EFSYS_OPT_PHY_TXC43128 1
 126 #define EFSYS_OPT_PHY_PM8358 1
 127 #define EFSYS_OPT_PHY_SFT9001 1
 128 #define EFSYS_OPT_PHY_QT2025C 1
 129 #define EFSYS_OPT_PHY_STATS 1
 130 #define EFSYS_OPT_PHY_PROPS 1
 131 #define EFSYS_OPT_PHY_BIST 1
 132 #define EFSYS_OPT_PHY_LED_CONTROL 1
 133 
 134 #define EFSYS_OPT_VPD 1
 135 #define EFSYS_OPT_NVRAM 1
 136 #define EFSYS_OPT_NVRAM_FALCON_BOOTROM 1
 137 #define EFSYS_OPT_NVRAM_SFT9001 0
 138 #define EFSYS_OPT_NVRAM_SFX7101 0
 139 #define EFSYS_OPT_BOOTCFG 1
 140 
 141 #define EFSYS_OPT_PCIE_TUNE 1
 142 #define EFSYS_OPT_DIAG 1
 143 #define EFSYS_OPT_WOL 1
 144 #define EFSYS_OPT_RX_SCALE 1
 145 #define EFSYS_OPT_QSTATS 1
 146 
 147 #define EFSYS_OPT_EV_PREFETCH 0
 148 
 149 #define EFSYS_OPT_DECODE_INTR_FATAL 1
 150 
 151 /* ID */
 152 
 153 typedef struct __efsys_identifier_s     efsys_identifier_t;
 154 
 155 /* DMA */
 156 
 157 typedef uint64_t                efsys_dma_addr_t;
 158 
 159 typedef struct efsys_mem_s {
 160         ddi_dma_handle_t        esm_dma_handle; /* DMA memory allocate/bind */
 161         ddi_acc_handle_t        esm_acc_handle; /* DMA memory read/write */
 162         caddr_t                 esm_base;
 163         efsys_dma_addr_t        esm_addr;
 164         size_t                  esm_size;
 165 } efsys_mem_t;
 166 
 167 
 168 #define EFSYS_MEM_ZERO(_esmp, _size)                                    \
 169         do {                                                            \
 170                 (void) memset((_esmp)->esm_base, 0, (_size));                \
 171                                                                         \
 172         _NOTE(CONSTANTCONDITION)                                        \
 173         } while (B_FALSE)
 174 
 175 #define EFSYS_MEM_READD(_esmp, _offset, _edp)                           \
 176         do {                                                            \
 177                 uint32_t *addr;                                         \
 178                                                                         \
 179                 _NOTE(CONSTANTCONDITION)                                \
 180                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 181                                                                         \
 182                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 183                                                                         \
 184                 (_edp)->ed_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 185                     addr);                                              \
 186                                                                         \
 187                 DTRACE_PROBE2(mem_readd, unsigned int, (_offset),       \
 188                     uint32_t, (_edp)->ed_u32[0]);                    \
 189                                                                         \
 190         _NOTE(CONSTANTCONDITION)                                        \
 191         } while (B_FALSE)
 192 
 193 #define EFSYS_MEM_READQ(_esmp, _offset, _eqp)                           \
 194         do {                                                            \
 195                 uint32_t *addr;                                         \
 196                                                                         \
 197                 _NOTE(CONSTANTCONDITION)                                \
 198                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 199                                                                         \
 200                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 201                                                                         \
 202                 (_eqp)->eq_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 203                     addr++);                                            \
 204                 (_eqp)->eq_u32[1] = ddi_get32((_esmp)->esm_acc_handle,    \
 205                     addr);                                              \
 206                                                                         \
 207                 DTRACE_PROBE3(mem_readq, unsigned int, (_offset),       \
 208                     uint32_t, (_eqp)->eq_u32[1],                     \
 209                     uint32_t, (_eqp)->eq_u32[0]);                    \
 210                                                                         \
 211         _NOTE(CONSTANTCONDITION)                                        \
 212         } while (B_FALSE)
 213 
 214 #define EFSYS_MEM_READO(_esmp, _offset, _eop)                           \
 215         do {                                                            \
 216                 uint32_t *addr;                                         \
 217                                                                         \
 218                 _NOTE(CONSTANTCONDITION)                                \
 219                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 220                                                                         \
 221                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 222                                                                         \
 223                 (_eop)->eo_u32[0] = ddi_get32((_esmp)->esm_acc_handle,    \
 224                     addr++);                                            \
 225                 (_eop)->eo_u32[1] = ddi_get32((_esmp)->esm_acc_handle,    \
 226                     addr++);                                            \
 227                 (_eop)->eo_u32[2] = ddi_get32((_esmp)->esm_acc_handle,    \
 228                     addr++);                                            \
 229                 (_eop)->eo_u32[3] = ddi_get32((_esmp)->esm_acc_handle,    \
 230                     addr);                                              \
 231                                                                         \
 232                 DTRACE_PROBE5(mem_reado, unsigned int, (_offset),       \
 233                     uint32_t, (_eop)->eo_u32[3],                     \
 234                     uint32_t, (_eop)->eo_u32[2],                     \
 235                     uint32_t, (_eop)->eo_u32[1],                     \
 236                     uint32_t, (_eop)->eo_u32[0]);                    \
 237                                                                         \
 238         _NOTE(CONSTANTCONDITION)                                        \
 239         } while (B_FALSE)
 240 
 241 #define EFSYS_MEM_WRITED(_esmp, _offset, _edp)                          \
 242         do {                                                            \
 243                 uint32_t *addr;                                         \
 244                                                                         \
 245                 _NOTE(CONSTANTCONDITION)                                \
 246                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 247                                                                         \
 248                 DTRACE_PROBE2(mem_writed, unsigned int, (_offset),      \
 249                     uint32_t, (_edp)->ed_u32[0]);                    \
 250                                                                         \
 251                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 252                                                                         \
 253                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 254                     (_edp)->ed_u32[0]);                                      \
 255                                                                         \
 256         _NOTE(CONSTANTCONDITION)                                        \
 257         } while (B_FALSE)
 258 
 259 #define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp)                          \
 260         do {                                                            \
 261                 uint32_t *addr;                                         \
 262                                                                         \
 263                 _NOTE(CONSTANTCONDITION)                                \
 264                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 265                                                                         \
 266                 DTRACE_PROBE3(mem_writeq, unsigned int, (_offset),      \
 267                     uint32_t, (_eqp)->eq_u32[1],                     \
 268                     uint32_t, (_eqp)->eq_u32[0]);                    \
 269                                                                         \
 270                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 271                                                                         \
 272                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 273                     (_eqp)->eq_u32[0]);                                      \
 274                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 275                     (_eqp)->eq_u32[1]);                                      \
 276                                                                         \
 277         _NOTE(CONSTANTCONDITION)                                        \
 278         } while (B_FALSE)
 279 
 280 #define EFSYS_MEM_WRITEO(_esmp, _offset, _eop)                          \
 281         do {                                                            \
 282                 uint32_t *addr;                                         \
 283                                                                         \
 284                 _NOTE(CONSTANTCONDITION)                                \
 285                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 286                                                                         \
 287                 DTRACE_PROBE5(mem_writeo, unsigned int, (_offset),      \
 288                     uint32_t, (_eop)->eo_u32[3],                     \
 289                     uint32_t, (_eop)->eo_u32[2],                     \
 290                     uint32_t, (_eop)->eo_u32[1],                     \
 291                     uint32_t, (_eop)->eo_u32[0]);                    \
 292                                                                         \
 293                 addr = (void *)((_esmp)->esm_base + (_offset));              \
 294                                                                         \
 295                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 296                     (_eop)->eo_u32[0]);                                      \
 297                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 298                     (_eop)->eo_u32[1]);                                      \
 299                 ddi_put32((_esmp)->esm_acc_handle, addr++,           \
 300                     (_eop)->eo_u32[2]);                                      \
 301                 ddi_put32((_esmp)->esm_acc_handle, addr,             \
 302                     (_eop)->eo_u32[3]);                                      \
 303                                                                         \
 304         _NOTE(CONSTANTCONDITION)                                        \
 305         } while (B_FALSE)
 306 
 307 #define EFSYS_MEM_ADDR(_esmp)                                           \
 308         ((_esmp)->esm_addr)
 309 
 310 /* BAR */
 311 
 312 typedef struct efsys_bar_s {
 313         kmutex_t                esb_lock;
 314         ddi_acc_handle_t        esb_handle;
 315         caddr_t                 esb_base;
 316 } efsys_bar_t;
 317 
 318 #define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock)                    \
 319         do {                                                            \
 320                 uint32_t *addr;                                         \
 321                                                                         \
 322                 _NOTE(CONSTANTCONDITION)                                \
 323                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 324                                                                         \
 325                 _NOTE(CONSTANTCONDITION)                                \
 326                 if (_lock)                                              \
 327                         mutex_enter(&((_esbp)->esb_lock));               \
 328                                                                         \
 329                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 330                                                                         \
 331                 (_edp)->ed_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 332                     addr);                                              \
 333                                                                         \
 334                 DTRACE_PROBE2(bar_readd, unsigned int, (_offset),       \
 335                     uint32_t, (_edp)->ed_u32[0]);                    \
 336                                                                         \
 337                 _NOTE(CONSTANTCONDITION)                                \
 338                 if (_lock)                                              \
 339                         mutex_exit(&((_esbp)->esb_lock));                \
 340         _NOTE(CONSTANTCONDITION)                                        \
 341         } while (B_FALSE)
 342 
 343 #define EFSYS_BAR_READQ(_esbp, _offset, _eqp)                           \
 344         do {                                                            \
 345                 uint32_t *addr;                                         \
 346                                                                         \
 347                 _NOTE(CONSTANTCONDITION)                                \
 348                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 349                                                                         \
 350                 mutex_enter(&((_esbp)->esb_lock));                       \
 351                                                                         \
 352                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 353                                                                         \
 354                 (_eqp)->eq_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 355                     addr++);                                            \
 356                 (_eqp)->eq_u32[1] = ddi_get32((_esbp)->esb_handle,        \
 357                     addr);                                              \
 358                                                                         \
 359                 DTRACE_PROBE3(bar_readq, unsigned int, (_offset),       \
 360                     uint32_t, (_eqp)->eq_u32[1],                     \
 361                     uint32_t, (_eqp)->eq_u32[0]);                    \
 362                                                                         \
 363                 mutex_exit(&((_esbp)->esb_lock));                        \
 364         _NOTE(CONSTANTCONDITION)                                        \
 365         } while (B_FALSE)
 366 
 367 #define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock)                    \
 368         do {                                                            \
 369                 uint32_t *addr;                                         \
 370                                                                         \
 371                 _NOTE(CONSTANTCONDITION)                                \
 372                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 373                                                                         \
 374                 _NOTE(CONSTANTCONDITION)                                \
 375                 if (_lock)                                              \
 376                         mutex_enter(&((_esbp)->esb_lock));               \
 377                                                                         \
 378                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 379                                                                         \
 380                 (_eop)->eo_u32[0] = ddi_get32((_esbp)->esb_handle,        \
 381                     addr++);                                            \
 382                 (_eop)->eo_u32[1] = ddi_get32((_esbp)->esb_handle,        \
 383                     addr++);                                            \
 384                 (_eop)->eo_u32[2] = ddi_get32((_esbp)->esb_handle,        \
 385                     addr++);                                            \
 386                 (_eop)->eo_u32[3] = ddi_get32((_esbp)->esb_handle,        \
 387                     addr);                                              \
 388                                                                         \
 389                 DTRACE_PROBE5(bar_reado, unsigned int, (_offset),       \
 390                     uint32_t, (_eop)->eo_u32[3],                     \
 391                     uint32_t, (_eop)->eo_u32[2],                     \
 392                     uint32_t, (_eop)->eo_u32[1],                     \
 393                     uint32_t, (_eop)->eo_u32[0]);                    \
 394                                                                         \
 395                 _NOTE(CONSTANTCONDITION)                                \
 396                 if (_lock)                                              \
 397                         mutex_exit(&((_esbp)->esb_lock));                \
 398         _NOTE(CONSTANTCONDITION)                                        \
 399         } while (B_FALSE)
 400 
 401 #define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock)                   \
 402         do {                                                            \
 403                 uint32_t *addr;                                         \
 404                                                                         \
 405                 _NOTE(CONSTANTCONDITION)                                \
 406                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_dword_t)));    \
 407                                                                         \
 408                 _NOTE(CONSTANTCONDITION)                                \
 409                 if (_lock)                                              \
 410                         mutex_enter(&((_esbp)->esb_lock));               \
 411                                                                         \
 412                 DTRACE_PROBE2(bar_writed, unsigned int, (_offset),      \
 413                     uint32_t, (_edp)->ed_u32[0]);                    \
 414                                                                         \
 415                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 416                                                                         \
 417                 ddi_put32((_esbp)->esb_handle, addr,                 \
 418                     (_edp)->ed_u32[0]);                                      \
 419                                                                         \
 420                 _NOTE(CONSTANTCONDITION)                                \
 421                 if (_lock)                                              \
 422                         mutex_exit(&((_esbp)->esb_lock));                \
 423         _NOTE(CONSTANTCONDITION)                                        \
 424         } while (B_FALSE)
 425 
 426 #define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp)                          \
 427         do {                                                            \
 428                 uint32_t *addr;                                         \
 429                                                                         \
 430                 _NOTE(CONSTANTCONDITION)                                \
 431                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)));    \
 432                                                                         \
 433                 mutex_enter(&((_esbp)->esb_lock));                       \
 434                                                                         \
 435                 DTRACE_PROBE3(bar_writeq, unsigned int, (_offset),      \
 436                     uint32_t, (_eqp)->eq_u32[1],                     \
 437                     uint32_t, (_eqp)->eq_u32[0]);                    \
 438                                                                         \
 439                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 440                                                                         \
 441                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 442                     (_eqp)->eq_u32[0]);                                      \
 443                 ddi_put32((_esbp)->esb_handle, addr,                 \
 444                     (_eqp)->eq_u32[1]);                                      \
 445                                                                         \
 446                 mutex_exit(&((_esbp)->esb_lock));                        \
 447         _NOTE(CONSTANTCONDITION)                                        \
 448         } while (B_FALSE)
 449 
 450 #define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock)                   \
 451         do {                                                            \
 452                 uint32_t *addr;                                         \
 453                                                                         \
 454                 _NOTE(CONSTANTCONDITION)                                \
 455                 ASSERT(IS_P2ALIGNED(_offset, sizeof (efx_oword_t)));    \
 456                                                                         \
 457                 _NOTE(CONSTANTCONDITION)                                \
 458                 if (_lock)                                              \
 459                         mutex_enter(&((_esbp)->esb_lock));               \
 460                                                                         \
 461                 DTRACE_PROBE5(bar_writeo, unsigned int, (_offset),      \
 462                     uint32_t, (_eop)->eo_u32[3],                     \
 463                     uint32_t, (_eop)->eo_u32[2],                     \
 464                     uint32_t, (_eop)->eo_u32[1],                     \
 465                     uint32_t, (_eop)->eo_u32[0]);                    \
 466                                                                         \
 467                 addr = (void *)((_esbp)->esb_base + (_offset));              \
 468                                                                         \
 469                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 470                     (_eop)->eo_u32[0]);                                      \
 471                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 472                     (_eop)->eo_u32[1]);                                      \
 473                 ddi_put32((_esbp)->esb_handle, addr++,                       \
 474                     (_eop)->eo_u32[2]);                                      \
 475                 ddi_put32((_esbp)->esb_handle, addr,                 \
 476                     (_eop)->eo_u32[3]);                                      \
 477                                                                         \
 478                 _NOTE(CONSTANTCONDITION)                                \
 479                 if (_lock)                                              \
 480                         mutex_exit(&((_esbp)->esb_lock));                \
 481         _NOTE(CONSTANTCONDITION)                                        \
 482         } while (B_FALSE)
 483 
 484 /* SPIN */
 485 
 486 #define EFSYS_SPIN(_us)                                                 \
 487         do {                                                            \
 488                 drv_usecwait(_us);                                      \
 489         _NOTE(CONSTANTCONDITION)                                        \
 490         } while (B_FALSE)
 491 
 492 #define EFSYS_SLEEP     EFSYS_SPIN
 493 
 494 /* BARRIERS */
 495 
 496 /* Strict ordering guaranteed by devacc.devacc_attr_dataorder */
 497 #define EFSYS_MEM_READ_BARRIER()        membar_consumer()
 498 /* TODO: Is ddi_put32() properly barriered? */
 499 #define EFSYS_PIO_WRITE_BARRIER()
 500 
 501 /* TIMESTAMP */
 502 
 503 typedef clock_t efsys_timestamp_t;
 504 
 505 #define EFSYS_TIMESTAMP(_usp)                                           \
 506         do {                                                            \
 507                 clock_t now;                                            \
 508                                                                         \
 509                 now = ddi_get_lbolt();                                  \
 510                 *(_usp) = drv_hztousec(now);                            \
 511         _NOTE(CONSTANTCONDITION)                                        \
 512         } while (B_FALSE)
 513 
 514 /* KMEM */
 515 
 516 #define EFSYS_KMEM_ALLOC(_esip, _size, _p)                              \
 517         do {                                                            \
 518                 (_esip) = (_esip);                                      \
 519                 (_p) = kmem_zalloc((_size), KM_NOSLEEP);                \
 520         _NOTE(CONSTANTCONDITION)                                        \
 521         } while (B_FALSE)
 522 
 523 #define EFSYS_KMEM_FREE(_esip, _size, _p)                               \
 524         do {                                                            \
 525                 (_esip) = (_esip);                                      \
 526                 kmem_free((_p), (_size));                               \
 527         _NOTE(CONSTANTCONDITION)                                        \
 528         } while (B_FALSE)
 529 
 530 /* LOCK */
 531 
 532 typedef kmutex_t        efsys_lock_t;
 533 
 534 #define EFSYS_LOCK_MAGIC        0x000010c4
 535 
 536 #define EFSYS_LOCK(_lockp, _state)                                      \
 537         do {                                                            \
 538                 mutex_enter(_lockp);                                    \
 539                 (_state) = EFSYS_LOCK_MAGIC;                            \
 540         _NOTE(CONSTANTCONDITION)                                        \
 541         } while (B_FALSE)
 542 
 543 #define EFSYS_UNLOCK(_lockp, _state)                                    \
 544         do {                                                            \
 545                 if ((_state) != EFSYS_LOCK_MAGIC)                       \
 546                         ASSERT(B_FALSE);                                \
 547                 mutex_exit(_lockp);                                     \
 548         _NOTE(CONSTANTCONDITION)                                        \
 549         } while (B_FALSE)
 550 
 551 /* PREEMPT */
 552 
 553 #define EFSYS_PREEMPT_DISABLE(_state)                                   \
 554         do {                                                            \
 555                 (_state) = ddi_enter_critical();                        \
 556         _NOTE(CONSTANTCONDITION)                                        \
 557         } while (B_FALSE)
 558 
 559 #define EFSYS_PREEMPT_ENABLE(_state)                                    \
 560         do {                                                            \
 561                 ddi_exit_critical(_state);                              \
 562         _NOTE(CONSTANTCONDITION)                                        \
 563         } while (B_FALSE)
 564 
 565 /* STAT */
 566 
 567 typedef kstat_named_t           efsys_stat_t;
 568 
 569 #define EFSYS_STAT_INCR(_knp, _delta)                                   \
 570         do {                                                            \
 571                 ((_knp)->value.ui64) += (_delta);                    \
 572         _NOTE(CONSTANTCONDITION)                                        \
 573         } while (B_FALSE)
 574 
 575 #define EFSYS_STAT_DECR(_knp, _delta)                                   \
 576         do {                                                            \
 577                 ((_knp)->value.ui64) -= (_delta);                    \
 578         _NOTE(CONSTANTCONDITION)                                        \
 579         } while (B_FALSE)
 580 
 581 #define EFSYS_STAT_SET(_knp, _val)                                      \
 582         do {                                                            \
 583                 ((_knp)->value.ui64) = (_val);                               \
 584         _NOTE(CONSTANTCONDITION)                                        \
 585         } while (B_FALSE)
 586 
 587 #define EFSYS_STAT_SET_QWORD(_knp, _valp)                               \
 588         do {                                                            \
 589                 ((_knp)->value.ui64) = LE_64((_valp)->eq_u64[0]); \
 590         _NOTE(CONSTANTCONDITION)                                        \
 591         } while (B_FALSE)
 592 
 593 #define EFSYS_STAT_SET_DWORD(_knp, _valp)                               \
 594         do {                                                            \
 595                 ((_knp)->value.ui64) = LE_32((_valp)->ed_u32[0]); \
 596         _NOTE(CONSTANTCONDITION)                                        \
 597         } while (B_FALSE)
 598 
 599 #define EFSYS_STAT_INCR_QWORD(_knp, _valp)                              \
 600         do {                                                            \
 601                 ((_knp)->value.ui64) += LE_64((_valp)->eq_u64[0]);        \
 602         _NOTE(CONSTANTCONDITION)                                        \
 603         } while (B_FALSE)
 604 
 605 #define EFSYS_STAT_SUBR_QWORD(_knp, _valp)                              \
 606         do {                                                            \
 607                 ((_knp)->value.ui64) -= LE_64((_valp)->eq_u64[0]);        \
 608         _NOTE(CONSTANTCONDITION)                                        \
 609         } while (B_FALSE)
 610 
 611 /* ERR */
 612 
 613 extern void     sfxge_err(efsys_identifier_t *, unsigned int,
 614                     uint32_t, uint32_t);
 615 
 616 #if EFSYS_OPT_DECODE_INTR_FATAL
 617 #define EFSYS_ERR(_esip, _code, _dword0, _dword1)                       \
 618         do {                                                            \
 619                 sfxge_err((_esip), (_code), (_dword0), (_dword1));      \
 620         _NOTE(CONSTANTCONDITION)                                        \
 621         } while (B_FALSE)
 622 #endif
 623 
 624 /* PROBE */
 625 
 626 #define EFSYS_PROBE(_name)                                              \
 627         DTRACE_PROBE(_name)
 628 
 629 #define EFSYS_PROBE1(_name, _type1, _arg1)                              \
 630         DTRACE_PROBE1(_name, _type1, _arg1)
 631 
 632 #define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2)               \
 633         DTRACE_PROBE2(_name, _type1, _arg1, _type2, _arg2)
 634 
 635 #define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2,               \
 636             _type3, _arg3)                                              \
 637         DTRACE_PROBE3(_name, _type1, _arg1, _type2, _arg2,              \
 638             _type3, _arg3)
 639 
 640 #define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2,               \
 641             _type3, _arg3, _type4, _arg4)                               \
 642         DTRACE_PROBE4(_name, _type1, _arg1, _type2, _arg2,              \
 643             _type3, _arg3, _type4, _arg4)
 644 
 645 #define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2,               \
 646             _type3, _arg3, _type4, _arg4, _type5, _arg5)                \
 647         DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2,              \
 648             _type3, _arg3, _type4, _arg4, _type5, _arg5)
 649 
 650 #ifdef DTRACE_PROBE6
 651 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
 652             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 653             _type6, _arg6)                                              \
 654         DTRACE_PROBE6(_name, _type1, _arg1, _type2, _arg2,              \
 655             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 656             _type6, _arg6)
 657 #else
 658 #define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2,               \
 659             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 660             _type6, _arg6)                                              \
 661         DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2,              \
 662             _type3, _arg3, _type4, _arg4, _type5, _arg5)
 663 #endif
 664 
 665 #ifdef DTRACE_PROBE7
 666 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
 667             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 668             _type6, _arg6, _type7, _arg7)                               \
 669         DTRACE_PROBE7(_name, _type1, _arg1, _type2, _arg2,              \
 670             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 671             _type6, _arg6, _type7, _arg7)
 672 #else
 673 #define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2,               \
 674             _type3, _arg3, _type4, _arg4, _type5, _arg5,                \
 675             _type6, _arg6, _type7, _arg7)                               \
 676         DTRACE_PROBE5(_name, _type1, _arg1, _type2, _arg2,              \
 677             _type3, _arg3, _type4, _arg4, _type5, _arg5)
 678 #endif
 679 
 680 /* ASSERT */
 681 
 682 #define EFSYS_ASSERT(_exp)              ASSERT(_exp)
 683 #define EFSYS_ASSERT3U(_x, _op, _y)     ASSERT3U(_x, _op, _y)
 684 #define EFSYS_ASSERT3S(_x, _op, _y)     ASSERT3S(_x, _op, _y)
 685 #define EFSYS_ASSERT3P(_x, _op, _y)     ASSERT3P(_x, _op, _y)
 686 
 687 #ifdef  __cplusplus
 688 }
 689 #endif
 690 
 691 #endif  /* _SYS_EFSYS_H */