Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 124b4dcb authored by Dave Olson's avatar Dave Olson Committed by Roland Dreier
Browse files

IB/ipath: add calls to new 7220 code and enable in build



This patch adds the initialization calls into the new 7220 HCA files,
changes the Makefile to compile and link the new files, and code to
handle send DMA.

Signed-off-by: default avatarDave Olson <dave.olson@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent bb917144
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -20,17 +20,20 @@ ib_ipath-y := \
	ipath_qp.o \
	ipath_qp.o \
	ipath_rc.o \
	ipath_rc.o \
	ipath_ruc.o \
	ipath_ruc.o \
	ipath_sdma.o \
	ipath_srq.o \
	ipath_srq.o \
	ipath_stats.o \
	ipath_stats.o \
	ipath_sysfs.o \
	ipath_sysfs.o \
	ipath_uc.o \
	ipath_uc.o \
	ipath_ud.o \
	ipath_ud.o \
	ipath_user_pages.o \
	ipath_user_pages.o \
	ipath_user_sdma.o \
	ipath_verbs_mcast.o \
	ipath_verbs_mcast.o \
	ipath_verbs.o
	ipath_verbs.o


ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o
ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o
ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba7220.o ipath_sd7220.o ipath_sd7220_img.o


ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o
ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o
+14 −2
Original line number Original line Diff line number Diff line
@@ -447,8 +447,9 @@ struct ipath_user_info {
#define IPATH_CMD_PIOAVAILUPD	27	/* force an update of PIOAvail reg */
#define IPATH_CMD_PIOAVAILUPD	27	/* force an update of PIOAvail reg */
#define IPATH_CMD_POLL_TYPE	28	/* set the kind of polling we want */
#define IPATH_CMD_POLL_TYPE	28	/* set the kind of polling we want */
#define IPATH_CMD_ARMLAUNCH_CTRL	29 /* armlaunch detection control */
#define IPATH_CMD_ARMLAUNCH_CTRL	29 /* armlaunch detection control */

/* 30 is unused */
#define IPATH_CMD_MAX		29
#define IPATH_CMD_SDMA_INFLIGHT 31	/* sdma inflight counter request */
#define IPATH_CMD_SDMA_COMPLETE 32	/* sdma completion counter request */


/*
/*
 * Poll types
 * Poll types
@@ -486,6 +487,17 @@ struct ipath_cmd {
	union {
	union {
		struct ipath_tid_info tid_info;
		struct ipath_tid_info tid_info;
		struct ipath_user_info user_info;
		struct ipath_user_info user_info;

		/*
		 * address in userspace where we should put the sdma
		 * inflight counter
		 */
		__u64 sdma_inflight;
		/*
		 * address in userspace where we should put the sdma
		 * completion counter
		 */
		__u64 sdma_complete;
		/* address in userspace of struct ipath_port_info to
		/* address in userspace of struct ipath_port_info to
		   write result to */
		   write result to */
		__u64 port_info;
		__u64 port_info;
+132 −18
Original line number Original line Diff line number Diff line
@@ -129,8 +129,10 @@ static int __devinit ipath_init_one(struct pci_dev *,


/* Only needed for registration, nothing else needs this info */
/* Only needed for registration, nothing else needs this info */
#define PCI_VENDOR_ID_PATHSCALE 0x1fc1
#define PCI_VENDOR_ID_PATHSCALE 0x1fc1
#define PCI_VENDOR_ID_QLOGIC 0x1077
#define PCI_DEVICE_ID_INFINIPATH_HT 0xd
#define PCI_DEVICE_ID_INFINIPATH_HT 0xd
#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10
#define PCI_DEVICE_ID_INFINIPATH_7220 0x7220


/* Number of seconds before our card status check...  */
/* Number of seconds before our card status check...  */
#define STATUS_TIMEOUT 60
#define STATUS_TIMEOUT 60
@@ -138,6 +140,7 @@ static int __devinit ipath_init_one(struct pci_dev *,
static const struct pci_device_id ipath_pci_tbl[] = {
static const struct pci_device_id ipath_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
	{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) },
	{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
	{ PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) },
	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_INFINIPATH_7220) },
	{ 0, }
	{ 0, }
};
};


@@ -532,6 +535,13 @@ static int __devinit ipath_init_one(struct pci_dev *pdev,
			      "CONFIG_PCI_MSI is not enabled\n", ent->device);
			      "CONFIG_PCI_MSI is not enabled\n", ent->device);
		return -ENODEV;
		return -ENODEV;
