/*
 * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/pci.h>
#include <linux/poll.h>
#include <linux/cdev.h>
#include <linux/swap.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h>
#include <asm/pgtable.h>

#include "ipath_kernel.h"
#include "ipath_common.h"
#include "ipath_user_sdma.h"

static int ipath_open(struct inode *, struct file *);
static int ipath_close(struct inode *, struct file *);
static ssize_t ipath_write(struct file *, const char __user *, size_t,
			   loff_t *);
static ssize_t ipath_writev(struct kiocb *, const struct iovec *,
			    unsigned long , loff_t);
static unsigned int ipath_poll(struct file *, struct poll_table_struct *);
static int ipath_mmap(struct file *, struct vm_area_struct *);

static const struct file_operations ipath_file_ops = {
	.owner = THIS_MODULE,
	.write = ipath_write,
	.aio_write = ipath_writev,
	.open = ipath_open,
	.release = ipath_close,
	.poll = ipath_poll,
	.mmap = ipath_mmap
};

/*
 * Convert kernel virtual addresses to physical addresses so they don't
 * potentially conflict with the chip addresses used as mmap offsets.
 * It doesn't really matter what mmap offset we use as long as we can
 * interpret it correctly.
 */
static u64 cvt_kvaddr(void *p)
{
	struct page *page;
	u64 paddr = 0;

	page = vmalloc_to_page(p);
	if (page)
		paddr = page_to_pfn(page) << PAGE_SHIFT;

	return paddr;
}

static int ipath_get_base_info(struct file *fp,
			       void __user *ubase, size_t ubase_size)
{
	struct ipath_portdata *pd = port_fp(fp);
	int ret = 0;
	struct ipath_base_info *kinfo = NULL;
	struct ipath_devdata *dd = pd->port_dd;
	unsigned subport_cnt;
	int shared, master;
	size_t sz;

	subport_cnt = pd->port_subport_cnt;
	if (!subport_cnt) {
		shared = 0;
		master = 0;
		subport_cnt = 1;
	} else {
		shared = 1;
		master = !subport_fp(fp);
	}

	sz = sizeof(*kinfo);
	/* If port sharing is not requested, allow the old size structure */
	if (!shared)
		sz -= 7 * sizeof(u64);
	if (ubase_size < sz) {
		ipath_cdbg(PROC,
			   "Base size %zu, need %zu (version mismatch?)\n",
			   ubase_size, sz);
		ret = -EINVAL;
		goto bail;
	}

	kinfo = kzalloc(sizeof(*kinfo), GFP_KERNEL);
	if (kinfo == NULL) {
		ret = -ENOMEM;
		goto bail;
	}

	ret = dd->ipath_f_get_base_info(pd, kinfo);
	if (ret < 0)
		goto bail;

	kinfo->spi_rcvhdr_cnt = dd->ipath_rcvhdrcnt;
	kinfo->spi_rcvhdrent_size = dd->ipath_rcvhdrentsize;
	kinfo->spi_tidegrcnt = dd->ipath_rcvegrcnt;
	kinfo->spi_rcv_egrbufsize = dd->ipath_rcvegrbufsize;
	/*
	 * have to mmap whole thing
	 */
	kinfo->spi_rcv_egrbuftotlen =
		pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size;
	kinfo->spi_rcv_egrperchunk = pd->port_rcvegrbufs_perchunk;
	kinfo->spi_rcv_egrchunksize = kinfo->spi_rcv_egrbuftotlen /
		pd->port_rcvegrbuf_chunks;
	kinfo->spi_tidcnt = dd->ipath_rcvtidcnt / subport_cnt;
	if (master)
		kinfo->spi_tidcnt += dd->ipath_rcvtidcnt % subport_cnt;
	/*
	 * for this use, may be ipath_cfgports summed over all chips that
	 * are are configured and present
	 */
	kinfo->spi_nports = dd->ipath_cfgports;
	/* unit (chip/board) our port is on */
	kinfo->spi_unit = dd->ipath_unit;
	/* for now, only a single page */
	kinfo->spi_tid_maxsize = PAGE_SIZE;

	/*
	 * Doing this per port, and based on the skip value, etc.  This has
	 * to be the actual buffer size, since the protocol code treats it
	 * as an array.
	 *
	 * These have to be set to user addresses in the user code via mmap.
	 * These values are used on return to user code for the mmap target
	 * addresses only.  For 32 bit, same 44 bit address problem, so use
	 * the physical address, not virtual.  Before 2.6.11, using the
	 * page_address() macro worked, but in 2.6.11, even that returns the
	 * full 64 bit address (upper bits all 1's).  So far, using the
	 * physical addresses (or chip offsets, for chip mapping) works, but
	 * no doubt some future kernel release will change that, and we'll be
	 * on to yet another method of dealing with this.
	 */
	kinfo->spi_rcvhdr_base = (u64) pd->port_rcvhdrq_phys;
	kinfo->spi_rcvhdr_tailaddr = (u64) pd->port_rcvhdrqtailaddr_phys;
	kinfo->spi_rcv_egrbufs = (u64) pd->port_rcvegr_phys;
	kinfo->spi_pioavailaddr = (u64) dd->ipath_pioavailregs_phys;
	kinfo->spi_status = (u64) kinfo->spi_pioavailaddr +
		(void *) dd->ipath_statusp -
		(void *) dd->ipath_pioavailregs_dma;
	if (!shared) {
		kinfo->spi_piocnt = pd->port_piocnt;
		kinfo->spi_piobufbase = (u64) pd->port_piobufs;
		kinfo->__spi_uregbase = (u64) dd->ipath_uregbase +
			dd->ipath_ureg_align * pd->port_port;
	} else if (master) {
		kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) +
				    (pd->port_piocnt % subport_cnt);
		/* Master's PIO buffers are after all the slave's */
		kinfo->spi_piobufbase = (u64) pd->port_piobufs +
			dd->ipath_palign *
			(pd->port_piocnt - kinfo->spi_piocnt);
	} else {
		unsigned slave = subport_fp(fp) - 1;

		kinfo->spi_piocnt = pd->port_piocnt / subport_cnt;
		kinfo->spi_piobufbase = (u64) pd->port_piobufs +
			dd->ipath_palign * kinfo->spi_piocnt * slave;
	}

	if (shared) {
		kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase +
			dd->ipath_ureg_align * pd->port_port;
		kinfo->spi_port_rcvegrbuf = kinfo->spi_rcv_egrbufs;
		kinfo->spi_port_rcvhdr_base = kinfo->spi_rcvhdr_base;
		kinfo->spi_port_rcvhdr_tailaddr = kinfo->spi_rcvhdr_tailaddr;

		kinfo->__spi_uregbase = cvt_kvaddr(pd->subport_uregbase +
			PAGE_SIZE * subport_fp(fp));

		kinfo->spi_rcvhdr_base = cvt_kvaddr(pd->subport_rcvhdr_base +
			pd->port_rcvhdrq_size * subport_fp(fp));
		kinfo->spi_rcvhdr_tailaddr = 0;
		kinfo->spi_rcv_egrbufs = cvt_kvaddr(pd->subport_rcvegrbuf +
			pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size *
			subport_fp(fp));

		kinfo->spi_subport_uregbase =
			cvt_kvaddr(pd->subport_uregbase);
		kinfo->spi_subport_rcvegrbuf =
			cvt_kvaddr(pd->subport_rcvegrbuf);
		kinfo->spi_subport_rcvhdr_base =
			cvt_kvaddr(pd->subport_rcvhdr_base);
		ipath_cdbg(PROC, "port %u flags %x %llx %llx %llx\n",
			kinfo->spi_port, kinfo->spi_runtime_flags,
			(unsigned long long) kinfo->spi_subport_uregbase,
			(unsigned long long) kinfo->spi_subport_rcvegrbuf,
			(unsigned long long) kinfo->spi_subport_rcvhdr_base);
	}

	/*
	 * All user buffers are 2KB buffers.  If we ever support
	 * giving 4KB buffers to user processes, this will need some
	 * work.
	 */
	kinfo->spi_pioindex = (kinfo->spi_piobufbase -
		(dd->ipath_piobufbase & 0xffffffff)) / dd->ipath_palign;
	kinfo->spi_pioalign = dd->ipath_palign;

	kinfo->spi_qpair = IPATH_KD_QP;
	/*
	 * user mode PIO buffers are always 2KB, even when 4KB can
	 * be received, and sent via the kernel; this is ibmaxlen
	 * for 2K MTU.
	 */
	kinfo->spi_piosize = dd->ipath_piosize2k - 2 * sizeof(u32);
	kinfo->spi_mtu = dd->ipath_ibmaxlen;	/* maxlen, not ibmtu */
	kinfo->spi_port = pd->port_port;
	kinfo->spi_subport = subport_fp(fp);
	kinfo->spi_sw_version = IPATH_KERN_SWVERSION;
	kinfo->spi_hw_version = dd->ipath_revision;

	if (master) {
		kinfo->spi_runtime_flags |= IPATH_RUNTIME_MASTER;
	}

	sz = (ubase_size < sizeof(*kinfo)) ? ubase_size : sizeof(*kinfo);
	if (copy_to_user(ubase, kinfo, sz))
		ret = -EFAULT;

bail:
	kfree(kinfo);
	return ret;
}

/**
 * ipath_tid_update - update a port TID
 * @pd: the port
 * @fp: the ipath device file
 * @ti: the TID information
 *
 * The new implementation as of Oct 2004 is that the driver assigns
 * the tid and returns it to the caller.   To make it easier to
 * catch bugs, and to reduce search time, we keep a cursor for
 * each port, walking the shadow tid array to find one that's not
 * in use.
 *
 * For now, if we can't allocate the full list, we fail, although
 * in the long run, we'll allocate as many as we can, and the
 * caller will deal with that by trying the remaining pages later.
 * That means that when we fail, we have to mark the tids as not in
 * use again, in our shadow copy.
 *
 * It's up to the caller to free the tids when they are done.
 * We'll unlock the pages as they free them.
 *
 * Also, right now we are locking one page at a time, but since
 * the intended use of this routine is for a single group of
 * virtually contiguous pages, that should change to improve
 * performance.
 */
