103831d35Sstevel /* 203831d35Sstevel * CDDL HEADER START 303831d35Sstevel * 403831d35Sstevel * The contents of this file are subject to the terms of the 503831d35Sstevel * Common Development and Distribution License (the "License"). 603831d35Sstevel * You may not use this file except in compliance with the License. 703831d35Sstevel * 803831d35Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 903831d35Sstevel * or http://www.opensolaris.org/os/licensing. 1003831d35Sstevel * See the License for the specific language governing permissions 1103831d35Sstevel * and limitations under the License. 1203831d35Sstevel * 1303831d35Sstevel * When distributing Covered Code, include this CDDL HEADER in each 1403831d35Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1503831d35Sstevel * If applicable, add the following below this CDDL HEADER, with the 1603831d35Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 1703831d35Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 1803831d35Sstevel * 1903831d35Sstevel * CDDL HEADER END 2003831d35Sstevel */ 2103831d35Sstevel 2203831d35Sstevel /* 23*dd4eeefdSeota * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2403831d35Sstevel * Use is subject to license terms. 2503831d35Sstevel */ 2603831d35Sstevel 2703831d35Sstevel #ifndef _SYS_RMC_COMM_H 2803831d35Sstevel #define _SYS_RMC_COMM_H 2903831d35Sstevel 3003831d35Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 3103831d35Sstevel 3203831d35Sstevel #ifdef __cplusplus 3303831d35Sstevel extern "C" { 3403831d35Sstevel #endif 3503831d35Sstevel 3603831d35Sstevel /* 3703831d35Sstevel * Hardware: serial chip register numbers 3803831d35Sstevel */ 3903831d35Sstevel #define SIO_RXD 0 /* read */ 4003831d35Sstevel #define SIO_TXD 0 /* write */ 4103831d35Sstevel #define SIO_IER 1 4203831d35Sstevel #define SIO_EIR 2 /* read */ 4303831d35Sstevel #define SIO_FCR 2 /* write */ 4403831d35Sstevel #define SIO_LCR 3 4503831d35Sstevel #define SIO_BSR 3 /* wierd */ 4603831d35Sstevel #define SIO_MCR 4 4703831d35Sstevel #define SIO_LSR 5 4803831d35Sstevel #define SIO_MSR 6 4903831d35Sstevel #define SIO_SCR 7 5003831d35Sstevel 5103831d35Sstevel #define SIO_LBGDL 0 /* bank 1 */ 5203831d35Sstevel #define SIO_LBGDH 1 /* bank 1 */ 5303831d35Sstevel 5403831d35Sstevel /* 5503831d35Sstevel * Hardware: serial chip register bits 5603831d35Sstevel */ 5703831d35Sstevel #define SIO_IER_RXHDL_IE 0x01 5803831d35Sstevel #define SIO_IER_STD 0x00 5903831d35Sstevel 6003831d35Sstevel #define SIO_FCR_FIFO_EN 0x01 6103831d35Sstevel #define SIO_FCR_RXSR 0x02 6203831d35Sstevel #define SIO_FCR_TXSR 0x04 6303831d35Sstevel #define SIO_FCR_RXFTH0 0x40 6403831d35Sstevel #define SIO_FCR_STD (SIO_FCR_RXFTH0|SIO_FCR_FIFO_EN) 6503831d35Sstevel 6603831d35Sstevel #define SIO_LCR_WLS0 0x01 6703831d35Sstevel #define SIO_LCR_WLS1 0x02 6803831d35Sstevel #define SIO_LCR_PEN 0x08 6903831d35Sstevel #define SIO_LCR_EPS 0x10 7003831d35Sstevel #define SIO_LCR_BKSE 0x80 7103831d35Sstevel #define SIO_LCR_8BIT (SIO_LCR_WLS0|SIO_LCR_WLS1) 7203831d35Sstevel #define SIO_LCR_STD (SIO_LCR_8BIT) 7303831d35Sstevel #define SIO_BSR_BANK0 (SIO_LCR_STD) 7403831d35Sstevel #define SIO_BSR_BANK1 (SIO_LCR_BKSE|SIO_LCR_STD) 7503831d35Sstevel 7603831d35Sstevel #define SIO_MCR_ISEN 0x08 7703831d35Sstevel #define SIO_MCR_STD (SIO_MCR_ISEN) 7803831d35Sstevel 7903831d35Sstevel /* Line Status Register */ 8003831d35Sstevel #define SIO_LSR_RXDA 0x01 /* data ready */ 8103831d35Sstevel #define SIO_LSR_OVRRUN 0x02 /* overrun error */ 8203831d35Sstevel #define SIO_LSR_PARERR 0x04 /* parity error */ 8303831d35Sstevel #define SIO_LSR_FRMERR 0x08 /* framing error */ 8403831d35Sstevel #define SIO_LSR_BRKDET 0x10 /* a break has arrived */ 8503831d35Sstevel #define SIO_LSR_XHRE 0x20 /* tx hold reg is now empty */ 8603831d35Sstevel #define SIO_LSR_XSRE 0x40 /* tx shift reg is now empty */ 8703831d35Sstevel #define SIO_LSR_RFBE 0x80 /* rx FIFO Buffer error */ 8803831d35Sstevel 8903831d35Sstevel /* 9003831d35Sstevel * Min/max/default baud rates, and a macro to convert from a baud 9103831d35Sstevel * rate to the number (divisor) to put in the baud rate registers 9203831d35Sstevel */ 9303831d35Sstevel #define SIO_BAUD_MIN 50 9403831d35Sstevel #define SIO_BAUD_MAX 115200 9503831d35Sstevel #define SIO_BAUD_DEFAULT 115200 9603831d35Sstevel #define SIO_BAUD_TO_DIVISOR(b) (115200 / (b)) 9703831d35Sstevel #define SIO_BAUD_DIVISOR_MIN 1 9803831d35Sstevel #define SIO_BAUD_DIVISOR_MAX 64 9903831d35Sstevel 10003831d35Sstevel /* 10103831d35Sstevel * serial rx buffer size: set to maximum message size + 'bits' 10203831d35Sstevel * (protocol overhead) 10303831d35Sstevel */ 10403831d35Sstevel 10503831d35Sstevel #define SIO_MAX_RXBUF_SIZE (DP_MAX_MSGLEN + 128) 10603831d35Sstevel 10703831d35Sstevel /* 10803831d35Sstevel * protocol status struct 10903831d35Sstevel */ 11003831d35Sstevel 11103831d35Sstevel typedef struct rmc_comm_serdev_state { 11203831d35Sstevel 11303831d35Sstevel ddi_acc_handle_t sio_handle; 11403831d35Sstevel uint8_t *sio_regs; 11503831d35Sstevel ddi_softintr_t softid; 116*dd4eeefdSeota ddi_periodic_t cycid; /* periodical callback */ 11703831d35Sstevel 11803831d35Sstevel /* 11903831d35Sstevel * Hardware mutex (initialised using <hw_iblk>), 12003831d35Sstevel * used to prevent retriggering the softint while 12103831d35Sstevel * it's still fetching data out of the chip FIFO. 12203831d35Sstevel */ 12303831d35Sstevel kmutex_t hw_mutex[1]; 12403831d35Sstevel ddi_iblock_cookie_t hw_iblk; 12503831d35Sstevel boolean_t hw_int_enabled; 12603831d35Sstevel 12703831d35Sstevel /* 12803831d35Sstevel * Flag to indicate that we've incurred a hardware fault on 12903831d35Sstevel * accesses to the SIO; once this is set, we fake all further 13003831d35Sstevel * accesses in order not to provoke additional bus errors. 13103831d35Sstevel */ 13203831d35Sstevel boolean_t sio_fault; 13303831d35Sstevel 13403831d35Sstevel /* 13503831d35Sstevel * serial device receive buffer 13603831d35Sstevel */ 13703831d35Sstevel char serdev_rx_buf[SIO_MAX_RXBUF_SIZE]; 13803831d35Sstevel uint16_t serdev_rx_count; 13903831d35Sstevel 14003831d35Sstevel } rmc_comm_serdev_state_t; 14103831d35Sstevel 14203831d35Sstevel /* 14303831d35Sstevel * This driver's soft-state structure 14403831d35Sstevel */ 14503831d35Sstevel struct rmc_comm_state { 14603831d35Sstevel /* 14703831d35Sstevel * Configuration data, set during attach 14803831d35Sstevel */ 14903831d35Sstevel dev_info_t *dip; 15003831d35Sstevel major_t majornum; 15103831d35Sstevel int instance; 15203831d35Sstevel int n_registrations; 15303831d35Sstevel boolean_t is_attached; 15403831d35Sstevel 15503831d35Sstevel /* 15603831d35Sstevel * Parameters derived from .conf properties 15703831d35Sstevel */ 15803831d35Sstevel int baud; 15903831d35Sstevel uint32_t debug; 16003831d35Sstevel int baud_divisor_factor; 16103831d35Sstevel 16203831d35Sstevel /* 16303831d35Sstevel * serial device status... 16403831d35Sstevel */ 16503831d35Sstevel rmc_comm_serdev_state_t sd_state; 16603831d35Sstevel 16703831d35Sstevel /* 16803831d35Sstevel * protocol status struct 16903831d35Sstevel */ 17003831d35Sstevel rmc_comm_dp_state_t dp_state; 17103831d35Sstevel 17203831d35Sstevel /* 17303831d35Sstevel * driver interface status struct 17403831d35Sstevel */ 17503831d35Sstevel rmc_comm_drvintf_state_t drvi_state; 17603831d35Sstevel }; 17703831d35Sstevel 17803831d35Sstevel 17903831d35Sstevel /* 18003831d35Sstevel * Time periods, in nanoseconds 18103831d35Sstevel */ 18203831d35Sstevel #define RMC_COMM_ONE_SEC 1000000000LL 18303831d35Sstevel 18403831d35Sstevel /* 18503831d35Sstevel * debugging 18603831d35Sstevel */ 18703831d35Sstevel 18803831d35Sstevel #define DSER 0x01 /* serial device */ 18903831d35Sstevel #define DPRO 0x02 /* protocol */ 19003831d35Sstevel #define DAPI 0x04 /* API */ 19103831d35Sstevel #define DPKT 0x08 /* packet handling routine */ 19203831d35Sstevel #define DGEN 0x10 /* generic */ 19303831d35Sstevel #define DDSC 0x20 /* datascope */ 19403831d35Sstevel #define DMEM 0x40 /* memory alloc/release */ 19503831d35Sstevel 19603831d35Sstevel #ifdef DEBUG 19703831d35Sstevel #define DPRINTF(rcs, d, ARGLIST) { if (rcs->debug & d) cmn_err ARGLIST; } 19803831d35Sstevel #define DATASCOPE(rcs, c, b, l) { int i, j; char s[80]; \ 19903831d35Sstevel s[0] = (c); \ 20003831d35Sstevel s[1] = '\0'; \ 20103831d35Sstevel for (i = 1; i < (l)+1; i++) { \ 20203831d35Sstevel j = strlen(s); \ 20303831d35Sstevel (void) sprintf(s+j, "%02x ", \ 20403831d35Sstevel (uchar_t)b[i-1]); \ 20503831d35Sstevel if (i%24 == 0) { \ 20603831d35Sstevel DPRINTF(rcs, DDSC, \ 20703831d35Sstevel (CE_CONT, "%s\n", s)); \ 20803831d35Sstevel s[0] = (c); \ 20903831d35Sstevel s[1] = '\0'; \ 21003831d35Sstevel } \ 21103831d35Sstevel } \ 21203831d35Sstevel if (i%24 != 0) \ 21303831d35Sstevel DPRINTF(rcs, DDSC, \ 21403831d35Sstevel (CE_CONT, "%s\n", s)); \ 21503831d35Sstevel } 21603831d35Sstevel #else 21703831d35Sstevel #define DPRINTF(rcs, d, ARGLIST) 21803831d35Sstevel #define DATASCOPE(rcs, c, b, l) 21903831d35Sstevel #endif /* DEBUG */ 22003831d35Sstevel 22103831d35Sstevel 22203831d35Sstevel /* 22303831d35Sstevel * function prototypes 22403831d35Sstevel */ 22503831d35Sstevel 22603831d35Sstevel int rmc_comm_serdev_init(struct rmc_comm_state *, dev_info_t *); 22703831d35Sstevel void rmc_comm_serdev_fini(struct rmc_comm_state *, dev_info_t *); 22803831d35Sstevel void rmc_comm_serdev_receive(struct rmc_comm_state *); 22903831d35Sstevel void rmc_comm_serdev_send(struct rmc_comm_state *, char *, int); 23003831d35Sstevel void rmc_comm_serdev_drain(struct rmc_comm_state *); 23103831d35Sstevel struct rmc_comm_state *rmc_comm_getstate(dev_info_t *, int, const char *); 23203831d35Sstevel int rmc_comm_register(void); 23303831d35Sstevel void rmc_comm_unregister(void); 23403831d35Sstevel 23503831d35Sstevel void rmc_comm_dp_init(struct rmc_comm_state *); 23603831d35Sstevel void rmc_comm_dp_fini(struct rmc_comm_state *); 23703831d35Sstevel void rmc_comm_dp_drecv(struct rmc_comm_state *, uint8_t *, int); 23803831d35Sstevel void rmc_comm_dp_mrecv(struct rmc_comm_state *, uint8_t *); 23903831d35Sstevel int rmc_comm_dp_msend(struct rmc_comm_state *, dp_message_t *); 24003831d35Sstevel void rmc_comm_bp_msend(struct rmc_comm_state *, bp_msg_t *); 24103831d35Sstevel void rmc_comm_bp_srecsend(struct rmc_comm_state *, char *, int); 24203831d35Sstevel int rmc_comm_dp_ctlsend(struct rmc_comm_state *, uint8_t); 24303831d35Sstevel void rmc_comm_dp_mcleanup(struct rmc_comm_state *); 24403831d35Sstevel 24503831d35Sstevel int rmc_comm_drvintf_init(struct rmc_comm_state *); 24603831d35Sstevel void rmc_comm_drvintf_fini(struct rmc_comm_state *); 24703831d35Sstevel 24803831d35Sstevel #ifdef __cplusplus 24903831d35Sstevel } 25003831d35Sstevel #endif 25103831d35Sstevel 25203831d35Sstevel #endif /* _SYS_RMC_COMM_H */ 253