#endif
#endif
	case PCI_DEVICE_ID_INFINIPATH_7220:
#ifndef CONFIG_PCI_MSI
		ipath_dbg("CONFIG_PCI_MSI is not enabled, "
			  "using IntX for unit %u\n", dd->ipath_unit);
#endif
		ipath_init_iba7220_funcs(dd);
		break;
	default:
	default:
		ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, "
		ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, "
			      "failing\n", ent->device);
			      "failing\n", ent->device);
@@ -887,13 +897,47 @@ int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs)
	return (dd->ipath_flags & state) ? 0 : -ETIMEDOUT;
	return (dd->ipath_flags & state) ? 0 : -ETIMEDOUT;
}
}


static void decode_sdma_errs(struct ipath_devdata *dd, ipath_err_t err,
	char *buf, size_t blen)
{
	static const struct {
		ipath_err_t err;
		const char *msg;
	} errs[] = {
		{ INFINIPATH_E_SDMAGENMISMATCH, "SDmaGenMismatch" },
		{ INFINIPATH_E_SDMAOUTOFBOUND, "SDmaOutOfBound" },
		{ INFINIPATH_E_SDMATAILOUTOFBOUND, "SDmaTailOutOfBound" },
		{ INFINIPATH_E_SDMABASE, "SDmaBase" },
		{ INFINIPATH_E_SDMA1STDESC, "SDma1stDesc" },
		{ INFINIPATH_E_SDMARPYTAG, "SDmaRpyTag" },
		{ INFINIPATH_E_SDMADWEN, "SDmaDwEn" },
		{ INFINIPATH_E_SDMAMISSINGDW, "SDmaMissingDw" },
		{ INFINIPATH_E_SDMAUNEXPDATA, "SDmaUnexpData" },
		{ INFINIPATH_E_SDMADESCADDRMISALIGN, "SDmaDescAddrMisalign" },
		{ INFINIPATH_E_SENDBUFMISUSE, "SendBufMisuse" },
		{ INFINIPATH_E_SDMADISABLED, "SDmaDisabled" },
	};
	int i;
	int expected;
	size_t bidx = 0;

	for (i = 0; i < ARRAY_SIZE(errs); i++) {
		expected = (errs[i].err != INFINIPATH_E_SDMADISABLED) ? 0 :
			test_bit(IPATH_SDMA_ABORTING, &dd->ipath_sdma_status);
		if ((err & errs[i].err) && !expected)
			bidx += snprintf(buf + bidx, blen - bidx,
					 "%s ", errs[i].msg);
	}
}

/*
/*
 * Decode the error status into strings, deciding whether to always
 * Decode the error status into strings, deciding whether to always
 * print * it or not depending on "normal packet errors" vs everything
 * print * it or not depending on "normal packet errors" vs everything
 * else.   Return 1 if "real" errors, otherwise 0 if only packet
 * else.   Return 1 if "real" errors, otherwise 0 if only packet
 * errors, so caller can decide what to print with the string.
 * errors, so caller can decide what to print with the string.
 */
 */