static int ipath_tid_update(struct ipath_portdata *pd, struct file *fp,
			    const struct ipath_tid_info *ti)
{
	int ret = 0, ntids;
	u32 tid, porttid, cnt, i, tidcnt, tidoff;
	u16 *tidlist;
	struct ipath_devdata *dd = pd->port_dd;
	u64 physaddr;
	unsigned long vaddr;
	u64 __iomem *tidbase;
	unsigned long tidmap[8];
	struct page **pagep = NULL;
	unsigned subport = subport_fp(fp);

	if (!dd->ipath_pageshadow) {
		ret = -ENOMEM;
		goto done;
	}

	cnt = ti->tidcnt;
	if (!cnt) {
		ipath_dbg("After copyin, tidcnt 0, tidlist %llx\n",
			  (unsigned long long) ti->tidlist);
		/*
		 * Should we treat as success?  likely a bug
		 */
		ret = -EFAULT;
		goto done;
	}
	porttid = pd->port_port * dd->ipath_rcvtidcnt;
	if (!pd->port_subport_cnt) {
		tidcnt = dd->ipath_rcvtidcnt;
		tid = pd->port_tidcursor;
		tidoff = 0;
	} else if (!subport) {
		tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
			 (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
		tidoff = dd->ipath_rcvtidcnt - tidcnt;
		porttid += tidoff;
		tid = tidcursor_fp(fp);
	} else {
		tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
		tidoff = tidcnt * (subport - 1);
		porttid += tidoff;
		tid = tidcursor_fp(fp);
	}
	if (cnt > tidcnt) {
		/* make sure it all fits in port_tid_pg_list */
		dev_info(&dd->pcidev->dev, "Process tried to allocate %u "
			 "TIDs, only trying max (%u)\n", cnt, tidcnt);
		cnt = tidcnt;
	}
	pagep = &((struct page **) pd->port_tid_pg_list)[tidoff];
	tidlist = &((u16 *) &pagep[dd->ipath_rcvtidcnt])[tidoff];

	memset(tidmap, 0, sizeof(tidmap));
	/* before decrement; chip actual # */
	ntids = tidcnt;
	tidbase = (u64 __iomem *) (((char __iomem *) dd->ipath_kregbase) +
				   dd->ipath_rcvtidbase +
				   porttid * sizeof(*tidbase));

	ipath_cdbg(VERBOSE, "Port%u %u tids, cursor %u, tidbase %p\n",
		   pd->port_port, cnt, tid, tidbase);

	/* virtual address of first page in transfer */
	vaddr = ti->tidvaddr;
	if (!access_ok(VERIFY_WRITE, (void __user *) vaddr,
		       cnt * PAGE_SIZE)) {
		ipath_dbg("Fail vaddr %p, %u pages, !access_ok\n",
			  (void *)vaddr, cnt);
		ret = -EFAULT;
		goto done;
	}
	ret = ipath_get_user_pages(vaddr, cnt, pagep);
	if (ret) {
		if (ret == -EBUSY) {
			ipath_dbg("Failed to lock addr %p, %u pages "
				  "(already locked)\n",
				  (void *) vaddr, cnt);
			/*
			 * for now, continue, and see what happens but with
			 * the new implementation, this should never happen,
			 * unless perhaps the user has mpin'ed the pages
			 * themselves (something we need to test)
			 */
			ret = 0;
		} else {
			dev_info(&dd->pcidev->dev,
				 "Failed to lock addr %p, %u pages: "
				 "errno %d\n", (void *) vaddr, cnt, -ret);
			goto done;
		}
	}
	for (i = 0; i < cnt; i++, vaddr += PAGE_SIZE) {
		for (; ntids--; tid++) {
			if (tid == tidcnt)
				tid = 0;
			if (!dd->ipath_pageshadow[porttid + tid])
				break;
		}
		if (ntids < 0) {
			/*
			 * oops, wrapped all the way through their TIDs,
			 * and didn't have enough free; see comments at
			 * start of routine
			 */
			ipath_dbg("Not enough free TIDs for %u pages "
				  "(index %d), failing\n", cnt, i);
			i--;	/* last tidlist[i] not filled in */
			ret = -ENOMEM;
			break;
		}
		tidlist[i] = tid + tidoff;
		ipath_cdbg(VERBOSE, "Updating idx %u to TID %u, "
			   "vaddr %lx\n", i, tid + tidoff, vaddr);
		/* we "know" system pages and TID pages are same size */
		dd->ipath_pageshadow[porttid + tid] = pagep[i];
		dd->ipath_physshadow[porttid + tid] = ipath_map_page(
			dd->pcidev, pagep[i], 0, PAGE_SIZE,
			PCI_DMA_FROMDEVICE);
		/*
		 * don't need atomic or it's overhead
		 */
		__set_bit(tid, tidmap);
		physaddr = dd->ipath_physshadow[porttid + tid];
		ipath_stats.sps_pagelocks++;
		ipath_cdbg(VERBOSE,
			   "TID %u, vaddr %lx, physaddr %llx pgp %p\n",
			   tid, vaddr, (unsigned long long) physaddr,
			   pagep[i]);
		dd->ipath_f_put_tid(dd, &tidbase[tid], RCVHQ_RCV_TYPE_EXPECTED,
				    physaddr);
		/*
		 * don't check this tid in ipath_portshadow, since we
		 * just filled it in; start with the next one.
		 */
		tid++;
	}

	if (ret) {
		u32 limit;
	cleanup:
		/* jump here if copy out of updated info failed... */
		ipath_dbg("After failure (ret=%d), undo %d of %d entries\n",
			  -ret, i, cnt);
		/* same code that's in ipath_free_tid() */
		limit = sizeof(tidmap) * BITS_PER_BYTE;
		if (limit > tidcnt)
			/* just in case size changes in future */
			limit = tidcnt;
		tid = find_first_bit((const unsigned long *)tidmap, limit);
		for (; tid < limit; tid++) {
			if (!test_bit(tid, tidmap))
				continue;
			if (dd->ipath_pageshadow[porttid + tid]) {
				ipath_cdbg(VERBOSE, "Freeing TID %u\n",
					   tid);
				dd->ipath_f_put_tid(dd, &tidbase[tid],
						    RCVHQ_RCV_TYPE_EXPECTED,
						    dd->ipath_tidinvalid);
				pci_unmap_page(dd->pcidev,
					dd->ipath_physshadow[porttid + tid],
					PAGE_SIZE, PCI_DMA_FROMDEVICE);
				dd->ipath_pageshadow[porttid + tid] = NULL;
				ipath_stats.sps_pageunlocks++;
			}
		}
		ipath_release_user_pages(pagep, cnt);
	} else {
		/*
		 * Copy the updated array, with ipath_tid's filled in, back
		 * to user.  Since we did the copy in already, this "should
		 * never fail" If it does, we have to clean up...
		 */
		if (copy_to_user((void __user *)
				 (unsigned long) ti->tidlist,
				 tidlist, cnt * sizeof(*tidlist))) {
			ret = -EFAULT;
			goto cleanup;
		}
		if (copy_to_user((void __user *) (unsigned long) ti->tidmap,
				 tidmap, sizeof tidmap)) {
			ret = -EFAULT;
			goto cleanup;
		}
		if (tid == tidcnt)
			tid = 0;
		if (!pd->port_subport_cnt)
			pd->port_tidcursor = tid;
		else
			tidcursor_fp(fp) = tid;
	}

done:
	if (ret)
		ipath_dbg("Failed to map %u TID pages, failing with %d\n",
			  ti->tidcnt, -ret);
	return ret;
}

/**
 * ipath_tid_free - free a port TID
 * @pd: the port
 * @subport: the subport
 * @ti: the TID info
 *
 * right now we are unlocking one page at a time, but since
 * the intended use of this routine is for a single group of
 * virtually contiguous pages, that should change to improve
 * performance.  We check that the TID is in range for this port
 * but otherwise don't check validity; if user has an error and
 * frees the wrong tid, it's only their own data that can thereby
 * be corrupted.  We do check that the TID was in use, for sanity
 * We always use our idea of the saved address, not the address that
 * they pass in to us.
 */

static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport,
			  const struct ipath_tid_info *ti)
{
	int ret = 0;
	u32 tid, porttid, cnt, limit, tidcnt;
	struct ipath_devdata *dd = pd->port_dd;
	u64 __iomem *tidbase;
	unsigned long tidmap[8];

	if (!dd->ipath_pageshadow) {
		ret = -ENOMEM;
		goto done;
	}

	if (copy_from_user(tidmap, (void __user *)(unsigned long)ti->tidmap,
			   sizeof tidmap)) {
		ret = -EFAULT;
		goto done;
	}

	porttid = pd->port_port * dd->ipath_rcvtidcnt;
	if (!pd->port_subport_cnt)
		tidcnt = dd->ipath_rcvtidcnt;
	else if (!subport) {
		tidcnt = (dd->ipath_rcvtidcnt / pd->port_subport_cnt) +
			 (dd->ipath_rcvtidcnt % pd->port_subport_cnt);
		porttid += dd->ipath_rcvtidcnt - tidcnt;
	} else {
		tidcnt = dd->ipath_rcvtidcnt / pd->port_subport_cnt;
		porttid += tidcnt * (subport - 1);
	}
	tidbase = (u64 __iomem *) ((char __iomem *)(dd->ipath_kregbase) +
				   dd->ipath_rcvtidbase +
				   porttid * sizeof(*tidbase));

	limit = sizeof(tidmap) * BITS_PER_BYTE;
	if (limit > tidcnt)
		/* just in case size changes in future */
		limit = tidcnt;
	tid = find_first_bit(tidmap, limit);
	ipath_cdbg(VERBOSE, "Port%u free %u tids; first bit (max=%d) "
		   "set is %d, porttid %u\n", pd->port_port, ti->tidcnt,
		   limit, tid, porttid);
	for (cnt = 0; tid < limit; tid++) {
		/*
		 * small optimization; if we detect a run of 3 or so without
		 * any set, use find_first_bit again.  That's mainly to
		 * accelerate the case where we wrapped, so we have some at
		 * the beginning, and some at the end, and a big gap
		 * in the middle.
		 */
		if (!test_bit(tid, tidmap))
			continue;
		cnt++;
		if (dd->ipath_pageshadow[porttid + tid]) {
			struct page *p;
			p = dd->ipath_pageshadow[porttid + tid];
			dd->ipath_pageshadow[porttid + tid] = NULL;
			ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n",
				   pid_nr(pd->port_pid), tid);
			dd->ipath_f_put_tid(dd, &tidbase[tid],
					    RCVHQ_RCV_TYPE_EXPECTED,
					    dd->ipath_tidinvalid);
			pci_unmap_page(dd->pcidev,
				dd->ipath_physshadow[porttid + tid],
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
			ipath_release_user_pages(&p, 1);
			ipath_stats.sps_pageunlocks++;
		} else
			ipath_dbg("Unused tid %u, ignoring\n", tid);
	}
	if (cnt != ti->tidcnt)
		ipath_dbg("passed in tidcnt %d, only %d bits set in map\n",
			  ti->tidcnt, cnt);
done:
	if (ret)
		ipath_dbg("Failed to unmap %u TID pages, failing with %d\n",
			  ti->tidcnt, -ret);
	return ret;
}

/**
 * ipath_set_part_key - set a partition key
 * @pd: the port
 * @key: the key
 *
 * We can have up to 4 active at a time (other than the default, which is
 * always allowed).  This is somewhat tricky, since multiple ports may set
 * the same key, so we reference count them, and clean up at exit.  All 4
 * partition keys are packed into a single infinipath register.  It's an
 * error for a process to set the same pkey multiple times.  We provide no
 * mechanism to de-allocate a pkey at this time, we may eventually need to
 * do that.  I've used the atomic operations, and no locking, and only make
 * a single pass through what's available.  This should be more than
 * adequate for some time. I'll think about spinlocks or the like if and as
 * it's necessary.
 */
