/* drivers/tty/smux_private.h * * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #ifndef SMUX_PRIVATE_H #define SMUX_PRIVATE_H #define SMUX_MAX_PKT_SIZE 8192 #define SMUX_BROADCAST_LCID 0xFF /* SMUX Protocol Characters */ #define SMUX_MAGIC 0x33FC #define SMUX_MAGIC_WORD1 0xFC #define SMUX_MAGIC_WORD2 0x33 #define SMUX_WAKEUP_REQ 0xFD #define SMUX_WAKEUP_ACK 0xFE /* Unit testing characters */ #define SMUX_UT_ECHO_REQ 0xF0 #define SMUX_UT_ECHO_ACK_OK 0xF1 #define SMUX_UT_ECHO_ACK_FAIL 0xF2 /* Maximum number of packets in retry queue */ #define SMUX_RX_RETRY_MAX_PKTS 128 #define SMUX_RX_WM_HIGH 4 #define SMUX_RX_WM_LOW 0 #define SMUX_TX_WM_LOW 2 #define SMUX_TX_WM_HIGH 4 struct tty_struct; /** * Logical Channel Structure. One instance per channel. * * Locking Hierarchy * Each lock has a postfix that describes the locking level. If multiple locks * are required, only increasing lock hierarchy numbers may be locked which * ensures avoiding a deadlock. * * Locking Example * If state_lock_lhb1 is currently held and the TX list needs to be * manipulated, then tx_lock_lhb2 may be locked since it's locking hierarchy * is greater. However, if tx_lock_lhb2 is held, then state_lock_lhb1 may * not be acquired since it would result in a deadlock. * * Note that the Line Discipline locks (*_lha) should always be acquired * before the logical channel locks. */ struct smux_lch_t { /* channel state */ spinlock_t state_lock_lhb1; uint8_t lcid; unsigned local_state; unsigned local_mode; uint8_t local_tiocm; unsigned options; unsigned remote_state; unsigned remote_mode; uint8_t remote_tiocm; int tx_flow_control; int rx_flow_control_auto; int rx_flow_control_client; /* client callbacks and private data */ void *priv; void (*notify)(void *priv, int event_type, const void *metadata); int (*get_rx_buffer)(void *priv, void **pkt_priv, void **buffer, int size); /* RX Info */ struct list_head rx_retry_queue; unsigned rx_retry_queue_cnt; struct delayed_work rx_retry_work; /* TX Info */ spinlock_t tx_lock_lhb2; struct list_head tx_queue; struct list_head tx_ready_list; unsigned tx_pending_data_cnt; unsigned notify_lwm; }; /* Each instance of smux_lch_t */ extern struct smux_lch_t smux_lch[SMUX_NUM_LOGICAL_CHANNELS]; /* Packet header. */ struct smux_hdr_t { uint16_t magic; uint8_t flags; uint8_t cmd; uint8_t pad_len; uint8_t lcid; uint16_t payload_len; }; /* Internal packet structure. */ struct smux_pkt_t { struct smux_hdr_t hdr; int allocated; unsigned char *payload; int free_payload; struct list_head list; void *priv; }; /* SMUX Packet Commands */ enum { SMUX_CMD_DATA = 0x0, SMUX_CMD_OPEN_LCH = 0x1, SMUX_CMD_CLOSE_LCH = 0x2, SMUX_CMD_STATUS = 0x3, SMUX_CMD_PWR_CTL = 0x4, SMUX_CMD_DELAY = 0x5, SMUX_CMD_BYTE, /* for internal usage */ SMUX_NUM_COMMANDS }; /* Open command flags */ enum { SMUX_CMD_OPEN_ACK = 1 << 0, SMUX_CMD_OPEN_POWER_COLLAPSE = 1 << 1, SMUX_CMD_OPEN_REMOTE_LOOPBACK = 1 << 2, }; /* Close command flags */ enum { SMUX_CMD_CLOSE_ACK = 1 << 0, }; /* Power command flags */ enum { SMUX_CMD_PWR_CTL_ACK = 1 << 0, }; /* Local logical channel states */ enum { SMUX_LCH_LOCAL_CLOSED, SMUX_LCH_LOCAL_OPENING, SMUX_LCH_LOCAL_OPENED, SMUX_LCH_LOCAL_CLOSING, }; /* Remote logical channel states */ enum { SMUX_LCH_REMOTE_CLOSED, SMUX_LCH_REMOTE_OPENED, }; /* Enum used to report various undefined actions */ enum { SMUX_UNDEF_LONG, SMUX_UNDEF_SHORT, }; long msm_smux_tiocm_get_atomic(struct smux_lch_t *ch); const char *local_lch_state(unsigned state); const char *remote_lch_state(unsigned state); const char *lch_mode(unsigned mode); int smux_assert_lch_id(uint32_t lcid); void smux_init_pkt(struct smux_pkt_t *pkt); struct smux_pkt_t *smux_alloc_pkt(void); int smux_alloc_pkt_payload(struct smux_pkt_t *pkt); void smux_free_pkt(struct smux_pkt_t *pkt); int smux_serialize(struct smux_pkt_t *pkt, char *out, unsigned int *out_len); void smux_rx_state_machine(const unsigned char *data, int len, int flag); void smuxld_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count); bool smux_remote_is_active(void); void smux_set_loopback_data_reply_delay(uint32_t ms); void smux_get_wakeup_counts(int *local_cnt, int *remote_cnt); /* testing parameters */ extern int smux_byte_loopback; extern int smux_simulate_wakeup_delay; #endif /* SMUX_PRIVATE_H */