linux/drivers/misc/mic/scif/scif_epd.h
<<
>>
Prefs
   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 */
 211