static int ipath_set_part_key(struct ipath_portdata *pd, u16 key)
{
	struct ipath_devdata *dd = pd->port_dd;
	int i, any = 0, pidx = -1;
	u16 lkey = key & 0x7FFF;
	int ret;

	if (lkey == (IPATH_DEFAULT_P_KEY & 0x7FFF)) {
		/* nothing to do; this key always valid */
		ret = 0;
		goto bail;
	}

	ipath_cdbg(VERBOSE, "p%u try to set pkey %hx, current keys "
		   "%hx:%x %hx:%x %hx:%x %hx:%x\n",
		   pd->port_port, key, dd->ipath_pkeys[0],
		   atomic_read(&dd->ipath_pkeyrefs[0]), dd->ipath_pkeys[1],
		   atomic_read(&dd->ipath_pkeyrefs[1]), dd->ipath_pkeys[2],
		   atomic_read(&dd->ipath_pkeyrefs[2]), dd->ipath_pkeys[3],
		   atomic_read(&dd->ipath_pkeyrefs[3]));

	if (!lkey) {
		ipath_cdbg(PROC, "p%u tries to set key 0, not allowed\n",
			   pd->port_port);
		ret = -EINVAL;
		goto bail;
	}

	/*
	 * Set the full membership bit, because it has to be
	 * set in the register or the packet, and it seems
	 * cleaner to set in the register than to force all
	 * callers to set it. (see bug 4331)
	 */
	key |= 0x8000;

	for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) {
		if (!pd->port_pkeys[i] && pidx == -1)
			pidx = i;
		if (pd->port_pkeys[i] == key) {
			ipath_cdbg(VERBOSE, "p%u tries to set same pkey "
				   "(%x) more than once\n",
				   pd->port_port, key);
			ret = -EEXIST;
			goto bail;
		}
	}
	if (pidx == -1) {
		ipath_dbg("All pkeys for port %u already in use, "
			  "can't set %x\n", pd->port_port, key);
		ret = -EBUSY;
		goto bail;
	}
	for (any = i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
		if (!dd->ipath_pkeys[i]) {
			any++;
			continue;
		}
		if (dd->ipath_pkeys[i] == key) {
			atomic_t *pkrefs = &dd->ipath_pkeyrefs[i];

			if (atomic_inc_return(pkrefs) > 1) {
				pd->port_pkeys[pidx] = key;
				ipath_cdbg(VERBOSE, "p%u set key %x "
					   "matches #%d, count now %d\n",
					   pd->port_port, key, i,
					   atomic_read(pkrefs));
				ret = 0;
				goto bail;
			} else {
				/*
				 * lost race, decrement count, catch below
				 */
				atomic_dec(pkrefs);
				ipath_cdbg(VERBOSE, "Lost race, count was "
					   "0, after dec, it's %d\n",
					   atomic_read(pkrefs));
				any++;
			}
		}
		if ((dd->ipath_pkeys[i] & 0x7FFF) == lkey) {
			/*
			 * It makes no sense to have both the limited and
			 * full membership PKEY set at the same time since
			 * the unlimited one will disable the limited one.
			 */
			ret = -EEXIST;
			goto bail;
		}
	}
	if (!any) {
		ipath_dbg("port %u, all pkeys already in use, "
			  "can't set %x\n", pd->port_port, key);
		ret = -EBUSY;
		goto bail;
	}
	for (any = i = 0; i < ARRAY_SIZE(dd->ipath_pkeys); i++) {
		if (!dd->ipath_pkeys[i] &&
		    atomic_inc_return(&dd->ipath_pkeyrefs[i]) == 1) {
			u64 pkey;

			/* for ipathstats, etc. */
			ipath_stats.sps_pkeys[i] = lkey;
			pd->port_pkeys[pidx] = dd->ipath_pkeys[i] = key;
			pkey =
				(u64) dd->ipath_pkeys[0] |
				((u64) dd->ipath_pkeys[1] << 16) |
				((u64) dd->ipath_pkeys[2] << 32) |
				((u64) dd->ipath_pkeys[3] << 48);
			ipath_cdbg(PROC, "p%u set key %x in #%d, "
				   "portidx %d, new pkey reg %llx\n",
				   pd->port_port, key, i, pidx,
				   (unsigned long long) pkey);
			ipath_write_kreg(
				dd, dd->ipath_kregs->kr_partitionkey, pkey);

			ret = 0;
			goto bail;
		}
	}
	ipath_dbg("port %u, all pkeys already in use 2nd pass, "
		  "can't set %x\n", pd->port_port, key);
	ret = -EBUSY;

bail:
	return ret;
}

/**
 * ipath_manage_rcvq - manage a port's receive queue
 * @pd: the port
 * @subport: the subport
 * @start_stop: action to carry out
 *
 * start_stop == 0 disables receive on the port, for use in queue
 * overflow conditions.  start_stop==1 re-enables, to be used to
 * re-init the software copy of the head register
 */
static int ipath_manage_rcvq(struct ipath_portdata *pd, unsigned subport,
			     int start_stop)
{
	struct ipath_devdata *dd = pd->port_dd;

	ipath_cdbg(PROC, "%sabling rcv for unit %u port %u:%u\n",
		   start_stop ? "en" : "dis", dd->ipath_unit,
		   pd->port_port, subport);
	if (subport)
		goto bail;
	/* atomically clear receive enable port. */
	if (start_stop) {
		/*
		 * On enable, force in-memory copy of the tail register to
		 * 0, so that protocol code doesn't have to worry about
		 * whether or not the chip has yet updated the in-memory
		 * copy or not on return from the system call. The chip
		 * always resets it's tail register back to 0 on a
		 * transition from disabled to enabled.  This could cause a
		 * problem if software was broken, and did the enable w/o
		 * the disable, but eventually the in-memory copy will be
		 * updated and correct itself, even in the face of software
		 * bugs.
		 */
		if (pd->port_rcvhdrtail_kvaddr)
			ipath_clear_rcvhdrtail(pd);
		set_bit(dd->ipath_r_portenable_shift + pd->port_port,
			&dd->ipath_rcvctrl);
	} else
		clear_bit(dd->ipath_r_portenable_shift + pd->port_port,
			  &dd->ipath_rcvctrl);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
			 dd->ipath_rcvctrl);
	/* now be sure chip saw it before we return */
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
	if (start_stop) {
		/*
		 * And try to be sure that tail reg update has happened too.
		 * This should in theory interlock with the RXE changes to
		 * the tail register.  Don't assign it to the tail register
		 * in memory copy, since we could overwrite an update by the
		 * chip if we did.
		 */
		ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port);
	}
	/* always; new head should be equal to new tail; see above */
bail:
	return 0;
}

static void ipath_clean_part_key(struct ipath_portdata *pd,
				 struct ipath_devdata *dd)
{
	int i, j, pchanged = 0;
	u64 oldpkey;

	/* for debugging only */
	oldpkey = (u64) dd->ipath_pkeys[0] |
		((u64) dd->ipath_pkeys[1] << 16) |
		((u64) dd->ipath_pkeys[2] << 32) |
		((u64) dd->ipath_pkeys[3] << 48);

	for (i = 0; i < ARRAY_SIZE(pd->port_pkeys); i++) {
		if (!pd->port_pkeys[i])
			continue;
		ipath_cdbg(VERBOSE, "look for key[%d] %hx in pkeys\n", i,
			   pd->port_pkeys[i]);
		for (j = 0; j < ARRAY_SIZE(dd->ipath_pkeys); j++) {
			/* check for match independent of the global bit */
			if ((dd->ipath_pkeys[j] & 0x7fff) !=
			    (pd->port_pkeys[i] & 0x7fff))
				continue;
			if (atomic_dec_and_test(&dd->ipath_pkeyrefs[j])) {
				ipath_cdbg(VERBOSE, "p%u clear key "
					   "%x matches #%d\n",
					   pd->port_port,
					   pd->port_pkeys[i], j);
				ipath_stats.sps_pkeys[j] =
					dd->ipath_pkeys[j] = 0;
				pchanged++;
			}
			else ipath_cdbg(
				VERBOSE, "p%u key %x matches #%d, "
				"but ref still %d\n", pd->port_port,
				pd->port_pkeys[i], j,
				atomic_read(&dd->ipath_pkeyrefs[j]));
			break;
		}
		pd->port_pkeys[i] = 0;
	}
	if (pchanged) {
		u64 pkey = (u64) dd->ipath_pkeys[0] |
			((u64) dd->ipath_pkeys[1] << 16) |
			((u64) dd->ipath_pkeys[2] << 32) |
			((u64) dd->ipath_pkeys[3] << 48);
		ipath_cdbg(VERBOSE, "p%u old pkey reg %llx, "
			   "new pkey reg %llx\n", pd->port_port,
			   (unsigned long long) oldpkey,
			   (unsigned long long) pkey);
		ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey,
				 pkey);
	}
}

/*
 * Initialize the port data with the receive buffer sizes
 * so this can be done while the master port is locked.
 * Otherwise, there is a race with a slave opening the port
 * and seeing these fields uninitialized.
 */
static void init_user_egr_sizes(struct ipath_portdata *pd)
{
	struct ipath_devdata *dd = pd->port_dd;
	unsigned egrperchunk, egrcnt, size;

	/*
	 * to avoid wasting a lot of memory, we allocate 32KB chunks of
	 * physically contiguous memory, advance through it until used up
	 * and then allocate more.  Of course, we need memory to store those
	 * extra pointers, now.  Started out with 256KB, but under heavy
	 * memory pressure (creating large files and then copying them over
	 * NFS while doing lots of MPI jobs), we hit some allocation
	 * failures, even though we can sleep...  (2.6.10) Still get
	 * failures at 64K.  32K is the lowest we can go without wasting
	 * additional memory.
	 */
	size = 0x8000;
	egrperchunk = size / dd->ipath_rcvegrbufsize;
	egrcnt = dd->ipath_rcvegrcnt;
	pd->port_rcvegrbuf_chunks = (egrcnt + egrperchunk - 1) / egrperchunk;
	pd->port_rcvegrbufs_perchunk = egrperchunk;
	pd->port_rcvegrbuf_size = size;
}

/**
 * ipath_create_user_egr - allocate eager TID buffers
 * @pd: the port to allocate TID buffers for
 *
 * This routine is now quite different for user and kernel, because
 * the kernel uses skb's, for the accelerated network performance
 * This is the user port version
 *
 * Allocate the eager TID buffers and program them into infinipath
 * They are no longer completely contiguous, we do multiple allocation
 * calls.
 */