int ipath_decode_err(char *buf, size_t blen, ipath_err_t err)
int ipath_decode_err(struct ipath_devdata *dd, char *buf, size_t blen,
	ipath_err_t err)
{
{
	int iserr = 1;
	int iserr = 1;
	*buf = '\0';
	*buf = '\0';
@@ -975,6 +1019,8 @@ int ipath_decode_err(char *buf, size_t blen, ipath_err_t err)
		strlcat(buf, "hardware ", blen);
		strlcat(buf, "hardware ", blen);
	if (err & INFINIPATH_E_RESET)
	if (err & INFINIPATH_E_RESET)
		strlcat(buf, "reset ", blen);
		strlcat(buf, "reset ", blen);
	if (err & INFINIPATH_E_SDMAERRS)
		decode_sdma_errs(dd, err, buf, blen);
	if (err & INFINIPATH_E_INVALIDEEPCMD)
	if (err & INFINIPATH_E_INVALIDEEPCMD)
		strlcat(buf, "invalideepromcmd ", blen);
		strlcat(buf, "invalideepromcmd ", blen);
done:
done:
@@ -1730,30 +1776,80 @@ int ipath_create_rcvhdrq(struct ipath_devdata *dd,
 */
 */
void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
{
{
	unsigned long flags;

	if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) {
	if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) {
		ipath_cdbg(VERBOSE, "Ignore while in autonegotiation\n");
		ipath_cdbg(VERBOSE, "Ignore while in autonegotiation\n");
		goto bail;
		goto bail;
	}
	}
	/*
	 * If we have SDMA, and it's not disabled, we have to kick off the
	 * abort state machine, provided we aren't already aborting.
	 * If we are in the process of aborting SDMA (!DISABLED, but ABORTING),
	 * we skip the rest of this routine. It is already "in progress"
	 */
	if (dd->ipath_flags & IPATH_HAS_SEND_DMA) {
		int skip_cancel;
		u64 *statp = &dd->ipath_sdma_status;

		spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
		skip_cancel =
			!test_bit(IPATH_SDMA_DISABLED, statp) &&
			test_and_set_bit(IPATH_SDMA_ABORTING, statp);
		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
		if (skip_cancel)
			goto bail;
	}

	ipath_dbg("Cancelling all in-progress send buffers\n");
	ipath_dbg("Cancelling all in-progress send buffers\n");


	/* skip armlaunch errs for a while */
	/* skip armlaunch errs for a while */
	dd->ipath_lastcancel = jiffies + HZ / 2;
	dd->ipath_lastcancel = jiffies + HZ / 2;


	/*
	/*
	 * the abort bit is auto-clearing.  We read scratch to be sure
	 * The abort bit is auto-clearing.  We also don't want pioavail
	 * that cancels and the abort have taken effect in the chip.
	 * update happening during this, and we don't want any other
	 * sends going out, so turn those off for the duration.  We read
	 * the scratch register to be sure that cancels and the abort
	 * have taken effect in the chip.  Otherwise two parts are same
	 * as ipath_force_pio_avail_update()
	 */
	 */
	spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
	dd->ipath_sendctrl &= ~(INFINIPATH_S_PIOBUFAVAILUPD
		| INFINIPATH_S_PIOENABLE);
	ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
	ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
		INFINIPATH_S_ABORT);
		dd->ipath_sendctrl | INFINIPATH_S_ABORT);
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
	ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
	spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);

	/* disarm all send buffers */
	ipath_disarm_piobufs(dd, 0,
	ipath_disarm_piobufs(dd, 0,
		(unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k));
		dd->ipath_piobcnt2k + dd->ipath_piobcnt4k);
	if (restore_sendctrl) /* else done by caller later */

	if (restore_sendctrl) {
		/* else done by caller later if needed */
		spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags);
		dd->ipath_sendctrl |= INFINIPATH_S_PIOBUFAVAILUPD |
			INFINIPATH_S_PIOENABLE;
		ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
		ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
			dd->ipath_sendctrl);
			dd->ipath_sendctrl);

		/* and again, be sure all have hit the chip */
		/* and again, be sure all have hit the chip */
		ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
		ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch);
		spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags);
	}

	if ((dd->ipath_flags & IPATH_HAS_SEND_DMA) &&
	    !test_bit(IPATH_SDMA_DISABLED, &dd->ipath_sdma_status) &&
	    test_bit(IPATH_SDMA_RUNNING, &dd->ipath_sdma_status)) {
		spin_lock_irqsave(&dd->ipath_sdma_lock, flags);
		/* only wait so long for intr */
		dd->ipath_sdma_abort_intr_timeout = jiffies + HZ;
		dd->ipath_sdma_reset_wait = 200;
		__set_bit(IPATH_SDMA_DISARMED, &dd->ipath_sdma_status);
		if (!test_bit(IPATH_SDMA_SHUTDOWN, &dd->ipath_sdma_status))
			tasklet_hi_schedule(&dd->ipath_sdma_abort_task);
		spin_unlock_irqrestore(&dd->ipath_sdma_lock, flags);
	}
bail:;
bail:;
}
}


@@ -1952,7 +2048,7 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
 * sanity checking on this, and we don't deal with what happens to
 * sanity checking on this, and we don't deal with what happens to
 * programs that are already running when the size changes.
 * programs that are already running when the size changes.
 * NOTE: changing the MTU will usually cause the IBC to go back to
 * NOTE: changing the MTU will usually cause the IBC to go back to
 * link initialize (IPATH_IBSTATE_INIT) state...
 * link INIT state...
 */
 */
