linux/drivers/infiniband/hw/qib/qib_user_sdma.c

/*
 * Copyright (c) 2007, 2008, 2009 QLogic Corporation. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/dmapool.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/uio.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/delay.h>

#include "qib.h"
#include "qib_user_sdma.h"

/* minimum size of header */
#define QIB_USER_SDMA_MIN_HEADER_LENGTH
/* expected size of headers (for dma_pool) */
#define QIB_USER_SDMA_EXP_HEADER_LENGTH
/* attempt to drain the queue for 5secs */
#define QIB_USER_SDMA_DRAIN_TIMEOUT

/*
 * track how many times a process open this driver.
 */
static struct rb_root qib_user_sdma_rb_root =;

struct qib_user_sdma_rb_node {};

struct qib_user_sdma_pkt {};

struct qib_user_sdma_queue {};

static struct qib_user_sdma_rb_node *
qib_user_sdma_rb_search(struct rb_root *root, pid_t pid)
{}

static int
qib_user_sdma_rb_insert(struct rb_root *root, struct qib_user_sdma_rb_node *new)
{}

struct qib_user_sdma_queue *
qib_user_sdma_queue_create(struct device *dev, int unit, int ctxt, int sctxt)
{}

static void qib_user_sdma_init_frag(struct qib_user_sdma_pkt *pkt,
				    int i, u16 offset, u16 len,
				    u16 first_desc, u16 last_desc,
				    u16 put_page, u16 dma_mapped,
				    struct page *page, void *kvaddr,
				    dma_addr_t dma_addr, u16 dma_length)
{}

static void *qib_user_sdma_alloc_header(struct qib_user_sdma_queue *pq,
				size_t len, dma_addr_t *dma_addr)
{}

static int qib_user_sdma_page_to_frags(const struct qib_devdata *dd,
				       struct qib_user_sdma_queue *pq,
				       struct qib_user_sdma_pkt *pkt,
				       struct page *page, u16 put,
				       u16 offset, u16 len, void *kvaddr)
{}

/* we've too many pages in the iovec, coalesce to a single page */
static int qib_user_sdma_coalesce(const struct qib_devdata *dd,
				  struct qib_user_sdma_queue *pq,
				  struct qib_user_sdma_pkt *pkt,
				  const struct iovec *iov,
				  unsigned long niov)
{}

/*
 * How many pages in this iovec element?
 */
static size_t qib_user_sdma_num_pages(const struct iovec *iov)
{}

static void qib_user_sdma_free_pkt_frag(struct device *dev,
					struct qib_user_sdma_queue *pq,
					struct qib_user_sdma_pkt *pkt,
					int frag)
{}

/* return number of pages pinned... */
static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
				   struct qib_user_sdma_queue *pq,
				   struct qib_user_sdma_pkt *pkt,
				   unsigned long addr, int tlen, size_t npages)
{}

static int qib_user_sdma_pin_pkt(const struct qib_devdata *dd,
				 struct qib_user_sdma_queue *pq,
				 struct qib_user_sdma_pkt *pkt,
				 const struct iovec *iov,
				 unsigned long niov)
{}

static int qib_user_sdma_init_payload(const struct qib_devdata *dd,
				      struct qib_user_sdma_queue *pq,
				      struct qib_user_sdma_pkt *pkt,
				      const struct iovec *iov,
				      unsigned long niov, int npages)
{}

/* free a packet list -- return counter value of last packet */
static void qib_user_sdma_free_pkt_list(struct device *dev,
					struct qib_user_sdma_queue *pq,
					struct list_head *list)
{}

/*
 * copy headers, coalesce etc -- pq->lock must be held
 *
 * we queue all the packets to list, returning the
 * number of bytes total.  list must be empty initially,
 * as, if there is an error we clean it...
 */
static int qib_user_sdma_queue_pkts(const struct qib_devdata *dd,
				    struct qib_pportdata *ppd,
				    struct qib_user_sdma_queue *pq,
				    const struct iovec *iov,
				    unsigned long niov,
				    struct list_head *list,
				    int *maxpkts, int *ndesc)
{}

static void qib_user_sdma_set_complete_counter(struct qib_user_sdma_queue *pq,
					       u32 c)
{}

/* try to clean out queue -- needs pq->lock */
static int qib_user_sdma_queue_clean(struct qib_pportdata *ppd,
				     struct qib_user_sdma_queue *pq)
{}

void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq)
{}

/* clean descriptor queue, returns > 0 if some elements cleaned */
static int qib_user_sdma_hwqueue_clean(struct qib_pportdata *ppd)
{}

/* we're in close, drain packets so that we can cleanup successfully... */
void qib_user_sdma_queue_drain(struct qib_pportdata *ppd,
			       struct qib_user_sdma_queue *pq)
{}

static inline __le64 qib_sdma_make_desc0(u8 gen,
					 u64 addr, u64 dwlen, u64 dwoffset)
{}

static inline __le64 qib_sdma_make_first_desc0(__le64 descq)
{}

static inline __le64 qib_sdma_make_last_desc0(__le64 descq)
{}

static inline __le64 qib_sdma_make_desc1(u64 addr)
{}

static void qib_user_sdma_send_frag(struct qib_pportdata *ppd,
				    struct qib_user_sdma_pkt *pkt, int idx,
				    unsigned ofs, u16 tail, u8 gen)
{}

void qib_user_sdma_send_desc(struct qib_pportdata *ppd,
				struct list_head *pktlist)
{}

/* pq->lock must be held, get packets on the wire... */
static int qib_user_sdma_push_pkts(struct qib_pportdata *ppd,
				 struct qib_user_sdma_queue *pq,
				 struct list_head *pktlist, int count)
{}

int qib_user_sdma_writev(struct qib_ctxtdata *rcd,
			 struct qib_user_sdma_queue *pq,
			 const struct iovec *iov,
			 unsigned long dim)
{}

int qib_user_sdma_make_progress(struct qib_pportdata *ppd,
				struct qib_user_sdma_queue *pq)
{}

u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq)
{}

u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq)
{}