static int ipath_create_user_egr(struct ipath_portdata *pd)
{
	struct ipath_devdata *dd = pd->port_dd;
	unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
	size_t size;
	int ret;
	gfp_t gfp_flags;

	/*
	 * GFP_USER, but without GFP_FS, so buffer cache can be
	 * coalesced (we hope); otherwise, even at order 4,
	 * heavy filesystem activity makes these fail, and we can
	 * use compound pages.
	 */
	gfp_flags = __GFP_WAIT | __GFP_IO | __GFP_COMP;

	egrcnt = dd->ipath_rcvegrcnt;
	/* TID number offset for this port */
	egroff = (pd->port_port - 1) * egrcnt + dd->ipath_p0_rcvegrcnt;
	egrsize = dd->ipath_rcvegrbufsize;
	ipath_cdbg(VERBOSE, "Allocating %d egr buffers, at egrtid "
		   "offset %x, egrsize %u\n", egrcnt, egroff, egrsize);

	chunk = pd->port_rcvegrbuf_chunks;
	egrperchunk = pd->port_rcvegrbufs_perchunk;
	size = pd->port_rcvegrbuf_size;
	pd->port_rcvegrbuf = kmalloc(chunk * sizeof(pd->port_rcvegrbuf[0]),
				     GFP_KERNEL);
	if (!pd->port_rcvegrbuf) {
		ret = -ENOMEM;
		goto bail;
	}
	pd->port_rcvegrbuf_phys =
		kmalloc(chunk * sizeof(pd->port_rcvegrbuf_phys[0]),
			GFP_KERNEL);
	if (!pd->port_rcvegrbuf_phys) {
		ret = -ENOMEM;
		goto bail_rcvegrbuf;
	}
	for (e = 0; e < pd->port_rcvegrbuf_chunks; e++) {

		pd->port_rcvegrbuf[e] = dma_alloc_coherent(
			&dd->pcidev->dev, size, &pd->port_rcvegrbuf_phys[e],
			gfp_flags);

		if (!pd->port_rcvegrbuf[e]) {
			ret = -ENOMEM;
			goto bail_rcvegrbuf_phys;
		}
	}

	pd->port_rcvegr_phys = pd->port_rcvegrbuf_phys[0];

	for (e = chunk = 0; chunk < pd->port_rcvegrbuf_chunks; chunk++) {
		dma_addr_t pa = pd->port_rcvegrbuf_phys[chunk];
		unsigned i;

		for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) {
			dd->ipath_f_put_tid(dd, e + egroff +
					    (u64 __iomem *)
					    ((char __iomem *)
					     dd->ipath_kregbase +
					     dd->ipath_rcvegrbase),
					    RCVHQ_RCV_TYPE_EAGER, pa);
			pa += egrsize;
		}
		cond_resched();	/* don't hog the cpu */
	}

	ret = 0;
	goto bail;

bail_rcvegrbuf_phys:
	for (e = 0; e < pd->port_rcvegrbuf_chunks &&
		pd->port_rcvegrbuf[e]; e++) {
		dma_free_coherent(&dd->pcidev->dev, size,
				  pd->port_rcvegrbuf[e],
				  pd->port_rcvegrbuf_phys[e]);

	}
	kfree(pd->port_rcvegrbuf_phys);
	pd->port_rcvegrbuf_phys = NULL;
bail_rcvegrbuf:
	kfree(pd->port_rcvegrbuf);
	pd->port_rcvegrbuf = NULL;
bail:
	return ret;
}


/* common code for the mappings on dma_alloc_coherent mem */
static int ipath_mmap_mem(struct vm_area_struct *vma,
	struct ipath_portdata *pd, unsigned len, int write_ok,
	void *kvaddr, char *what)
{
	struct ipath_devdata *dd = pd->port_dd;
	unsigned long pfn;
	int ret;

	if ((vma->vm_end - vma->vm_start) > len) {
		dev_info(&dd->pcidev->dev,
		         "FAIL on %s: len %lx > %x\n", what,
			 vma->vm_end - vma->vm_start, len);
		ret = -EFAULT;
		goto bail;
	}

	if (!write_ok) {
		if (vma->vm_flags & VM_WRITE) {
			dev_info(&dd->pcidev->dev,
				 "%s must be mapped readonly\n", what);
			ret = -EPERM;
			goto bail;
		}

		/* don't allow them to later change with mprotect */
		vma->vm_flags &= ~VM_MAYWRITE;
	}

	pfn = virt_to_phys(kvaddr) >> PAGE_SHIFT;
	ret = remap_pfn_range(vma, vma->vm_start, pfn,
			      len, vma->vm_page_prot);
	if (ret)
		dev_info(&dd->pcidev->dev, "%s port%u mmap of %lx, %x "
			 "bytes r%c failed: %d\n", what, pd->port_port,
			 pfn, len, write_ok?'w':'o', ret);
	else
		ipath_cdbg(VERBOSE, "%s port%u mmaped %lx, %x bytes "
			   "r%c\n", what, pd->port_port, pfn, len,
			   write_ok?'w':'o');
bail:
	return ret;
}

static int mmap_ureg(struct vm_area_struct *vma, struct ipath_devdata *dd,
		     u64 ureg)
{
	unsigned long phys;
	int ret;

	/*
	 * This is real hardware, so use io_remap.  This is the mechanism
	 * for the user process to update the head registers for their port
	 * in the chip.
	 */
	if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) {
		dev_info(&dd->pcidev->dev, "FAIL mmap userreg: reqlen "
			 "%lx > PAGE\n", vma->vm_end - vma->vm_start);
		ret = -EFAULT;
	} else {
		phys = dd->ipath_physaddr + ureg;
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

		vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
		ret = io_remap_pfn_range(vma, vma->vm_start,
					 phys >> PAGE_SHIFT,
					 vma->vm_end - vma->vm_start,
					 vma->vm_page_prot);
	}
	return ret;
}

static int mmap_piobufs(struct vm_area_struct *vma,
			struct ipath_devdata *dd,
			struct ipath_portdata *pd,
			unsigned piobufs, unsigned piocnt)
{
	unsigned long phys;
	int ret;

	/*
	 * When we map the PIO buffers in the chip, we want to map them as
	 * writeonly, no read possible.   This prevents access to previous
	 * process data, and catches users who might try to read the i/o
	 * space due to a bug.
	 */
	if ((vma->vm_end - vma->vm_start) > (piocnt * dd->ipath_palign)) {
		dev_info(&dd->pcidev->dev, "FAIL mmap piobufs: "
			 "reqlen %lx > PAGE\n",
			 vma->vm_end - vma->vm_start);
		ret = -EINVAL;
		goto bail;
	}

	phys = dd->ipath_physaddr + piobufs;

#if defined(__powerpc__)
	/* There isn't a generic way to specify writethrough mappings */
	pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
	pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU;
	pgprot_val(vma->vm_page_prot) &= ~_PAGE_GUARDED;
#endif

	/*
	 * don't allow them to later change to readable with mprotect (for when
	 * not initially mapped readable, as is normally the case)
	 */
	vma->vm_flags &= ~VM_MAYREAD;
	vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;

	ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT,
				 vma->vm_end - vma->vm_start,
				 vma->vm_page_prot);
bail:
	return ret;
}

static int mmap_rcvegrbufs(struct vm_area_struct *vma,
			   struct ipath_portdata *pd)
{
	struct ipath_devdata *dd = pd->port_dd;
	unsigned long start, size;
	size_t total_size, i;
	unsigned long pfn;
	int ret;

	size = pd->port_rcvegrbuf_size;
	total_size = pd->port_rcvegrbuf_chunks * size;
	if ((vma->vm_end - vma->vm_start) > total_size) {
		dev_info(&dd->pcidev->dev, "FAIL on egr bufs: "
			 "reqlen %lx > actual %lx\n",
			 vma->vm_end - vma->vm_start,
			 (unsigned long) total_size);
		ret = -EINVAL;
		goto bail;
	}

	if (vma->vm_flags & VM_WRITE) {
		dev_info(&dd->pcidev->dev, "Can't map eager buffers as "
			 "writable (flags=%lx)\n", vma->vm_flags);
		ret = -EPERM;
		goto bail;
	}
	/* don't allow them to later change to writeable with mprotect */
	vma->vm_flags &= ~VM_MAYWRITE;

	start = vma->vm_start;

	for (i = 0; i < pd->port_rcvegrbuf_chunks; i++, start += size) {
		pfn = virt_to_phys(pd->port_rcvegrbuf[i]) >> PAGE_SHIFT;
		ret = remap_pfn_range(vma, start, pfn, size,
				      vma->vm_page_prot);
		if (ret < 0)
			goto bail;
	}
	ret = 0;

bail:
	return ret;
}

/*
 * ipath_file_vma_fault - handle a VMA page fault.
 */
static int ipath_file_vma_fault(struct vm_area_struct *vma,
					struct vm_fault *vmf)
{
	struct page *page;

	page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT));
	if (!page)
		return VM_FAULT_SIGBUS;
	get_page(page);
	vmf->page = page;

	return 0;
}

static const struct vm_operations_struct ipath_file_vm_ops = {
	.fault = ipath_file_vma_fault,
};

static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr,
		       struct ipath_portdata *pd, unsigned subport)
{
	unsigned long len;
	struct ipath_devdata *dd;
	void *addr;
	size_t size;
	int ret = 0;

	/* If the port is not shared, all addresses should be physical */
	if (!pd->port_subport_cnt)
		goto bail;

	dd = pd->port_dd;
	size = pd->port_rcvegrbuf_chunks * pd->port_rcvegrbuf_size;

	/*
	 * Each process has all the subport uregbase, rcvhdrq, and
	 * rcvegrbufs mmapped - as an array for all the processes,
	 * and also separately for this process.
	 */
	if (pgaddr == cvt_kvaddr(pd->subport_uregbase)) {
		addr = pd->subport_uregbase;
		size = PAGE_SIZE * pd->port_subport_cnt;
	} else if (pgaddr == cvt_kvaddr(pd->subport_rcvhdr_base)) {
		addr = pd->subport_rcvhdr_base;
		size = pd->port_rcvhdrq_size * pd->port_subport_cnt;
	} else if (pgaddr == cvt_kvaddr(pd->subport_rcvegrbuf)) {
		addr = pd->subport_rcvegrbuf;
		size *= pd->port_subport_cnt;
        } else if (pgaddr == cvt_kvaddr(pd->subport_uregbase +
                                        PAGE_SIZE * subport)) {
                addr = pd->subport_uregbase + PAGE_SIZE * subport;
                size = PAGE_SIZE;
        } else if (pgaddr == cvt_kvaddr(pd->subport_rcvhdr_base +
                                pd->port_rcvhdrq_size * subport)) {
                addr = pd->subport_rcvhdr_base +
                        pd->port_rcvhdrq_size * subport;
                size = pd->port_rcvhdrq_size;
        } else if (pgaddr == cvt_kvaddr(pd->subport_rcvegrbuf +
                               size * subport)) {
                addr = pd->subport_rcvegrbuf + size * subport;
                /* rcvegrbufs are read-only on the slave */
                if (vma->vm_flags & VM_WRITE) {
                        dev_info(&dd->pcidev->dev,
                                 "Can't map eager buffers as "
                                 "writable (flags=%lx)\n", vma->vm_flags);
                        ret = -EPERM;
                        goto bail;
                }
                /*
                 * Don't allow permission to later change to writeable
                 * with mprotect.
                 */
                vma->vm_flags &= ~VM_MAYWRITE;
	} else {
		goto bail;
	}
	len = vma->vm_end - vma->vm_start;
	if (len > size) {
		ipath_cdbg(MM, "FAIL: reqlen %lx > %zx\n", len, size);
		ret = -EINVAL;
		goto bail;
	}

	vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
	vma->vm_ops = &ipath_file_vm_ops;
	vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
	ret = 1;

bail:
	return ret;
}

/**
 * ipath_mmap - mmap various structures into user space
 * @fp: the file pointer
 * @vma: the VM area
 *
 * We use this to have a shared buffer between the kernel and the user code
 * for the rcvhdr queue, egr buffers, and the per-port user regs and pio
 * buffers in the chip.  We have the open and close entries so we can bump
 * the ref count and keep the driver from being unloaded while still mapped.
 */
