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 2004 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _SYS_ECPPVAR_H
  28 #define _SYS_ECPPVAR_H
  29 
  30 #include <sys/note.h>
  31 #include <sys/sysmacros.h>
  32 
  33 #ifdef  __cplusplus
  34 extern "C" {
  35 #endif
  36 
  37 struct ecppunit;
  38 
  39 /*
  40  * Hardware-abstraction structure
  41  */
  42 struct ecpp_hw {
  43         int     (*map_regs)(struct ecppunit *);         /* map registers */
  44         void    (*unmap_regs)(struct ecppunit *);       /* unmap registers */
  45         int     (*config_chip)(struct ecppunit *);      /* configure SuperIO */
  46         void    (*config_mode)(struct ecppunit *);      /* config new mode */
  47         void    (*mask_intr)(struct ecppunit *);        /* mask interrupts */
  48         void    (*unmask_intr)(struct ecppunit *);      /* unmask interrupts */
  49         int     (*dma_start)(struct ecppunit *);        /* start DMA transfer */
  50         int     (*dma_stop)(struct ecppunit *, size_t *); /* stop DMA xfer */
  51         size_t  (*dma_getcnt)(struct ecppunit *);       /* get DMA counter */
  52         ddi_dma_attr_t  *attr;                          /* DMA attributes */
  53 };
  54 
  55 #define ECPP_MAP_REGS(pp)               (pp)->hw->map_regs(pp)
  56 #define ECPP_UNMAP_REGS(pp)             (pp)->hw->unmap_regs(pp)
  57 #define ECPP_CONFIG_CHIP(pp)            (pp)->hw->config_chip(pp)
  58 #define ECPP_CONFIG_MODE(pp)            (pp)->hw->config_mode(pp)
  59 #define ECPP_MASK_INTR(pp)              (pp)->hw->mask_intr(pp)
  60 #define ECPP_UNMASK_INTR(pp)            (pp)->hw->unmask_intr(pp)
  61 #define ECPP_DMA_START(pp)              (pp)->hw->dma_start(pp)
  62 #define ECPP_DMA_STOP(pp, cnt)          (pp)->hw->dma_stop(pp, cnt)
  63 #define ECPP_DMA_GETCNT(pp)             (pp)->hw->dma_getcnt(pp)
  64 
  65 /* NSC 87332/97317 and EBus DMAC */
  66 struct ecpp_ebus {
  67         struct config_reg       *c_reg;         /* configuration registers */
  68         ddi_acc_handle_t        c_handle;       /* handle for conf regs */
  69         struct cheerio_dma_reg  *dmac;          /* ebus dmac registers */
  70         ddi_acc_handle_t        d_handle;       /* handle for dmac registers */
  71         struct config2_reg      *c2_reg;        /* 97317 2nd level conf regs */
  72         ddi_acc_handle_t        c2_handle;      /* handle for c2_reg */
  73 };
  74 
  75 /* Southbridge SuperIO and 8237 DMAC */
  76 struct ecpp_m1553 {
  77         struct isaspace         *isa_space;     /* all of isa space */
  78         ddi_acc_handle_t        d_handle;       /* handle for isa space */
  79         uint8_t                 chn;            /* 8237 dma channel */
  80         int                     isadma_entered; /* Southbridge DMA workaround */
  81 };
  82 
  83 #if defined(__x86)
  84 struct ecpp_x86 {
  85         uint8_t                 chn;
  86 };
  87 #endif
  88 
  89 /*
  90  * Hardware binding structure
  91  */
  92 struct ecpp_hw_bind {
  93         char            *name;          /* binding name */
  94         struct ecpp_hw  *hw;            /* hw description */
  95         char            *info;          /* info string */
  96 };
  97 
  98 /* ecpp e_busy states */
  99 typedef enum {
 100         ECPP_IDLE = 1,  /* No ongoing transfers */
 101         ECPP_BUSY = 2,  /* Ongoing transfers on the cable */
 102         ECPP_DATA = 3,  /* Not used */
 103         ECPP_ERR = 4,   /* Bad status in Centronics mode */
 104         ECPP_FLUSH = 5  /* Currently flushing the q */
 105 } ecpp_busy_t;
 106 
 107 /*
 108  * ecpp soft state structure
 109  */
 110 struct ecppunit {
 111         kmutex_t        umutex;         /* lock for this structure */
 112         int             instance;       /* instance number */
 113         dev_info_t      *dip;           /* device information */
 114         ddi_iblock_cookie_t ecpp_trap_cookie;   /* interrupt cookie */
 115         ecpp_busy_t     e_busy;         /* ecpp busy flag */
 116         kcondvar_t      pport_cv;       /* cv to signal idle state */
 117         /*
 118          * common SuperIO registers
 119          */
 120         struct info_reg         *i_reg;         /* info registers */
 121         struct fifo_reg         *f_reg;         /* fifo register */
 122         ddi_acc_handle_t        i_handle;
 123         ddi_acc_handle_t        f_handle;
 124         /*
 125          * DMA support
 126          */
 127         ddi_dma_handle_t        dma_handle;     /* DMA handle */
 128         ddi_dma_cookie_t        dma_cookie;     /* current cookie */
 129         uint_t                  dma_cookie_count;       /* # of cookies */
 130         uint_t                  dma_nwin;       /* # of DMA windows */
 131         uint_t                  dma_curwin;     /* current window number */
 132         uint_t                  dma_dir;        /* transfer direction */
 133         /*
 134          * hardware-dependent stuff
 135          */
 136         struct ecpp_hw  *hw;            /* operations/attributes */
 137         union {                         /* hw-dependent data */
 138                 struct ecpp_ebus        ebus;
 139                 struct ecpp_m1553       m1553;
 140 #if defined(__x86)
 141                 struct ecpp_x86         x86;
 142 #endif
 143         } uh;
 144         /*
 145          * DDI/STREAMS stuff
 146          */
 147         boolean_t       oflag;          /* instance open flag */
 148         queue_t         *readq;         /* pointer to readq */
 149         queue_t         *writeq;        /* pointer to writeq */
 150         mblk_t          *msg;           /* current message block */
 151         boolean_t       suspended;      /* driver suspended status */
 152         /*
 153          * Modes of operation
 154          */
 155         int             current_mode;   /* 1284 mode */
 156         uchar_t         current_phase;  /* 1284 phase */
 157         uchar_t         backchannel;    /* backchannel mode supported */
 158         uchar_t         io_mode;        /* transfer mode: PIO/DMA */
 159         /*
 160          * Ioctls support
 161          */
 162         struct ecpp_transfer_parms xfer_parms;  /* transfer parameters */
 163         struct ecpp_regs regs;          /* control/status registers */
 164         uint8_t         saved_dsr;      /* store the dsr returned from TESTIO */
 165         boolean_t       timeout_error;  /* store the timeout for GETERR */
 166         uchar_t         port;           /* xfer type: dma/pio/tfifo */
 167         struct prn_timeouts prn_timeouts; /* prnio timeouts */
 168         /*
 169          * ecpp.conf parameters
 170          */
 171         uchar_t         init_seq;       /* centronics init seq */
 172         uint32_t        wsrv_retry;     /* delay (ms) before next wsrv */
 173         uint32_t        wait_for_busy;  /* wait for BUSY to deassert */
 174         uint32_t        data_setup_time; /* pio centronics handshake */
 175         uint32_t        strobe_pulse_width; /* pio centronics handshake */
 176         uint8_t         fast_centronics; /* DMA/PIO centronics */
 177         uint8_t         fast_compat;    /* DMA/PIO 1284 compatible mode */
 178         uint32_t        ecp_rev_speed;  /* rev xfer speed in ECP, bytes/sec */
 179         uint32_t        rev_watchdog;   /* rev xfer watchdog period, ms */
 180         /*
 181          * Timeouts
 182          */
 183         timeout_id_t    timeout_id;     /* io transfers timer */
 184         timeout_id_t    fifo_timer_id;  /* drain SuperIO FIFO */
 185         timeout_id_t    wsrv_timer_id;  /* wsrv timeout */
 186         /*
 187          * Softintr data
 188          */
 189         ddi_softintr_t  softintr_id;
 190         int             softintr_flags; /* flags indicating softintr task */
 191         uint8_t         softintr_pending;
 192         /*
 193          * Misc stuff
 194          */
 195         caddr_t         ioblock;        /* transfer buffer block */
 196         size_t          xfercnt;        /* # of bytes to transfer */
 197         size_t          resid;          /* # of bytes not transferred */
 198         caddr_t         next_byte;      /* next byte for PIO transfer */
 199         caddr_t         last_byte;      /* last byte for PIO transfer */
 200         uint32_t        ecpp_drain_counter;     /* allows fifo to drain */
 201         uchar_t         dma_cancelled;  /* flushed while dma'ing */
 202         uint8_t         tfifo_intr;     /* TFIFO switch interrupt workaround */
 203         size_t          nread;          /* requested read */
 204         size_t          last_dmacnt;    /* DMA counter value for rev watchdog */
 205         uint32_t        rev_timeout_cnt; /* number of watchdog invocations */
 206         /*
 207          * Spurious interrupt detection
 208          */
 209         hrtime_t        lastspur;       /* last time spurious intrs started */
 210         long            nspur;          /* spurious intrs counter */
 211         /*
 212          * Statistics
 213          */
 214         kstat_t         *ksp;           /* kstat pointer */
 215         kstat_t         *intrstats;     /* kstat interrupt counter */
 216         /*
 217          * number of bytes, transferred in and out in each mode
 218          */
 219         uint32_t        ctxpio_obytes;
 220         uint32_t        obytes[ECPP_EPP_MODE+1];
 221         uint32_t        ibytes[ECPP_EPP_MODE+1];
 222         /*
 223          * other stats
 224          */
 225         uint32_t        to_mode[ECPP_EPP_MODE+1]; /* # transitions to mode */
 226         uint32_t        xfer_tout;      /* # transfer timeouts */
 227         uint32_t        ctx_cf;         /* # periph check failures */
 228         uint32_t        joblen;         /* of bytes xfer'd since open */
 229         uint32_t        isr_reattempt_high;     /* max times isr has looped */
 230         /*
 231          * interrupt stats
 232          */
 233         uint_t          intr_hard;
 234         uint_t          intr_spurious;
 235         uint_t          intr_soft;
 236         /*
 237          * identify second register set for ecp mode on Sx86
 238          */
 239         int             noecpregs;
 240 };
 241 
 242 _NOTE(MUTEX_PROTECTS_DATA(ecppunit::umutex, ecppunit))
 243 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::dip))
 244 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::instance))
 245 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::i_reg))
 246 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::f_reg))
 247 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::i_handle))
 248 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::f_handle))
 249 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::ecpp_trap_cookie))
 250 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::readq))
 251 _NOTE(DATA_READABLE_WITHOUT_LOCK(ecppunit::writeq))
 252 
 253 /*
 254  * current_phase values
 255  */
 256 #define ECPP_PHASE_INIT         0x00    /* initialization */
 257 #define ECPP_PHASE_NEGO         0x01    /* negotiation */
 258 #define ECPP_PHASE_TERM         0x02    /* termination */
 259 #define ECPP_PHASE_PO           0x03    /* power-on */
 260 
 261 #define ECPP_PHASE_C_FWD_DMA    0x10    /* cntrx/compat fwd dma xfer */
 262 #define ECPP_PHASE_C_FWD_PIO    0x11    /* cntrx/compat fwd PIO xfer */
 263 #define ECPP_PHASE_C_IDLE       0x12    /* cntrx/compat idle */
 264 
 265 #define ECPP_PHASE_NIBT_REVDATA 0x20    /* nibble/byte reverse data */
 266 #define ECPP_PHASE_NIBT_AVAIL   0x21    /* nibble/byte reverse data available */
 267 #define ECPP_PHASE_NIBT_NAVAIL  0x22    /* nibble/byte reverse data not avail */
 268 #define ECPP_PHASE_NIBT_REVIDLE 0x22    /* nibble/byte reverse idle */
 269 #define ECPP_PHASE_NIBT_REVINTR 0x23    /* nibble/byte reverse interrupt */
 270 
 271 #define ECPP_PHASE_ECP_SETUP    0x30    /* ecp setup */
 272 #define ECPP_PHASE_ECP_FWD_XFER 0x31    /* ecp forward transfer */
 273 #define ECPP_PHASE_ECP_FWD_IDLE 0x32    /* ecp forward idle */
 274 #define ECPP_PHASE_ECP_FWD_REV  0x33    /* ecp forward to reverse */
 275 #define ECPP_PHASE_ECP_REV_XFER 0x34    /* ecp reverse transfer */
 276 #define ECPP_PHASE_ECP_REV_IDLE 0x35    /* ecp reverse idle */
 277 #define ECPP_PHASE_ECP_REV_FWD  0x36    /* ecp reverse to forward */
 278 
 279 #define ECPP_PHASE_EPP_INIT_IDLE 0x40   /* epp init phase */
 280 #define ECPP_PHASE_EPP_IDLE     0x41    /* epp all-round phase */
 281 
 282 #define FAILURE_PHASE           0x80
 283 #define UNDEFINED_PHASE         0x81
 284 
 285 /* ecpp return values */
 286 #define SUCCESS         1
 287 #define FAILURE         2
 288 
 289 #define TRUE            1
 290 #define FALSE           0
 291 
 292 /* message type */
 293 #define ECPP_BACKCHANNEL        0x45
 294 
 295 /* transfer modes */
 296 #define ECPP_DMA                0x1
 297 #define ECPP_PIO                0x2
 298 
 299 /* tuneable timing defaults */
 300 #define CENTRONICS_RETRY        750     /* 750 milliseconds */
 301 #define WAIT_FOR_BUSY           1000    /* 1000 microseconds */
 302 #define SUSPEND_TOUT            10      /* # seconds before suspend fails */
 303 
 304 /* Centronics hanshaking defaults */
 305 #define DATA_SETUP_TIME         2       /* 2 uSec Data Setup Time (2x min) */
 306 #define STROBE_PULSE_WIDTH      2       /* 2 uSec Strobe Pulse (2x min) */
 307 
 308 /* 1284 Extensibility Request values */
 309 #define ECPP_XREQ_NIBBLE        0x00    /* Nibble Mode Rev Channel Transfer */
 310 #define ECPP_XREQ_BYTE          0x01    /* Byte Mode Rev Channel Transfer */
 311 #define ECPP_XREQ_ID            0x04    /* Request Device ID */
 312 #define ECPP_XREQ_ECP           0x10    /* Request ECP Mode */
 313 #define ECPP_XREQ_ECPRLE        0x30    /* Request ECP Mode with RLE */
 314 #define ECPP_XREQ_EPP           0x40    /* Request EPP Mode */
 315 #define ECPP_XREQ_XLINK         0x80    /* Request Extensibility Link */
 316 
 317 /* softintr flags */
 318 #define ECPP_SOFTINTR_PIONEXT   0x1     /* write next byte in PIO mode */
 319 
 320 /* Stream  defaults */
 321 #define IO_BLOCK_SZ     1024 * 128      /* transfer buffer size */
 322 #define ECPPHIWAT       32 * 1024  * 6
 323 #define ECPPLOWAT       32 * 1024  * 4
 324 
 325 /* Loop timers */
 326 #define ECPP_REG_WRITE_MAX_LOOP 100     /* cpu is faster than superio */
 327 #define ECPP_ISR_MAX_DELAY      30      /* DMAC slow PENDING status */
 328 
 329 /* misc constants */
 330 #define ECPP_FIFO_SZ            16      /* FIFO size */
 331 #define FIFO_DRAIN_PERIOD       250000  /* max FIFO drain period in usec */
 332 #define NIBBLE_REV_BLKSZ        1024    /* send up to # bytes at a time */
 333 #define FWD_TIMEOUT_DEFAULT     90      /* forward xfer timeout in seconds */
 334 #define REV_TIMEOUT_DEFAULT     0       /* reverse xfer timeout in seconds */
 335 
 336 /* ECP mode constants */
 337 #define ECP_REV_BLKSZ           1024    /* send up to # bytes at a time */
 338 #define ECP_REV_BLKSZ_MAX       (4 * 1024)      /* maximum of # bytes */
 339 #define ECP_REV_SPEED           (1 * 1024 * 1024)       /* bytes/sec */
 340 #define ECP_REV_MINTOUT         5       /* min ECP rev xfer timeout in ms */
 341 #define REV_WATCHDOG            100     /* poll DMA counter every # ms */
 342 
 343 /* spurious interrupt detection */
 344 #define SPUR_CRITICAL           100     /* number of interrupts... */
 345 #define SPUR_PERIOD             1000000000 /* in # ns */
 346 
 347 /*
 348  * Copyin/copyout states
 349  */
 350 #define ECPP_STRUCTIN           0
 351 #define ECPP_STRUCTOUT          1
 352 #define ECPP_ADDRIN             2
 353 #define ECPP_ADDROUT            3
 354 
 355 /*
 356  * As other ioctls require the same structure, put inner struct's into union
 357  */
 358 struct ecpp_copystate {
 359         int     state;          /* see above */
 360         void    *uaddr;         /* user address of the following structure */
 361         union {
 362                 struct ecpp_device_id           devid;
 363                 struct prn_1284_device_id       prn_devid;
 364                 struct prn_interface_info       prn_if;
 365         } un;
 366 };
 367 
 368 /*
 369  * The structure is dynamically created for each M_IOCTL and is bound to mblk
 370  */
 371 _NOTE(SCHEME_PROTECTS_DATA("unique per call", ecpp_copystate))
 372 
 373 /* kstat structure */
 374 struct ecppkstat {
 375         /*
 376          * number of bytes, transferred in and out in each mode
 377          */
 378         struct kstat_named      ek_ctx_obytes;
 379         struct kstat_named      ek_ctxpio_obytes;
 380         struct kstat_named      ek_nib_ibytes;
 381         struct kstat_named      ek_ecp_obytes;
 382         struct kstat_named      ek_ecp_ibytes;
 383         struct kstat_named      ek_epp_obytes;
 384         struct kstat_named      ek_epp_ibytes;
 385         struct kstat_named      ek_diag_obytes;
 386         /*
 387          * number of transitions to particular mode
 388          */
 389         struct kstat_named      ek_to_ctx;
 390         struct kstat_named      ek_to_nib;
 391         struct kstat_named      ek_to_ecp;
 392         struct kstat_named      ek_to_epp;
 393         struct kstat_named      ek_to_diag;
 394         /*
 395          * other stats
 396          */
 397         struct kstat_named      ek_xfer_tout;   /* # transfer timeouts */
 398         struct kstat_named      ek_ctx_cf;      /* # periph check failures */
 399         struct kstat_named      ek_joblen;      /* # bytes xfer'd since open */
 400         struct kstat_named      ek_isr_reattempt_high;  /* max # times */
 401                                                         /* isr has looped */
 402         struct kstat_named      ek_mode;        /* 1284 mode */
 403         struct kstat_named      ek_phase;       /* 1284 ECP phase */
 404         struct kstat_named      ek_backchan;    /* backchannel mode supported */
 405         struct kstat_named      ek_iomode;      /* transfer mode: pio/dma */
 406         struct kstat_named      ek_state;       /* ecpp busy flag */
 407 };
 408 
 409 /* Macros for superio programming */
 410 #define PP_PUTB(x, y, z)        ddi_put8(x, y, z)
 411 #define PP_GETB(x, y)           ddi_get8(x, y)
 412 
 413 #define DSR_READ(pp)            PP_GETB((pp)->i_handle, &(pp)->i_reg->dsr)
 414 #define DCR_READ(pp)            PP_GETB((pp)->i_handle, &(pp)->i_reg->dcr)
 415 #define ECR_READ(pp)            \
 416         (pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->ecr)
 417 #define DATAR_READ(pp)          PP_GETB((pp)->i_handle, &(pp)->i_reg->ir.datar)
 418 #define DFIFO_READ(pp)          \
 419         (pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->fr.dfifo)
 420 #define TFIFO_READ(pp)          \
 421         (pp->noecpregs) ? 0xff : PP_GETB((pp)->f_handle, &(pp)->f_reg->fr.tfifo)
 422 
 423 #define DCR_WRITE(pp, val)      PP_PUTB((pp)->i_handle, &(pp)->i_reg->dcr, val)
 424 #define ECR_WRITE(pp, val)      \
 425         if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->ecr, val)
 426 #define DATAR_WRITE(pp, val)    \
 427                         PP_PUTB((pp)->i_handle, &(pp)->i_reg->ir.datar, val)
 428 #define DFIFO_WRITE(pp, val)    \
 429         if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->fr.dfifo, val)
 430 #define TFIFO_WRITE(pp, val)    \
 431         if (!pp->noecpregs) PP_PUTB((pp)->f_handle, &(pp)->f_reg->fr.tfifo, val)
 432 
 433 /*
 434  * Macros to manipulate register bits
 435  */
 436 #define OR_SET_BYTE_R(handle, addr, val) \
 437 {               \
 438         uint8_t tmpval;                                 \
 439         tmpval = ddi_get8(handle, (uint8_t *)addr);     \
 440         tmpval |= val;                                  \
 441         ddi_put8(handle, (uint8_t *)addr, tmpval);      \
 442 }
 443 
 444 #define OR_SET_LONG_R(handle, addr, val) \
 445 {               \
 446         uint32_t tmpval;                                \
 447         tmpval = ddi_get32(handle, (uint32_t *)addr);   \
 448         tmpval |= val;                                  \
 449         ddi_put32(handle, (uint32_t *)addr, tmpval);    \
 450 }
 451 
 452 #define AND_SET_BYTE_R(handle, addr, val) \
 453 {               \
 454         uint8_t tmpval;                                 \
 455         tmpval = ddi_get8(handle, (uint8_t *)addr);     \
 456         tmpval &= val;                                      \
 457         ddi_put8(handle, (uint8_t *)addr, tmpval);      \
 458 }
 459 
 460 #define AND_SET_LONG_R(handle, addr, val) \
 461 {               \
 462         uint32_t tmpval;                                \
 463         tmpval = ddi_get32(handle, (uint32_t *)addr);   \
 464         tmpval &= val;                                      \
 465         ddi_put32(handle, (uint32_t *)addr, tmpval);    \
 466 }
 467 
 468 #define NOR_SET_LONG_R(handle, addr, val, mask) \
 469 {               \
 470         uint32_t tmpval;                                \
 471         tmpval = ddi_get32(handle, (uint32_t *)addr);   \
 472         tmpval &= ~(mask);                          \
 473         tmpval |= val;                                  \
 474         ddi_put32(handle, (uint32_t *)addr, tmpval);    \
 475 }
 476 
 477 /*
 478  * Macros for Cheerio/RIO DMAC programming
 479  */
 480 #define SET_DMAC_CSR(pp, val)   ddi_put32(pp->uh.ebus.d_handle, \
 481                                 ((uint32_t *)&pp->uh.ebus.dmac->csr), \
 482                                 ((uint32_t)val))
 483 #define GET_DMAC_CSR(pp)        ddi_get32(pp->uh.ebus.d_handle, \
 484                                 (uint32_t *)&(pp->uh.ebus.dmac->csr))
 485 
 486 #define SET_DMAC_ACR(pp, val)   ddi_put32(pp->uh.ebus.d_handle, \
 487                                 ((uint32_t *)&pp->uh.ebus.dmac->acr), \
 488                                 ((uint32_t)val))
 489 
 490 #define GET_DMAC_ACR(pp)        ddi_get32(pp->uh.ebus.d_handle, \
 491                                 (uint32_t *)&pp->uh.ebus.dmac->acr)
 492 
 493 #define SET_DMAC_BCR(pp, val)   ddi_put32(pp->uh.ebus.d_handle, \
 494                                 ((uint32_t *)&pp->uh.ebus.dmac->bcr), \
 495                                 ((uint32_t)val))
 496 
 497 #define GET_DMAC_BCR(pp)        ddi_get32(pp->uh.ebus.d_handle, \
 498                                 ((uint32_t *)&pp->uh.ebus.dmac->bcr))
 499 
 500 #define DMAC_RESET_TIMEOUT      10000   /* in usec */
 501 
 502 /*
 503  * Macros to distinguish between PIO and DMA Compatibility mode
 504  */
 505 #define COMPAT_PIO(pp) (((pp)->io_mode == ECPP_PIO) &&               \
 506                     ((pp)->current_mode == ECPP_CENTRONICS ||        \
 507                     (pp)->current_mode == ECPP_COMPAT_MODE))
 508 
 509 #define COMPAT_DMA(pp) (((pp)->io_mode == ECPP_DMA) &&               \
 510                     ((pp)->current_mode == ECPP_CENTRONICS ||        \
 511                     (pp)->current_mode == ECPP_COMPAT_MODE))
 512 
 513 /*
 514  * Other useful macros
 515  */
 516 #define NELEM(a)        (sizeof (a) / sizeof (*(a)))
 517 
 518 #ifdef  __cplusplus
 519 }
 520 #endif
 521 
 522 #endif  /* _SYS_ECPPVAR_H */