Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.5 210 lines 6.4 kB view raw
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 */