static int ipath_mmap(struct file *fp, struct vm_area_struct *vma)
{
	struct ipath_portdata *pd;
	struct ipath_devdata *dd;
	u64 pgaddr, ureg;
	unsigned piobufs, piocnt;
	int ret;

	pd = port_fp(fp);
	if (!pd) {
		ret = -EINVAL;
		goto bail;
	}
	dd = pd->port_dd;

	/*
	 * This is the ipath_do_user_init() code, mapping the shared buffers
	 * into the user process. The address referred to by vm_pgoff is the
	 * file offset passed via mmap().  For shared ports, this is the
	 * kernel vmalloc() address of the pages to share with the master.
	 * For non-shared or master ports, this is a physical address.
	 * We only do one mmap for each space mapped.
	 */
	pgaddr = vma->vm_pgoff << PAGE_SHIFT;

	/*
	 * Check for 0 in case one of the allocations failed, but user
	 * called mmap anyway.
	 */
	if (!pgaddr)  {
		ret = -EINVAL;
		goto bail;
	}

	ipath_cdbg(MM, "pgaddr %llx vm_start=%lx len %lx port %u:%u:%u\n",
		   (unsigned long long) pgaddr, vma->vm_start,
		   vma->vm_end - vma->vm_start, dd->ipath_unit,
		   pd->port_port, subport_fp(fp));

	/*
	 * Physical addresses must fit in 40 bits for our hardware.
	 * Check for kernel virtual addresses first, anything else must
	 * match a HW or memory address.
	 */
	ret = mmap_kvaddr(vma, pgaddr, pd, subport_fp(fp));
	if (ret) {
		if (ret > 0)
			ret = 0;
		goto bail;
	}

	ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port;
	if (!pd->port_subport_cnt) {
		/* port is not shared */
		piocnt = pd->port_piocnt;
		piobufs = pd->port_piobufs;
	} else if (!subport_fp(fp)) {
		/* caller is the master */
		piocnt = (pd->port_piocnt / pd->port_subport_cnt) +
			 (pd->port_piocnt % pd->port_subport_cnt);
		piobufs = pd->port_piobufs +
			dd->ipath_palign * (pd->port_piocnt - piocnt);
	} else {
		unsigned slave = subport_fp(fp) - 1;

		/* caller is a slave */
		piocnt = pd->port_piocnt / pd->port_subport_cnt;
		piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave;
	}

	if (pgaddr == ureg)
		ret = mmap_ureg(vma, dd, ureg);
	else if (pgaddr == piobufs)
		ret = mmap_piobufs(vma, dd, pd, piobufs, piocnt);
	else if (pgaddr == dd->ipath_pioavailregs_phys)
		/* in-memory copy of pioavail registers */
		ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
			      	     (void *) dd->ipath_pioavailregs_dma,
				     "pioavail registers");
	else if (pgaddr == pd->port_rcvegr_phys)
		ret = mmap_rcvegrbufs(vma, pd);
	else if (pgaddr == (u64) pd->port_rcvhdrq_phys)
		/*
		 * The rcvhdrq itself; readonly except on HT (so have
		 * to allow writable mapping), multiple pages, contiguous
		 * from an i/o perspective.
		 */
		ret = ipath_mmap_mem(vma, pd, pd->port_rcvhdrq_size, 1,
				     pd->port_rcvhdrq,
				     "rcvhdrq");
	else if (pgaddr == (u64) pd->port_rcvhdrqtailaddr_phys)
		/* in-memory copy of rcvhdrq tail register */
		ret = ipath_mmap_mem(vma, pd, PAGE_SIZE, 0,
				     pd->port_rcvhdrtail_kvaddr,
				     "rcvhdrq tail");
	else
		ret = -EINVAL;

	vma->vm_private_data = NULL;

	if (ret < 0)
		dev_info(&dd->pcidev->dev,
			 "Failure %d on off %llx len %lx\n",
			 -ret, (unsigned long long)pgaddr,
			 vma->vm_end - vma->vm_start);
bail:
	return ret;
}

static unsigned ipath_poll_hdrqfull(struct ipath_portdata *pd)
{
	unsigned pollflag = 0;

	if ((pd->poll_type & IPATH_POLL_TYPE_OVERFLOW) &&
	    pd->port_hdrqfull != pd->port_hdrqfull_poll) {
		pollflag |= POLLIN | POLLRDNORM;
		pd->port_hdrqfull_poll = pd->port_hdrqfull;
	}

	return pollflag;
}

static unsigned int ipath_poll_urgent(struct ipath_portdata *pd,
				      struct file *fp,
				      struct poll_table_struct *pt)
{
	unsigned pollflag = 0;
	struct ipath_devdata *dd;

	dd = pd->port_dd;

	/* variable access in ipath_poll_hdrqfull() needs this */
	rmb();
	pollflag = ipath_poll_hdrqfull(pd);

	if (pd->port_urgent != pd->port_urgent_poll) {
		pollflag |= POLLIN | POLLRDNORM;
		pd->port_urgent_poll = pd->port_urgent;
	}

	if (!pollflag) {
		/* this saves a spin_lock/unlock in interrupt handler... */
		set_bit(IPATH_PORT_WAITING_URG, &pd->port_flag);
		/* flush waiting flag so don't miss an event... */
		wmb();
		poll_wait(fp, &pd->port_wait, pt);
	}

	return pollflag;
}

static unsigned int ipath_poll_next(struct ipath_portdata *pd,
				    struct file *fp,
				    struct poll_table_struct *pt)
{
	u32 head;
	u32 tail;
	unsigned pollflag = 0;
	struct ipath_devdata *dd;

	dd = pd->port_dd;

	/* variable access in ipath_poll_hdrqfull() needs this */
	rmb();
	pollflag = ipath_poll_hdrqfull(pd);

	head = ipath_read_ureg32(dd, ur_rcvhdrhead, pd->port_port);
	if (pd->port_rcvhdrtail_kvaddr)
		tail = ipath_get_rcvhdrtail(pd);
	else
		tail = ipath_read_ureg32(dd, ur_rcvhdrtail, pd->port_port);

	if (head != tail)
		pollflag |= POLLIN | POLLRDNORM;
	else {
		/* this saves a spin_lock/unlock in interrupt handler */
		set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
		/* flush waiting flag so we don't miss an event */
		wmb();

		set_bit(pd->port_port + dd->ipath_r_intravail_shift,
			&dd->ipath_rcvctrl);

		ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
				 dd->ipath_rcvctrl);

		if (dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
			ipath_write_ureg(dd, ur_rcvhdrhead,
					 dd->ipath_rhdrhead_intr_off | head,
					 pd->port_port);

		poll_wait(fp, &pd->port_wait, pt);
	}

	return pollflag;
}

static unsigned int ipath_poll(struct file *fp,
			       struct poll_table_struct *pt)
{
	struct ipath_portdata *pd;
	unsigned pollflag;

	pd = port_fp(fp);
	if (!pd)
		pollflag = 0;
	else if (pd->poll_type & IPATH_POLL_TYPE_URGENT)
		pollflag = ipath_poll_urgent(pd, fp, pt);
	else
		pollflag = ipath_poll_next(pd, fp, pt);

	return pollflag;
}

static int ipath_supports_subports(int user_swmajor, int user_swminor)
{
	/* no subport implementation prior to software version 1.3 */
	return (user_swmajor > 1) || (user_swminor >= 3);
}

static int ipath_compatible_subports(int user_swmajor, int user_swminor)
{
	/* this code is written long-hand for clarity */
	if (IPATH_USER_SWMAJOR != user_swmajor) {
		/* no promise of compatibility if major mismatch */
		return 0;
	}
	if (IPATH_USER_SWMAJOR == 1) {
		switch (IPATH_USER_SWMINOR) {
		case 0:
		case 1:
		case 2:
			/* no subport implementation so cannot be compatible */
			return 0;
		case 3:
			/* 3 is only compatible with itself */
			return user_swminor == 3;
		default:
			/* >= 4 are compatible (or are expected to be) */
			return user_swminor >= 4;
		}
	}
	/* make no promises yet for future major versions */
	return 0;
}

static int init_subports(struct ipath_devdata *dd,
			 struct ipath_portdata *pd,
			 const struct ipath_user_info *uinfo)
{
	int ret = 0;
	unsigned num_subports;
	size_t size;

	/*
	 * If the user is requesting zero subports,
	 * skip the subport allocation.
	 */
	if (uinfo->spu_subport_cnt <= 0)
		goto bail;

	/* Self-consistency check for ipath_compatible_subports() */
	if (ipath_supports_subports(IPATH_USER_SWMAJOR, IPATH_USER_SWMINOR) &&
	    !ipath_compatible_subports(IPATH_USER_SWMAJOR,
				       IPATH_USER_SWMINOR)) {
		dev_info(&dd->pcidev->dev,
			 "Inconsistent ipath_compatible_subports()\n");
		goto bail;
	}

	/* Check for subport compatibility */
	if (!ipath_compatible_subports(uinfo->spu_userversion >> 16,
				       uinfo->spu_userversion & 0xffff)) {
		dev_info(&dd->pcidev->dev,
			 "Mismatched user version (%d.%d) and driver "
			 "version (%d.%d) while port sharing. Ensure "
                         "that driver and library are from the same "
                         "release.\n",
			 (int) (uinfo->spu_userversion >> 16),
                         (int) (uinfo->spu_userversion & 0xffff),
			 IPATH_USER_SWMAJOR,
	                 IPATH_USER_SWMINOR);
		goto bail;
	}
	if (uinfo->spu_subport_cnt > INFINIPATH_MAX_SUBPORT) {
		ret = -EINVAL;
		goto bail;
	}

	num_subports = uinfo->spu_subport_cnt;
	pd->subport_uregbase = vmalloc(PAGE_SIZE * num_subports);
	if (!pd->subport_uregbase) {
		ret = -ENOMEM;
		goto bail;
	}
	/* Note: pd->port_rcvhdrq_size isn't initialized yet. */
	size = ALIGN(dd->ipath_rcvhdrcnt * dd->ipath_rcvhdrentsize *
		     sizeof(u32), PAGE_SIZE) * num_subports;
	pd->subport_rcvhdr_base = vmalloc(size);
	if (!pd->subport_rcvhdr_base) {
		ret = -ENOMEM;
		goto bail_ureg;
	}

	pd->subport_rcvegrbuf = vmalloc(pd->port_rcvegrbuf_chunks *
					pd->port_rcvegrbuf_size *
					num_subports);
	if (!pd->subport_rcvegrbuf) {
		ret = -ENOMEM;
		goto bail_rhdr;
	}

	pd->port_subport_cnt = uinfo->spu_subport_cnt;
	pd->port_subport_id = uinfo->spu_subport_id;
	pd->active_slaves = 1;
	set_bit(IPATH_PORT_MASTER_UNINIT, &pd->port_flag);
	memset(pd->subport_uregbase, 0, PAGE_SIZE * num_subports);
	memset(pd->subport_rcvhdr_base, 0, size);
	memset(pd->subport_rcvegrbuf, 0, pd->port_rcvegrbuf_chunks *
				         pd->port_rcvegrbuf_size *
				         num_subports);
	goto bail;

bail_rhdr:
	vfree(pd->subport_rcvhdr_base);
bail_ureg:
	vfree(pd->subport_uregbase);
	pd->subport_uregbase = NULL;
bail:
	return ret;
}

