zsdev.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ZSDEV_H
#define _SYS_ZSDEV_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Onboard serial ports.
* Device dependent software definitions.
* All interfaces described in this file are private to the Sun 'zs' driver
* implementation and may change at any time without notice.
*/
/*
* Chip, buffer, and register definitions for Z8530 SCC
*/
#include <sys/spl.h>
#include <sys/ksynch.h>
#include <sys/dditypes.h>
#include <sys/ser_zscc.h>
#ifdef _MACHDEP
#include <sys/zsmach.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _MACHDEP
#define ZSDELAY()
#define ZSFLUSH()
#define ZSNEXTPOLL(zscurr)
#endif
/*
* OUTLINE defines the high-order flag bit in the minor device number that
* controls use of a tty line for dialin and dialout simultaneously.
*/
#define OUTLINE ((minor_t)1 << (NBITSMINOR32 - 1))
#define UNIT(x) (getminor(x) & ~OUTLINE)
#define ZSWR1_INIT (ZSWR1_SIE|ZSWR1_TIE|ZSWR1_RIE)
extern int zs_usec_delay;
#define ZS_REG_SIZE (2 * sizeof (struct zscc_device))
#define PCLK (19660800/4) /* basic clock rate for UARTs */
#define SDLCFLAG 0x7E
#define ZS_ON (ZSWR5_DTR|ZSWR5_RTS)
#define ZS_OFF 0
/*
* Modem control commands.
*/
#define DMSET 0
#define DMBIS 1
#define DMBIC 2
#define DMGET 3
/*
* Macros to access a port
*/
#define SCC_WRITEA(reg, val) { \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \
ZSDELAY(); \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = val; \
ZSDELAY(); \
zs->zs_wreg[reg] = val; \
}
#define SCC_WRITEB(reg, val) { \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \
ZSDELAY(); \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = val; \
ZSDELAY(); \
zs->zs_wreg[reg] = val; \
}
#define SCC_WRITE(reg, val) { \
zs->zs_addr->zscc_control = reg; \
ZSDELAY(); \
zs->zs_addr->zscc_control = val; \
ZSDELAY(); \
zs->zs_wreg[reg] = val; \
}
#define SCC_READA(reg, var) { \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control = reg; \
ZSDELAY(); \
var = ((struct zscc_device *) \
((uintptr_t)zs->zs_addr | ZSOFF))->zscc_control; \
ZSDELAY(); \
}
#define SCC_READB(reg, var) { \
((struct zscc_device *) \
((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control = reg; \
ZSDELAY(); \
var = ((struct zscc_device *) \
((uintptr_t)zs->zs_addr & ~ZSOFF))->zscc_control; \
ZSDELAY(); \
}
#define SCC_READ(reg, var) { \
register struct zscc_device *tmp; \
tmp = zs->zs_addr; \
tmp->zscc_control = reg; \
ZSDELAY(); \
var = tmp->zscc_control; \
ZSDELAY(); \
}
#define SCC_BIS(reg, val) { \
zs->zs_addr->zscc_control = reg; \
ZSDELAY(); \
zs->zs_addr->zscc_control = zs->zs_wreg[reg] |= val; \
ZSDELAY(); \
}
#define SCC_BIC(reg, val) { \
zs->zs_addr->zscc_control = reg; \
ZSDELAY(); \
zs->zs_addr->zscc_control = zs->zs_wreg[reg] &= ~val; \
ZSDELAY(); \
}
#define SCC_WRITE0(val) { \
zs->zs_addr->zscc_control = val; \
ZSDELAY(); \
ZSFLUSH(); \
}
#define SCC_WRITEDATA(val) { \
zs->zs_addr->zscc_data = val; \
ZSDELAY(); \
ZSFLUSH(); \
}
#define SCC_READ0() zs->zs_addr->zscc_control
#define SCC_READDATA() zs->zs_addr->zscc_data
/*
* Protocol specific entry points for driver routines.
*/
struct zsops {
void (*zsop_txint)(); /* xmit buffer empty */
void (*zsop_xsint)(); /* external/status */
void (*zsop_rxint)(); /* receive char available */
void (*zsop_srint)(); /* special receive condition */
int (*zsop_softint)(); /* second stage interrupt handler */
int (*zsop_suspend)(); /* suspend driver */
int (*zsop_resume)(); /* resume driver */
};
/*
* Hardware channel common data. One structure per port.
* Each of the fields in this structure is required to be protected by a
* mutex lock at the highest priority at which it can be altered.
* The zs_flags, zs_wreg and zs_next fields can be altered by interrupt
* handling code that runs at ZS_PL_HI (IPL 12), so they must be protected
* by the mutex whose handle is stored in zs_excl_hi. All others can be
* protected by the zs_excl mutex, which is lower priority and adaptive.
*/
#define ZS_MAX_PRIV_STR 800 /* int */
struct zscom {
void (*zs_txint)(); /* SCC interrupt vector routines */
unsigned char *zs_wr_cur;
unsigned char *zs_wr_lim;
void (*zs_rxint)(); /* SCC interrupt vector routines */
unsigned char *zs_rd_cur;
unsigned char *zs_rd_lim;
struct zscc_device *zs_addr; /* address of second half of chip */
void (*zs_xsint)(); /* SCC interrupt vector routines */
void (*zs_srint)(); /* SCC interrupt vector routines */
int (*zs_suspend)(); /* routine to suspend driver */
int (*zs_resume)(); /* routine to resume driver */
uchar_t zs_wreg[16]; /* shadow of write registers */
caddr_t zs_priv; /* protocol private data */
struct zsops *zs_ops; /* basic operations vectors */
dev_info_t *zs_dip; /* dev_info */
dev_info_t *zs_hdlc_dip; /* zsh dev_info */
time_t zs_dtrlow; /* time dtr went low */
short zs_unit; /* which channel (0:NZSLINE) */
/*
* The zs_wreg, zs_next and zs_flags fields
* are protected by zs_excl_hi.
*/
uchar_t zs_suspended; /* True, if suspended */
struct zs_prog *zs_prog_save; /* H/W state, saved for CPR */
struct zscom *zs_next; /* next in the circularly linked list */
struct zscom *zs_back; /* back in the circularly linked list */
kmutex_t *zs_excl_hi; /* zs spinlock mutex */
kmutex_t *zs_excl; /* zs adaptive mutex */
kmutex_t *zs_ocexcl; /* zs adaptive mutex for open/close */
kcondvar_t zs_flags_cv; /* condition variable for flags */
ulong_t zs_priv_str[ZS_MAX_PRIV_STR];
uint_t zs_flags; /* ZS_* flags below */
kstat_t *intrstats; /* interrupt statistics */
timeout_id_t zs_timer; /* close timer */
};
/*
* Definition for zs_flags field
*
* ZS_CLOSED is for synchronizing with za_soft_active an za_kick_active.
*/
#define ZS_NEEDSOFT 0x00000001
#define ZS_PROGRESS 0x00000002
#define ZS_CLOSING 0x00000004 /* close has started */
#define ZS_CLOSED 0x00000008 /* close is done; stop other activity */
#ifdef _KERNEL
#define ZS_H_LOG_MAX 0x8000
/*
* ZSSETSOFT macro to pend a level 3 interrupt if one isn't already pending.
*/
extern kmutex_t zs_soft_lock; /* ptr to lock for zssoftpend */
extern int zssoftpend; /* secondary interrupt pending */
extern ddi_softintr_t zs_softintr_id;
#define ZSSETSOFT(zs) { \
zs->zs_flags |= ZS_NEEDSOFT; \
if (!zssoftpend) { \
zssoftpend = 1; \
ddi_trigger_softintr(zs_softintr_id); \
} \
}
#endif /* _KERNEL */
/*
* Lock priority definitions.
* XXX: These should be obtained from configuration data, eventually.
*/
#define ZS_PL ipltospl(SPL3) /* translates to SPARC IPL 6 */
#define ZS_PL_HI ipltospl(SPLTTY) /* translates to SPARC IPL 12 */
/*
* Definitions for generic SCC programming routine
*/
struct zs_prog {
struct zscom *zs; /* common data for this channel */
uchar_t flags; /* see definitions below */
uchar_t wr4; /* misc parameters and modes */
uchar_t wr11; /* clock mode control */
uchar_t wr12; /* BRG time constant Lo byte */
uchar_t wr13; /* BRG time constant Hi byte */
uchar_t wr3; /* receiver parameters and control */
uchar_t wr5; /* transmitter parameters and control */
uchar_t wr15; /* external status interrupt control */
};
/*
* Definitions for zs_prog flags field
*/
#define ZSP_SYNC 01 /* 0 = async line; 1 = synchronous */
#define ZSP_NRZI 02 /* 0 = NRZ encoding; 1 = NRZI */
#define ZSP_PLL 04 /* request use of PLL clock source */
#define ZSP_LOOP 010 /* request interal loopback mode */
#define ZSP_PARITY_SPECIAL 020 /* parity error causes ext status int */
#define ZSP_ECHO 040 /* request auto echo mode */
extern void zsa_init(struct zscom *zs);
extern int zsmctl(struct zscom *zs, int bits, int how);
extern void zs_program(struct zs_prog *zspp);
extern void zsopinit(struct zscom *zs, struct zsops *zso);
extern void setzssoft(void);
extern dev_info_t *zs_get_dev_info(dev_t dev, int otyp);
extern char *zssoftCAR;
extern int nzs;
extern struct zscom *zscom;
extern struct zs_prog *zs_prog;
extern kmutex_t zs_curr_lock; /* lock protecting zscurr use for clone */
extern struct zsops zsops_null;
extern int zs_drain_check;
#ifdef __cplusplus
}
#endif
#endif /* !_SYS_ZSDEV_H */