int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
int ipath_set_mtu(struct ipath_devdata *dd, u16 arg)
{
{
@@ -2092,9 +2188,8 @@ static void ipath_run_led_override(unsigned long opaque)
	 * but leave that to per-chip functions.
	 * but leave that to per-chip functions.
	 */
	 */
	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus);
	val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus);
	ltstate = (val >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) &
	ltstate = ipath_ib_linktrstate(dd, val);
		  dd->ibcs_lts_mask;
	lstate = ipath_ib_linkstate(dd, val);
	lstate = (val >> dd->ibcs_ls_shift) & INFINIPATH_IBCS_LINKSTATE_MASK;


	dd->ipath_f_setextled(dd, lstate, ltstate);
	dd->ipath_f_setextled(dd, lstate, ltstate);
	mod_timer(&dd->ipath_led_override_timer, jiffies + timeoff);
	mod_timer(&dd->ipath_led_override_timer, jiffies + timeoff);
@@ -2170,6 +2265,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
	ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
	ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl,
			 dd->ipath_rcvctrl);
			 dd->ipath_rcvctrl);


	if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
		teardown_sdma(dd);

	/*
	/*
	 * gracefully stop all sends allowing any in progress to trickle out
	 * gracefully stop all sends allowing any in progress to trickle out
	 * first.
	 * first.
@@ -2187,9 +2285,16 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
	 */
	 */
	udelay(5);
	udelay(5);


	dd->ipath_f_setextled(dd, 0, 0); /* make sure LEDs are off */

	ipath_set_ib_lstate(dd, 0, INFINIPATH_IBCC_LINKINITCMD_DISABLE);
	ipath_set_ib_lstate(dd, 0, INFINIPATH_IBCC_LINKINITCMD_DISABLE);
	ipath_cancel_sends(dd, 0);
	ipath_cancel_sends(dd, 0);


	/*
	 * we are shutting down, so tell components that care.  We don't do
	 * this on just a link state change, much like ethernet, a cable
	 * unplug, etc. doesn't change driver state
	 */
	signal_ib_event(dd, IB_EVENT_PORT_ERR);
	signal_ib_event(dd, IB_EVENT_PORT_ERR);


	/* disable IBC */
	/* disable IBC */