static int try_alloc_port(struct ipath_devdata *dd, int port,
			  struct file *fp,
			  const struct ipath_user_info *uinfo)
{
	struct ipath_portdata *pd;
	int ret;

	if (!(pd = dd->ipath_pd[port])) {
		void *ptmp;

		pd = kzalloc(sizeof(struct ipath_portdata), GFP_KERNEL);

		/*
		 * Allocate memory for use in ipath_tid_update() just once
		 * at open, not per call.  Reduces cost of expected send
		 * setup.
		 */
		ptmp = kmalloc(dd->ipath_rcvtidcnt * sizeof(u16) +
			       dd->ipath_rcvtidcnt * sizeof(struct page **),
			       GFP_KERNEL);
		if (!pd || !ptmp) {
			ipath_dev_err(dd, "Unable to allocate portdata "
				      "memory, failing open\n");
			ret = -ENOMEM;
			kfree(pd);
			kfree(ptmp);
			goto bail;
		}
		dd->ipath_pd[port] = pd;
		dd->ipath_pd[port]->port_port = port;
		dd->ipath_pd[port]->port_dd = dd;
		dd->ipath_pd[port]->port_tid_pg_list = ptmp;
		init_waitqueue_head(&dd->ipath_pd[port]->port_wait);
	}
	if (!pd->port_cnt) {
		pd->userversion = uinfo->spu_userversion;
		init_user_egr_sizes(pd);
		if ((ret = init_subports(dd, pd, uinfo)) != 0)
			goto bail;
		ipath_cdbg(PROC, "%s[%u] opened unit:port %u:%u\n",
			   current->comm, current->pid, dd->ipath_unit,
			   port);
		pd->port_cnt = 1;
		port_fp(fp) = pd;
		pd->port_pid = get_pid(task_pid(current));
		strlcpy(pd->port_comm, current->comm, sizeof(pd->port_comm));
		ipath_stats.sps_ports++;
		ret = 0;
	} else
		ret = -EBUSY;

bail:
	return ret;
}

static inline int usable(struct ipath_devdata *dd)
{
	return dd &&
		(dd->ipath_flags & IPATH_PRESENT) &&
		dd->ipath_kregbase &&
		dd->ipath_lid &&
		!(dd->ipath_flags & (IPATH_LINKDOWN | IPATH_DISABLED
				     | IPATH_LINKUNK));
}

static int find_free_port(int unit, struct file *fp,
			  const struct ipath_user_info *uinfo)
{
	struct ipath_devdata *dd = ipath_lookup(unit);
	int ret, i;

	if (!dd) {
		ret = -ENODEV;
		goto bail;
	}

	if (!usable(dd)) {
		ret = -ENETDOWN;
		goto bail;
	}

	for (i = 1; i < dd->ipath_cfgports; i++) {
		ret = try_alloc_port(dd, i, fp, uinfo);
		if (ret != -EBUSY)
			goto bail;
	}
	ret = -EBUSY;

bail:
	return ret;
}

static int find_best_unit(struct file *fp,
			  const struct ipath_user_info *uinfo)
{
	int ret = 0, i, prefunit = -1, devmax;
	int maxofallports, npresent, nup;
	int ndev;

	devmax = ipath_count_units(&npresent, &nup, &maxofallports);

	/*
	 * This code is present to allow a knowledgeable person to
	 * specify the layout of processes to processors before opening
	 * this driver, and then we'll assign the process to the "closest"
	 * InfiniPath chip to that processor (we assume reasonable connectivity,
	 * for now).  This code assumes that if affinity has been set
	 * before this point, that at most one cpu is set; for now this
	 * is reasonable.  I check for both cpumask_empty() and cpumask_full(),
	 * in case some kernel variant sets none of the bits when no
	 * affinity is set.  2.6.11 and 12 kernels have all present
	 * cpus set.  Some day we'll have to fix it up further to handle
	 * a cpu subset.  This algorithm fails for two HT chips connected
	 * in tunnel fashion.  Eventually this needs real topology
	 * information.  There may be some issues with dual core numbering
	 * as well.  This needs more work prior to release.
	 */
	if (!cpumask_empty(&current->cpus_allowed) &&
	    !cpumask_full(&current->cpus_allowed)) {
		int ncpus = num_online_cpus(), curcpu = -1, nset = 0;
		for (i = 0; i < ncpus; i++)
			if (cpumask_test_cpu(i, &current->cpus_allowed)) {
				ipath_cdbg(PROC, "%s[%u] affinity set for "
					   "cpu %d/%d\n", current->comm,
					   current->pid, i, ncpus);
				curcpu = i;
				nset++;
			}
		if (curcpu != -1 && nset != ncpus) {
			if (npresent) {
				prefunit = curcpu / (ncpus / npresent);
				ipath_cdbg(PROC,"%s[%u] %d chips, %d cpus, "
					  "%d cpus/chip, select unit %d\n",
					  current->comm, current->pid,
					  npresent, ncpus, ncpus / npresent,
					  prefunit);
			}
		}
	}

	/*
	 * user ports start at 1, kernel port is 0
	 * For now, we do round-robin access across all chips
	 */

	if (prefunit != -1)
		devmax = prefunit + 1;
recheck:
	for (i = 1; i < maxofallports; i++) {
		for (ndev = prefunit != -1 ? prefunit : 0; ndev < devmax;
		     ndev++) {
			struct ipath_devdata *dd = ipath_lookup(ndev);

			if (!usable(dd))
				continue; /* can't use this unit */
			if (i >= dd->ipath_cfgports)
				/*
				 * Maxed out on users of this unit. Try
				 * next.
				 */
				continue;
			ret = try_alloc_port(dd, i, fp, uinfo);
			if (!ret)
				goto done;
		}
	}

	if (npresent) {
		if (nup == 0) {
			ret = -ENETDOWN;
			ipath_dbg("No ports available (none initialized "
				  "and ready)\n");
		} else {
			if (prefunit > 0) {
				/* if started above 0, retry from 0 */
				ipath_cdbg(PROC,
					   "%s[%u] no ports on prefunit "
					   "%d, clear and re-check\n",
					   current->comm, current->pid,
					   prefunit);
				devmax = ipath_count_units(NULL, NULL,
							   NULL);
				prefunit = -1;
				goto recheck;
			}
			ret = -EBUSY;
			ipath_dbg("No ports available\n");
		}
	} else {
		ret = -ENXIO;
		ipath_dbg("No boards found\n");
	}

done:
	return ret;
}

static int find_shared_port(struct file *fp,
			    const struct ipath_user_info *uinfo)
{
	int devmax, ndev, i;
	int ret = 0;

	devmax = ipath_count_units(NULL, NULL, NULL);

	for (ndev = 0; ndev < devmax; ndev++) {
		struct ipath_devdata *dd = ipath_lookup(ndev);

		if (!usable(dd))
			continue;
		for (i = 1; i < dd->ipath_cfgports; i++) {
			struct ipath_portdata *pd = dd->ipath_pd[i];

			/* Skip ports which are not yet open */
			if (!pd || !pd->port_cnt)
				continue;
			/* Skip port if it doesn't match the requested one */
			if (pd->port_subport_id != uinfo->spu_subport_id)
				continue;
			/* Verify the sharing process matches the master */
			if (pd->port_subport_cnt != uinfo->spu_subport_cnt ||
			    pd->userversion != uinfo->spu_userversion ||
			    pd->port_cnt >= pd->port_subport_cnt) {
				ret = -EINVAL;
				goto done;
			}
			port_fp(fp) = pd;
			subport_fp(fp) = pd->port_cnt++;
			pd->port_subpid[subport_fp(fp)] =
				get_pid(task_pid(current));
			tidcursor_fp(fp) = 0;
			pd->active_slaves |= 1 << subport_fp(fp);
			ipath_cdbg(PROC,
				   "%s[%u] %u sharing %s[%u] unit:port %u:%u\n",
				   current->comm, current->pid,
				   subport_fp(fp),
				   pd->port_comm, pid_nr(pd->port_pid),
				   dd->ipath_unit, pd->port_port);
			ret = 1;
			goto done;
		}
	}

done:
	return ret;
}

static int ipath_open(struct inode *in, struct file *fp)
{
	/* The real work is performed later in ipath_assign_port() */
	fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
	return fp->private_data ? 0 : -ENOMEM;
}

/* Get port early, so can set affinity prior to memory allocation */
static int ipath_assign_port(struct file *fp,
			      const struct ipath_user_info *uinfo)
{
	int ret;
	int i_minor;
	unsigned swmajor, swminor;

	/* Check to be sure we haven't already initialized this file */
	if (port_fp(fp)) {
		ret = -EINVAL;
		goto done;
	}

	/* for now, if major version is different, bail */
	swmajor = uinfo->spu_userversion >> 16;
	if (swmajor != IPATH_USER_SWMAJOR) {
		ipath_dbg("User major version %d not same as driver "
			  "major %d\n", uinfo->spu_userversion >> 16,
			  IPATH_USER_SWMAJOR);
		ret = -ENODEV;
		goto done;
	}

	swminor = uinfo->spu_userversion & 0xffff;
	if (swminor != IPATH_USER_SWMINOR)
		ipath_dbg("User minor version %d not same as driver "
			  "minor %d\n", swminor, IPATH_USER_SWMINOR);

	mutex_lock(&ipath_mutex);

	if (ipath_compatible_subports(swmajor, swminor) &&
	    uinfo->spu_subport_cnt &&
	    (ret = find_shared_port(fp, uinfo))) {
		if (ret > 0)
			ret = 0;
		goto done_chk_sdma;
	}

	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
	ipath_cdbg(VERBOSE, "open on dev %lx (minor %d)\n",
		   (long)fp->f_path.dentry->d_inode->i_rdev, i_minor);

	if (i_minor)
		ret = find_free_port(i_minor - 1, fp, uinfo);
	else
		ret = find_best_unit(fp, uinfo);

done_chk_sdma:
	if (!ret) {
		struct ipath_filedata *fd = fp->private_data;
		const struct ipath_portdata *pd = fd->pd;
		const struct ipath_devdata *dd = pd->port_dd;

		fd->pq = ipath_user_sdma_queue_create(&dd->pcidev->dev,
						      dd->ipath_unit,
						      pd->port_port,
						      fd->subport);

		if (!fd->pq)
			ret = -ENOMEM;
	}

	mutex_unlock(&ipath_mutex);

done:
	return ret;
}


