11708Sstevel /* 21708Sstevel * CDDL HEADER START 31708Sstevel * 41708Sstevel * The contents of this file are subject to the terms of the 51708Sstevel * Common Development and Distribution License (the "License"). 61708Sstevel * You may not use this file except in compliance with the License. 71708Sstevel * 81708Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91708Sstevel * or http://www.opensolaris.org/os/licensing. 101708Sstevel * See the License for the specific language governing permissions 111708Sstevel * and limitations under the License. 121708Sstevel * 131708Sstevel * When distributing Covered Code, include this CDDL HEADER in each 141708Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151708Sstevel * If applicable, add the following below this CDDL HEADER, with the 161708Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 171708Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 181708Sstevel * 191708Sstevel * CDDL HEADER END 201708Sstevel */ 211708Sstevel 221708Sstevel /* 23*5107Seota * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 241708Sstevel * Use is subject to license terms. 251708Sstevel */ 261708Sstevel 271708Sstevel #ifndef _SYS_RMC_COMM_H 281708Sstevel #define _SYS_RMC_COMM_H 291708Sstevel 301708Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 311708Sstevel 321708Sstevel #ifdef __cplusplus 331708Sstevel extern "C" { 341708Sstevel #endif 351708Sstevel 361708Sstevel /* 371708Sstevel * Hardware: serial chip register numbers 381708Sstevel */ 391708Sstevel #define SIO_RXD 0 /* read */ 401708Sstevel #define SIO_TXD 0 /* write */ 411708Sstevel #define SIO_IER 1 421708Sstevel #define SIO_EIR 2 /* read */ 431708Sstevel #define SIO_FCR 2 /* write */ 441708Sstevel #define SIO_LCR 3 451708Sstevel #define SIO_BSR 3 /* wierd */ 461708Sstevel #define SIO_MCR 4 471708Sstevel #define SIO_LSR 5 481708Sstevel #define SIO_MSR 6 491708Sstevel #define SIO_SCR 7 501708Sstevel 511708Sstevel #define SIO_LBGDL 0 /* bank 1 */ 521708Sstevel #define SIO_LBGDH 1 /* bank 1 */ 531708Sstevel 541708Sstevel /* 551708Sstevel * Hardware: serial chip register bits 561708Sstevel */ 571708Sstevel #define SIO_IER_RXHDL_IE 0x01 581708Sstevel #define SIO_IER_STD 0x00 591708Sstevel 601708Sstevel #define SIO_FCR_FIFO_EN 0x01 611708Sstevel #define SIO_FCR_RXSR 0x02 621708Sstevel #define SIO_FCR_TXSR 0x04 631708Sstevel #define SIO_FCR_RXFTH0 0x40 641708Sstevel #define SIO_FCR_STD (SIO_FCR_RXFTH0|SIO_FCR_FIFO_EN) 651708Sstevel 661708Sstevel #define SIO_LCR_WLS0 0x01 671708Sstevel #define SIO_LCR_WLS1 0x02 681708Sstevel #define SIO_LCR_PEN 0x08 691708Sstevel #define SIO_LCR_EPS 0x10 701708Sstevel #define SIO_LCR_BKSE 0x80 711708Sstevel #define SIO_LCR_8BIT (SIO_LCR_WLS0|SIO_LCR_WLS1) 721708Sstevel #define SIO_LCR_STD (SIO_LCR_8BIT) 731708Sstevel #define SIO_BSR_BANK0 (SIO_LCR_STD) 741708Sstevel #define SIO_BSR_BANK1 (SIO_LCR_BKSE|SIO_LCR_STD) 751708Sstevel 761708Sstevel #define SIO_MCR_ISEN 0x08 771708Sstevel #define SIO_MCR_STD (SIO_MCR_ISEN) 781708Sstevel 791708Sstevel /* Line Status Register */ 801708Sstevel #define SIO_LSR_RXDA 0x01 /* data ready */ 811708Sstevel #define SIO_LSR_OVRRUN 0x02 /* overrun error */ 821708Sstevel #define SIO_LSR_PARERR 0x04 /* parity error */ 831708Sstevel #define SIO_LSR_FRMERR 0x08 /* framing error */ 841708Sstevel #define SIO_LSR_BRKDET 0x10 /* a break has arrived */ 851708Sstevel #define SIO_LSR_XHRE 0x20 /* tx hold reg is now empty */ 861708Sstevel #define SIO_LSR_XSRE 0x40 /* tx shift reg is now empty */ 871708Sstevel #define SIO_LSR_RFBE 0x80 /* rx FIFO Buffer error */ 881708Sstevel 891708Sstevel /* 901708Sstevel * Min/max/default baud rates, and a macro to convert from a baud 911708Sstevel * rate to the number (divisor) to put in the baud rate registers 921708Sstevel */ 931708Sstevel #define SIO_BAUD_MIN 50 941708Sstevel #define SIO_BAUD_MAX 115200 951708Sstevel #define SIO_BAUD_DEFAULT 115200 961708Sstevel #define SIO_BAUD_TO_DIVISOR(b) (115200 / (b)) 971708Sstevel #define SIO_BAUD_DIVISOR_MIN 1 981708Sstevel #define SIO_BAUD_DIVISOR_MAX 64 991708Sstevel 1001708Sstevel /* 1011708Sstevel * serial rx buffer size: set to maximum message size + 'bits' 1021708Sstevel * (protocol overhead) 1031708Sstevel */ 1041708Sstevel 1051708Sstevel #define SIO_MAX_RXBUF_SIZE (DP_MAX_MSGLEN + 128) 1061708Sstevel 1071708Sstevel /* 1081708Sstevel * protocol status struct 1091708Sstevel */ 1101708Sstevel 1111708Sstevel typedef struct rmc_comm_serdev_state { 1121708Sstevel 1131708Sstevel ddi_acc_handle_t sio_handle; 1141708Sstevel uint8_t *sio_regs; 1151708Sstevel ddi_softintr_t softid; 116*5107Seota ddi_periodic_t cycid; /* periodical callback */ 1171708Sstevel 1181708Sstevel /* 1191708Sstevel * Hardware mutex (initialised using <hw_iblk>), 1201708Sstevel * used to prevent retriggering the softint while 1211708Sstevel * it's still fetching data out of the chip FIFO. 1221708Sstevel */ 1231708Sstevel kmutex_t hw_mutex[1]; 1241708Sstevel ddi_iblock_cookie_t hw_iblk; 1251708Sstevel boolean_t hw_int_enabled; 1261708Sstevel 1271708Sstevel /* 1281708Sstevel * Flag to indicate that we've incurred a hardware fault on 1291708Sstevel * accesses to the SIO; once this is set, we fake all further 1301708Sstevel * accesses in order not to provoke additional bus errors. 1311708Sstevel */ 1321708Sstevel boolean_t sio_fault; 1331708Sstevel 1341708Sstevel /* 1351708Sstevel * serial device receive buffer 1361708Sstevel */ 1371708Sstevel char serdev_rx_buf[SIO_MAX_RXBUF_SIZE]; 1381708Sstevel uint16_t serdev_rx_count; 1391708Sstevel 1401708Sstevel } rmc_comm_serdev_state_t; 1411708Sstevel 1421708Sstevel /* 1431708Sstevel * This driver's soft-state structure 1441708Sstevel */ 1451708Sstevel struct rmc_comm_state { 1461708Sstevel /* 1471708Sstevel * Configuration data, set during attach 1481708Sstevel */ 1491708Sstevel dev_info_t *dip; 1501708Sstevel major_t majornum; 1511708Sstevel int instance; 1521708Sstevel int n_registrations; 1531708Sstevel boolean_t is_attached; 1541708Sstevel 1551708Sstevel /* 1561708Sstevel * Parameters derived from .conf properties 1571708Sstevel */ 1581708Sstevel int baud; 1591708Sstevel uint32_t debug; 1601708Sstevel int baud_divisor_factor; 1611708Sstevel 1621708Sstevel /* 1631708Sstevel * serial device status... 1641708Sstevel */ 1651708Sstevel rmc_comm_serdev_state_t sd_state; 1661708Sstevel 1671708Sstevel /* 1681708Sstevel * protocol status struct 1691708Sstevel */ 1701708Sstevel rmc_comm_dp_state_t dp_state; 1711708Sstevel 1721708Sstevel /* 1731708Sstevel * driver interface status struct 1741708Sstevel */ 1751708Sstevel rmc_comm_drvintf_state_t drvi_state; 1761708Sstevel }; 1771708Sstevel 1781708Sstevel 1791708Sstevel /* 1801708Sstevel * Time periods, in nanoseconds 1811708Sstevel */ 1821708Sstevel #define RMC_COMM_ONE_SEC 1000000000LL 1831708Sstevel 1841708Sstevel /* 1851708Sstevel * debugging 1861708Sstevel */ 1871708Sstevel 1881708Sstevel #define DSER 0x01 /* serial device */ 1891708Sstevel #define DPRO 0x02 /* protocol */ 1901708Sstevel #define DAPI 0x04 /* API */ 1911708Sstevel #define DPKT 0x08 /* packet handling routine */ 1921708Sstevel #define DGEN 0x10 /* generic */ 1931708Sstevel #define DDSC 0x20 /* datascope */ 1941708Sstevel #define DMEM 0x40 /* memory alloc/release */ 1951708Sstevel 1961708Sstevel #ifdef DEBUG 1971708Sstevel #define DPRINTF(rcs, d, ARGLIST) { if (rcs->debug & d) cmn_err ARGLIST; } 1981708Sstevel #define DATASCOPE(rcs, c, b, l) { int i, j; char s[80]; \ 1991708Sstevel s[0] = (c); \ 2001708Sstevel s[1] = '\0'; \ 2011708Sstevel for (i = 1; i < (l)+1; i++) { \ 2021708Sstevel j = strlen(s); \ 2031708Sstevel (void) sprintf(s+j, "%02x ", \ 2041708Sstevel (uchar_t)b[i-1]); \ 2051708Sstevel if (i%24 == 0) { \ 2061708Sstevel DPRINTF(rcs, DDSC, \ 2071708Sstevel (CE_CONT, "%s\n", s)); \ 2081708Sstevel s[0] = (c); \ 2091708Sstevel s[1] = '\0'; \ 2101708Sstevel } \ 2111708Sstevel } \ 2121708Sstevel if (i%24 != 0) \ 2131708Sstevel DPRINTF(rcs, DDSC, \ 2141708Sstevel (CE_CONT, "%s\n", s)); \ 2151708Sstevel } 2161708Sstevel #else 2171708Sstevel #define DPRINTF(rcs, d, ARGLIST) 2181708Sstevel #define DATASCOPE(rcs, c, b, l) 2191708Sstevel #endif /* DEBUG */ 2201708Sstevel 2211708Sstevel 2221708Sstevel /* 2231708Sstevel * function prototypes 2241708Sstevel */ 2251708Sstevel 2261708Sstevel int rmc_comm_serdev_init(struct rmc_comm_state *, dev_info_t *); 2271708Sstevel void rmc_comm_serdev_fini(struct rmc_comm_state *, dev_info_t *); 2281708Sstevel void rmc_comm_serdev_receive(struct rmc_comm_state *); 2291708Sstevel void rmc_comm_serdev_send(struct rmc_comm_state *, char *, int); 2301708Sstevel void rmc_comm_serdev_drain(struct rmc_comm_state *); 2311708Sstevel struct rmc_comm_state *rmc_comm_getstate(dev_info_t *, int, const char *); 2321708Sstevel int rmc_comm_register(void); 2331708Sstevel void rmc_comm_unregister(void); 2341708Sstevel 2351708Sstevel void rmc_comm_dp_init(struct rmc_comm_state *); 2361708Sstevel void rmc_comm_dp_fini(struct rmc_comm_state *); 2371708Sstevel void rmc_comm_dp_drecv(struct rmc_comm_state *, uint8_t *, int); 2381708Sstevel void rmc_comm_dp_mrecv(struct rmc_comm_state *, uint8_t *); 2391708Sstevel int rmc_comm_dp_msend(struct rmc_comm_state *, dp_message_t *); 2401708Sstevel void rmc_comm_bp_msend(struct rmc_comm_state *, bp_msg_t *); 2411708Sstevel void rmc_comm_bp_srecsend(struct rmc_comm_state *, char *, int); 2421708Sstevel int rmc_comm_dp_ctlsend(struct rmc_comm_state *, uint8_t); 2431708Sstevel void rmc_comm_dp_mcleanup(struct rmc_comm_state *); 2441708Sstevel 2451708Sstevel int rmc_comm_drvintf_init(struct rmc_comm_state *); 2461708Sstevel void rmc_comm_drvintf_fini(struct rmc_comm_state *); 2471708Sstevel 2481708Sstevel #ifdef __cplusplus 2491708Sstevel } 2501708Sstevel #endif 2511708Sstevel 2521708Sstevel #endif /* _SYS_RMC_COMM_H */ 253