@@ -2214,6 +2319,10 @@ void ipath_shutdown_device(struct ipath_devdata *dd)
		del_timer_sync(&dd->ipath_intrchk_timer);
		del_timer_sync(&dd->ipath_intrchk_timer);
		dd->ipath_intrchk_timer.data = 0;
		dd->ipath_intrchk_timer.data = 0;
	}
	}
	if (atomic_read(&dd->ipath_led_override_timer_active)) {
		del_timer_sync(&dd->ipath_led_override_timer);
		atomic_set(&dd->ipath_led_override_timer_active, 0);
	}


	/*
	/*
	 * clear all interrupts and errors, so that the next time the driver
	 * clear all interrupts and errors, so that the next time the driver
@@ -2408,13 +2517,18 @@ int ipath_reset_device(int unit)
			}
			}
		}
		}


	if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
		teardown_sdma(dd);

	dd->ipath_flags &= ~IPATH_INITTED;
	dd->ipath_flags &= ~IPATH_INITTED;
	ipath_write_kreg(dd, dd->ipath_kregs->kr_intmask, 0ULL);
	ret = dd->ipath_f_reset(dd);
	ret = dd->ipath_f_reset(dd);
	if (ret != 1)
	if (ret == 1) {
		ipath_dbg("reset was not successful\n");
		ipath_dbg("Reinitializing unit %u after reset attempt\n",
	ipath_dbg("Trying to reinitialize unit %u after reset attempt\n",
			  unit);
			  unit);
		ret = ipath_init_chip(dd, 1);
		ret = ipath_init_chip(dd, 1);
	} else
		ret = -EAGAIN;
	if (ret)
	if (ret)
		ipath_dev_err(dd, "Reinitialize unit %u after "
		ipath_dev_err(dd, "Reinitialize unit %u after "
			      "reset failed with %d\n", unit, ret);
			      "reset failed with %d\n", unit, ret);
+94 −3
Original line number Original line Diff line number Diff line
@@ -36,21 +36,28 @@
#include <linux/cdev.h>
#include <linux/cdev.h>
#include <linux/swap.h>
#include <linux/swap.h>
#include <linux/vmalloc.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>


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


static int ipath_open(struct inode *, struct file *);
static int ipath_open(struct inode *, struct file *);
static int ipath_close(struct inode *, struct file *);
static int ipath_close(struct inode *, struct file *);
static ssize_t ipath_write(struct file *, const char __user *, size_t,
static ssize_t ipath_write(struct file *, const char __user *, size_t,
			   loff_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 unsigned int ipath_poll(struct file *, struct poll_table_struct *);
static int ipath_mmap(struct file *, struct vm_area_struct *);
static int ipath_mmap(struct file *, struct vm_area_struct *);


static const struct file_operations ipath_file_ops = {
static const struct file_operations ipath_file_ops = {
	.owner = THIS_MODULE,
	.owner = THIS_MODULE,
	.write = ipath_write,
	.write = ipath_write,
	.aio_write = ipath_writev,
	.open = ipath_open,
	.open = ipath_open,
	.release = ipath_close,
	.release = ipath_close,
	.poll = ipath_poll,
	.poll = ipath_poll,
@@ -1870,10 +1877,9 @@ static int ipath_assign_port(struct file *fp,
	if (ipath_compatible_subports(swmajor, swminor) &&
	if (ipath_compatible_subports(swmajor, swminor) &&
	    uinfo->spu_subport_cnt &&
	    uinfo->spu_subport_cnt &&
	    (ret = find_shared_port(fp, uinfo))) {
	    (ret = find_shared_port(fp, uinfo))) {
		mutex_unlock(&ipath_mutex);
		if (ret > 0)
		if (ret > 0)
			ret = 0;
			ret = 0;
		goto done;
		goto done_chk_sdma;
	}
	}


	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
	i_minor = iminor(fp->f_path.dentry->d_inode) - IPATH_USER_MINOR_BASE;
@@ -1885,6 +1891,21 @@ static int ipath_assign_port(struct file *fp,
	else
	else
		ret = find_best_unit(fp, uinfo);
		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);
	mutex_unlock(&ipath_mutex);


done:
done:
@@ -2042,6 +2063,13 @@ static int ipath_close(struct inode *in, struct file *fp)
		mutex_unlock(&ipath_mutex);
		mutex_unlock(&ipath_mutex);
		goto bail;
		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) {
	if (--pd->port_cnt) {
		/*
		/*
		 * XXX If the master closes the port before the slave(s),
		 * XXX If the master closes the port before the slave(s),
@@ -2054,7 +2082,6 @@ static int ipath_close(struct inode *in, struct file *fp)
		goto bail;
		goto bail;
	}
	}
	port = pd->port_port;
	port = pd->port_port;
	dd = pd->port_dd;


	if (pd->port_hdrqfull) {
	if (pd->port_hdrqfull) {
		ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors "
		ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors "
@@ -2176,6 +2203,35 @@ static int ipath_get_slave_info(struct ipath_portdata *pd,
	return ret;
	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,
static ssize_t ipath_write(struct file *fp, const char __user *data,
			   size_t count, loff_t *off)
			   size_t count, loff_t *off)
{
{
@@ -2250,6 +2306,16 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
		dest = &cmd.cmd.armlaunch_ctrl;
		dest = &cmd.cmd.armlaunch_ctrl;
		src = &ucmd->cmd.armlaunch_ctrl;
		src = &ucmd->cmd.armlaunch_ctrl;
		break;
		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:
	default:
		ret = -EINVAL;
		ret = -EINVAL;
		goto bail;
		goto bail;
@@ -2331,6 +2397,17 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
		else
		else
			ipath_disable_armlaunch(pd->port_dd);
			ipath_disable_armlaunch(pd->port_dd);
		break;
		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)
	if (ret >= 0)
@@ -2340,6 +2417,20 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
	return ret;
	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 struct class *ipath_class;


static int init_cdev(int minor, char *name, const struct file_operations *fops,
static int init_cdev(int minor, char *name, const struct file_operations *fops,
+4 −0
Original line number Original line Diff line number Diff line
@@ -980,6 +980,10 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
		dd->ipath_stats_timer_active = 1;
		dd->ipath_stats_timer_active = 1;
	}
	}


	/* Set up SendDMA if chip supports it */
	if (dd->ipath_flags & IPATH_HAS_SEND_DMA)
		ret = setup_sdma(dd);

	/* Set up HoL state */
	/* Set up HoL state */
	init_timer(&dd->ipath_hol_timer);
	init_timer(&dd->ipath_hol_timer);
	dd->ipath_hol_timer.function = ipath_hol_event;
	dd->ipath_hol_timer.function = ipath_hol_event;
Loading