static int ipath_do_user_init(struct file *fp,
			      const struct ipath_user_info *uinfo)
{
	int ret;
	struct ipath_portdata *pd = port_fp(fp);
	struct ipath_devdata *dd;
	u32 head32;

	/* Subports don't need to initialize anything since master did it. */
	if (subport_fp(fp)) {
		ret = wait_event_interruptible(pd->port_wait,
			!test_bit(IPATH_PORT_MASTER_UNINIT, &pd->port_flag));
		goto done;
	}

	dd = pd->port_dd;

	if (uinfo->spu_rcvhdrsize) {
		ret = ipath_setrcvhdrsize(dd, uinfo->spu_rcvhdrsize);
		if (ret)
			goto done;
	}

	/* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */

	/* some ports may get extra buffers, calculate that here */
	if (pd->port_port <= dd->ipath_ports_extrabuf)
		pd->port_piocnt = dd->ipath_pbufsport + 1;
	else
		pd->port_piocnt = dd->ipath_pbufsport;

	/* for right now, kernel piobufs are at end, so port 1 is at 0 */
	if (pd->port_port <= dd->ipath_ports_extrabuf)
		pd->port_pio_base = (dd->ipath_pbufsport + 1)
			* (pd->port_port - 1);
	else
		pd->port_pio_base = dd->ipath_ports_extrabuf +
			dd->ipath_pbufsport * (pd->port_port - 1);
	pd->port_piobufs = dd->ipath_piobufbase +
		pd->port_pio_base * dd->ipath_palign;
	ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u,"
		" first pio %u\n", pd->port_port, pd->port_piobufs,
		pd->port_piocnt, pd->port_pio_base);
	ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0);

	/*
	 * Now allocate the rcvhdr Q and eager TIDs; skip the TID
	 * array for time being.  If pd->port_port > chip-supported,
	 * we need to do extra stuff here to handle by handling overflow
	 * through port 0, someday
	 */
	ret = ipath_create_rcvhdrq(dd, pd);
	if (!ret)
		ret = ipath_create_user_egr(pd);
	if (ret)
		goto done;

	/*
	 * set the eager head register for this port to the current values
	 * of the tail pointers, since we don't know if they were
	 * updated on last use of the port.
	 */
	head32 = ipath_read_ureg32(dd, ur_rcvegrindextail, pd->port_port);
	ipath_write_ureg(dd, ur_rcvegrindexhead, head32, pd->port_port);
	pd->port_lastrcvhdrqtail = -1;
	ipath_cdbg(VERBOSE, "Wrote port%d egrhead %x from tail regs\n",
		pd->port_port, head32);
	pd->port_tidcursor = 0;	/* start at beginning after open */

	/* initialize poll variables... */
	pd->port_urgent = 0;
	pd->port_urgent_poll = 0;
	pd->port_hdrqfull_poll = pd->port_hdrqfull;

	/*
	 * Now enable the port for receive.
	 * For chips that are set to DMA the tail register to memory
	 * when they change (and when the update bit transitions from
	 * 0 to 1.  So for those chips, we turn it off and then back on.
	 * This will (very briefly) affect any other open ports, but the
	 * duration is very short, and therefore isn't an issue.  We
	 * explictly set the in-memory tail copy to 0 beforehand, so we
	 * don't have to wait to be sure the DMA update has happened
	 * (chip resets head/tail to 0 on transition to enable).
	 */
	set_bit(dd->ipath_r_portenable_shift + pd->port_port,
		&dd->ipath_rcvctrl);
	if (!(dd->ipath_flags & IPATH_NODMA_RTAIL)) {
		if (pd->port_rcvhdrtail_kvaddr)
			ipath_clear_rcvhdrtail(pd);
		ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
			dd->ipath_rcvctrl &
			~(1ULL << dd->ipath_r_tailupd_shift));
	}
	ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
			 dd->ipath_rcvctrl);
	/* Notify any waiting slaves */
	if (pd->port_subport_cnt) {
		clear_bit(IPATH_PORT_MASTER_UNINIT, &pd->port_flag);
		wake_up(&pd->port_wait);
	}
done:
	return ret;
}

/**
 * unlock_exptid - unlock any expected TID entries port still had in use
 * @pd: port
 *
 * We don't actually update the chip here, because we do a bulk update
 * below, using ipath_f_clear_tids.
 */
static void unlock_expected_tids(struct ipath_portdata *pd)
{
	struct ipath_devdata *dd = pd->port_dd;
	int port_tidbase = pd->port_port * dd->ipath_rcvtidcnt;
	int i, cnt = 0, maxtid = port_tidbase + dd->ipath_rcvtidcnt;

	ipath_cdbg(VERBOSE, "Port %u unlocking any locked expTID pages\n",
		   pd->port_port);
	for (i = port_tidbase; i < maxtid; i++) {
		struct page *ps = dd->ipath_pageshadow[i];

		if (!ps)
			continue;

		dd->ipath_pageshadow[i] = NULL;
		pci_unmap_page(dd->pcidev, dd->ipath_physshadow[i],
			PAGE_SIZE, PCI_DMA_FROMDEVICE);
		ipath_release_user_pages_on_close(&ps, 1);
		cnt++;
		ipath_stats.sps_pageunlocks++;
	}
	if (cnt)
		ipath_cdbg(VERBOSE, "Port %u locked %u expTID entries\n",
			   pd->port_port, cnt);

	if (ipath_stats.sps_pagelocks || ipath_stats.sps_pageunlocks)
		ipath_cdbg(VERBOSE, "%llu pages locked, %llu unlocked\n",
			   (unsigned long long) ipath_stats.sps_pagelocks,
			   (unsigned long long)
			   ipath_stats.sps_pageunlocks);
}

static int ipath_close(struct inode *in, struct file *fp)
{
	int ret = 0;
	struct ipath_filedata *fd;
	struct ipath_portdata *pd;
	struct ipath_devdata *dd;
	unsigned long flags;
	unsigned port;
	struct pid *pid;

	ipath_cdbg(VERBOSE, "close on dev %lx, private data %p\n",
		   (long)in->i_rdev, fp->private_data);

	mutex_lock(&ipath_mutex);

	fd = (struct ipath_filedata *) fp->private_data;
	fp->private_data = NULL;
	pd = fd->pd;
	if (!pd) {
		mutex_unlock(&ipath_mutex);
		goto bail;
	}

	dd = pd->port_dd;

	/* drain user sdma queue */
	ipath_user_sdma_queue_drain(dd, fd->pq);
	ipath_user_sdma_queue_destroy(fd->pq);

	if (--pd->port_cnt) {
		/*
		 * XXX If the master closes the port before the slave(s),
		 * revoke the mmap for the eager receive queue so
		 * the slave(s) don't wait for receive data forever.
		 */
		pd->active_slaves &= ~(1 << fd->subport);
		put_pid(pd->port_subpid[fd->subport]);
		pd->port_subpid[fd->subport] = NULL;
		mutex_unlock(&ipath_mutex);
		goto bail;
	}
	/* early; no interrupt users after this */
	spin_lock_irqsave(&dd->ipath_uctxt_lock, flags);
	port = pd->port_port;
	dd->ipath_pd[port] = NULL;
	pid = pd->port_pid;
	pd->port_pid = NULL;
	spin_unlock_irqrestore(&dd->ipath_uctxt_lock, flags);

	if (pd->port_rcvwait_to || pd->port_piowait_to
	    || pd->port_rcvnowait || pd->port_pionowait) {
		ipath_cdbg(VERBOSE, "port%u, %u rcv, %u pio wait timeo; "
			   "%u rcv %u, pio already\n",
			   pd->port_port, pd->port_rcvwait_to,
			   pd->port_piowait_to, pd->port_rcvnowait,
			   pd->port_pionowait);
		pd->port_rcvwait_to = pd->port_piowait_to =
			pd->port_rcvnowait = pd->port_pionowait = 0;
	}
	if (pd->port_flag) {
		ipath_cdbg(PROC, "port %u port_flag set: 0x%lx\n",
			  pd->port_port, pd->port_flag);
		pd->port_flag = 0;
	}

	if (dd->ipath_kregbase) {
		/* atomically clear receive enable port and intr avail. */
		clear_bit(dd->ipath_r_portenable_shift + port,
			  &dd->ipath_rcvctrl);
		clear_bit(pd->port_port + dd->ipath_r_intravail_shift,
			  &dd->ipath_rcvctrl);
		ipath_write_kreg( dd, dd->ipath_kregs->kr_rcvctrl,
			dd->ipath_rcvctrl);
		/* and read back from chip to be sure that nothing
		 * else is in flight when we do the rest */
		(void)ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);

		/* clean up the pkeys for this port user */
		ipath_clean_part_key(pd, dd);
		/*
		 * be paranoid, and never write 0's to these, just use an
		 * unused part of the port 0 tail page.  Of course,
		 * rcvhdraddr points to a large chunk of memory, so this
		 * could still trash things, but at least it won't trash
		 * page 0, and by disabling the port, it should stop "soon",
		 * even if a packet or two is in already in flight after we
		 * disabled the port.
		 */
		ipath_write_kreg_port(dd,
		        dd->ipath_kregs->kr_rcvhdrtailaddr, port,
			dd->ipath_dummy_hdrq_phys);
		ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr,
			pd->port_port, dd->ipath_dummy_hdrq_phys);

		ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt);
		ipath_chg_pioavailkernel(dd, pd->port_pio_base,
			pd->port_piocnt, 1);

		dd->ipath_f_clear_tids(dd, pd->port_port);

		if (dd->ipath_pageshadow)
			unlock_expected_tids(pd);
		ipath_stats.sps_ports--;
		ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n",
			   pd->port_comm, pid_nr(pid),
			   dd->ipath_unit, port);
	}

	put_pid(pid);
	mutex_unlock(&ipath_mutex);
	ipath_free_pddata(dd, pd); /* after releasing the mutex */

bail:
	kfree(fd);
	return ret;
}

static int ipath_port_info(struct ipath_portdata *pd, u16 subport,
			   struct ipath_port_info __user *uinfo)
{
	struct ipath_port_info info;
	int nup;
	int ret;
	size_t sz;

	(void) ipath_count_units(NULL, &nup, NULL);
	info.num_active = nup;
	info.unit = pd->port_dd->ipath_unit;
	info.port = pd->port_port;
	info.subport = subport;
	/* Don't return new fields if old library opened the port. */
	if (ipath_supports_subports(pd->userversion >> 16,
				    pd->userversion & 0xffff)) {
		/* Number of user ports available for this device. */
		info.num_ports = pd->port_dd->ipath_cfgports - 1;
		info.num_subports = pd->port_subport_cnt;
		sz = sizeof(info);
	} else
		sz = sizeof(info) - 2 * sizeof(u16);

	if (copy_to_user(uinfo, &info, sz)) {
		ret = -EFAULT;
		goto bail;
	}
	ret = 0;

bail:
	return ret;
}

static int ipath_get_slave_info(struct ipath_portdata *pd,
				void __user *slave_mask_addr)
{
	int ret = 0;

	if (copy_to_user(slave_mask_addr, &pd->active_slaves, sizeof(u32)))
		ret = -EFAULT;
	return ret;
}

static int ipath_sdma_get_inflight(struct ipath_user_sdma_queue *pq,
				   u32 __user *inflightp)
{
	const u32 val = ipath_user_sdma_inflight_counter(pq);

	if (put_user(val, inflightp))
		return -EFAULT;

	return 0;
}

static int ipath_sdma_get_complete(struct ipath_devdata *dd,
				   struct ipath_user_sdma_queue *pq,
				   u32 __user *completep)
{
	u32 val;
	int err;

	err = ipath_user_sdma_make_progress(dd, pq);
	if (err < 0)
		return err;

	val = ipath_user_sdma_complete_counter(pq);
	if (put_user(val, completep))
		return -EFAULT;

	return 0;
}

