android_kernel_google_msm/drivers/tty/smux_private.h
Eric Holmberg 9359ddb5a2 tty: n_smux: Add function to determine if remote side is active
For subsystem restart unit tests, we need to know when the remote system
is back up to avoid having to add fixed delays.

Add private function to allow checking to see if the remote side is
active.

Change-Id: Ide2f5e4aba01479c2dc1e8c3b4332da7da6ad0c5
Signed-off-by: Eric Holmberg <eholmber@codeaurora.org>
2013-03-07 15:25:20 -08:00

189 lines
4.7 KiB
C

/* drivers/tty/smux_private.h
*
* Copyright (c) 2012, Code Aurora Forum. 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_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);
/* testing parameters */
extern int smux_byte_loopback;
extern int smux_simulate_wakeup_delay;
#endif /* SMUX_PRIVATE_H */