android_kernel_samsung_msm8976/include/linux/smux.h
Arun Kumar Neelakantam 5e5c417097 tty: n_smux: add separate close notifications
When an SMUX port state is closed, the close request is sent to the
remote system.  The port cannot be re-opened until the remote system
acknowledges the close request.  If the client attempts to re-open the
port during this time, then the -EAGAIN error code is returned and the
client must keep retrying to open the port.  An event-driven approach
would be better, but the client does not receive local state
notifications, so this is not possible.

Add local and remote closed notifications so clients can handle the
closing state transitions without using polling.

CRs-Fixed: 510114
Change-Id: I48008804d23dbfd05df0becd4bc1c695e599a835
Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
2013-09-04 17:10:05 -07:00

302 lines
7.1 KiB
C

/* include/linux/smux.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_H
#define SMUX_H
/**
* Logical Channel IDs
*
* This must be identical between local and remote clients.
*/
enum {
/* Data Ports */
SMUX_DATA_0,
SMUX_DATA_1,
SMUX_DATA_2,
SMUX_DATA_3,
SMUX_DATA_4,
SMUX_DATA_5,
SMUX_DATA_6,
SMUX_DATA_7,
SMUX_DATA_8,
SMUX_DATA_9,
SMUX_USB_RMNET_DATA_0,
SMUX_USB_DUN_0,
SMUX_USB_DIAG_0,
SMUX_SYS_MONITOR_0,
SMUX_CSVT_0,
/* add new data ports here */
/* Control Ports */
SMUX_DATA_CTL_0 = 32,
SMUX_DATA_CTL_1,
SMUX_DATA_CTL_2,
SMUX_DATA_CTL_3,
SMUX_DATA_CTL_4,
SMUX_DATA_CTL_5,
SMUX_DATA_CTL_6,
SMUX_DATA_CTL_7,
SMUX_DATA_CTL_8,
SMUX_DATA_CTL_9,
SMUX_USB_RMNET_CTL_0,
SMUX_USB_DUN_CTL_0_UNUSED,
SMUX_USB_DIAG_CTL_0,
SMUX_SYS_MONITOR_CTL_0,
SMUX_CSVT_CTL_0,
/* add new control ports here */
SMUX_TEST_LCID,
SMUX_NUM_LOGICAL_CHANNELS,
};
/**
* Notification events that are passed to the notify() function.
*
* If the @metadata argument in the notifier is non-null, then it will
* point to the associated struct smux_meta_* structure.
*/
enum {
SMUX_CONNECTED, /* @metadata is null */
SMUX_DISCONNECTED,
SMUX_READ_DONE,
SMUX_READ_FAIL,
SMUX_WRITE_DONE,
SMUX_WRITE_FAIL,
SMUX_TIOCM_UPDATE,
SMUX_LOW_WM_HIT, /* @metadata is NULL */
SMUX_HIGH_WM_HIT, /* @metadata is NULL */
SMUX_RX_RETRY_HIGH_WM_HIT, /* @metadata is NULL */
SMUX_RX_RETRY_LOW_WM_HIT, /* @metadata is NULL */
SMUX_LOCAL_CLOSED,
SMUX_REMOTE_CLOSED,
};
/**
* Channel options used to modify channel behavior.
*/
enum {
SMUX_CH_OPTION_LOCAL_LOOPBACK = 1 << 0,
SMUX_CH_OPTION_REMOTE_LOOPBACK = 1 << 1,
SMUX_CH_OPTION_REMOTE_TX_STOP = 1 << 2,
SMUX_CH_OPTION_AUTO_REMOTE_TX_STOP = 1 << 3,
};
/**
* Metadata for SMUX_DISCONNECTED notification
*
* @is_ssr: Disconnect caused by subsystem restart
*/
struct smux_meta_disconnected {
int is_ssr;
};
/**
* Metadata for SMUX_READ_DONE/SMUX_READ_FAIL notification
*
* @pkt_priv: Packet-specific private data
* @buffer: Buffer pointer passed into msm_smux_write
* @len: Buffer length passed into msm_smux_write
*/
struct smux_meta_read {
void *pkt_priv;
void *buffer;
int len;
};
/**
* Metadata for SMUX_WRITE_DONE/SMUX_WRITE_FAIL notification
*
* @pkt_priv: Packet-specific private data
* @buffer: Buffer pointer returned by get_rx_buffer()
* @len: Buffer length returned by get_rx_buffer()
*/
struct smux_meta_write {
void *pkt_priv;
void *buffer;
int len;
};
/**
* Metadata for SMUX_TIOCM_UPDATE notification
*
* @tiocm_old: Previous TIOCM state
* @tiocm_new: Current TIOCM state
*/
struct smux_meta_tiocm {
uint32_t tiocm_old;
uint32_t tiocm_new;
};
#ifdef CONFIG_N_SMUX
/**
* Starts the opening sequence for a logical channel.
*
* @lcid Logical channel ID
* @priv Free for client usage
* @notify Event notification function
* @get_rx_buffer Function used to provide a receive buffer to SMUX
*
* @returns 0 for success, <0 otherwise
*
* A channel must be fully closed (either not previously opened or
* msm_smux_close() has been called and the SMUX_DISCONNECTED has been
* recevied.
*
* One the remote side is opened, the client will receive a SMUX_CONNECTED
* event.
*/
int msm_smux_open(uint8_t lcid, 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));
/**
* Starts the closing sequence for a logical channel.
*
* @lcid Logical channel ID
* @returns 0 for success, <0 otherwise
*
* Once the close event has been acknowledge by the remote side, the client
* will receive a SMUX_DISCONNECTED notification.
*/
int msm_smux_close(uint8_t lcid);
/**
* Write data to a logical channel.
*
* @lcid Logical channel ID
* @pkt_priv Client data that will be returned with the SMUX_WRITE_DONE or
* SMUX_WRITE_FAIL notification.
* @data Data to write
* @len Length of @data
*
* @returns 0 for success, <0 otherwise
*
* Data may be written immediately after msm_smux_open() is called, but
* the data will wait in the transmit queue until the channel has been
* fully opened.
*
* Once the data has been written, the client will receive either a completion
* (SMUX_WRITE_DONE) or a failure notice (SMUX_WRITE_FAIL).
*/
int msm_smux_write(uint8_t lcid, void *pkt_priv, const void *data, int len);
/**
* Returns true if the TX queue is currently full (high water mark).
*
* @lcid Logical channel ID
*
* @returns 0 if channel is not full; 1 if it is full; < 0 for error
*/
int msm_smux_is_ch_full(uint8_t lcid);
/**
* Returns true if the TX queue has space for more packets it is at or
* below the low water mark).
*
* @lcid Logical channel ID
*
* @returns 0 if channel is above low watermark
* 1 if it's at or below the low watermark
* < 0 for error
*/
int msm_smux_is_ch_low(uint8_t lcid);
/**
* Get the TIOCM status bits.
*
* @lcid Logical channel ID
*
* @returns >= 0 TIOCM status bits
* < 0 Error condition
*/
long msm_smux_tiocm_get(uint8_t lcid);
/**
* Set/clear the TIOCM status bits.
*
* @lcid Logical channel ID
* @set Bits to set
* @clear Bits to clear
*
* @returns 0 for success; < 0 for failure
*
* If a bit is specified in both the @set and @clear masks, then the clear bit
* definition will dominate and the bit will be cleared.
*/
int msm_smux_tiocm_set(uint8_t lcid, uint32_t set, uint32_t clear);
/**
* Set or clear channel option using the SMUX_CH_OPTION_* channel
* flags.
*
* @lcid Logical channel ID
* @set Options to set
* @clear Options to clear
*
* @returns 0 for success, < 0 for failure
*/
int msm_smux_set_ch_option(uint8_t lcid, uint32_t set, uint32_t clear);
#else
static inline int msm_smux_open(uint8_t lcid, 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))
{
return -ENODEV;
}
static inline int msm_smux_close(uint8_t lcid)
{
return -ENODEV;
}
static inline int msm_smux_write(uint8_t lcid, void *pkt_priv,
const void *data, int len)
{
return -ENODEV;
}
static inline int msm_smux_is_ch_full(uint8_t lcid)
{
return -ENODEV;
}
static inline int msm_smux_is_ch_low(uint8_t lcid)
{
return -ENODEV;
}
static inline long msm_smux_tiocm_get(uint8_t lcid)
{
return 0;
}
static inline int msm_smux_tiocm_set(uint8_t lcid, uint32_t set, uint32_t clear)
{
return -ENODEV;
}
static inline int msm_smux_set_ch_option(uint8_t lcid, uint32_t set,
uint32_t clear)
{
return -ENODEV;
}
#endif /* CONFIG_N_SMUX */
#endif /* SMUX_H */