static ssize_t ipath_write(struct file *fp, const char __user *data,
			   size_t count, loff_t *off)
{
	const struct ipath_cmd __user *ucmd;
	struct ipath_portdata *pd;
	const void __user *src;
	size_t consumed, copy;
	struct ipath_cmd cmd;
	ssize_t ret = 0;
	void *dest;

	if (count < sizeof(cmd.type)) {
		ret = -EINVAL;
		goto bail;
	}

	ucmd = (const struct ipath_cmd __user *) data;

	if (copy_from_user(&cmd.type, &ucmd->type, sizeof(cmd.type))) {
		ret = -EFAULT;
		goto bail;
	}

	consumed = sizeof(cmd.type);

	switch (cmd.type) {
	case IPATH_CMD_ASSIGN_PORT:
	case __IPATH_CMD_USER_INIT:
	case IPATH_CMD_USER_INIT:
		copy = sizeof(cmd.cmd.user_info);
		dest = &cmd.cmd.user_info;
		src = &ucmd->cmd.user_info;
		break;
	case IPATH_CMD_RECV_CTRL:
		copy = sizeof(cmd.cmd.recv_ctrl);
		dest = &cmd.cmd.recv_ctrl;
		src = &ucmd->cmd.recv_ctrl;
		break;
	case IPATH_CMD_PORT_INFO:
		copy = sizeof(cmd.cmd.port_info);
		dest = &cmd.cmd.port_info;
		src = &ucmd->cmd.port_info;
		break;
	case IPATH_CMD_TID_UPDATE:
	case IPATH_CMD_TID_FREE:
		copy = sizeof(cmd.cmd.tid_info);
		dest = &cmd.cmd.tid_info;
		src = &ucmd->cmd.tid_info;
		break;
	case IPATH_CMD_SET_PART_KEY:
		copy = sizeof(cmd.cmd.part_key);
		dest = &cmd.cmd.part_key;
		src = &ucmd->cmd.part_key;
		break;
	case __IPATH_CMD_SLAVE_INFO:
		copy = sizeof(cmd.cmd.slave_mask_addr);
		dest = &cmd.cmd.slave_mask_addr;
		src = &ucmd->cmd.slave_mask_addr;
		break;
	case IPATH_CMD_PIOAVAILUPD:	// force an update of PIOAvail reg
		copy = 0;
		src = NULL;
		dest = NULL;
		break;
	case IPATH_CMD_POLL_TYPE:
		copy = sizeof(cmd.cmd.poll_type);
		dest = &cmd.cmd.poll_type;
		src = &ucmd->cmd.poll_type;
		break;
	case IPATH_CMD_ARMLAUNCH_CTRL:
		copy = sizeof(cmd.cmd.armlaunch_ctrl);
		dest = &cmd.cmd.armlaunch_ctrl;
		src = &ucmd->cmd.armlaunch_ctrl;
		break;
	case IPATH_CMD_SDMA_INFLIGHT:
		copy = sizeof(cmd.cmd.sdma_inflight);
		dest = &cmd.cmd.sdma_inflight;
		src = &ucmd->cmd.sdma_inflight;
		break;
	case IPATH_CMD_SDMA_COMPLETE:
		copy = sizeof(cmd.cmd.sdma_complete);
		dest = &cmd.cmd.sdma_complete;
		src = &ucmd->cmd.sdma_complete;
		break;
	default:
		ret = -EINVAL;
		goto bail;
	}

	if (copy) {
		if ((count - consumed) < copy) {
			ret = -EINVAL;
			goto bail;
		}

		if (copy_from_user(dest, src, copy)) {
			ret = -EFAULT;
			goto bail;
		}

		consumed += copy;
	}

	pd = port_fp(fp);
	if (!pd && cmd.type != __IPATH_CMD_USER_INIT &&
		cmd.type != IPATH_CMD_ASSIGN_PORT) {
		ret = -EINVAL;
		goto bail;
	}

	switch (cmd.type) {
	case IPATH_CMD_ASSIGN_PORT:
		ret = ipath_assign_port(fp, &cmd.cmd.user_info);
		if (ret)
			goto bail;
		break;
	case __IPATH_CMD_USER_INIT:
		/* backwards compatibility, get port first */
		ret = ipath_assign_port(fp, &cmd.cmd.user_info);
		if (ret)
			goto bail;
		/* and fall through to current version. */
	case IPATH_CMD_USER_INIT:
		ret = ipath_do_user_init(fp, &cmd.cmd.user_info);
		if (ret)
			goto bail;
		ret = ipath_get_base_info(
			fp, (void __user *) (unsigned long)
			cmd.cmd.user_info.spu_base_info,
			cmd.cmd.user_info.spu_base_info_size);
		break;
	case IPATH_CMD_RECV_CTRL:
		ret = ipath_manage_rcvq(pd, subport_fp(fp), cmd.cmd.recv_ctrl);
		break;
	case IPATH_CMD_PORT_INFO:
		ret = ipath_port_info(pd, subport_fp(fp),
				      (struct ipath_port_info __user *)
				      (unsigned long) cmd.cmd.port_info);
		break;
	case IPATH_CMD_TID_UPDATE:
		ret = ipath_tid_update(pd, fp, &cmd.cmd.tid_info);
		break;
	case IPATH_CMD_TID_FREE:
		ret = ipath_tid_free(pd, subport_fp(fp), &cmd.cmd.tid_info);
		break;
	case IPATH_CMD_SET_PART_KEY:
		ret = ipath_set_part_key(pd, cmd.cmd.part_key);
		break;
	case __IPATH_CMD_SLAVE_INFO:
		ret = ipath_get_slave_info(pd,
					   (void __user *) (unsigned long)
					   cmd.cmd.slave_mask_addr);
		break;
	case IPATH_CMD_PIOAVAILUPD:
		ipath_force_pio_avail_update(pd->port_dd);
		break;
	case IPATH_CMD_POLL_TYPE:
		pd->poll_type = cmd.cmd.poll_type;
		break;
	case IPATH_CMD_ARMLAUNCH_CTRL:
		if (cmd.cmd.armlaunch_ctrl)
			ipath_enable_armlaunch(pd->port_dd);
		else
			ipath_disable_armlaunch(pd->port_dd);
		break;
	case IPATH_CMD_SDMA_INFLIGHT:
		ret = ipath_sdma_get_inflight(user_sdma_queue_fp(fp),
					      (u32 __user *) (unsigned long)
					      cmd.cmd.sdma_inflight);
		break;
	case IPATH_CMD_SDMA_COMPLETE:
		ret = ipath_sdma_get_complete(pd->port_dd,
					      user_sdma_queue_fp(fp),
					      (u32 __user *) (unsigned long)
					      cmd.cmd.sdma_complete);
		break;
	}

	if (ret >= 0)
		ret = consumed;

bail:
	return ret;
}

static ssize_t ipath_writev(struct kiocb *iocb, const struct iovec *iov,
			    unsigned long dim, loff_t off)
{
	struct file *filp = iocb->ki_filp;
	struct ipath_filedata *fp = filp->private_data;
	struct ipath_portdata *pd = port_fp(filp);
	struct ipath_user_sdma_queue *pq = fp->pq;

	if (!dim)
		return -EINVAL;

	return ipath_user_sdma_writev(pd->port_dd, pq, iov, dim);
}

static struct class *ipath_class;

static int init_cdev(int minor, char *name, const struct file_operations *fops,
		     struct cdev **cdevp, struct device **devp)
{
	const dev_t dev = MKDEV(IPATH_MAJOR, minor);
	struct cdev *cdev = NULL;
	struct device *device = NULL;
	int ret;

	cdev = cdev_alloc();
	if (!cdev) {
		printk(KERN_ERR IPATH_DRV_NAME
		       ": Could not allocate cdev for minor %d, %s\n",
		       minor, name);
		ret = -ENOMEM;
		goto done;
	}

	cdev->owner = THIS_MODULE;
	cdev->ops = fops;
	kobject_set_name(&cdev->kobj, name);

	ret = cdev_add(cdev, dev, 1);
	if (ret < 0) {
		printk(KERN_ERR IPATH_DRV_NAME
		       ": Could not add cdev for minor %d, %s (err %d)\n",
		       minor, name, -ret);
		goto err_cdev;
	}

	device = device_create(ipath_class, NULL, dev, NULL, name);

	if (IS_ERR(device)) {
		ret = PTR_ERR(device);
		printk(KERN_ERR IPATH_DRV_NAME ": Could not create "
		       "device for minor %d, %s (err %d)\n",
		       minor, name, -ret);
		goto err_cdev;
	}

	goto done;

err_cdev:
	cdev_del(cdev);
	cdev = NULL;

done:
	if (ret >= 0) {
		*cdevp = cdev;
		*devp = device;
	} else {
		*cdevp = NULL;
		*devp = NULL;
	}

	return ret;
}

int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
		    struct cdev **cdevp, struct device **devp)
{
	return init_cdev(minor, name, fops, cdevp, devp);
}

static void cleanup_cdev(struct cdev **cdevp,
			 struct device **devp)
{
	struct device *dev = *devp;

	if (dev) {
		device_unregister(dev);
		*devp = NULL;
	}

	if (*cdevp) {
		cdev_del(*cdevp);
		*cdevp = NULL;
	}
}

void ipath_cdev_cleanup(struct cdev **cdevp,
			struct device **devp)
{
	cleanup_cdev(cdevp, devp);
}

static struct cdev *wildcard_cdev;
static struct device *wildcard_dev;

static const dev_t dev = MKDEV(IPATH_MAJOR, 0);

static int user_init(void)
{
	int ret;

	ret = register_chrdev_region(dev, IPATH_NMINORS, IPATH_DRV_NAME);
	if (ret < 0) {
		printk(KERN_ERR IPATH_DRV_NAME ": Could not register "
		       "chrdev region (err %d)\n", -ret);
		goto done;
	}

	ipath_class = class_create(THIS_MODULE, IPATH_DRV_NAME);

	if (IS_ERR(ipath_class)) {
		ret = PTR_ERR(ipath_class);
		printk(KERN_ERR IPATH_DRV_NAME ": Could not create "
		       "device class (err %d)\n", -ret);
		goto bail;
	}

	goto done;
bail:
	unregister_chrdev_region(dev, IPATH_NMINORS);
done:
	return ret;
}

static void user_cleanup(void)
{
	if (ipath_class) {
		class_destroy(ipath_class);
		ipath_class = NULL;
	}

	unregister_chrdev_region(dev, IPATH_NMINORS);
}

static atomic_t user_count = ATOMIC_INIT(0);
static atomic_t user_setup = ATOMIC_INIT(0);

int ipath_user_add(struct ipath_devdata *dd)
{
	char name[10];
	int ret;

	if (atomic_inc_return(&user_count) == 1) {
		ret = user_init();
		if (ret < 0) {
			ipath_dev_err(dd, "Unable to set up user support: "
				      "error %d\n", -ret);
			goto bail;
		}
		ret = init_cdev(0, "ipath", &ipath_file_ops, &wildcard_cdev,
				&wildcard_dev);
		if (ret < 0) {
			ipath_dev_err(dd, "Could not create wildcard "
				      "minor: error %d\n", -ret);
			goto bail_user;
		}

		atomic_set(&user_setup, 1);
	}

	snprintf(name, sizeof(name), "ipath%d", dd->ipath_unit);

	ret = init_cdev(dd->ipath_unit + 1, name, &ipath_file_ops,
			&dd->user_cdev, &dd->user_dev);
	if (ret < 0)
		ipath_dev_err(dd, "Could not create user minor %d, %s\n",
			      dd->ipath_unit + 1, name);

	goto bail;

bail_user:
	user_cleanup();
bail:
	return ret;
}

void ipath_user_remove(struct ipath_devdata *dd)
{
	cleanup_cdev(&dd->user_cdev, &dd->user_dev);

	if (atomic_dec_return(&user_count) == 0) {
		if (atomic_read(&user_setup) == 0)
			goto bail;

		cleanup_cdev(&wildcard_cdev, &wildcard_dev);
		user_cleanup();

		atomic_set(&user_setup, 0);
	}
bail:
	return;
}
