android_kernel_oneplus_msm8998/drivers/platform/msm/mhi/mhi.h
Sujeev Dias 632e3c71d3 mhi: core: fix potential buffer overflow
Fix a potential buffer overflow that could occur
during firmware download by storing buffer address
locally instead of inside MHI context.

CRs-Fixed: 1109397
Change-Id: If27ba602cdafdc8d25a94fdc0d74e8970bf0b0f4
Signed-off-by: Sujeev Dias <sdias@codeaurora.org>
2017-05-24 11:28:32 -07:00

771 lines
21 KiB
C

/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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 _H_MHI
#define _H_MHI
#include "mhi_macros.h"
#include <linux/msm_mhi.h>
#include <linux/types.h>
#include <linux/pm.h>
#include <linux/completion.h>
#include <linux/atomic.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/msm_pcie.h>
#include <linux/sched.h>
#include <linux/irqreturn.h>
#include <linux/list.h>
#include <linux/dma-mapping.h>
struct mhi_device_ctxt;
enum MHI_DEBUG_LEVEL {
MHI_MSG_RAW = 0x1,
MHI_MSG_VERBOSE = 0x2,
MHI_MSG_INFO = 0x4,
MHI_MSG_DBG = 0x8,
MHI_MSG_WARNING = 0x10,
MHI_MSG_ERROR = 0x20,
MHI_MSG_CRITICAL = 0x40,
MHI_MSG_reserved = 0x80000000
};
struct pcie_core_info {
u32 dev_id;
u32 manufact_id;
u32 mhi_ver;
void __iomem *bar0_base;
void __iomem *bar0_end;
u32 irq_base;
u32 max_nr_msis;
u32 domain;
u32 bus;
u32 slot;
struct pci_saved_state *pcie_state;
bool pci_master;
};
struct firmware_info {
const char *fw_image;
size_t max_sbl_len;
size_t segment_size;
};
struct bhie_mem_info {
void *pre_aligned;
void *aligned;
size_t alloc_size;
size_t size;
phys_addr_t phys_addr;
dma_addr_t dma_handle;
};
struct bhie_vec_table {
struct scatterlist *sg_list;
struct bhie_mem_info *bhie_mem_info;
struct bhi_vec_entry *bhi_vec_entry;
unsigned segment_count;
u32 sequence; /* sequence to indicate new xfer */
};
struct bhi_ctxt_t {
void __iomem *bhi_base;
dev_t bhi_dev;
struct cdev cdev;
struct device *dev;
u32 alignment;
u32 poll_timeout;
/* BHI/E vector table */
bool manage_boot; /* fw download done by MHI host */
bool support_rddm;
struct work_struct fw_load_work;
struct firmware_info firmware_info;
struct bhie_vec_table fw_table;
struct bhie_vec_table rddm_table;
size_t rddm_size;
};
enum MHI_CHAN_DIR {
MHI_INVALID = 0x0,
MHI_OUT = 0x1,
MHI_IN = 0x2,
MHI_CHAN_TYPE_reserved = 0x80000000
};
enum MHI_RING_CLASS {
MHI_RING_INVALID = 0x0,
MHI_HW_RING = 0x1,
MHI_SW_RING = 0x2,
MHI_RING_TYPE_reserved = 0x80000000
};
enum MHI_CHAN_STATE {
MHI_CHAN_STATE_DISABLED = 0x0,
MHI_CHAN_STATE_ENABLED = 0x1,
MHI_CHAN_STATE_RUNNING = 0x2,
MHI_CHAN_STATE_SUSPENDED = 0x3,
MHI_CHAN_STATE_STOP = 0x4,
MHI_CHAN_STATE_ERROR = 0x5,
MHI_CHAN_STATE_LIMIT = 0x6,
MHI_CHAN_STATE_reserved = 0x80000000
};
enum MHI_RING_TYPE {
MHI_RING_TYPE_CMD_RING = 0x0,
MHI_RING_TYPE_XFER_RING = 0x1,
MHI_RING_TYPE_EVENT_RING = 0x2,
MHI_RING_TYPE_MAX = 0x4,
MHI_RING_reserved = 0x80000000
};
enum MHI_CHAIN {
MHI_TRE_CHAIN_OFF = 0x0,
MHI_TRE_CHAIN_ON = 0x1,
MHI_TRE_CHAIN_LIMIT = 0x2,
MHI_TRE_CHAIN_reserved = 0x80000000
};
enum MHI_STATE {
MHI_STATE_RESET = 0x0,
MHI_STATE_READY = 0x1,
MHI_STATE_M0 = 0x2,
MHI_STATE_M1 = 0x3,
MHI_STATE_M2 = 0x4,
MHI_STATE_M3 = 0x5,
MHI_STATE_BHI = 0x7,
MHI_STATE_SYS_ERR = 0xFF,
MHI_STATE_LIMIT,
};
enum MHI_BRSTMODE {
/* BRST Mode Enable for HW Channels, SW Channel Disabled */
MHI_BRSTMODE_DEFAULT = 0x0,
MHI_BRSTMODE_RESERVED = 0x1,
MHI_BRSTMODE_DISABLE = 0x2,
MHI_BRSTMODE_ENABLE = 0x3
};
enum MHI_PM_STATE {
MHI_PM_DISABLE = BIT(0), /* MHI is not enabled */
MHI_PM_POR = BIT(1), /* Power On Reset State */
MHI_PM_M0 = BIT(2),
MHI_PM_M1 = BIT(3),
MHI_PM_M1_M2_TRANSITION = BIT(4), /* Register access not allowed */
MHI_PM_M2 = BIT(5),
MHI_PM_M3_ENTER = BIT(6),
MHI_PM_M3 = BIT(7),
MHI_PM_M3_EXIT = BIT(8),
MHI_PM_SYS_ERR_DETECT = BIT(9),
MHI_PM_SYS_ERR_PROCESS = BIT(10),
MHI_PM_SHUTDOWN_PROCESS = BIT(11),
MHI_PM_LD_ERR_FATAL_DETECT = BIT(12), /* Link not accessible */
MHI_PM_SSR_PENDING = BIT(13)
};
struct mhi_pm_transitions {
enum MHI_PM_STATE from_state;
u32 to_states;
};
#define MHI_DB_ACCESS_VALID(pm_state) (pm_state & (MHI_PM_M0 | MHI_PM_M1))
#define MHI_WAKE_DB_ACCESS_VALID(pm_state) (pm_state & (MHI_PM_M0 | \
MHI_PM_M1 | MHI_PM_M2))
#define MHI_REG_ACCESS_VALID(pm_state) ((pm_state & (MHI_PM_POR | MHI_PM_M0 | \
MHI_PM_M1 | MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \
MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \
MHI_PM_SHUTDOWN_PROCESS)))
#define MHI_EVENT_ACCESS_INVALID(pm_state) (pm_state == MHI_PM_DISABLE || \
pm_state >= MHI_PM_SYS_ERR_DETECT)
struct __packed mhi_event_ctxt {
u32 mhi_intmodt;
u32 mhi_event_er_type;
u32 mhi_msi_vector;
u64 mhi_event_ring_base_addr;
u64 mhi_event_ring_len;
u64 mhi_event_read_ptr;
u64 mhi_event_write_ptr;
};
struct __packed mhi_chan_ctxt {
u32 chstate : 8;
u32 brstmode : 2;
u32 pollcfg : 6;
u32 reserved : 16;
u32 chtype;
u32 mhi_event_ring_index;
u64 mhi_trb_ring_base_addr;
u64 mhi_trb_ring_len;
u64 mhi_trb_read_ptr;
u64 mhi_trb_write_ptr;
};
struct __packed mhi_cmd_ctxt {
u32 mhi_cmd_ctxt_reserved1;
u32 mhi_cmd_ctxt_reserved2;
u32 mhi_cmd_ctxt_reserved3;
u64 mhi_cmd_ring_base_addr;
u64 mhi_cmd_ring_len;
u64 mhi_cmd_ring_read_ptr;
u64 mhi_cmd_ring_write_ptr;
};
enum MHI_COMMAND {
MHI_COMMAND_NOOP = 0x0,
MHI_COMMAND_RESET_CHAN = 0x1,
MHI_COMMAND_STOP_CHAN = 0x2,
MHI_COMMAND_START_CHAN = 0x3,
MHI_COMMAND_RESUME_CHAN = 0x4,
MHI_COMMAND_MAX_NR = 0x5,
MHI_COMMAND_reserved = 0x80000000
};
enum MHI_PKT_TYPE {
MHI_PKT_TYPE_RESERVED = 0x0,
MHI_PKT_TYPE_NOOP_CMD = 0x1,
MHI_PKT_TYPE_TRANSFER = 0x2,
MHI_PKT_TYPE_RESET_CHAN_CMD = 0x10,
MHI_PKT_TYPE_STOP_CHAN_CMD = 0x11,
MHI_PKT_TYPE_START_CHAN_CMD = 0x12,
MHI_PKT_TYPE_STATE_CHANGE_EVENT = 0x20,
MHI_PKT_TYPE_CMD_COMPLETION_EVENT = 0x21,
MHI_PKT_TYPE_TX_EVENT = 0x22,
MHI_PKT_TYPE_EE_EVENT = 0x40,
MHI_PKT_TYPE_STALE_EVENT, /* Internal event */
};
struct __packed mhi_tx_pkt {
u64 buffer_ptr;
u32 buf_len;
u32 info;
};
struct __packed mhi_noop_tx_pkt {
u64 reserved1;
u32 reserved2;
u32 info;
};
struct __packed mhi_noop_cmd_pkt {
u64 reserved1;
u32 reserved2;
u32 info;
};
struct __packed mhi_reset_chan_cmd_pkt {
u32 reserved1;
u32 reserved2;
u32 reserved3;
u32 info;
};
struct __packed mhi_ee_state_change_event {
u64 reserved1;
u32 exec_env;
u32 info;
};
struct __packed mhi_xfer_event_pkt {
u64 xfer_ptr;
u32 xfer_details;
u32 info;
};
struct __packed mhi_cmd_complete_event_pkt {
u64 ptr;
u32 code;
u32 info;
};
struct __packed mhi_state_change_event_pkt {
u64 reserved1;
u32 state;
u32 info;
};
union __packed mhi_xfer_pkt {
struct mhi_tx_pkt data_tx_pkt;
struct mhi_noop_tx_pkt noop_tx_pkt;
struct mhi_tx_pkt type;
};
union __packed mhi_cmd_pkt {
struct mhi_reset_chan_cmd_pkt reset_cmd_pkt;
struct mhi_noop_cmd_pkt noop_cmd_pkt;
struct mhi_noop_cmd_pkt type;
};
union __packed mhi_event_pkt {
struct mhi_xfer_event_pkt xfer_event_pkt;
struct mhi_cmd_complete_event_pkt cmd_complete_event_pkt;
struct mhi_state_change_event_pkt state_change_event_pkt;
struct mhi_ee_state_change_event ee_event_pkt;
struct mhi_xfer_event_pkt type;
};
enum MHI_EVENT_CCS {
MHI_EVENT_CC_INVALID = 0x0,
MHI_EVENT_CC_SUCCESS = 0x1,
MHI_EVENT_CC_EOT = 0x2,
MHI_EVENT_CC_OVERFLOW = 0x3,
MHI_EVENT_CC_EOB = 0x4,
MHI_EVENT_CC_OOB = 0x5,
MHI_EVENT_CC_DB_MODE = 0x6,
MHI_EVENT_CC_UNDEFINED_ERR = 0x10,
MHI_EVENT_CC_BAD_TRE = 0x11,
};
struct db_mode {
/* if set do not reset DB_Mode during M0 resume */
u32 preserve_db_state : 1;
u32 db_mode : 1;
enum MHI_BRSTMODE brstmode;
void (*process_db)(struct mhi_device_ctxt *mhi_dev_ctxt,
void __iomem *io_addr, unsigned int chan,
dma_addr_t val);
};
struct mhi_ring {
void *base;
void *wp;
void *rp;
void *ack_rp;
uintptr_t len;
uintptr_t el_size;
u32 overwrite_en;
enum MHI_CHAN_DIR dir;
enum MHI_CHAN_STATE ch_state;
struct db_mode db_mode;
u32 msi_disable_cntr;
u32 msi_enable_cntr;
spinlock_t ring_lock;
struct dma_pool *dma_pool;
struct tasklet_struct ev_task;
struct work_struct ev_worker;
struct mhi_device_ctxt *mhi_dev_ctxt;
int index;
};
enum MHI_CMD_STATUS {
MHI_CMD_NOT_PENDING = 0x0,
MHI_CMD_PENDING = 0x1,
MHI_CMD_RESET_PENDING = 0x2,
MHI_CMD_RESERVED = 0x80000000
};
enum MHI_EVENT_RING_TYPE {
MHI_EVENT_RING_TYPE_INVALID = 0x0,
MHI_EVENT_RING_TYPE_VALID = 0x1,
MHI_EVENT_RING_TYPE_reserved = 0x80000000
};
enum MHI_INIT_ERROR_STAGE {
MHI_INIT_ERROR_STAGE_UNWIND_ALL = 0x1,
MHI_INIT_ERROR_STAGE_DEVICE_CTRL = 0x2,
MHI_INIT_ERROR_STAGE_THREADS = 0x3,
MHI_INIT_ERROR_STAGE_EVENTS = 0x4,
MHI_INIT_ERROR_STAGE_MEM_ZONES = 0x5,
MHI_INIT_ERROR_STAGE_SYNC = 0x6,
MHI_INIT_ERROR_STAGE_THREAD_QUEUES = 0x7,
MHI_INIT_ERROR_TIMERS = 0x8,
MHI_INIT_ERROR_STAGE_RESERVED = 0x80000000
};
enum STATE_TRANSITION {
STATE_TRANSITION_RESET = MHI_STATE_RESET,
STATE_TRANSITION_READY = MHI_STATE_READY,
STATE_TRANSITION_M0 = MHI_STATE_M0,
STATE_TRANSITION_M1 = MHI_STATE_M1,
STATE_TRANSITION_M2 = MHI_STATE_M2,
STATE_TRANSITION_M3 = MHI_STATE_M3,
STATE_TRANSITION_BHI,
STATE_TRANSITION_SBL,
STATE_TRANSITION_AMSS,
STATE_TRANSITION_LINK_DOWN,
STATE_TRANSITION_WAKE,
STATE_TRANSITION_BHIE,
STATE_TRANSITION_RDDM,
STATE_TRANSITION_SYS_ERR = MHI_STATE_SYS_ERR,
STATE_TRANSITION_MAX
};
enum MHI_EXEC_ENV {
MHI_EXEC_ENV_PBL = 0x0,
MHI_EXEC_ENV_SBL = 0x1,
MHI_EXEC_ENV_AMSS = 0x2,
MHI_EXEC_ENV_BHIE = 0x3,
MHI_EXEC_ENV_RDDM = 0x4,
MHI_EXEC_ENV_DISABLE_TRANSITION, /* local EE, not related to mhi spec */
};
struct mhi_chan_info {
u32 chan_nr;
u32 max_desc;
u32 ev_ring;
u32 flags;
};
struct mhi_chan_cfg {
enum MHI_COMMAND current_cmd;
struct mutex chan_lock;
spinlock_t event_lock; /* completion event lock */
struct completion cmd_complete;
struct mhi_cmd_complete_event_pkt cmd_event_pkt;
union mhi_cmd_pkt cmd_pkt;
};
struct mhi_client_config {
struct mhi_chan_info chan_info;
struct mhi_device_ctxt *mhi_dev_ctxt;
struct mhi_client_info_t client_info;
void *user_data;
struct mhi_result result;
u32 device_index;
u32 msi_vec;
u32 intmod_t;
u32 pkt_count;
int magic;
int chan_status;
int event_ring_index;
};
enum MHI_TYPE_EVENT_RING {
MHI_ER_DATA_TYPE = 0x1,
MHI_ER_CTRL_TYPE = 0x2,
MHI_ER_TYPE_RESERVED = 0x80000000
};
struct mhi_state_work_queue {
spinlock_t *q_lock;
struct mhi_ring q_info;
u32 queue_full_cntr;
enum STATE_TRANSITION buf[MHI_WORK_Q_MAX_SIZE];
};
struct mhi_buf_info {
dma_addr_t bb_p_addr;
dma_addr_t pre_alloc_p_addr;
void *bb_v_addr;
void *pre_alloc_v_addr;
void *client_buf;
size_t buf_len;
size_t pre_alloc_len;
size_t filled_size;
enum dma_data_direction dir;
int bb_active;
};
struct mhi_counters {
u32 m0_m1;
u32 m1_m2;
u32 m2_m0;
u32 m0_m3;
u32 m1_m3;
u32 m3_m0;
u32 chan_pkts_xferd[MHI_MAX_CHANNELS];
u32 bb_used[MHI_MAX_CHANNELS];
atomic_t device_wake;
atomic_t outbound_acks;
u32 *msi_counter;
u32 mhi_reset_cntr;
u32 link_down_cntr;
u32 link_up_cntr;
};
struct mhi_flags {
bool mhi_initialized;
u32 link_up;
bool bb_required;
};
struct mhi_wait_queues {
wait_queue_head_t *m0_event;
wait_queue_head_t *m3_event;
wait_queue_head_t *bhi_event;
};
struct dev_mmio_info {
void __iomem *mmio_addr;
void __iomem *chan_db_addr;
void __iomem *event_db_addr;
void __iomem *cmd_db_addr;
u64 mmio_len;
u32 nr_event_rings;
u32 nr_hw_event_rings;
u32 nr_sw_event_rings;
u32 nr_sw_xfer_rings;
u32 nr_hw_xfer_rings;
dma_addr_t dma_ev_ctxt; /* Bus address of ECABAP*/
};
struct mhi_ring_ctxt {
struct mhi_event_ctxt *ec_list;
struct mhi_chan_ctxt *cc_list;
struct mhi_cmd_ctxt *cmd_ctxt;
dma_addr_t dma_ec_list;
dma_addr_t dma_cc_list;
dma_addr_t dma_cmd_ctxt;
};
struct mhi_dev_space {
void *dev_mem_start;
dma_addr_t dma_dev_mem_start;
size_t dev_mem_len;
struct mhi_ring_ctxt ring_ctxt;
u64 start_win_addr;
u64 end_win_addr;
};
struct mhi_device_ctxt {
struct list_head node;
struct pcie_core_info core;
struct msm_pcie_register_event mhi_pci_link_event;
struct pci_dev *pcie_device;
struct bhi_ctxt_t bhi_ctxt;
struct platform_device *plat_dev;
enum MHI_PM_STATE mhi_pm_state; /* Host driver state */
enum MHI_STATE mhi_state; /* protocol state */
enum MHI_EXEC_ENV dev_exec_env;
struct mhi_dev_space dev_space;
struct mhi_ring chan_bb_list[MHI_MAX_CHANNELS];
struct mhi_ring mhi_local_chan_ctxt[MHI_MAX_CHANNELS];
struct mhi_ring *mhi_local_event_ctxt;
struct mhi_ring mhi_local_cmd_ctxt[NR_OF_CMD_RINGS];
struct mhi_chan_cfg mhi_chan_cfg[MHI_MAX_CHANNELS];
struct mhi_client_handle *client_handle_list[MHI_MAX_CHANNELS];
struct mhi_event_ring_cfg *ev_ring_props;
struct work_struct st_thread_worker;
struct work_struct process_m1_worker;
struct work_struct process_sys_err_worker;
struct mhi_wait_queues mhi_ev_wq;
struct dev_mmio_info mmio_info;
struct mhi_state_work_queue state_change_work_item_list;
struct mhi_counters counters;
struct mhi_flags flags;
struct hrtimer m1_timer;
ktime_t m1_timeout;
u32 poll_reset_timeout_ms;
struct notifier_block mhi_ssr_nb;
struct esoc_desc *esoc_handle;
void *esoc_ssr_handle;
u32 bus_client;
struct msm_bus_scale_pdata *bus_scale_table;
struct notifier_block mhi_cpu_notifier;
unsigned long esoc_notif;
enum STATE_TRANSITION base_state;
rwlock_t pm_xfer_lock; /* lock to control PM State */
spinlock_t dev_wake_lock; /* lock to set wake bit */
struct mutex pm_lock;
struct wakeup_source w_lock;
char *chan_info;
struct dentry *child;
struct dentry *parent;
void *mhi_ipc_log;
/* Shadow functions since not all device supports runtime pm */
int (*bus_master_rt_get)(struct pci_dev *pci_dev);
void (*bus_master_rt_put)(struct pci_dev *pci_dev);
void (*runtime_get)(struct mhi_device_ctxt *mhi_dev_ctxt);
void (*runtime_put)(struct mhi_device_ctxt *mhi_dev_ctxt);
void (*assert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt,
bool force_set);
void (*deassert_wake)(struct mhi_device_ctxt *mhi_dev_ctxt);
void (*status_cb)(enum MHI_CB_REASON, void *priv);
void *priv_data; /* private data for bus master */
struct completion cmd_complete;
};
struct mhi_device_driver {
struct mutex lock;
struct list_head head;
struct class *mhi_bhi_class;
struct dentry *parent;
};
struct mhi_event_ring_cfg {
u32 nr_desc;
u32 msi_vec;
u32 intmod;
enum MHI_CLIENT_CHANNEL chan;
u32 flags;
/*
* Priority of event handling:
* 0 = highest, handle events in isr (reserved for future)
* 1 = handles event using tasklet
* 2 = handles events using workerthread
*/
u32 priority;
enum MHI_RING_CLASS class;
irqreturn_t (*mhi_handler_ptr)(int , void *);
};
#define MHI_EV_PRIORITY_TASKLET (1)
struct mhi_data_buf {
dma_addr_t bounce_buffer;
dma_addr_t client_buffer;
u32 bounce_flag;
};
extern struct mhi_device_driver *mhi_device_drv;
irqreturn_t mhi_msi_ipa_handlr(int irq_number, void *dev_id);
int mhi_reset_all_thread_queues(
struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_add_elements_to_event_rings(
struct mhi_device_ctxt *mhi_dev_ctxt,
enum STATE_TRANSITION new_state);
int get_nr_avail_ring_elements(struct mhi_device_ctxt *mhi_dev_ctxt,
struct mhi_ring *ring);
int get_nr_enclosed_el(struct mhi_ring *ring, void *loc_1,
void *loc_2, u32 *nr_el);
int mhi_init_mmio(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_init_device_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_init_local_event_ring(struct mhi_device_ctxt *mhi_dev_ctxt,
u32 nr_ev_el, u32 event_ring_index);
int mhi_send_cmd(struct mhi_device_ctxt *dest_device,
enum MHI_COMMAND which_cmd, u32 chan);
int mhi_queue_tx_pkt(struct mhi_device_ctxt *mhi_dev_ctxt,
enum MHI_CLIENT_CHANNEL chan,
void *payload,
size_t payload_size);
int mhi_init_chan_ctxt(struct mhi_chan_ctxt *cc_list,
uintptr_t trb_list_phy,
uintptr_t trb_list_virt,
u64 el_per_ring,
enum MHI_CHAN_DIR chan_type,
u32 event_ring,
struct mhi_ring *ring,
enum MHI_CHAN_STATE chan_state,
bool preserve_db_state,
enum MHI_BRSTMODE brstmode);
int mhi_populate_event_cfg(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_get_event_ring_for_channel(struct mhi_device_ctxt *mhi_dev_ctxt,
u32 chan);
int delete_element(struct mhi_ring *ring, void **rp,
void **wp, void **assigned_addr);
int ctxt_add_element(struct mhi_ring *ring, void **assigned_addr);
int ctxt_del_element(struct mhi_ring *ring, void **assigned_addr);
int get_element_index(struct mhi_ring *ring, void *address,
uintptr_t *index);
int recycle_trb_and_ring(struct mhi_device_ctxt *mhi_dev_ctxt,
struct mhi_ring *ring, enum MHI_RING_TYPE ring_type, u32 ring_index);
int parse_xfer_event(struct mhi_device_ctxt *ctxt,
union mhi_event_pkt *event, u32 event_id);
enum MHI_EVENT_CCS get_cmd_pkt(struct mhi_device_ctxt *mhi_dev_ctxt,
union mhi_event_pkt *ev_pkt,
union mhi_cmd_pkt **cmd_pkt, u32 event_index);
int parse_cmd_event(struct mhi_device_ctxt *ctxt,
union mhi_event_pkt *event, u32 event_index);
int mhi_test_for_device_ready(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_test_for_device_reset(struct mhi_device_ctxt *mhi_dev_ctxt);
int validate_ring_el_addr(struct mhi_ring *ring, uintptr_t addr);
int validate_ev_el_addr(struct mhi_ring *ring, uintptr_t addr);
void mhi_state_change_worker(struct work_struct *work);
void mhi_sys_err_worker(struct work_struct *work);
int mhi_init_state_transition(struct mhi_device_ctxt *mhi_dev_ctxt,
enum STATE_TRANSITION new_state);
int mhi_wait_for_mdm(struct mhi_device_ctxt *mhi_dev_ctxt);
enum hrtimer_restart mhi_initiate_m1(struct hrtimer *timer);
int mhi_pci_suspend(struct device *dev);
int mhi_pci_resume(struct device *dev);
int mhi_init_pcie_device(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_init_pm_sysfs(struct device *dev);
void mhi_rem_pm_sysfs(struct device *dev);
void mhi_pci_remove(struct pci_dev *mhi_device);
int mhi_ctxt_init(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_get_chan_max_buffers(u32 chan);
int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_link_state_cb(struct msm_pcie_notify *notify);
void mhi_notify_clients(struct mhi_device_ctxt *mhi_dev_ctxt,
enum MHI_CB_REASON reason);
void mhi_notify_client(struct mhi_client_handle *client_handle,
enum MHI_CB_REASON reason);
void mhi_master_mode_runtime_get(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_master_mode_runtime_put(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_slave_mode_runtime_get(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_slave_mode_runtime_put(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_deassert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_assert_device_wake(struct mhi_device_ctxt *mhi_dev_ctxt,
bool force_set);
int mhi_reg_notifiers(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_cpu_notifier_cb(struct notifier_block *nfb, unsigned long action,
void *hcpu);
int init_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_turn_off_pcie_link(struct mhi_device_ctxt *mhi_dev_ctxt, bool graceful);
int mhi_turn_on_pcie_link(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_initiate_m0(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_initiate_m3(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_set_bus_request(struct mhi_device_ctxt *mhi_dev_ctxt,
int index);
int start_chan_sync(struct mhi_client_handle *client_handle);
void mhi_process_db_brstmode(struct mhi_device_ctxt *mhi_dev_ctxt,
void __iomem *io_addr, unsigned int chan,
dma_addr_t val);
void mhi_process_db_brstmode_disable(struct mhi_device_ctxt *mhi_dev_ctxt,
void __iomem *io_addr, unsigned int chan,
dma_addr_t val);
void mhi_process_db(struct mhi_device_ctxt *mhi_dev_ctxt, void __iomem *io_addr,
unsigned int chan, dma_addr_t val);
void mhi_reg_write_field(struct mhi_device_ctxt *mhi_dev_ctxt,
void __iomem *io_addr,
uintptr_t io_offset,
u32 mask, u32 shift, u32 val);
void mhi_reg_write(struct mhi_device_ctxt *mhi_dev_ctxt,
void __iomem *io_addr, uintptr_t io_offset, u32 val);
u32 mhi_reg_read(void __iomem *io_addr, uintptr_t io_offset);
u32 mhi_reg_read_field(void __iomem *io_addr, uintptr_t io_offset,
u32 mask, u32 shift);
void mhi_exit_m2(struct mhi_device_ctxt *mhi_dev_ctxt);
int mhi_runtime_suspend(struct device *dev);
int get_chan_props(struct mhi_device_ctxt *mhi_dev_ctxt, int chan,
struct mhi_chan_info *chan_info);
int mhi_runtime_resume(struct device *dev);
int mhi_runtime_idle(struct device *dev);
int init_ev_rings(struct mhi_device_ctxt *mhi_dev_ctxt,
enum MHI_TYPE_EVENT_RING type);
void mhi_reset_ev_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt,
int index);
void init_event_ctxt_array(struct mhi_device_ctxt *mhi_dev_ctxt);
int create_local_ev_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt);
enum MHI_STATE mhi_get_m_state(struct mhi_device_ctxt *mhi_dev_ctxt);
void process_m1_transition(struct work_struct *work);
int set_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt);
void mhi_set_m_state(struct mhi_device_ctxt *mhi_dev_ctxt,
enum MHI_STATE new_state);
const char *state_transition_str(enum STATE_TRANSITION state);
void mhi_ev_task(unsigned long data);
void process_event_ring(struct work_struct *work);
int process_m0_transition(struct mhi_device_ctxt *mhi_dev_ctxt);
int process_m3_transition(struct mhi_device_ctxt *mhi_dev_ctxt);
enum MHI_PM_STATE __must_check mhi_tryset_pm_state(struct mhi_device_ctxt *,
enum MHI_PM_STATE);
void mhi_reset_chan(struct mhi_device_ctxt *mhi_dev_ctxt, int chan);
void free_tre_ring(struct mhi_device_ctxt *mhi_dev_ctxt, int chan);
void process_disable_transition(enum MHI_PM_STATE transition_state,
struct mhi_device_ctxt *mhi_dev_ctxt);
bool mhi_in_sys_err(struct mhi_device_ctxt *mhi_dev_ctxt);
void bhi_exit(struct mhi_device_ctxt *mhi_dev_ctxt);
#endif