Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Intel MIC Platform Software Stack (MPSS)
  3 *
  4 * Copyright(c) 2014 Intel Corporation.
  5 *
  6 * This program is free software; you can redistribute it and/or modify
  7 * it under the terms of the GNU General Public License, version 2, as
  8 * published by the Free Software Foundation.
  9 *
 10 * This program is distributed in the hope that it will be useful, but
 11 * WITHOUT ANY WARRANTY; without even the implied warranty of
 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 13 * General Public License for more details.
 14 *
 15 * Intel SCIF driver.
 16 *
 17 */
 18#ifndef SCIF_EPD_H
 19#define SCIF_EPD_H
 20
 21#include <linux/delay.h>
 22#include <linux/scif.h>
 23#include <linux/scif_ioctl.h>
 24
 25#define SCIF_EPLOCK_HELD true
 26
 27enum scif_epd_state {
 28	SCIFEP_UNBOUND,
 29	SCIFEP_BOUND,
 30	SCIFEP_LISTENING,
 31	SCIFEP_CONNECTED,
 32	SCIFEP_CONNECTING,
 33	SCIFEP_MAPPING,
 34	SCIFEP_CLOSING,
 35	SCIFEP_CLLISTEN,
 36	SCIFEP_DISCONNECTED,
 37	SCIFEP_ZOMBIE
 38};
 39
 40/*
 41 * struct scif_conreq - Data structure added to the connection list.
 42 *
 43 * @msg: connection request message received
 44 * @list: link to list of connection requests
 45 */
 46struct scif_conreq {
 47	struct scifmsg msg;
 48	struct list_head list;
 49};
 50
 51/* Size of the RB for the Endpoint QP */
 52#define SCIF_ENDPT_QP_SIZE 0x1000
 53
 54/*
 55 * scif_endpt_qp_info - SCIF endpoint queue pair
 56 *
 57 * @qp - Qpair for this endpoint
 58 * @qp_offset - DMA address of the QP
 59 * @gnt_pld - Payload in a SCIF_CNCT_GNT message containing the
 60 * physical address of the remote_qp.
 61 */
 62struct scif_endpt_qp_info {
 63	struct scif_qp *qp;
 64	dma_addr_t qp_offset;
 65	dma_addr_t gnt_pld;
 66};
 67
 68/*
 69 * struct scif_endpt - The SCIF endpoint data structure
 70 *
 71 * @state: end point state
 72 * @lock: lock synchronizing access to endpoint fields like state etc
 73 * @port: self port information
 74 * @peer: peer port information
 75 * @backlog: maximum pending connection requests
 76 * @qp_info: Endpoint QP information for SCIF messaging
 77 * @remote_dev: scifdev used by this endpt to communicate with remote node.
 78 * @remote_ep: remote endpoint
 79 * @conreqcnt: Keep track of number of connection requests.
 80 * @files: Open file information used to match the id passed in with
 81 *         the flush routine.
 82 * @conlist: list of connection requests
 83 * @conwq: waitqueue for connection processing
 84 * @discon: completion used during disconnection
 85 * @sendwq: waitqueue used during sending messages
 86 * @recvwq: waitqueue used during message receipt
 87 * @sendlock: Synchronize ordering of messages sent
 88 * @recvlock: Synchronize ordering of messages received
 89 * @list: link to list of various endpoints like connected, listening etc
 90 * @li_accept: pending ACCEPTREG
 91 * @acceptcnt: pending ACCEPTREG cnt
 92 * @liacceptlist: link to listen accept
 93 * @miacceptlist: link to uaccept
 94 * @listenep: associated listen ep
 95 * @conn_work: Non blocking connect work
 96 * @conn_port: Connection port
 97 * @conn_err: Errors during connection
 98 * @conn_async_state: Async connection
 99 * @conn_pend_wq: Used by poll while waiting for incoming connections
100 * @conn_list: List of async connection requests
101 * @rma_info: Information for triggering SCIF RMA and DMA operations
102 * @mmu_list: link to list of MMU notifier cleanup work
103 * @anon: anonymous file for use in kernel mode scif poll
104 */
105struct scif_endpt {
106	enum scif_epd_state state;
107	spinlock_t lock;
108	struct scif_port_id port;
109	struct scif_port_id peer;
110	int backlog;
111	struct scif_endpt_qp_info qp_info;
112	struct scif_dev *remote_dev;
113	u64 remote_ep;
114	int conreqcnt;
115	struct files_struct *files;
116	struct list_head conlist;
117	wait_queue_head_t conwq;
118	struct completion discon;
119	wait_queue_head_t sendwq;
120	wait_queue_head_t recvwq;
121	struct mutex sendlock;
122	struct mutex recvlock;
123	struct list_head list;
124	struct list_head li_accept;
125	int acceptcnt;
126	struct list_head liacceptlist;
127	struct list_head miacceptlist;
128	struct scif_endpt *listenep;
129	struct scif_port_id conn_port;
130	int conn_err;
131	int conn_async_state;
132	wait_queue_head_t conn_pend_wq;
133	struct list_head conn_list;
134	struct scif_endpt_rma_info rma_info;
135	struct list_head mmu_list;
136	struct file *anon;
137};
138
139static inline int scifdev_alive(struct scif_endpt *ep)
140{
141	return _scifdev_alive(ep->remote_dev);
142}
143
144/*
145 * scif_verify_epd:
146 * ep: SCIF endpoint
147 *
148 * Checks several generic error conditions and returns the
149 * appropriate error.
150 */
151static inline int scif_verify_epd(struct scif_endpt *ep)
152{
153	if (ep->state == SCIFEP_DISCONNECTED)
154		return -ECONNRESET;
155
156	if (ep->state != SCIFEP_CONNECTED)
157		return -ENOTCONN;
158
159	if (!scifdev_alive(ep))
160		return -ENODEV;
161
162	return 0;
163}
164
165static inline int scif_anon_inode_getfile(scif_epd_t epd)
166{
167	epd->anon = anon_inode_getfile("scif", &scif_anon_fops, NULL, 0);
168	if (IS_ERR(epd->anon))
169		return PTR_ERR(epd->anon);
170	return 0;
171}
172
173static inline void scif_anon_inode_fput(scif_epd_t epd)
174{
175	if (epd->anon) {
176		fput(epd->anon);
177		epd->anon = NULL;
178	}
179}
180
181void scif_cleanup_zombie_epd(void);
182void scif_teardown_ep(void *endpt);
183void scif_cleanup_ep_qp(struct scif_endpt *ep);
184void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held);
185void scif_get_node_info(void);
186void scif_send_acks(struct scif_dev *dev);
187void scif_conn_handler(struct work_struct *work);
188int scif_rsrv_port(u16 port);
189void scif_get_port(u16 port);
190int scif_get_new_port(void);
191void scif_put_port(u16 port);
192int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags);
193int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags);
194void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg);
195void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg);
196void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
197void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg);
198void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg);
199void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg);
200void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
201void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg);
202void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg);
203int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block);
204int __scif_flush(scif_epd_t epd);
205int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd);
206unsigned int __scif_pollfd(struct file *f, poll_table *wait,
207			   struct scif_endpt *ep);
208int __scif_pin_pages(void *addr, size_t len, int *out_prot,
209		     int map_flags, scif_pinned_pages_t *pages);
210#endif /* SCIF_EPD_H */