rmc_comm.h revision 03831d35f7499c87d51205817c93e9a8d42c4bae
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_RMC_COMM_H
#define _SYS_RMC_COMM_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Hardware: serial chip register numbers
*/
#define SIO_RXD 0 /* read */
#define SIO_TXD 0 /* write */
#define SIO_IER 1
#define SIO_EIR 2 /* read */
#define SIO_FCR 2 /* write */
#define SIO_LCR 3
#define SIO_BSR 3 /* wierd */
#define SIO_MCR 4
#define SIO_LSR 5
#define SIO_MSR 6
#define SIO_SCR 7
#define SIO_LBGDL 0 /* bank 1 */
#define SIO_LBGDH 1 /* bank 1 */
/*
* Hardware: serial chip register bits
*/
#define SIO_IER_RXHDL_IE 0x01
#define SIO_IER_STD 0x00
#define SIO_FCR_FIFO_EN 0x01
#define SIO_FCR_RXSR 0x02
#define SIO_FCR_TXSR 0x04
#define SIO_FCR_RXFTH0 0x40
#define SIO_FCR_STD (SIO_FCR_RXFTH0|SIO_FCR_FIFO_EN)
#define SIO_LCR_WLS0 0x01
#define SIO_LCR_WLS1 0x02
#define SIO_LCR_PEN 0x08
#define SIO_LCR_EPS 0x10
#define SIO_LCR_BKSE 0x80
#define SIO_LCR_8BIT (SIO_LCR_WLS0|SIO_LCR_WLS1)
#define SIO_LCR_STD (SIO_LCR_8BIT)
#define SIO_BSR_BANK0 (SIO_LCR_STD)
#define SIO_BSR_BANK1 (SIO_LCR_BKSE|SIO_LCR_STD)
#define SIO_MCR_ISEN 0x08
#define SIO_MCR_STD (SIO_MCR_ISEN)
/* Line Status Register */
#define SIO_LSR_RXDA 0x01 /* data ready */
#define SIO_LSR_OVRRUN 0x02 /* overrun error */
#define SIO_LSR_PARERR 0x04 /* parity error */
#define SIO_LSR_FRMERR 0x08 /* framing error */
#define SIO_LSR_BRKDET 0x10 /* a break has arrived */
#define SIO_LSR_XHRE 0x20 /* tx hold reg is now empty */
#define SIO_LSR_XSRE 0x40 /* tx shift reg is now empty */
#define SIO_LSR_RFBE 0x80 /* rx FIFO Buffer error */
/*
* Min/max/default baud rates, and a macro to convert from a baud
* rate to the number (divisor) to put in the baud rate registers
*/
#define SIO_BAUD_MIN 50
#define SIO_BAUD_MAX 115200
#define SIO_BAUD_DEFAULT 115200
#define SIO_BAUD_TO_DIVISOR(b) (115200 / (b))
#define SIO_BAUD_DIVISOR_MIN 1
#define SIO_BAUD_DIVISOR_MAX 64
/*
* serial rx buffer size: set to maximum message size + 'bits'
* (protocol overhead)
*/
#define SIO_MAX_RXBUF_SIZE (DP_MAX_MSGLEN + 128)
/*
* protocol status struct
*/
typedef struct rmc_comm_serdev_state {
ddi_acc_handle_t sio_handle;
uint8_t *sio_regs;
ddi_softintr_t softid;
cyclic_id_t cycid;
/*
* Hardware mutex (initialised using <hw_iblk>),
* used to prevent retriggering the softint while
* it's still fetching data out of the chip FIFO.
*/
kmutex_t hw_mutex[1];
ddi_iblock_cookie_t hw_iblk;
boolean_t hw_int_enabled;
/*
* Flag to indicate that we've incurred a hardware fault on
* accesses to the SIO; once this is set, we fake all further
* accesses in order not to provoke additional bus errors.
*/
boolean_t sio_fault;
/*
* serial device receive buffer
*/
char serdev_rx_buf[SIO_MAX_RXBUF_SIZE];
uint16_t serdev_rx_count;
} rmc_comm_serdev_state_t;
/*
* This driver's soft-state structure
*/
struct rmc_comm_state {
/*
* Configuration data, set during attach
*/
dev_info_t *dip;
major_t majornum;
int instance;
int n_registrations;
boolean_t is_attached;
/*
* Parameters derived from .conf properties
*/
int baud;
uint32_t debug;
int baud_divisor_factor;
/*
* serial device status...
*/
rmc_comm_serdev_state_t sd_state;
/*
* protocol status struct
*/
rmc_comm_dp_state_t dp_state;
/*
* driver interface status struct
*/
rmc_comm_drvintf_state_t drvi_state;
};
/*
* Time periods, in nanoseconds
*/
#define RMC_COMM_ONE_SEC 1000000000LL
/*
* debugging
*/
#define DSER 0x01 /* serial device */
#define DPRO 0x02 /* protocol */
#define DAPI 0x04 /* API */
#define DPKT 0x08 /* packet handling routine */
#define DGEN 0x10 /* generic */
#define DDSC 0x20 /* datascope */
#define DMEM 0x40 /* memory alloc/release */
#ifdef DEBUG
#define DPRINTF(rcs, d, ARGLIST) { if (rcs->debug & d) cmn_err ARGLIST; }
#define DATASCOPE(rcs, c, b, l) { int i, j; char s[80]; \
s[0] = (c); \
s[1] = '\0'; \
for (i = 1; i < (l)+1; i++) { \
j = strlen(s); \
(void) sprintf(s+j, "%02x ", \
(uchar_t)b[i-1]); \
if (i%24 == 0) { \
DPRINTF(rcs, DDSC, \
(CE_CONT, "%s\n", s)); \
s[0] = (c); \
s[1] = '\0'; \
} \
} \
if (i%24 != 0) \
DPRINTF(rcs, DDSC, \
(CE_CONT, "%s\n", s)); \
}
#else
#define DPRINTF(rcs, d, ARGLIST)
#define DATASCOPE(rcs, c, b, l)
#endif /* DEBUG */
/*
* function prototypes
*/
int rmc_comm_serdev_init(struct rmc_comm_state *, dev_info_t *);
void rmc_comm_serdev_fini(struct rmc_comm_state *, dev_info_t *);
void rmc_comm_serdev_receive(struct rmc_comm_state *);
void rmc_comm_serdev_send(struct rmc_comm_state *, char *, int);
void rmc_comm_serdev_drain(struct rmc_comm_state *);
struct rmc_comm_state *rmc_comm_getstate(dev_info_t *, int, const char *);
int rmc_comm_register(void);
void rmc_comm_unregister(void);
void rmc_comm_dp_init(struct rmc_comm_state *);
void rmc_comm_dp_fini(struct rmc_comm_state *);
void rmc_comm_dp_drecv(struct rmc_comm_state *, uint8_t *, int);
void rmc_comm_dp_mrecv(struct rmc_comm_state *, uint8_t *);
int rmc_comm_dp_msend(struct rmc_comm_state *, dp_message_t *);
void rmc_comm_bp_msend(struct rmc_comm_state *, bp_msg_t *);
void rmc_comm_bp_srecsend(struct rmc_comm_state *, char *, int);
int rmc_comm_dp_ctlsend(struct rmc_comm_state *, uint8_t);
void rmc_comm_dp_mcleanup(struct rmc_comm_state *);
int rmc_comm_drvintf_init(struct rmc_comm_state *);
void rmc_comm_drvintf_fini(struct rmc_comm_state *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_RMC_COMM_H */