Loading arch/arm/mach-msm/include/mach/msm_ipc_router.h +116 −6 Original line number Diff line number Diff line Loading @@ -27,9 +27,41 @@ * enum msm_ipc_router_event - Events that will be generated by IPC Router */ enum msm_ipc_router_event { MSM_IPC_ROUTER_READ_CB = 0, MSM_IPC_ROUTER_WRITE_DONE, MSM_IPC_ROUTER_RESUME_TX, IPC_ROUTER_CTRL_CMD_DATA = 1, IPC_ROUTER_CTRL_CMD_HELLO, IPC_ROUTER_CTRL_CMD_BYE, IPC_ROUTER_CTRL_CMD_NEW_SERVER, IPC_ROUTER_CTRL_CMD_REMOVE_SERVER, IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT, IPC_ROUTER_CTRL_CMD_RESUME_TX, }; /** * rr_control_msg - Control message structure * @cmd: Command identifier for HELLO message in Version 1. * @hello: Message structure for HELLO message in Version 2. * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. * @cli: Message structure for REMOVE_CLIENT event. */ union rr_control_msg { uint32_t cmd; struct { uint32_t cmd; uint32_t magic; uint32_t capability; } hello; struct { uint32_t cmd; uint32_t service; uint32_t instance; uint32_t node_id; uint32_t port_id; } srv; struct { uint32_t cmd; uint32_t node_id; uint32_t port_id; } cli; }; struct comm_mode_info { Loading @@ -37,6 +69,32 @@ struct comm_mode_info { void *xprt_info; }; /** * msm_ipc_port - Definition of IPC Router port * @list: List(local/control ports) in which this port is present. * @this_port: Contains port's node_id and port_id information. * @port_name: Contains service & instance info if the port hosts a service. * @type: Type of the port - Client, Service, Control or Security Config. * @flags: Flags to identify the port state. * @port_lock: Lock to protect access to the port information. * @mode_info: Communication mode of the port owner. * @port_rx_q: Receive queue where incoming messages are queued. * @port_rx_q_lock_lhb3: Lock to protect access to the port's rx_q. * @rx_wakelock_name: Name of the receive wakelock. * @port_rx_wake_lock: Wakelock to prevent suspend until the rx_q is empty. * @port_rx_wait_q: Wait queue to wait for the incoming messages. * @restart_state: Flag to hold the restart state information. * @restart_lock: Lock to protect access to the restart_state. * @restart_wait: Wait Queue to wait for any restart events. * @endpoint: Contains the information related to user-space interface. * @notify: Function to notify the incoming events on the port. * @check_send_permissions: Function to check access control from this port. * @num_tx: Number of packets transmitted. * @num_rx: Number of packets received. * @num_tx_bytes: Number of bytes transmitted. * @num_rx_bytes: Number of bytes received. * @priv: Private information registered by the port owner. */ struct msm_ipc_port { struct list_head list; Loading @@ -58,7 +116,8 @@ struct msm_ipc_port { wait_queue_head_t restart_wait; void *endpoint; void (*notify)(unsigned event, void *priv); void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv); int (*check_send_permissions)(void *data); uint32_t num_tx; Loading @@ -72,14 +131,27 @@ struct msm_ipc_port { /** * msm_ipc_router_create_port() - Create a IPC Router port/endpoint * @notify: Callback function to notify any event on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private info to be passed while the notification is generated. * * @return: Pointer to the port on success, NULL on error. */ struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv); /** * msm_ipc_router_bind_control_port() - Bind a port as a control port * @port_ptr: Port which needs to be marked as a control port. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); /** * msm_ipc_router_lookup_server_name() - Resolve server address * @srv_name: Name<service:instance> of the server to be resolved. Loading Loading @@ -139,15 +211,40 @@ int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, */ int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr); /** * msm_ipc_router_register_server() - Register a service on a port * @server_port: IPC Router port with which a service is registered. * @name: Service name <service_id:instance_id> that gets registered. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_register_server(struct msm_ipc_port *server_port, struct msm_ipc_addr *name); /** * msm_ipc_router_unregister_server() - Unregister a service from a port * @server_port: Port with with a service is already registered. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port); #else struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { return NULL; } static inline int msm_ipc_router_bind_control_port( struct msm_ipc_port *port_ptr) { return -ENODEV; } int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, struct msm_ipc_server_info *srv_info, int num_entries_in_array, Loading Loading @@ -181,6 +278,19 @@ int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr) return -ENODEV; } static inline int msm_ipc_router_register_server( struct msm_ipc_port *server_port, struct msm_ipc_addr *name) { return -ENODEV; } static inline int msm_ipc_router_unregister_server( struct msm_ipc_port *server_port) { return -ENODEV; } #endif #endif arch/arm/mach-msm/include/mach/msm_qmi_interface.h +209 −8 Original line number Diff line number Diff line Loading @@ -30,24 +30,55 @@ enum qmi_event_type { QMI_SERVER_EXIT, }; /** * struct qmi_handle - QMI Handle Data Structure * @src_port: Pointer to port used for message exchange. * @ctl_port: Pointer to port used for out-of-band event exchange. * @handle_type: Type of handle(Service/Client). * @next_txn_id: Transaction ID of the next outgoing request. * @handle_lock: Lock to protect access to elements in the handle. * @notify_lock: Lock to protect and generate notification atomically. * @notify: Function to notify the handle owner of an event. * @notify_priv: Private info to be passed during the notifcation. * @handle_reset: Flag to hold the reset state of the handle. * @reset_waitq: Wait queue to wait for any reset events. * @ctl_work: Work to handle the out-of-band events for this handle. * @dest_info: Destination to which this handle is connected to. * @txn_list: List of transactions waiting for the response. * @ind_cb: Function to notify the handle owner of an indication message. * @ind_cb_priv: Private info to be passed during an indication notification. * @resume_tx_work: Work to resume the tx when the transport is not busy. * @pending_txn_list: List of requests pending tx due to busy transport. * @conn_list: List of connections handled by the service. * @svc_ops_options: Service specific operations and options. */ struct qmi_handle { void *src_port; void *dest_info; void *ctl_port; unsigned handle_type; uint16_t next_txn_id; struct list_head txn_list; struct mutex handle_lock; spinlock_t notify_lock; void (*notify)(struct qmi_handle *handle, enum qmi_event_type event, void *notify_priv); void *notify_priv; int handle_reset; wait_queue_head_t reset_waitq; struct delayed_work ctl_work; /* Client specific elements */ void *dest_info; struct list_head txn_list; void (*ind_cb)(struct qmi_handle *handle, unsigned int msg_id, void *msg, unsigned int msg_len, void *ind_cb_priv); void *ind_cb_priv; int handle_reset; wait_queue_head_t reset_waitq; struct list_head pending_txn_list; struct delayed_work resume_tx_work; struct list_head pending_txn_list; /* Service specific elements */ struct list_head conn_list; struct qmi_svc_ops_options *svc_ops_options; }; enum qmi_result_type_v01 { Loading @@ -60,14 +91,17 @@ enum qmi_result_type_v01 { enum qmi_error_type_v01 { /* To force a 32 bit signed enum. Do not change or use*/ QMI_ERROR_TYPE_MIN_ENUM_VAL_V01 = INT_MIN, QMI_ERR_TYPE_MIN_ENUM_VAL_V01 = INT_MIN, QMI_ERR_NONE_V01 = 0x0000, QMI_ERROR_MALFORMED_MSG_V01 = 0x0001, QMI_ERR_MALFORMED_MSG_V01 = 0x0001, QMI_ERR_NO_MEMORY_V01 = 0x0002, QMI_ERR_INTERNAL_V01 = 0x0003, QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 = 0x0005, QMI_ERR_INVALID_ID_V01 = 0x0029, QMI_ERR_ENCODING_V01 = 0x003A, QMI_ERR_INCOMPATIBLE_STATE_V01 = 0x005A, QMI_ERROR_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, QMI_ERR_NOT_SUPPORTED_V01 = 0x005E, QMI_ERR_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, }; struct qmi_response_type_v01 { Loading @@ -75,6 +109,37 @@ struct qmi_response_type_v01 { enum qmi_error_type_v01 error; }; /** * qmi_svc_ops_options - Operations and options to be specified when * a service registers. * @version: Version field to identify the ops_options structure. * @service_id: Service ID of the service. * @service_vers: Version to identify the client-service compatibility. * @service_ins: Instance ID registered by the service. * @connect_cb: Callback when a new client connects with the service. * @disconnect_cb: Callback when the client exits the connection. * @req_desc_cb: Callback to get request structure and its descriptor * for a message id. * @req_cb: Callback to process the request. */ struct qmi_svc_ops_options { unsigned version; uint32_t service_id; uint32_t service_vers; uint32_t service_ins; int (*connect_cb)(struct qmi_handle *handle, void *conn_handle); int (*disconnect_cb)(struct qmi_handle *handle, void *conn_handle); int (*req_desc_cb)(unsigned int msg_id, struct msg_desc **req_desc); int (*req_cb)(struct qmi_handle *handle, void *conn_handle, void *req_handle, unsigned int msg_id, void *req); }; #ifdef CONFIG_MSM_QMI_INTERFACE /* Element info array describing common qmi response structure */ Loading Loading @@ -211,6 +276,93 @@ int qmi_svc_event_notifier_unregister(uint32_t service_id, uint32_t service_vers, uint32_t service_ins, struct notifier_block *nb); /** * qmi_svc_register() - Register a QMI service with a QMI handle * @handle: QMI handle on which the service has to be registered. * @ops_options: Service specific operations and options. * * @return: 0 if successfully registered, < 0 on error. */ int qmi_svc_register(struct qmi_handle *handle, void *ops_options); /** * qmi_send_resp() - Send response to a request * @handle: QMI handle from which the response is sent. * @clnt: Client to which the response is sent. * @req_handle: Request for which the response is sent. * @resp_desc: Descriptor explaining the response structure. * @resp: Pointer to the response structure. * @resp_len: Length of the response structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_resp(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len); /** * qmi_send_resp_from_cb() - Send response to a request from request_cb * @handle: QMI handle from which the response is sent. * @clnt: Client to which the response is sent. * @req_handle: Request for which the response is sent. * @resp_desc: Descriptor explaining the response structure. * @resp: Pointer to the response structure. * @resp_len: Length of the response structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_resp_from_cb(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len); /** * qmi_send_ind() - Send unsolicited event/indication to a client * @handle: QMI handle from which the indication is sent. * @clnt: Client to which the indication is sent. * @ind_desc: Descriptor explaining the indication structure. * @ind: Pointer to the indication structure. * @ind_len: Length of the indication structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_ind(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len); /** * qmi_send_ind_from_cb() - Send indication to a client from registration_cb * @handle: QMI handle from which the indication is sent. * @clnt: Client to which the indication is sent. * @ind_desc: Descriptor explaining the indication structure. * @ind: Pointer to the indication structure. * @ind_len: Length of the indication structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_ind_from_cb(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len); /** * qmi_svc_unregister() - Unregister the service from a QMI handle * @handle: QMI handle from which the service has to be unregistered. * * return: 0 on success, < 0 on error. */ int qmi_svc_unregister(struct qmi_handle *handle); #else #define get_qmi_response_type_v01_ei() NULL Loading Loading @@ -289,6 +441,55 @@ static inline int qmi_svc_event_notifier_unregister(uint32_t service_id, return -ENODEV; } static inline int qmi_svc_register(struct qmi_handle *handle, void *ops_options) { return -ENODEV; } static inline int qmi_send_resp(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len) { return -ENODEV; } static inline int qmi_send_resp_from_cb(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len) { return -ENODEV; } static inline int qmi_send_ind(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len) { return -ENODEV; } static inline int qmi_send_ind_from_cb(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len) { return -ENODEV; } static inline int qmi_svc_unregister(struct qmi_handle *handle) { return -ENODEV; } #endif #endif arch/arm/mach-msm/ipc_router.c +39 −15 Original line number Diff line number Diff line Loading @@ -819,7 +819,8 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, struct rr_packet *pkt, int clone) { struct rr_packet *temp_pkt = pkt; void (*notify)(unsigned event, void *priv); void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv); if (unlikely(!port_ptr || !pkt)) return -EINVAL; Loading @@ -841,7 +842,7 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, notify = port_ptr->notify; mutex_unlock(&port_ptr->port_rx_q_lock_lhb3); if (notify) notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv); notify(pkt->hdr.type, NULL, 0, port_ptr->priv); return 0; } Loading Loading @@ -908,8 +909,24 @@ void msm_ipc_router_add_local_port(struct msm_ipc_port *port_ptr) up_write(&local_ports_lock_lha2); } /** * msm_ipc_router_create_raw_port() - Create an IPC Router port * @endpoint: User-space space socket information to be cached. * @notify: Function to notify incoming events on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private Data to be passed during the event notification. * * @return: Valid pointer to port on success, NULL on failure. * * This function is used to create an IPC Router port. The port is used for * communication locally or outside the subsystem. */ struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint, void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { struct msm_ipc_port *port_ptr; Loading Loading @@ -1071,6 +1088,7 @@ static int msm_ipc_router_lookup_resume_tx_port( * post_resume_tx() - Post the resume_tx event * @rport_ptr: Pointer to the remote port * @pkt : The data packet that is received on a resume_tx event * @msg: Out of band data to be passed to kernel drivers * * This function informs about the reception of the resume_tx message from a * remote port pointed by rport_ptr to all the local ports that are in the Loading @@ -1081,7 +1099,7 @@ static int msm_ipc_router_lookup_resume_tx_port( * Must be called with rport_ptr->quota_lock_lhb2 locked. */ static void post_resume_tx(struct msm_ipc_router_remote_port *rport_ptr, struct rr_packet *pkt) struct rr_packet *pkt, union rr_control_msg *msg) { struct msm_ipc_resume_tx_port *rtx_port, *tmp_rtx_port; struct msm_ipc_port *local_port; Loading @@ -1091,8 +1109,8 @@ static void post_resume_tx(struct msm_ipc_router_remote_port *rport_ptr, local_port = msm_ipc_router_lookup_local_port(rtx_port->port_id); if (local_port && local_port->notify) local_port->notify(MSM_IPC_ROUTER_RESUME_TX, local_port->priv); local_port->notify(IPC_ROUTER_CTRL_CMD_RESUME_TX, msg, sizeof(*msg), local_port->priv); else if (local_port) post_pkt_to_port(local_port, pkt, 1); else Loading Loading @@ -1417,8 +1435,6 @@ static char *type_to_str(int i) return "rmv_clnt"; case IPC_ROUTER_CTRL_CMD_RESUME_TX: return "resum_tx"; case IPC_ROUTER_CTRL_CMD_EXIT: return "cmd_exit"; default: return "invalid"; } Loading Loading @@ -1901,7 +1917,7 @@ static int process_resume_tx_msg(union rr_control_msg *msg, } mutex_lock(&rport_ptr->quota_lock_lhb2); rport_ptr->tx_quota_cnt = 0; post_resume_tx(rport_ptr, pkt); post_resume_tx(rport_ptr, pkt, msg); mutex_unlock(&rport_ptr->quota_lock_lhb2); prtm_out: up_read(&routing_table_lock_lha3); Loading Loading @@ -2075,10 +2091,6 @@ static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info, case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT: rc = process_rmv_client_msg(xprt_info, msg, pkt); break; case IPC_ROUTER_CTRL_CMD_PING: /* No action needed for ping messages received */ RR("o PING\n"); break; default: RR("o UNKNOWN(%08x)\n", msg->cmd); rc = -ENOSYS; Loading Loading @@ -2766,8 +2778,20 @@ int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, return 0; } /** * msm_ipc_router_create_port() - Create a IPC Router port/endpoint * @notify: Callback function to notify any event on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private info to be passed while the notification is generated. * * @return: Pointer to the port on success, NULL on error. */ struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { struct msm_ipc_port *port_ptr; Loading arch/arm/mach-msm/ipc_router.h +20 −42 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <net/sock.h> #include <mach/msm_ipc_router.h> /* definitions for the R2R wire protcol */ #define IPC_ROUTER_V1 1 /* Loading @@ -36,16 +38,6 @@ #define IPC_ROUTER_NID_LOCAL 1 #define MAX_IPC_PKT_SIZE 66000 #define IPC_ROUTER_CTRL_CMD_DATA 1 #define IPC_ROUTER_CTRL_CMD_HELLO 2 #define IPC_ROUTER_CTRL_CMD_BYE 3 #define IPC_ROUTER_CTRL_CMD_NEW_SERVER 4 #define IPC_ROUTER_CTRL_CMD_REMOVE_SERVER 5 #define IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT 6 #define IPC_ROUTER_CTRL_CMD_RESUME_TX 7 #define IPC_ROUTER_CTRL_CMD_EXIT 8 #define IPC_ROUTER_CTRL_CMD_PING 9 #define IPC_ROUTER_DEFAULT_RX_QUOTA 5 #define IPC_ROUTER_XPRT_EVENT_DATA 1 Loading Loading @@ -78,34 +70,6 @@ enum { MULTI_LINK_MODE, }; /** * rr_control_msg - Control message structure * @cmd: Command identifier for HELLO message in Version 1. * @hello: Message structure for HELLO message in Version 2. * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. * @cli: Message structure for REMOVE_CLIENT event. */ union rr_control_msg { uint32_t cmd; struct { uint32_t cmd; uint32_t magic; uint32_t capability; } hello; struct { uint32_t cmd; uint32_t service; uint32_t instance; uint32_t node_id; uint32_t port_id; } srv; struct { uint32_t cmd; uint32_t node_id; uint32_t port_id; } cli; }; /** * rr_header_v1 - IPC Router header version 1 * @version: Version information. Loading Loading @@ -217,9 +181,24 @@ void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt, struct rr_packet *clone_pkt(struct rr_packet *pkt); void release_pkt(struct rr_packet *pkt); /** * msm_ipc_router_create_raw_port() - Create an IPC Router port * @endpoint: User-space space socket information to be cached. * @notify: Function to notify incoming events on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private Data to be passed during the event notification. * * @return: Valid pointer to port on success, NULL on failure. * * This function is used to create an IPC Router port. The port is used for * communication locally or outside the subsystem. */ struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint, void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv); int msm_ipc_router_send_to(struct msm_ipc_port *src, struct sk_buff_head *data, Loading @@ -227,7 +206,6 @@ int msm_ipc_router_send_to(struct msm_ipc_port *src, int msm_ipc_router_read(struct msm_ipc_port *port_ptr, struct rr_packet **pkt, size_t buf_len); int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr, struct rr_packet **pkt, Loading Loading
arch/arm/mach-msm/include/mach/msm_ipc_router.h +116 −6 Original line number Diff line number Diff line Loading @@ -27,9 +27,41 @@ * enum msm_ipc_router_event - Events that will be generated by IPC Router */ enum msm_ipc_router_event { MSM_IPC_ROUTER_READ_CB = 0, MSM_IPC_ROUTER_WRITE_DONE, MSM_IPC_ROUTER_RESUME_TX, IPC_ROUTER_CTRL_CMD_DATA = 1, IPC_ROUTER_CTRL_CMD_HELLO, IPC_ROUTER_CTRL_CMD_BYE, IPC_ROUTER_CTRL_CMD_NEW_SERVER, IPC_ROUTER_CTRL_CMD_REMOVE_SERVER, IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT, IPC_ROUTER_CTRL_CMD_RESUME_TX, }; /** * rr_control_msg - Control message structure * @cmd: Command identifier for HELLO message in Version 1. * @hello: Message structure for HELLO message in Version 2. * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. * @cli: Message structure for REMOVE_CLIENT event. */ union rr_control_msg { uint32_t cmd; struct { uint32_t cmd; uint32_t magic; uint32_t capability; } hello; struct { uint32_t cmd; uint32_t service; uint32_t instance; uint32_t node_id; uint32_t port_id; } srv; struct { uint32_t cmd; uint32_t node_id; uint32_t port_id; } cli; }; struct comm_mode_info { Loading @@ -37,6 +69,32 @@ struct comm_mode_info { void *xprt_info; }; /** * msm_ipc_port - Definition of IPC Router port * @list: List(local/control ports) in which this port is present. * @this_port: Contains port's node_id and port_id information. * @port_name: Contains service & instance info if the port hosts a service. * @type: Type of the port - Client, Service, Control or Security Config. * @flags: Flags to identify the port state. * @port_lock: Lock to protect access to the port information. * @mode_info: Communication mode of the port owner. * @port_rx_q: Receive queue where incoming messages are queued. * @port_rx_q_lock_lhb3: Lock to protect access to the port's rx_q. * @rx_wakelock_name: Name of the receive wakelock. * @port_rx_wake_lock: Wakelock to prevent suspend until the rx_q is empty. * @port_rx_wait_q: Wait queue to wait for the incoming messages. * @restart_state: Flag to hold the restart state information. * @restart_lock: Lock to protect access to the restart_state. * @restart_wait: Wait Queue to wait for any restart events. * @endpoint: Contains the information related to user-space interface. * @notify: Function to notify the incoming events on the port. * @check_send_permissions: Function to check access control from this port. * @num_tx: Number of packets transmitted. * @num_rx: Number of packets received. * @num_tx_bytes: Number of bytes transmitted. * @num_rx_bytes: Number of bytes received. * @priv: Private information registered by the port owner. */ struct msm_ipc_port { struct list_head list; Loading @@ -58,7 +116,8 @@ struct msm_ipc_port { wait_queue_head_t restart_wait; void *endpoint; void (*notify)(unsigned event, void *priv); void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv); int (*check_send_permissions)(void *data); uint32_t num_tx; Loading @@ -72,14 +131,27 @@ struct msm_ipc_port { /** * msm_ipc_router_create_port() - Create a IPC Router port/endpoint * @notify: Callback function to notify any event on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private info to be passed while the notification is generated. * * @return: Pointer to the port on success, NULL on error. */ struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv); /** * msm_ipc_router_bind_control_port() - Bind a port as a control port * @port_ptr: Port which needs to be marked as a control port. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); /** * msm_ipc_router_lookup_server_name() - Resolve server address * @srv_name: Name<service:instance> of the server to be resolved. Loading Loading @@ -139,15 +211,40 @@ int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, */ int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr); /** * msm_ipc_router_register_server() - Register a service on a port * @server_port: IPC Router port with which a service is registered. * @name: Service name <service_id:instance_id> that gets registered. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_register_server(struct msm_ipc_port *server_port, struct msm_ipc_addr *name); /** * msm_ipc_router_unregister_server() - Unregister a service from a port * @server_port: Port with with a service is already registered. * * @return: 0 on success, standard Linux error codes on error. */ int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port); #else struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { return NULL; } static inline int msm_ipc_router_bind_control_port( struct msm_ipc_port *port_ptr) { return -ENODEV; } int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name, struct msm_ipc_server_info *srv_info, int num_entries_in_array, Loading Loading @@ -181,6 +278,19 @@ int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr) return -ENODEV; } static inline int msm_ipc_router_register_server( struct msm_ipc_port *server_port, struct msm_ipc_addr *name) { return -ENODEV; } static inline int msm_ipc_router_unregister_server( struct msm_ipc_port *server_port) { return -ENODEV; } #endif #endif
arch/arm/mach-msm/include/mach/msm_qmi_interface.h +209 −8 Original line number Diff line number Diff line Loading @@ -30,24 +30,55 @@ enum qmi_event_type { QMI_SERVER_EXIT, }; /** * struct qmi_handle - QMI Handle Data Structure * @src_port: Pointer to port used for message exchange. * @ctl_port: Pointer to port used for out-of-band event exchange. * @handle_type: Type of handle(Service/Client). * @next_txn_id: Transaction ID of the next outgoing request. * @handle_lock: Lock to protect access to elements in the handle. * @notify_lock: Lock to protect and generate notification atomically. * @notify: Function to notify the handle owner of an event. * @notify_priv: Private info to be passed during the notifcation. * @handle_reset: Flag to hold the reset state of the handle. * @reset_waitq: Wait queue to wait for any reset events. * @ctl_work: Work to handle the out-of-band events for this handle. * @dest_info: Destination to which this handle is connected to. * @txn_list: List of transactions waiting for the response. * @ind_cb: Function to notify the handle owner of an indication message. * @ind_cb_priv: Private info to be passed during an indication notification. * @resume_tx_work: Work to resume the tx when the transport is not busy. * @pending_txn_list: List of requests pending tx due to busy transport. * @conn_list: List of connections handled by the service. * @svc_ops_options: Service specific operations and options. */ struct qmi_handle { void *src_port; void *dest_info; void *ctl_port; unsigned handle_type; uint16_t next_txn_id; struct list_head txn_list; struct mutex handle_lock; spinlock_t notify_lock; void (*notify)(struct qmi_handle *handle, enum qmi_event_type event, void *notify_priv); void *notify_priv; int handle_reset; wait_queue_head_t reset_waitq; struct delayed_work ctl_work; /* Client specific elements */ void *dest_info; struct list_head txn_list; void (*ind_cb)(struct qmi_handle *handle, unsigned int msg_id, void *msg, unsigned int msg_len, void *ind_cb_priv); void *ind_cb_priv; int handle_reset; wait_queue_head_t reset_waitq; struct list_head pending_txn_list; struct delayed_work resume_tx_work; struct list_head pending_txn_list; /* Service specific elements */ struct list_head conn_list; struct qmi_svc_ops_options *svc_ops_options; }; enum qmi_result_type_v01 { Loading @@ -60,14 +91,17 @@ enum qmi_result_type_v01 { enum qmi_error_type_v01 { /* To force a 32 bit signed enum. Do not change or use*/ QMI_ERROR_TYPE_MIN_ENUM_VAL_V01 = INT_MIN, QMI_ERR_TYPE_MIN_ENUM_VAL_V01 = INT_MIN, QMI_ERR_NONE_V01 = 0x0000, QMI_ERROR_MALFORMED_MSG_V01 = 0x0001, QMI_ERR_MALFORMED_MSG_V01 = 0x0001, QMI_ERR_NO_MEMORY_V01 = 0x0002, QMI_ERR_INTERNAL_V01 = 0x0003, QMI_ERR_CLIENT_IDS_EXHAUSTED_V01 = 0x0005, QMI_ERR_INVALID_ID_V01 = 0x0029, QMI_ERR_ENCODING_V01 = 0x003A, QMI_ERR_INCOMPATIBLE_STATE_V01 = 0x005A, QMI_ERROR_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, QMI_ERR_NOT_SUPPORTED_V01 = 0x005E, QMI_ERR_TYPE_MAX_ENUM_VAL_V01 = INT_MAX, }; struct qmi_response_type_v01 { Loading @@ -75,6 +109,37 @@ struct qmi_response_type_v01 { enum qmi_error_type_v01 error; }; /** * qmi_svc_ops_options - Operations and options to be specified when * a service registers. * @version: Version field to identify the ops_options structure. * @service_id: Service ID of the service. * @service_vers: Version to identify the client-service compatibility. * @service_ins: Instance ID registered by the service. * @connect_cb: Callback when a new client connects with the service. * @disconnect_cb: Callback when the client exits the connection. * @req_desc_cb: Callback to get request structure and its descriptor * for a message id. * @req_cb: Callback to process the request. */ struct qmi_svc_ops_options { unsigned version; uint32_t service_id; uint32_t service_vers; uint32_t service_ins; int (*connect_cb)(struct qmi_handle *handle, void *conn_handle); int (*disconnect_cb)(struct qmi_handle *handle, void *conn_handle); int (*req_desc_cb)(unsigned int msg_id, struct msg_desc **req_desc); int (*req_cb)(struct qmi_handle *handle, void *conn_handle, void *req_handle, unsigned int msg_id, void *req); }; #ifdef CONFIG_MSM_QMI_INTERFACE /* Element info array describing common qmi response structure */ Loading Loading @@ -211,6 +276,93 @@ int qmi_svc_event_notifier_unregister(uint32_t service_id, uint32_t service_vers, uint32_t service_ins, struct notifier_block *nb); /** * qmi_svc_register() - Register a QMI service with a QMI handle * @handle: QMI handle on which the service has to be registered. * @ops_options: Service specific operations and options. * * @return: 0 if successfully registered, < 0 on error. */ int qmi_svc_register(struct qmi_handle *handle, void *ops_options); /** * qmi_send_resp() - Send response to a request * @handle: QMI handle from which the response is sent. * @clnt: Client to which the response is sent. * @req_handle: Request for which the response is sent. * @resp_desc: Descriptor explaining the response structure. * @resp: Pointer to the response structure. * @resp_len: Length of the response structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_resp(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len); /** * qmi_send_resp_from_cb() - Send response to a request from request_cb * @handle: QMI handle from which the response is sent. * @clnt: Client to which the response is sent. * @req_handle: Request for which the response is sent. * @resp_desc: Descriptor explaining the response structure. * @resp: Pointer to the response structure. * @resp_len: Length of the response structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_resp_from_cb(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len); /** * qmi_send_ind() - Send unsolicited event/indication to a client * @handle: QMI handle from which the indication is sent. * @clnt: Client to which the indication is sent. * @ind_desc: Descriptor explaining the indication structure. * @ind: Pointer to the indication structure. * @ind_len: Length of the indication structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_ind(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len); /** * qmi_send_ind_from_cb() - Send indication to a client from registration_cb * @handle: QMI handle from which the indication is sent. * @clnt: Client to which the indication is sent. * @ind_desc: Descriptor explaining the indication structure. * @ind: Pointer to the indication structure. * @ind_len: Length of the indication structure. * * @return: 0 on success, < 0 on error. */ int qmi_send_ind_from_cb(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len); /** * qmi_svc_unregister() - Unregister the service from a QMI handle * @handle: QMI handle from which the service has to be unregistered. * * return: 0 on success, < 0 on error. */ int qmi_svc_unregister(struct qmi_handle *handle); #else #define get_qmi_response_type_v01_ei() NULL Loading Loading @@ -289,6 +441,55 @@ static inline int qmi_svc_event_notifier_unregister(uint32_t service_id, return -ENODEV; } static inline int qmi_svc_register(struct qmi_handle *handle, void *ops_options) { return -ENODEV; } static inline int qmi_send_resp(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len) { return -ENODEV; } static inline int qmi_send_resp_from_cb(struct qmi_handle *handle, void *conn_handle, void *req_handle, struct msg_desc *resp_desc, void *resp, unsigned int resp_len) { return -ENODEV; } static inline int qmi_send_ind(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len) { return -ENODEV; } static inline int qmi_send_ind_from_cb(struct qmi_handle *handle, void *conn_handle, struct msg_desc *ind_desc, void *ind, unsigned int ind_len) { return -ENODEV; } static inline int qmi_svc_unregister(struct qmi_handle *handle) { return -ENODEV; } #endif #endif
arch/arm/mach-msm/ipc_router.c +39 −15 Original line number Diff line number Diff line Loading @@ -819,7 +819,8 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, struct rr_packet *pkt, int clone) { struct rr_packet *temp_pkt = pkt; void (*notify)(unsigned event, void *priv); void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv); if (unlikely(!port_ptr || !pkt)) return -EINVAL; Loading @@ -841,7 +842,7 @@ static int post_pkt_to_port(struct msm_ipc_port *port_ptr, notify = port_ptr->notify; mutex_unlock(&port_ptr->port_rx_q_lock_lhb3); if (notify) notify(MSM_IPC_ROUTER_READ_CB, port_ptr->priv); notify(pkt->hdr.type, NULL, 0, port_ptr->priv); return 0; } Loading Loading @@ -908,8 +909,24 @@ void msm_ipc_router_add_local_port(struct msm_ipc_port *port_ptr) up_write(&local_ports_lock_lha2); } /** * msm_ipc_router_create_raw_port() - Create an IPC Router port * @endpoint: User-space space socket information to be cached. * @notify: Function to notify incoming events on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private Data to be passed during the event notification. * * @return: Valid pointer to port on success, NULL on failure. * * This function is used to create an IPC Router port. The port is used for * communication locally or outside the subsystem. */ struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint, void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { struct msm_ipc_port *port_ptr; Loading Loading @@ -1071,6 +1088,7 @@ static int msm_ipc_router_lookup_resume_tx_port( * post_resume_tx() - Post the resume_tx event * @rport_ptr: Pointer to the remote port * @pkt : The data packet that is received on a resume_tx event * @msg: Out of band data to be passed to kernel drivers * * This function informs about the reception of the resume_tx message from a * remote port pointed by rport_ptr to all the local ports that are in the Loading @@ -1081,7 +1099,7 @@ static int msm_ipc_router_lookup_resume_tx_port( * Must be called with rport_ptr->quota_lock_lhb2 locked. */ static void post_resume_tx(struct msm_ipc_router_remote_port *rport_ptr, struct rr_packet *pkt) struct rr_packet *pkt, union rr_control_msg *msg) { struct msm_ipc_resume_tx_port *rtx_port, *tmp_rtx_port; struct msm_ipc_port *local_port; Loading @@ -1091,8 +1109,8 @@ static void post_resume_tx(struct msm_ipc_router_remote_port *rport_ptr, local_port = msm_ipc_router_lookup_local_port(rtx_port->port_id); if (local_port && local_port->notify) local_port->notify(MSM_IPC_ROUTER_RESUME_TX, local_port->priv); local_port->notify(IPC_ROUTER_CTRL_CMD_RESUME_TX, msg, sizeof(*msg), local_port->priv); else if (local_port) post_pkt_to_port(local_port, pkt, 1); else Loading Loading @@ -1417,8 +1435,6 @@ static char *type_to_str(int i) return "rmv_clnt"; case IPC_ROUTER_CTRL_CMD_RESUME_TX: return "resum_tx"; case IPC_ROUTER_CTRL_CMD_EXIT: return "cmd_exit"; default: return "invalid"; } Loading Loading @@ -1901,7 +1917,7 @@ static int process_resume_tx_msg(union rr_control_msg *msg, } mutex_lock(&rport_ptr->quota_lock_lhb2); rport_ptr->tx_quota_cnt = 0; post_resume_tx(rport_ptr, pkt); post_resume_tx(rport_ptr, pkt, msg); mutex_unlock(&rport_ptr->quota_lock_lhb2); prtm_out: up_read(&routing_table_lock_lha3); Loading Loading @@ -2075,10 +2091,6 @@ static int process_control_msg(struct msm_ipc_router_xprt_info *xprt_info, case IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT: rc = process_rmv_client_msg(xprt_info, msg, pkt); break; case IPC_ROUTER_CTRL_CMD_PING: /* No action needed for ping messages received */ RR("o PING\n"); break; default: RR("o UNKNOWN(%08x)\n", msg->cmd); rc = -ENOSYS; Loading Loading @@ -2766,8 +2778,20 @@ int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr, return 0; } /** * msm_ipc_router_create_port() - Create a IPC Router port/endpoint * @notify: Callback function to notify any event on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private info to be passed while the notification is generated. * * @return: Pointer to the port on success, NULL on error. */ struct msm_ipc_port *msm_ipc_router_create_port( void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv) { struct msm_ipc_port *port_ptr; Loading
arch/arm/mach-msm/ipc_router.h +20 −42 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include <net/sock.h> #include <mach/msm_ipc_router.h> /* definitions for the R2R wire protcol */ #define IPC_ROUTER_V1 1 /* Loading @@ -36,16 +38,6 @@ #define IPC_ROUTER_NID_LOCAL 1 #define MAX_IPC_PKT_SIZE 66000 #define IPC_ROUTER_CTRL_CMD_DATA 1 #define IPC_ROUTER_CTRL_CMD_HELLO 2 #define IPC_ROUTER_CTRL_CMD_BYE 3 #define IPC_ROUTER_CTRL_CMD_NEW_SERVER 4 #define IPC_ROUTER_CTRL_CMD_REMOVE_SERVER 5 #define IPC_ROUTER_CTRL_CMD_REMOVE_CLIENT 6 #define IPC_ROUTER_CTRL_CMD_RESUME_TX 7 #define IPC_ROUTER_CTRL_CMD_EXIT 8 #define IPC_ROUTER_CTRL_CMD_PING 9 #define IPC_ROUTER_DEFAULT_RX_QUOTA 5 #define IPC_ROUTER_XPRT_EVENT_DATA 1 Loading Loading @@ -78,34 +70,6 @@ enum { MULTI_LINK_MODE, }; /** * rr_control_msg - Control message structure * @cmd: Command identifier for HELLO message in Version 1. * @hello: Message structure for HELLO message in Version 2. * @srv: Message structure for NEW_SERVER/REMOVE_SERVER events. * @cli: Message structure for REMOVE_CLIENT event. */ union rr_control_msg { uint32_t cmd; struct { uint32_t cmd; uint32_t magic; uint32_t capability; } hello; struct { uint32_t cmd; uint32_t service; uint32_t instance; uint32_t node_id; uint32_t port_id; } srv; struct { uint32_t cmd; uint32_t node_id; uint32_t port_id; } cli; }; /** * rr_header_v1 - IPC Router header version 1 * @version: Version information. Loading Loading @@ -217,9 +181,24 @@ void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt, struct rr_packet *clone_pkt(struct rr_packet *pkt); void release_pkt(struct rr_packet *pkt); /** * msm_ipc_router_create_raw_port() - Create an IPC Router port * @endpoint: User-space space socket information to be cached. * @notify: Function to notify incoming events on the port. * @event: Event ID to be handled. * @oob_data: Any out-of-band data associated with the event. * @oob_data_len: Size of the out-of-band data, if valid. * @priv: Private data registered during the port creation. * @priv: Private Data to be passed during the event notification. * * @return: Valid pointer to port on success, NULL on failure. * * This function is used to create an IPC Router port. The port is used for * communication locally or outside the subsystem. */ struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint, void (*notify)(unsigned event, void *priv), void (*notify)(unsigned event, void *oob_data, size_t oob_data_len, void *priv), void *priv); int msm_ipc_router_send_to(struct msm_ipc_port *src, struct sk_buff_head *data, Loading @@ -227,7 +206,6 @@ int msm_ipc_router_send_to(struct msm_ipc_port *src, int msm_ipc_router_read(struct msm_ipc_port *port_ptr, struct rr_packet **pkt, size_t buf_len); int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr); int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr, struct rr_packet **pkt, Loading