[PATCH v3 30/52] IB/qib: Add qib_qsfp.h

2010-05-06 Thread Ralph Campbell
creates the qib_qsfp.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qsfp.h |  184 ++
 1 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.h

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h 
b/drivers/infiniband/hw/qib/qib_qsfp.h
new file mode 100644
index 000..19b527b
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+/* QSFP support common definitions, for ib_qib driver */
+
+#define QSFP_DEV 0xA0
+#define QSFP_PWR_LAG_MSEC 2000
+
+/*
+ * Below are masks for various QSFP signals, for Port 1.
+ * Port2 equivalents are shifted by QSFP_GPIO_PORT2_SHIFT.
+ * _N means asserted low
+ */
+#define QSFP_GPIO_MOD_SEL_N (4)
+#define QSFP_GPIO_MOD_PRS_N (8)
+#define QSFP_GPIO_INT_N (0x10)
+#define QSFP_GPIO_MOD_RST_N (0x20)
+#define QSFP_GPIO_LP_MODE (0x40)
+#define QSFP_GPIO_PORT2_SHIFT 5
+
+#define QSFP_PAGESIZE 128
+/* Defined fields that QLogic requires of qualified cables */
+/* Byte 0 is Identifier, not checked */
+/* Byte 1 is reserved "status MSB" */
+/* Byte 2 is "status LSB" We only care that D2 "Flat Mem" is set. */
+/*
+ * Rest of first 128 not used, although 127 is reserved for page select
+ * if module is not "Flat memory".
+ */
+/* Byte 128 is Identifier: must be 0x0c for QSFP, or 0x0d for QSFP+ */
+#define QSFP_MOD_ID_OFFS 128
+/*
+ * Byte 129 is "Extended Identifier". We only care about D7,D6: Power class
+ *  0:1.5W, 1:2.0W, 2:2.5W, 3:3.5W
+ */
+#define QSFP_MOD_PWR_OFFS 129
+/* Byte 130 is Connector type. Not QLogic req'd */
+/* Bytes 131..138 are Transceiver types, bit maps for various tech, none IB */
+/* Byte 139 is encoding. code 0x01 is 8b10b. Not QLogic req'd */
+/* byte 140 is nominal bit-rate, in units of 100Mbits/sec Not QLogic req'd */
+/* Byte 141 is Extended Rate Select. Not QLogic req'd */
+/* Bytes 142..145 are lengths for various fiber types. Not QLogic req'd */
+/* Byte 146 is length for Copper. Units of 1 meter */
+#define QSFP_MOD_LEN_OFFS 146
+/*
+ * Byte 147 is Device technology. D0..3 not Qlogc req'd
+ * D4..7 select from 15 choices, translated by table:
+ */
+#define QSFP_MOD_TECH_OFFS 147
+extern const char *const qib_qsfp_devtech[16];
+/* Active Equalization includes fiber, copper full EQ, and copper near Eq */
+#define QSFP_IS_ACTIVE(tech) ((0xA2FF >> ((tech) >> 4)) & 1)
+/* Attenuation should be valid for copper other than full/near Eq */
+#define QSFP_HAS_ATTEN(tech) ((0x4D00 >> ((tech) >> 4)) & 1)
+/* Length is only valid if technology is "copper" */
+#define QSFP_IS_CU(tech) ((0xED00 >> ((tech) >> 4)) & 1)
+#define QSFP_TECH_1490 9
+
+#define QSFP_OUI(oui) (((unsigned)oui[0] << 16) | ((unsigned)oui[1] << 8) | \
+   oui[2])
+#define QSFP_OUI_AMPHENOL 0x415048
+#define QSFP_OUI_FINISAR  0x009065
+#define QSFP_OUI_GORE 0x002177
+
+/* Bytes 148..163 are Vendor Name, Left-justified Blank-filled */
+#define QSFP_VEND_OFFS 148
+#define QSFP_VEND_LEN 16
+/* Byte 164 is IB Extended tranceiver codes Bits D0..3 are SDR,DDR,QDR,EDR */
+#define QSFP_IBXCV_OFFS 164
+/* Bytes 165..167 are Vendor OUI number */
+#define QSFP_VOUI_OFFS 165
+#define QSFP_VOUI_LEN 3
+/* Bytes 168..183 are Vendor Part Number, string */
+#defi

[PATCH v3 29/52] IB/qib: Add qib_qsfp.c

2010-05-06 Thread Ralph Campbell
creates the qib_qsfp.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qsfp.c |  564 ++
 1 files changed, 564 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.c

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c 
b/drivers/infiniband/hw/qib/qib_qsfp.c
new file mode 100644
index 000..35b3604
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_qsfp.h"
+
+/*
+ * QSFP support for ib_qib driver, using "Two Wire Serial Interface" driver
+ * in qib_twsi.c
+ */
+#define QSFP_MAX_RETRY 4
+
+static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
+{
+   struct qib_devdata *dd = ppd->dd;
+   u32 out, mask;
+   int ret, cnt, pass = 0;
+   int stuck = 0;
+   u8 *buff = bp;
+
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (ret)
+   goto no_unlock;
+
+   if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
+   ret = -ENXIO;
+   goto bail;
+   }
+
+   /*
+* We presume, if we are called at all, that this board has
+* QSFP. This is on the same i2c chain as the legacy parts,
+* but only responds if the module is selected via GPIO pins.
+* Further, there are very long setup and hold requirements
+* on MODSEL.
+*/
+   mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   if (ppd->hw_pidx) {
+   mask <<= QSFP_GPIO_PORT2_SHIFT;
+   out <<= QSFP_GPIO_PORT2_SHIFT;
+   }
+
+   dd->f_gpio_mod(dd, out, mask, mask);
+
+   /*
+* Module could take up to 2 Msec to respond to MOD_SEL, and there
+* is no way to tell if it is ready, so we must wait.
+*/
+   msleep(2);
+
+   /* Make sure TWSI bus is in sane state. */
+   ret = qib_twsi_reset(dd);
+   if (ret) {
+   qib_dev_porterr(dd, ppd->port,
+   "QSFP interface Reset for read failed\n");
+   ret = -EIO;
+   stuck = 1;
+   goto deselect;
+   }
+
+   /* All QSFP modules are at A0 */
+
+   cnt = 0;
+   while (cnt < len) {
+   unsigned in_page;
+   int wlen = len - cnt;
+   in_page = addr % QSFP_PAGESIZE;
+   if ((in_page + wlen) > QSFP_PAGESIZE)
+   wlen = QSFP_PAGESIZE - in_page;
+   ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
+   /* Some QSFP's fail first try. Retry as experiment */
+   if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY)
+   continue;
+   if (ret) {
+   /* qib_twsi_blk_rd() 1 for error, else 0 */
+   ret = -EIO;
+   goto deselect;
+   }
+   addr += wlen;
+   cnt += wlen;
+   }
+   ret = cnt;
+
+deselect:
+   /*
+* Module could take up to 10 uSec after transfer before
+* ready to respond to MOD_SEL negation, and there is no way
+* to tell if it is ready, so we must wait.
+  

[PATCH v3 28/52] IB/qib: Add qib_qp.c

2010-05-06 Thread Ralph Campbell
creates the qib_qp.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qp.c | 1255 
 1 files changed, 1255 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qp.c

diff --git a/drivers/infiniband/hw/qib/qib_qp.c 
b/drivers/infiniband/hw/qib/qib_qp.c
new file mode 100644
index 000..e0f65e3
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -0,0 +1,1255 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
+ * All rights reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib.h"
+
+#define BITS_PER_PAGE   (PAGE_SIZE*BITS_PER_BYTE)
+#define BITS_PER_PAGE_MASK  (BITS_PER_PAGE-1)
+
+static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
+ struct qpn_map *map, unsigned off)
+{
+   return (map - qpt->map) * BITS_PER_PAGE + off;
+}
+
+static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
+   struct qpn_map *map, unsigned off,
+   unsigned r)
+{
+   if (qpt->mask) {
+   off++;
+   if ((off & qpt->mask) >> 1 != r)
+   off = ((off & qpt->mask) ?
+   (off | qpt->mask) + 1 : off) | (r << 1);
+   } else
+   off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
+   return off;
+}
+
+/*
+ * Convert the AETH credit code into the number of credits.
+ */
+static u32 credit_table[31] = {
+   0,  /* 0 */
+   1,  /* 1 */
+   2,  /* 2 */
+   3,  /* 3 */
+   4,  /* 4 */
+   6,  /* 5 */
+   8,  /* 6 */
+   12, /* 7 */
+   16, /* 8 */
+   24, /* 9 */
+   32, /* A */
+   48, /* B */
+   64, /* C */
+   96, /* D */
+   128,/* E */
+   192,/* F */
+   256,/* 10 */
+   384,/* 11 */
+   512,/* 12 */
+   768,/* 13 */
+   1024,   /* 14 */
+   1536,   /* 15 */
+   2048,   /* 16 */
+   3072,   /* 17 */
+   4096,   /* 18 */
+   6144,   /* 19 */
+   8192,   /* 1A */
+   12288,  /* 1B */
+   16384,  /* 1C */
+   24576,  /* 1D */
+   32768   /* 1E */
+};
+
+static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
+{
+   unsigned long page = get_zeroed_page(GFP_KERNEL);
+
+   /*
+* Free the page if someone raced with us installing it.
+*/
+
+   spin_lock(&qpt->lock);
+   if (map->page)
+   free_page(page);
+   else
+   map->page = (void *)page;
+   spin_unlock(&qpt->lock);
+}
+
+/*
+ * Allocate the next available QPN or
+ * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
+ */
+static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
+enum ib_qp_type type, u8 port)
+{
+   u32 i, offset, max_scan, 

[PATCH v3 27/52] IB/qib: Add qib_pio_copy.c

2010-05-06 Thread Ralph Campbell
creates the qib_pio_copy.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_pio_copy.c |   64 ++
 1 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pio_copy.c

diff --git a/drivers/infiniband/hw/qib/qib_pio_copy.c 
b/drivers/infiniband/hw/qib/qib_pio_copy.c
new file mode 100644
index 000..10b8c44
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pio_copy.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "qib.h"
+
+/**
+ * qib_pio_copy - copy data to MMIO space, in multiples of 32-bits
+ * @to: destination, in MMIO space (must be 64-bit aligned)
+ * @from: source (must be 64-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from kernel space to MMIO space, in multiples of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void qib_pio_copy(void __iomem *to, const void *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+   u64 __iomem *dst = to;
+   const u64 *src = from;
+   const u64 *end = src + (count >> 1);
+
+   while (src < end)
+   __raw_writeq(*src++, dst++);
+   if (count & 1)
+   __raw_writel(*(const u32 *)src, dst);
+#else
+   u32 __iomem *dst = to;
+   const u32 *src = from;
+   const u32 *end = src + count;
+
+   while (src < end)
+   __raw_writel(*src++, dst++);
+#endif
+}

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 26/52] IB/qib: Add qib_pcie.c

2010-05-06 Thread Ralph Campbell
creates the qib_pcie.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_pcie.c |  738 ++
 1 files changed, 738 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pcie.c

diff --git a/drivers/infiniband/hw/qib/qib_pcie.c 
b/drivers/infiniband/hw/qib/qib_pcie.c
new file mode 100644
index 000..c926bf4
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * This file contains PCIe utility routines that are common to the
+ * various QLogic InfiniPath adapters
+ */
+
+/*
+ * Code to adjust PCIe capabilities.
+ * To minimize the change footprint, we call it
+ * from qib_pcie_params, which every chip-specific
+ * file calls, even though this violates some
+ * expectations of harmlessness.
+ */
+static int qib_tune_pcie_caps(struct qib_devdata *);
+static int qib_tune_pcie_coalesce(struct qib_devdata *);
+
+/*
+ * Do all the common PCIe setup and initialization.
+ * devdata is not yet allocated, and is not allocated until after this
+ * routine returns success.  Therefore qib_dev_err() can't be used for error
+ * printing.
+ */
+int qib_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+   int ret;
+
+   ret = pci_enable_device(pdev);
+   if (ret) {
+   /*
+* This can happen (in theory) iff:
+* We did a chip reset, and then failed to reprogram the
+* BAR, or the chip reset due to an internal error.  We then
+* unloaded the driver and reloaded it.
+*
+* Both reset cases set the BAR back to initial state.  For
+* the latter case, the AER sticky error bit at offset 0x718
+* should be set, but the Linux kernel doesn't yet know
+* about that, it appears.  If the original BAR was retained
+* in the kernel data structures, this may be OK.
+*/
+   qib_early_err(&pdev->dev, "pci enable failed: error %d\n",
+ -ret);
+   goto done;
+   }
+
+   ret = pci_request_regions(pdev, QIB_DRV_NAME);
+   if (ret) {
+   qib_devinfo(pdev, "pci_request_regions fails: err %d\n", -ret);
+   goto bail;
+   }
+
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret) {
+   /*
+* If the 64 bit setup fails, try 32 bit.  Some systems
+* do not setup 64 bit maps on systems with 2GB or less
+* memory installed.
+*/
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (ret) {
+   qib_devinfo(pdev, "Unable to set DMA mask: %d\n", ret);
+   goto bail;
+   }
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+   } else
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret)
+   qib_early_err(&pdev->dev,
+ "Unable to set DMA consistent mask: %d\n", ret);
+
+   pci_set_master(pdev);
+   ret = pci_enable_pcie_error_reporting(pdev);
+   if (ret)
+   qib_early_err(&pdev->dev,
+ "Unable to en

[PATCH v3 25/52] IB/qib: Add qib_mr.c

2010-05-06 Thread Ralph Campbell
creates the qib_mr.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mr.c |  503 
 1 files changed, 503 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mr.c

diff --git a/drivers/infiniband/hw/qib/qib_mr.c 
b/drivers/infiniband/hw/qib/qib_mr.c
new file mode 100644
index 000..5f95f0f
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib.h"
+
+/* Fast memory region */
+struct qib_fmr {
+   struct ib_fmr ibfmr;
+   u8 page_shift;
+   struct qib_mregion mr;/* must be last */
+};
+
+static inline struct qib_fmr *to_ifmr(struct ib_fmr *ibfmr)
+{
+   return container_of(ibfmr, struct qib_fmr, ibfmr);
+}
+
+/**
+ * qib_get_dma_mr - get a DMA memory region
+ * @pd: protection domain for this memory region
+ * @acc: access flags
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ * Note that all DMA addresses should be created via the
+ * struct ib_dma_mapping_ops functions (see qib_dma.c).
+ */
+struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc)
+{
+   struct qib_ibdev *dev = to_idev(pd->device);
+   struct qib_mr *mr;
+   struct ib_mr *ret;
+   unsigned long flags;
+
+   if (to_ipd(pd)->user) {
+   ret = ERR_PTR(-EPERM);
+   goto bail;
+   }
+
+   mr = kzalloc(sizeof *mr, GFP_KERNEL);
+   if (!mr) {
+   ret = ERR_PTR(-ENOMEM);
+   goto bail;
+   }
+
+   mr->mr.access_flags = acc;
+   atomic_set(&mr->mr.refcount, 0);
+
+   spin_lock_irqsave(&dev->lk_table.lock, flags);
+   if (!dev->dma_mr)
+   dev->dma_mr = &mr->mr;
+   spin_unlock_irqrestore(&dev->lk_table.lock, flags);
+
+   ret = &mr->ibmr;
+
+bail:
+   return ret;
+}
+
+static struct qib_mr *alloc_mr(int count, struct qib_lkey_table *lk_table)
+{
+   struct qib_mr *mr;
+   int m, i = 0;
+
+   /* Allocate struct plus pointers to first level page tables. */
+   m = (count + QIB_SEGSZ - 1) / QIB_SEGSZ;
+   mr = kmalloc(sizeof *mr + m * sizeof mr->mr.map[0], GFP_KERNEL);
+   if (!mr)
+   goto done;
+
+   /* Allocate first level page tables. */
+   for (; i < m; i++) {
+   mr->mr.map[i] = kmalloc(sizeof *mr->mr.map[0], GFP_KERNEL);
+   if (!mr->mr.map[i])
+   goto bail;
+   }
+   mr->mr.mapsz = m;
+   mr->mr.max_segs = count;
+
+   /*
+* ib_reg_phys_mr() will initialize mr->ibmr except for
+* lkey and rkey.
+*/
+   if (!qib_alloc_lkey(lk_table, &mr->mr))
+   goto bail;
+   mr->ibmr.lkey = mr->mr.lkey;
+   mr->ibmr.rkey = mr->mr.lkey;
+
+   atomic_set(&mr->mr.refcount, 0);
+   goto done;
+
+bail:
+   while (i)
+   kfree(mr->mr.map[--i]);
+   kfree(mr);
+   mr = NULL;
+
+done:
+   return mr;
+}
+
+/**
+ * qib_reg_phys_mr - register a physical memory region
+ * @pd: protection domain for this memory region
+ * @buffer_list: pointer to the list of physical buffers to register
+ * @num_phys_buf: the number of physical buffers to register
+ * @iova_start: the starting address passed over IB which maps to this MR
+ *

[PATCH v3 24/52] IB/qib: Add qib_mmap.c

2010-05-06 Thread Ralph Campbell
creates the qib_mmap.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mmap.c |  173 ++
 1 files changed, 173 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mmap.c

diff --git a/drivers/infiniband/hw/qib/qib_mmap.c 
b/drivers/infiniband/hw/qib/qib_mmap.c
new file mode 100644
index 000..ae15d38
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mmap.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib_verbs.h"
+
+/**
+ * qib_release_mmap_info - free mmap info structure
+ * @ref: a pointer to the kref within struct qib_mmap_info
+ */
+void qib_release_mmap_info(struct kref *ref)
+{
+   struct qib_mmap_info *ip =
+   container_of(ref, struct qib_mmap_info, ref);
+   struct qib_ibdev *dev = to_idev(ip->context->device);
+
+   spin_lock_irq(&dev->pending_lock);
+   list_del(&ip->pending_mmaps);
+   spin_unlock_irq(&dev->pending_lock);
+
+   vfree(ip->obj);
+   kfree(ip);
+}
+
+/*
+ * open and close keep track of how many times the CQ is mapped,
+ * to avoid releasing it.
+ */
+static void qib_vma_open(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma->vm_private_data;
+
+   kref_get(&ip->ref);
+}
+
+static void qib_vma_close(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma->vm_private_data;
+
+   kref_put(&ip->ref, qib_release_mmap_info);
+}
+
+static struct vm_operations_struct qib_vm_ops = {
+   .open = qib_vma_open,
+   .close =qib_vma_close,
+};
+
+/**
+ * qib_mmap - create a new mmap region
+ * @context: the IB user context of the process making the mmap() call
+ * @vma: the VMA to be initialized
+ * Return zero if the mmap is OK. Otherwise, return an errno.
+ */
+int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
+{
+   struct qib_ibdev *dev = to_idev(context->device);
+   unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+   unsigned long size = vma->vm_end - vma->vm_start;
+   struct qib_mmap_info *ip, *pp;
+   int ret = -EINVAL;
+
+   /*
+* Search the device's list of objects waiting for a mmap call.
+* Normally, this list is very short since a call to create a
+* CQ, QP, or SRQ is soon followed by a call to mmap().
+*/
+   spin_lock_irq(&dev->pending_lock);
+   list_for_each_entry_safe(ip, pp, &dev->pending_mmaps,
+pending_mmaps) {
+   /* Only the creator is allowed to mmap the object */
+   if (context != ip->context || (__u64) offset != ip->offset)
+   continue;
+   /* Don't allow a mmap larger than the object. */
+   if (size > ip->size)
+   break;
+
+   list_del_init(&ip->pending_mmaps);
+   spin_unlock_irq(&dev->pending_lock);
+
+   ret = remap_vmalloc_range(vma, ip->obj, 0);
+   if (ret)
+   goto done;
+   vma->vm_ops = &qib_vm_ops;
+   vma->vm_private_data = ip;
+   qib_vma_open(vma);
+   goto done;
+   }
+   spin_unlock_irq(&dev->pending_lock);
+done:
+   return ret;
+}
+
+/*
+ *

[PATCH v3 23/52] IB/qib: Add qib_mad.h

2010-05-06 Thread Ralph Campbell
creates the qib_mad.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mad.h |  373 +++
 1 files changed, 373 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.h

diff --git a/drivers/infiniband/hw/qib/qib_mad.h 
b/drivers/infiniband/hw/qib/qib_mad.h
new file mode 100644
index 000..147aff9
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.h
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
+ * All rights reserved.
+ * Copyright (c) 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.
+ */
+
+#define IB_SMP_UNSUP_VERSIONcpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR  cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELDcpu_to_be16(0x001C)
+
+struct ib_node_info {
+   u8 base_version;
+   u8 class_version;
+   u8 node_type;
+   u8 num_ports;
+   __be64 sys_guid;
+   __be64 node_guid;
+   __be64 port_guid;
+   __be16 partition_cap;
+   __be16 device_id;
+   __be32 revision;
+   u8 local_port_num;
+   u8 vendor_id[3];
+} __attribute__ ((packed));
+
+struct ib_mad_notice_attr {
+   u8 generic_type;
+   u8 prod_type_msb;
+   __be16 prod_type_lsb;
+   __be16 trap_num;
+   __be16 issuer_lid;
+   __be16 toggle_count;
+
+   union {
+   struct {
+   u8  details[54];
+   } raw_data;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* where violation happened */
+   u8  port_num;   /* where violation happened */
+   } __attribute__ ((packed)) ntc_129_131;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* LID where change occured */
+   u8  reserved2;
+   u8  local_changes;  /* low bit - local changes */
+   __be32  new_cap_mask;   /* new capability mask */
+   u8  reserved3;
+   u8  change_flags;   /* low 3 bits only */
+   } __attribute__ ((packed)) ntc_144;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* lid where sys guid changed */
+   __be16  reserved2;
+   __be64  new_sys_guid;
+   } __attribute__ ((packed)) ntc_145;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;
+   __be16  dr_slid;
+   u8  method;
+   u8  reserved2;
+   __be16  attr_id;
+   __be32  attr_mod;
+   __be64  mkey;
+   u8  reserved3;
+   u8  dr_trunc_hop;
+   u8  dr_rtn_path[30];
+   } __attribute__ ((packed)) ntc_256;
+
+   struct {
+   __be16  reserved;
+   __be16  lid1;
+   __be16  lid2;
+   __be32  key;
+   __be32  sl_qp1; /* SL: high 4 bits */
+   __be32  qp2;/* high 8 bits reserved */
+   union ib_gidgid1;
+   union ib_g

[PATCH v3 21/52] IB/qib: Add qib_keys.c

2010-05-06 Thread Ralph Campbell
creates the qib_keys.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_keys.c |  328 ++
 1 files changed, 328 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_keys.c

diff --git a/drivers/infiniband/hw/qib/qib_keys.c 
b/drivers/infiniband/hw/qib/qib_keys.c
new file mode 100644
index 000..4b80eb1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_keys.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved.
+ * Copyright (c) 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 "qib.h"
+
+/**
+ * qib_alloc_lkey - allocate an lkey
+ * @rkt: lkey table in which to allocate the lkey
+ * @mr: memory region that this lkey protects
+ *
+ * Returns 1 if successful, otherwise returns 0.
+ */
+
+int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 r;
+   u32 n;
+   int ret;
+
+   spin_lock_irqsave(&rkt->lock, flags);
+
+   /* Find the next available LKEY */
+   r = rkt->next;
+   n = r;
+   for (;;) {
+   if (rkt->table[r] == NULL)
+   break;
+   r = (r + 1) & (rkt->max - 1);
+   if (r == n) {
+   spin_unlock_irqrestore(&rkt->lock, flags);
+   ret = 0;
+   goto bail;
+   }
+   }
+   rkt->next = (r + 1) & (rkt->max - 1);
+   /*
+* Make sure lkey is never zero which is reserved to indicate an
+* unrestricted LKEY.
+*/
+   rkt->gen++;
+   mr->lkey = (r << (32 - ib_qib_lkey_table_size)) |
+   1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen)
+<< 8);
+   if (mr->lkey == 0) {
+   mr->lkey |= 1 << 8;
+   rkt->gen++;
+   }
+   rkt->table[r] = mr;
+   spin_unlock_irqrestore(&rkt->lock, flags);
+
+   ret = 1;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_free_lkey - free an lkey
+ * @rkt: table from which to free the lkey
+ * @lkey: lkey id to free
+ */
+int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 lkey = mr->lkey;
+   u32 r;
+   int ret;
+
+   spin_lock_irqsave(&dev->lk_table.lock, flags);
+   if (lkey == 0) {
+   if (dev->dma_mr && dev->dma_mr == mr) {
+   ret = atomic_read(&dev->dma_mr->refcount);
+   if (!ret)
+   dev->dma_mr = NULL;
+   } else
+   ret = 0;
+   } else {
+   r = lkey >> (32 - ib_qib_lkey_table_size);
+   ret = atomic_read(&dev->lk_table.table[r]->refcount);
+   if (!ret)
+   dev->lk_table.table[r] = NULL;
+   }
+   spin_unlock_irqrestore(&dev->lk_table.lock, flags);
+
+   if (ret)
+   ret = -EBUSY;
+   return ret;
+}
+
+/**
+ * qib_lkey_ok - check IB SGE for validity and initialize
+ * @rkt: table containing lkey to check SGE against
+ * @isge: outgoing internal SGE
+ * @sge: SGE to check
+ * @acc: access flags
+ *
+ * Return 1 if valid and successful, otherwise returns 0.
+ *
+ * Check the IB SGE for validity and initialize our internal version
+ * of it.
+ */
+int qib_lkey_ok(struct qib_lkey_table *rkt, struct 

[PATCH v3 20/52] IB/qib: Add qib_intr.c

2010-05-06 Thread Ralph Campbell
creates the qib_intr.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_intr.c |  236 ++
 1 files changed, 236 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_intr.c

diff --git a/drivers/infiniband/hw/qib/qib_intr.c 
b/drivers/infiniband/hw/qib/qib_intr.c
new file mode 100644
index 000..54a4082
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_intr.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 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 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/**
+ * qib_format_hwmsg - format a single hwerror message
+ * @msg message buffer
+ * @msgl length of message buffer
+ * @hwmsg message to add to message buffer
+ */
+static void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
+{
+   strlcat(msg, "[", msgl);
+   strlcat(msg, hwmsg, msgl);
+   strlcat(msg, "]", msgl);
+}
+
+/**
+ * qib_format_hwerrors - format hardware error messages for display
+ * @hwerrs hardware errors bit vector
+ * @hwerrmsgs hardware error descriptions
+ * @nhwerrmsgs number of hwerrmsgs
+ * @msg message buffer
+ * @msgl message buffer length
+ */
+void qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs,
+size_t nhwerrmsgs, char *msg, size_t msgl)
+{
+   int i;
+
+   for (i = 0; i < nhwerrmsgs; i++)
+   if (hwerrs & hwerrmsgs[i].mask)
+   qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
+}
+
+static void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev)
+{
+   struct ib_event event;
+   struct qib_devdata *dd = ppd->dd;
+
+   event.device = &dd->verbs_dev.ibdev;
+   event.element.port_num = ppd->port;
+   event.event = ev;
+   ib_dispatch_event(&event);
+}
+
+void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs)
+{
+   struct qib_devdata *dd = ppd->dd;
+   unsigned long flags;
+   u32 lstate;
+   u8 ltstate;
+   enum ib_event_type ev = 0;
+
+   lstate = dd->f_iblink_state(ibcs); /* linkstate */
+   ltstate = dd->f_ibphys_portstate(ibcs);
+
+   /*
+* If linkstate transitions into INIT from any of the various down
+* states, or if it transitions from any of the up (INIT or better)
+* states into any of the down states (except link recovery), then
+* call the chip-specific code to take appropriate actions.
+*/
+   if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) &&
+   ltstate == IB_PHYSPORTSTATE_LINKUP) {
+   /* transitioned to UP */
+   if (dd->f_ib_updown(ppd, 1, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   } else if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED |
+  QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) {
+   if (ltstate != IB_PHYSPORTSTATE_LINKUP &&
+   ltstate <= IB_PHYSPORTSTATE_CFG_TRAIN &&
+   dd->f_ib_updown(ppd, 0, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT);
+   }
+
+   if (lstate != IB_PORT_DOWN) {
+   /* lstate is INIT, ARMED, or ACTIVE */
+   if (lstate 

[PATCH v3 19/52] IB/qib: Add qib_init.c

2010-05-06 Thread Ralph Campbell
creates the qib_init.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_init.c | 1568 ++
 1 files changed, 1568 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_init.c

diff --git a/drivers/infiniband/hw/qib/qib_init.c 
b/drivers/infiniband/hw/qib/qib_init.c
new file mode 100644
index 000..262a608
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -0,0 +1,1568 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/*
+ * min buffers we want to have per context, after driver
+ */
+#define QIB_MIN_USER_CTXT_BUFCNT 7
+
+#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF
+#define QLOGIC_IB_R_SOFTWARE_SHIFT 24
+#define QLOGIC_IB_R_EMULATOR_MASK (1ULL<<62)
+
+/*
+ * Number of ctxts we are configured to use (to allow for more pio
+ * buffers per ctxt, etc.)  Zero means use chip value.
+ */
+ushort qib_cfgctxts;
+module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
+MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use");
+
+/*
+ * If set, do not write to any regs if avoidable, hack to allow
+ * check for deranged default register values.
+ */
+ushort qib_mini_init;
+module_param_named(mini_init, qib_mini_init, ushort, S_IRUGO);
+MODULE_PARM_DESC(mini_init, "If set, do minimal diag init");
+
+unsigned qib_n_krcv_queues;
+module_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO);
+MODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port");
+
+/*
+ * qib_wc_pat parameter:
+ *  0 is WC via MTRR
+ *  1 is WC via PAT
+ *  If PAT initialization fails, code reverts back to MTRR
+ */
+unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */
+module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
+MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism");
+
+struct workqueue_struct *qib_wq;
+
+static void verify_interrupt(unsigned long);
+
+static struct idr qib_unit_table;
+u32 qib_cpulist_count;
+unsigned long *qib_cpulist;
+
+/* set number of contexts we'll actually use */
+void qib_set_ctxtcnt(struct qib_devdata *dd)
+{
+   if (!qib_cfgctxts)
+   dd->cfgctxts = dd->ctxtcnt;
+   else if (qib_cfgctxts < dd->num_pports)
+   dd->cfgctxts = dd->ctxtcnt;
+   else if (qib_cfgctxts <= dd->ctxtcnt)
+   dd->cfgctxts = qib_cfgctxts;
+   else
+   dd->cfgctxts = dd->ctxtcnt;
+}
+
+/*
+ * Common code for creating the receive context array.
+ */
+int qib_create_ctxts(struct qib_devdata *dd)
+{
+   unsigned i;
+   int ret;
+
+   /*
+* Allocate full ctxtcnt array, rather than just cfgctxts, because
+* cleanup iterates across all possible ctxts.
+*/
+   dd->rcd = kzalloc(sizeof(*dd->rcd) * dd->ctxtcnt, GFP_KERNEL);
+   if (!dd->rcd) {
+   qib_dev_err(dd, "Unable to allocate ctxtdata array, "
+   "failing\n");
+   ret = -ENOMEM;
+   goto done;
+   }
+
+   /* create (one or more) kctxt */
+   for (i = 0; i < dd->first_user_ctxt; ++i) {
+   struct qib_pportdata *ppd;
+   struct qib_ctxtdata *rcd;
+
+   if (dd->skip_kctxt_ma

[PATCH v3 15/52] IB/qib: Add qib_fs.c

2010-05-06 Thread Ralph Campbell
creates the qib_fs.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_fs.c |  613 
 1 files changed, 613 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_fs.c

diff --git a/drivers/infiniband/hw/qib/qib_fs.c 
b/drivers/infiniband/hw/qib/qib_fs.c
new file mode 100644
index 000..7554704
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+#define QIBFS_MAGIC 0x726a77
+
+static struct super_block *qib_super;
+
+#define private2dd(file) ((file)->f_dentry->d_inode->i_private)
+
+static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
+  int mode, const struct file_operations *fops,
+  void *data)
+{
+   int error;
+   struct inode *inode = new_inode(dir->i_sb);
+
+   if (!inode) {
+   error = -EPERM;
+   goto bail;
+   }
+
+   inode->i_mode = mode;
+   inode->i_uid = 0;
+   inode->i_gid = 0;
+   inode->i_blocks = 0;
+   inode->i_atime = CURRENT_TIME;
+   inode->i_mtime = inode->i_atime;
+   inode->i_ctime = inode->i_atime;
+   inode->i_private = data;
+   if ((mode & S_IFMT) == S_IFDIR) {
+   inode->i_op = &simple_dir_inode_operations;
+   inc_nlink(inode);
+   inc_nlink(dir);
+   }
+
+   inode->i_fop = fops;
+
+   d_instantiate(dentry, inode);
+   error = 0;
+
+bail:
+   return error;
+}
+
+static int create_file(const char *name, mode_t mode,
+  struct dentry *parent, struct dentry **dentry,
+  const struct file_operations *fops, void *data)
+{
+   int error;
+
+   *dentry = NULL;
+   mutex_lock(&parent->d_inode->i_mutex);
+   *dentry = lookup_one_len(name, parent, strlen(name));
+   if (!IS_ERR(*dentry))
+   error = qibfs_mknod(parent->d_inode, *dentry,
+   mode, fops, data);
+   else
+   error = PTR_ERR(*dentry);
+   mutex_unlock(&parent->d_inode->i_mutex);
+
+   return error;
+}
+
+static ssize_t driver_stats_read(struct file *file, char __user *buf,
+size_t count, loff_t *ppos)
+{
+   return simple_read_from_buffer(buf, count, ppos, &qib_stats,
+  sizeof qib_stats);
+}
+
+/*
+ * driver stats field names, one line per stat, single string.  Used by
+ * programs like ipathstats to print the stats in a way which works for
+ * different versions of drivers, without changing program source.
+ * if qlogic_ib_stats changes, this needs to change.  Names need to be
+ * 12 chars or less (w/o newline), for proper display by ipathstats utility.
+ */
+static const char qib_statnames[] =
+   "KernIntr\n"
+   "ErrorIntr\n"
+   "Tx_Errs\n"
+   "Rcv_Errs\n"
+   "H/W_Errs\n"
+   "NoPIOBufs\n"
+   "CtxtsOpen\n"
+   "RcvLen_Errs\n"
+   "EgrBufFull\n"
+   "EgrHdrFull\n"
+   ;
+
+static ssize_t driver_names_read(struct file *file, char __user *buf,
+size_t co

[PATCH v3 13/52] IB/qib: Add qib_eeprom.c

2010-05-06 Thread Ralph Campbell
creates the qib_eeprom.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_eeprom.c |  451 
 1 files changed, 451 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_eeprom.c

diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c 
b/drivers/infiniband/hw/qib/qib_eeprom.c
new file mode 100644
index 000..92d9cfe
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_eeprom.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * Functions specific to the serial EEPROM on cards handled by ib_qib.
+ * The actual serail interface code is in qib_twsi.c. This file is a client
+ */
+
+/**
+ * qib_eeprom_read - receives bytes from the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: address to read from
+ * @buffer: where to store result
+ * @len: number of bytes to receive
+ */
+int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset,
+   void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (!ret) {
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, "EEPROM Reset for read failed\n");
+   else
+   ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev,
+ eeprom_offset, buff, len);
+   mutex_unlock(&dd->eep_lock);
+   }
+
+   return ret;
+}
+
+/*
+ * Actually update the eeprom, first doing write enable if
+ * needed, then restoring write enable state.
+ * Must be called with eep_lock held
+ */
+static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset,
+const void *buf, int len)
+{
+   int ret, pwen;
+
+   pwen = dd->f_eeprom_wen(dd, 1);
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, "EEPROM Reset for write failed\n");
+   else
+   ret = qib_twsi_blk_wr(dd, dd->twsi_eeprom_dev,
+ offset, buf, len);
+   dd->f_eeprom_wen(dd, pwen);
+   return ret;
+}
+
+/**
+ * qib_eeprom_write - writes data to the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: where to place data
+ * @buffer: data to write
+ * @len: number of bytes to write
+ */
+int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset,
+const void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (!ret) {
+   ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len);
+   mutex_unlock(&dd->eep_lock);
+   }
+
+   return ret;
+}
+
+static u8 flash_csum(struct qib_flash *ifp, int adjust)
+{
+   u8 *ip = (u8 *) ifp;
+   u8 csum = 0, len;
+
+   /*
+* Limit length checksummed to max length of actual data.
+* Checksum of erased eeprom will still be bad, but we avoid
+* reading past the end of the buffer we were passed.
+*/
+   len = ifp->if_length;
+   if (len > sizeof(struct qib_flash))
+   len = sizeof(struct qib_flash);
+   while (len--)
+   csum += *ip++;
+   csum -= ifp->if_csum;
+   csum = ~csum;
+   if (adjust)
+   ifp->if_csum = csum;
+
+   

[PATCH v3 12/52] IB/qib: Add qib_driver.c

2010-05-06 Thread Ralph Campbell
creates the qib_driver.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_driver.c |  665 
 1 files changed, 665 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_driver.c

diff --git a/drivers/infiniband/hw/qib/qib_driver.c 
b/drivers/infiniband/hw/qib/qib_driver.c
new file mode 100644
index 000..f15ce07
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * The size has to be longer than this string, so we can append
+ * board/chip information to it in the init code.
+ */
+const char ib_qib_version[] = QIB_IDSTR "\n";
+
+DEFINE_SPINLOCK(qib_devs_lock);
+LIST_HEAD(qib_dev_list);
+DEFINE_MUTEX(qib_mutex);   /* general driver use */
+
+unsigned qib_ibmtu;
+module_param_named(ibmtu, qib_ibmtu, uint, S_IRUGO);
+MODULE_PARM_DESC(ibmtu, "Set max IB MTU (0=2KB, 1=256, 2=512, ... 5=4096");
+
+unsigned qib_compat_ddr_negotiate = 1;
+module_param_named(compat_ddr_negotiate, qib_compat_ddr_negotiate, uint,
+  S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(compat_ddr_negotiate,
+"Attempt pre-IBTA 1.2 DDR speed negotiation");
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("QLogic ");
+MODULE_DESCRIPTION("QLogic IB driver");
+
+/*
+ * QIB_PIO_MAXIBHDR is the max IB header size allowed for in our
+ * PIO send buffers.  This is well beyond anything currently
+ * defined in the InfiniBand spec.
+ */
+#define QIB_PIO_MAXIBHDR 128
+
+struct qlogic_ib_stats qib_stats;
+
+const char *qib_get_unit_name(int unit)
+{
+   static char iname[16];
+
+   snprintf(iname, sizeof iname, "infinipath%u", unit);
+   return iname;
+}
+
+/*
+ * Return count of units with at least one port ACTIVE.
+ */
+int qib_count_active_units(void)
+{
+   struct qib_devdata *dd;
+   struct qib_pportdata *ppd;
+   unsigned long flags;
+   int pidx, nunits_active = 0;
+
+   spin_lock_irqsave(&qib_devs_lock, flags);
+   list_for_each_entry(dd, &qib_dev_list, list) {
+   if (!(dd->flags & QIB_PRESENT) || !dd->kregbase)
+   continue;
+   for (pidx = 0; pidx < dd->num_pports; ++pidx) {
+   ppd = dd->pport + pidx;
+   if (ppd->lid && (ppd->lflags & (QIBL_LINKINIT |
+QIBL_LINKARMED | QIBL_LINKACTIVE))) {
+   nunits_active++;
+   break;
+   }
+   }
+   }
+   spin_unlock_irqrestore(&qib_devs_lock, flags);
+   return nunits_active;
+}
+
+/*
+ * Return count of all units, optionally return in arguments
+ * the number of usable (present) units, and the number of
+ * ports that are up.
+ */
+int qib_count_units(int *npresentp, int *nupp)
+{
+   int nunits = 0, npresent = 0, nup = 0;
+   struct qib_devdata *dd;
+   unsigned long flags;
+   int pidx;
+   struct qib_pportdata *ppd;
+
+   spin_lock_irqsave(&qib_devs_lock, flags);
+
+   list_for_each_entry(dd, &qib_dev_list, list) {
+   nunits++;
+   if ((dd->flags & QIB_PRESENT) &&

[PATCH v3 11/52] IB/qib: Add qib_dma.c

2010-05-06 Thread Ralph Campbell
creates the qib_dma.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_dma.c |  182 +++
 1 files changed, 182 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_dma.c

diff --git a/drivers/infiniband/hw/qib/qib_dma.c 
b/drivers/infiniband/hw/qib/qib_dma.c
new file mode 100644
index 000..c1b13a6
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_dma.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006, 2009 QLogic, Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include 
+#include 
+
+#include "qib_verbs.h"
+
+#define BAD_DMA_ADDRESS ((u64) 0)
+
+/*
+ * The following functions implement driver specific replacements
+ * for the ib_dma_*() functions.
+ *
+ * These functions return kernel virtual addresses instead of
+ * device bus addresses since the driver uses the CPU to copy
+ * data instead of using hardware DMA.
+ */
+
+static int qib_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+   return dma_addr == BAD_DMA_ADDRESS;
+}
+
+static u64 qib_dma_map_single(struct ib_device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+   return (u64) cpu_addr;
+}
+
+static void qib_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_dma_map_page(struct ib_device *dev, struct page *page,
+   unsigned long offset, size_t size,
+   enum dma_data_direction direction)
+{
+   u64 addr;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   if (offset + size > PAGE_SIZE) {
+   addr = BAD_DMA_ADDRESS;
+   goto done;
+   }
+
+   addr = (u64) page_address(page);
+   if (addr)
+   addr += offset;
+   /* TODO: handle highmem pages */
+
+done:
+   return addr;
+}
+
+static void qib_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size,
+  enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static int qib_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction)
+{
+   struct scatterlist *sg;
+   u64 addr;
+   int i;
+   int ret = nents;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   for_each_sg(sgl, sg, nents, i) {
+   addr = (u64) page_address(sg_page(sg));
+   /* TODO: handle highmem pages */
+   if (!addr) {
+   ret = 0;
+   break;
+   }
+   }
+   return ret;
+}
+
+static void qib_unmap_sg(struct ib_device *dev,
+struct scatterlist *sg, int nents,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
+{
+   u64 addr = (u64) page_address(sg_page(sg));
+
+   if (addr)
+   addr += sg->offset;
+   return addr;
+}
+
+static unsigned int qib_sg_dma_len(struct ib_device *dev,
+  struct scatterlist *sg)
+{
+   return sg->length;
+}
+
+static void qib_sync_single_for_cpu(struct ib_device *dev, u64 addr,
+   size_t size, enum dma_data_direction dir)
+{
+}
+
+static void qib_

[PATCH v3 10/52] IB/qib: Add qib_diag.c

2010-05-06 Thread Ralph Campbell
creates the qib_diag.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_diag.c |  893 ++
 1 files changed, 893 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_diag.c

diff --git a/drivers/infiniband/hw/qib/qib_diag.c 
b/drivers/infiniband/hw/qib/qib_diag.c
new file mode 100644
index 000..b040fb6
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_diag.c
@@ -0,0 +1,893 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+
+/*
+ * This file contains support for diagnostic functions.  It is accessed by
+ * opening the qib_diag device, normally minor number 129.  Diagnostic use
+ * of the QLogic_IB chip may render the chip or board unusable until the
+ * driver is unloaded, or in some cases, until the system is rebooted.
+ *
+ * Accesses to the chip through this interface are not similar to going
+ * through the /sys/bus/pci resource mmap interface.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/*
+ * Each client that opens the diag device must read then write
+ * offset 0, to prevent lossage from random cat or od. diag_state
+ * sequences this "handshake".
+ */
+enum diag_state { UNUSED = 0, OPENED, INIT, READY };
+
+/* State for an individual client. PID so children cannot abuse handshake */
+static struct qib_diag_client {
+   struct qib_diag_client *next;
+   struct qib_devdata *dd;
+   pid_t pid;
+   enum diag_state state;
+} *client_pool;
+
+/*
+ * Get a client struct. Recycled if possible, else kmalloc.
+ * Must be called with qib_mutex held
+ */
+static struct qib_diag_client *get_client(struct qib_devdata *dd)
+{
+   struct qib_diag_client *dc;
+
+   dc = client_pool;
+   if (dc)
+   /* got from pool remove it and use */
+   client_pool = dc->next;
+   else
+   /* None in pool, alloc and init */
+   dc = kmalloc(sizeof *dc, GFP_KERNEL);
+
+   if (dc) {
+   dc->next = NULL;
+   dc->dd = dd;
+   dc->pid = current->pid;
+   dc->state = OPENED;
+   }
+   return dc;
+}
+
+/*
+ * Return to pool. Must be called with qib_mutex held
+ */
+static void return_client(struct qib_diag_client *dc)
+{
+   struct qib_devdata *dd = dc->dd;
+   struct qib_diag_client *tdc, *rdc;
+
+   rdc = NULL;
+   if (dc == dd->diag_client) {
+   dd->diag_client = dc->next;
+   rdc = dc;
+   } else {
+   tdc = dc->dd->diag_client;
+   while (tdc) {
+   if (dc == tdc->next) {
+   tdc->next = dc->next;
+   rdc = dc;
+   break;
+   }
+   tdc = tdc->next;
+   }
+   }
+   if (rdc) {
+   rdc->state = UNUSED;
+   rdc->dd = NULL;
+   rdc->pid = 0;
+   rdc->next = client_pool;
+   client_pool = rdc;
+   }
+}
+
+static int qib_diag_open(struct inode *in, struct file *fp);
+static int qib_diag_release(struct inode *in, struct file *fp);
+static ssize_t qib_diag_read(struct file *fp, char __user *data,
+size_t count, loff_t *off);
+static ssize_t

[PATCH v3 09/52] IB/qib: Add qib_cq.c

2010-05-06 Thread Ralph Campbell
creates the qib_cq.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_cq.c |  483 
 1 files changed, 483 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_cq.c

diff --git a/drivers/infiniband/hw/qib/qib_cq.c 
b/drivers/infiniband/hw/qib/qib_cq.c
new file mode 100644
index 000..179a9f8
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_cq.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib_verbs.h"
+
+/**
+ * qib_cq_enter - add a new entry to the completion queue
+ * @cq: completion queue
+ * @entry: work completion entry to add
+ * @sig: true if @entry is a solicitated entry
+ *
+ * This may be called with qp->s_lock held.
+ */
+void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int solicited)
+{
+   struct qib_cq_wc *wc;
+   unsigned long flags;
+   u32 head;
+   u32 next;
+
+   spin_lock_irqsave(&cq->lock, flags);
+
+   /*
+* Note that the head pointer might be writable by user processes.
+* Take care to verify it is a sane value.
+*/
+   wc = cq->queue;
+   head = wc->head;
+   if (head >= (unsigned) cq->ibcq.cqe) {
+   head = cq->ibcq.cqe;
+   next = 0;
+   } else
+   next = head + 1;
+   if (unlikely(next == wc->tail)) {
+   spin_unlock_irqrestore(&cq->lock, flags);
+   if (cq->ibcq.event_handler) {
+   struct ib_event ev;
+
+   ev.device = cq->ibcq.device;
+   ev.element.cq = &cq->ibcq;
+   ev.event = IB_EVENT_CQ_ERR;
+   cq->ibcq.event_handler(&ev, cq->ibcq.cq_context);
+   }
+   return;
+   }
+   if (cq->ip) {
+   wc->uqueue[head].wr_id = entry->wr_id;
+   wc->uqueue[head].status = entry->status;
+   wc->uqueue[head].opcode = entry->opcode;
+   wc->uqueue[head].vendor_err = entry->vendor_err;
+   wc->uqueue[head].byte_len = entry->byte_len;
+   wc->uqueue[head].ex.imm_data =
+   (__u32 __force)entry->ex.imm_data;
+   wc->uqueue[head].qp_num = entry->qp->qp_num;
+   wc->uqueue[head].src_qp = entry->src_qp;
+   wc->uqueue[head].wc_flags = entry->wc_flags;
+   wc->uqueue[head].pkey_index = entry->pkey_index;
+   wc->uqueue[head].slid = entry->slid;
+   wc->uqueue[head].sl = entry->sl;
+   wc->uqueue[head].dlid_path_bits = entry->dlid_path_bits;
+   wc->uqueue[head].port_num = entry->port_num;
+   /* Make sure entry is written before the head index. */
+   smp_wmb();
+   } else
+   wc->kqueue[head] = *entry;
+   wc->head = next;
+
+   if (cq->notify == IB_CQ_NEXT_COMP ||
+   (cq->notify == IB_CQ_SOLICITED && solicited)) {
+   cq->notify = IB_CQ_NONE;
+   cq->triggered++;
+   /*
+* This will cause send_complete() to be called in
+* another thread.
+*/
+   queue_work(qib_wq, &cq->comptask);
+   }

[PATCH v3 08/52] IB/qib: Add qib_common.h

2010-05-06 Thread Ralph Campbell
creates the qib_common.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_common.h |  758 
 1 files changed, 758 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_common.h

diff --git a/drivers/infiniband/hw/qib/qib_common.h 
b/drivers/infiniband/hw/qib/qib_common.h
new file mode 100644
index 000..b3955ed
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_common.h
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 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.
+ */
+
+#ifndef _QIB_COMMON_H
+#define _QIB_COMMON_H
+
+/*
+ * This file contains defines, structures, etc. that are used
+ * to communicate between kernel and user code.
+ */
+
+/* This is the IEEE-assigned OUI for QLogic Inc. QLogic_IB */
+#define QIB_SRC_OUI_1 0x00
+#define QIB_SRC_OUI_2 0x11
+#define QIB_SRC_OUI_3 0x75
+
+/* version of protocol header (known to chip also). In the long run,
+ * we should be able to generate and accept a range of version numbers;
+ * for now we only accept one, and it's compiled in.
+ */
+#define IPS_PROTO_VERSION 2
+
+/*
+ * These are compile time constants that you may want to enable or disable
+ * if you are trying to debug problems with code or performance.
+ * QIB_VERBOSE_TRACING define as 1 if you want additional tracing in
+ * fastpath code
+ * QIB_TRACE_REGWRITES define as 1 if you want register writes to be
+ * traced in faspath code
+ * _QIB_TRACING define as 0 if you want to remove all tracing in a
+ * compilation unit
+ */
+
+/*
+ * The value in the BTH QP field that QLogic_IB uses to differentiate
+ * an qlogic_ib protocol IB packet vs standard IB transport
+ * This it needs to be even (0x656b78), because the LSB is sometimes
+ * used for the MSB of context. The change may cause a problem
+ * interoperating with older software.
+ */
+#define QIB_KD_QP 0x656b78
+
+/*
+ * These are the status bits readable (in ascii form, 64bit value)
+ * from the "status" sysfs file.  For binary compatibility, values
+ * must remain as is; removed states can be reused for different
+ * purposes.
+ */
+#define QIB_STATUS_INITTED   0x1/* basic initialization done */
+/* Chip has been found and initted */
+#define QIB_STATUS_CHIP_PRESENT 0x20
+/* IB link is at ACTIVE, usable for data traffic */
+#define QIB_STATUS_IB_READY 0x40
+/* link is configured, LID, MTU, etc. have been set */
+#define QIB_STATUS_IB_CONF  0x80
+/* A Fatal hardware error has occurred. */
+#define QIB_STATUS_HWERROR 0x200
+
+/*
+ * The list of usermode accessible registers.  Also see Reg_* later in file.
+ */
+enum qib_ureg {
+   /* (RO)  DMA RcvHdr to be used next. */
+   ur_rcvhdrtail = 0,
+   /* (RW)  RcvHdr entry to be processed next by host. */
+   ur_rcvhdrhead = 1,
+   /* (RO)  Index of next Eager index to use. */
+   ur_rcvegrindextail = 2,
+   /* (RW)  Eager TID to be processed next */
+   ur_rcvegrindexhead = 3,
+   /* For internal use only; max register number. */
+   _QIB_UregMax
+};
+
+/* bit values for spi_runtime_flags */
+#define QIB_RUNTIME_PCIE0x0002
+#define QIB_RUNTIME_FORCE_WC_ORDER  0x0004
+#define QIB_RUNTIME_RCVHDR_COPY 0x0008
+#define QIB_RUNTIME_MASTER  0x0010
+#define QIB_RUNTIME_RCHK0x0020
+#define QIB_RUNTIME_NODMA_RTAIL 0x0080
+#define QIB_RUNTIME_SPECIAL_TRIGGER 0x0100
+#define QIB_RUNTIME_SDMA0x0200
+#define Q

[PATCH v3 05/52] IB/qib: Add qib_7220.h

2010-05-06 Thread Ralph Campbell
creates the qib_7220.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_7220.h |  158 ++
 1 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_7220.h

diff --git a/drivers/infiniband/hw/qib/qib_7220.h 
b/drivers/infiniband/hw/qib/qib_7220.h
new file mode 100644
index 000..a68230e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_7220.h
@@ -0,0 +1,158 @@
+#ifndef _QIB_7220_H
+#define _QIB_7220_H
+/*
+ * Copyright (c) 2007, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* grab register-defs auto-generated by HW */
+#include "qib_7220_regs.h"
+
+/* The number of eager receive TIDs for context zero. */
+#define IBA7220_KRCVEGRCNT  2048U
+
+#define IB_7220_LT_STATE_CFGRCVFCFG  0x09
+#define IB_7220_LT_STATE_CFGWAITRMT  0x0a
+#define IB_7220_LT_STATE_TXREVLANES  0x0d
+#define IB_7220_LT_STATE_CFGENH  0x10
+
+struct qib_chip_specific {
+   u64 __iomem *cregbase;
+   u64 *cntrs;
+   u64 *portcntrs;
+   spinlock_t sdepb_lock; /* serdes EPB bus */
+   spinlock_t rcvmod_lock; /* protect rcvctrl shadow changes */
+   spinlock_t gpio_lock; /* RMW of shadows/regs for ExtCtrl and GPIO */
+   u64 hwerrmask;
+   u64 errormask;
+   u64 gpio_out; /* shadow of kr_gpio_out, for rmw ops */
+   u64 gpio_mask; /* shadow the gpio mask register */
+   u64 extctrl; /* shadow the gpio output enable, etc... */
+   u32 ncntrs;
+   u32 nportcntrs;
+   u32 cntrnamelen;
+   u32 portcntrnamelen;
+   u32 numctxts;
+   u32 rcvegrcnt;
+   u32 autoneg_tries;
+   u32 serdes_first_init_done;
+   u32 sdmabufcnt;
+   u32 lastbuf_for_pio;
+   u32 updthresh; /* current AvailUpdThld */
+   u32 updthresh_dflt; /* default AvailUpdThld */
+   int irq;
+   u8 presets_needed;
+   char emsgbuf[128];
+   char sdmamsgbuf[192];
+   char bitsmsgbuf[64];
+   struct qib_relock {
+   atomic_t relock_timer_active;
+   struct timer_list relock_timer;
+   unsigned int relock_interval; /* in jiffies */
+   } relock_st;
+};
+
+struct qib_chippport_specific {
+   struct qib_pportdata pportdata;
+   wait_queue_head_t autoneg_wait;
+   struct delayed_work autoneg_work;
+   struct timer_list chase_timer;
+   /*
+* these 5 fields are used to establish deltas for IB symbol
+* errors and linkrecovery errors.  They can be reported on
+* some chips during link negotiation prior to INIT, and with
+* DDR when faking DDR negotiations with non-IBTA switches.
+* The chip counters are adjusted at driver unload if there is
+* a non-zero delta.
+*/
+   u64 ibdeltainprog;
+   u64 ibsymdelta;
+   u64 ibsymsnap;
+   u64 iblnkerrdelta;
+   u64 iblnkerrsnap;
+   u64 ibcctrl; /* kr_ibcctrl shadow */
+   u64 ibcddrctrl; /* kr_ibcddrctrl shadow */
+   u64 chase_end;
+   u32 last_delay_mult;
+};
+
+/*
+ * This header file provides the declarations and common definitions
+ * for (mostly) manipulation of the SerDes blocks within the IBA7220.
+ * the functions declared should only be called from within other
+ * 7220-related files such as qib_iba7220.c or qib_sd7220.c.
+ */
+int qib_sd7220_presets(struct qib_devdata *dd);
+int qib_sd7220_init(struct qib_devdata *dd);
+int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, u8 *img,
+  int len, int offset);
+int qib_sd7220_prog_vfy(struct 

[PATCH v3 04/52] IB/qib: Add qib_6120_regs.h

2010-05-06 Thread Ralph Campbell
This creates the qib_6120_regs.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_6120_regs.h |  977 +
 1 files changed, 977 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_6120_regs.h

diff --git a/drivers/infiniband/hw/qib/qib_6120_regs.h 
b/drivers/infiniband/hw/qib/qib_6120_regs.h
new file mode 100644
index 000..8108b89
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_6120_regs.h
@@ -0,0 +1,977 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* This file is mechanically generated from RTL. Any hand-edits will be lost! 
*/
+
+#define QIB_6120_Revision_OFFS 0x0
+#define QIB_6120_Revision_R_Simulator_LSB 0x3F
+#define QIB_6120_Revision_R_Simulator_RMASK 0x1
+#define QIB_6120_Revision_Reserved_LSB 0x28
+#define QIB_6120_Revision_Reserved_RMASK 0x7F
+#define QIB_6120_Revision_BoardID_LSB 0x20
+#define QIB_6120_Revision_BoardID_RMASK 0xFF
+#define QIB_6120_Revision_R_SW_LSB 0x18
+#define QIB_6120_Revision_R_SW_RMASK 0xFF
+#define QIB_6120_Revision_R_Arch_LSB 0x10
+#define QIB_6120_Revision_R_Arch_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMajor_LSB 0x8
+#define QIB_6120_Revision_R_ChipRevMajor_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMinor_LSB 0x0
+#define QIB_6120_Revision_R_ChipRevMinor_RMASK 0xFF
+
+#define QIB_6120_Control_OFFS 0x8
+#define QIB_6120_Control_TxLatency_LSB 0x4
+#define QIB_6120_Control_TxLatency_RMASK 0x1
+#define QIB_6120_Control_PCIERetryBufDiagEn_LSB 0x3
+#define QIB_6120_Control_PCIERetryBufDiagEn_RMASK 0x1
+#define QIB_6120_Control_LinkEn_LSB 0x2
+#define QIB_6120_Control_LinkEn_RMASK 0x1
+#define QIB_6120_Control_FreezeMode_LSB 0x1
+#define QIB_6120_Control_FreezeMode_RMASK 0x1
+#define QIB_6120_Control_SyncReset_LSB 0x0
+#define QIB_6120_Control_SyncReset_RMASK 0x1
+
+#define QIB_6120_PageAlign_OFFS 0x10
+
+#define QIB_6120_PortCnt_OFFS 0x18
+
+#define QIB_6120_SendRegBase_OFFS 0x30
+
+#define QIB_6120_UserRegBase_OFFS 0x38
+
+#define QIB_6120_CntrRegBase_OFFS 0x40
+
+#define QIB_6120_Scratch_OFFS 0x48
+#define QIB_6120_Scratch_TopHalf_LSB 0x20
+#define QIB_6120_Scratch_TopHalf_RMASK 0x
+#define QIB_6120_Scratch_BottomHalf_LSB 0x0
+#define QIB_6120_Scratch_BottomHalf_RMASK 0x
+
+#define QIB_6120_IntBlocked_OFFS 0x60
+#define QIB_6120_IntBlocked_ErrorIntBlocked_LSB 0x1F
+#define QIB_6120_IntBlocked_ErrorIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioSetIntBlocked_LSB 0x1E
+#define QIB_6120_IntBlocked_PioSetIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_LSB 0x1D
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_LSB 0x1C
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved_LSB 0xF
+#define QIB_6120_IntBlocked_Reserved_RMASK 0x1FFF
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_LSB 0x10
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_LSB 0xF
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_LSB 0xE
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_LSB 0xD
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_LSB 0xC
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved1_LSB 0x5
+#define QIB_6120_IntBlocked_Reserved1_RMASK 0x7

[PATCH v3 03/52] IB/qib: Add qib.h

2010-05-06 Thread Ralph Campbell
This creates the qib.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib.h | 1439 +++
 1 files changed, 1439 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib.h

diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
new file mode 100644
index 000..32d9208
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -0,0 +1,1439 @@
+#ifndef _QIB_KERNEL_H
+#define _QIB_KERNEL_H
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010 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.
+ */
+
+/*
+ * This header file is the base header file for qlogic_ib kernel code
+ * qib_user.h serves a similar purpose for user code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib_common.h"
+#include "qib_verbs.h"
+
+/* only s/w major version of QLogic_IB we can handle */
+#define QIB_CHIP_VERS_MAJ 2U
+
+/* don't care about this except printing */
+#define QIB_CHIP_VERS_MIN 0U
+
+/* The Organization Unique Identifier (Mfg code), and its position in GUID */
+#define QIB_OUI 0x001175
+#define QIB_OUI_LSB 40
+
+/*
+ * per driver stats, either not device nor port-specific, or
+ * summed over all of the devices and ports.
+ * They are described by name via ipathfs filesystem, so layout
+ * and number of elements can change without breaking compatibility.
+ * If members are added or deleted qib_statnames[] in qib_fs.c must
+ * change to match.
+ */
+struct qlogic_ib_stats {
+   __u64 sps_ints; /* number of interrupts handled */
+   __u64 sps_errints; /* number of error interrupts */
+   __u64 sps_txerrs; /* tx-related packet errors */
+   __u64 sps_rcverrs; /* non-crc rcv packet errors */
+   __u64 sps_hwerrs; /* hardware errors reported (parity, etc.) */
+   __u64 sps_nopiobufs; /* no pio bufs avail from kernel */
+   __u64 sps_ctxts; /* number of contexts currently open */
+   __u64 sps_lenerrs; /* number of kernel packets where RHF != LRH len */
+   __u64 sps_buffull;
+   __u64 sps_hdrfull;
+};
+
+extern struct qlogic_ib_stats qib_stats;
+extern struct pci_error_handlers qib_pci_err_handler;
+extern struct pci_driver qib_driver;
+
+#define QIB_CHIP_SWVERSION QIB_CHIP_VERS_MAJ
+/*
+ * First-cut critierion for "device is active" is
+ * two thousand dwords combined Tx, Rx traffic per
+ * 5-second interval. SMA packets are 64 dwords,
+ * and occur "a few per second", presumably each way.
+ */
+#define QIB_TRAFFIC_ACTIVE_THRESHOLD (2000)
+
+/*
+ * Struct used to indicate which errors are logged in each of the
+ * error-counters that are logged to EEPROM. A counter is incremented
+ * _once_ (saturating at 255) for each event with any bits set in
+ * the error or hwerror register masks below.
+ */
+#define QIB_EEP_LOG_CNT (4)
+struct qib_eep_log_mask {
+   u64 errs_to_log;
+   u64 hwerrs_to_log;
+};
+
+/*
+ * Below contains all data related to a single context (formerly called port).
+ */
+struct qib_ctxtdata {
+   void **rcvegrbuf;
+   dma_addr_t *rcvegrbuf_phys;
+   /* rcvhdrq base, needs mmap before useful */
+   void *rcvhdrq;
+   /* kernel virtual address where hdrqtail is updated */
+   void *rcvhdrtail_kvaddr;
+   /*
+* temp buffer for expected send setup, allocated at open, instead
+* of each setup call
+*/
+   void *tid_pg_list;
+   

[PATCH v3 02/52] IB/qib: Add Makefile

2010-05-06 Thread Ralph Campbell
This creates the Makefile file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/Makefile |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Makefile

diff --git a/drivers/infiniband/hw/qib/Makefile 
b/drivers/infiniband/hw/qib/Makefile
new file mode 100644
index 000..c6515a1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_INFINIBAND_QIB) += ib_qib.o
+
+ib_qib-y := qib_cq.o qib_diag.o qib_dma.o qib_driver.o qib_eeprom.o \
+   qib_file_ops.o qib_fs.o qib_init.o qib_intr.o qib_keys.o \
+   qib_mad.o qib_mmap.o qib_mr.o qib_pcie.o qib_pio_copy.o \
+   qib_qp.o qib_qsfp.o qib_rc.o qib_ruc.o qib_sdma.o qib_srq.o \
+   qib_sysfs.o qib_twsi.o qib_tx.o qib_uc.o qib_ud.o \
+   qib_user_pages.o qib_user_sdma.o qib_verbs_mcast.o qib_iba7220.o \
+   qib_sd7220.o qib_sd7220_img.o qib_iba7322.o qib_verbs.o
+
+# 6120 has no fallback if no MSI interrupts, others can do INTx
+ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o
+
+ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
+ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 01/52] IB/qib: Add Kconfig

2010-05-06 Thread Ralph Campbell
This creates the Kconfig file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/Kconfig |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Kconfig

diff --git a/drivers/infiniband/hw/qib/Kconfig 
b/drivers/infiniband/hw/qib/Kconfig
new file mode 100644
index 000..1acfb54
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Kconfig
@@ -0,0 +1,11 @@
+config INFINIBAND_QIB
+   tristate "QLogic PCIe HCA support"
+   depends on 64BIT && NET
+   ---help---
+   This is a driver for QLogic PCIe QLE IB host channel adapters,
+   including InfiniBand verbs support.  This driver allows these
+   devices to be used with both kernel upper level protocols such
+   as IP-over-InfiniBand as well as with userspace applications
+   (in conjunction with InfiniBand userspace access).
+   This driver does not support the QLogic HyperTransport card
+   (model QHT7140).

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/52] IB/qib: add

2010-05-06 Thread Ralph Campbell
The following patches introduce an updated and renamed version of
the ipath HCA driver which supports the QLogic PCIe QLE SDR, DDR,
and QDR series of HCAs.
Rather than try to patch the ipath driver to include support for QDR,
multiple ports, bug fixes, and many other structual changes, the
ib_qib driver replaces the ib_ipath driver.

Changes in v3:

Added .xxx = yyy to qib_dma_mapping_ops initializer.
Added ib_post_send(IB_WR_FAST_REG_MR) support.
Changed ib_register_device() to pass a function for creating the
port sysfs files.
Changed /sys/class/infiniband/qib0/stats to
/sys/class/infiniband/qib0/ports/1/diag_counters/*
Moved /sys/class/infiniband/qib0/ports/1/linkcontrol/qsfp
to ipathfs//qsfp
Removed debug printks until they can be replaced with event tracing.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-05-05 Thread Ralph Campbell
Basically, a struct sk_buff has a pointer to a struct dst_entry
which has a pointer to a struct neighbour. IPoIB uses
struct neighbour.ha to store the IB "hardware address" and a pointer
to a struct ipoib_neigh. When using connected mode, struct ipoib_neigh
has a pointer to struct ipoib_cm_tx which contains pointers back to struct
ipoib_neigh and ipoib_path. The core network code will call
ipoib_neigh_cleanup() when it is destroying struct neighbour and IPoIB
should guarantee that the struct ipoib_neigh and all the memory it points
to are destroyed. Also, the connected mode RC QP contains a pointer back
to the struct ipoib_cm_tx which can be dereferenced in the CQ completion 
handler.
The problem is that there are several places where the struct ipoib_cm_tx
can be used after it has been freed. The easiest way to reproduce this
bug is to run a UDP bandwidth test while loading/unloading the IPoIB module
or ifup/ifdown the interface.
The fix is rather complex since the RC QP connection setup, tear down,
and CQ completion draining are asynchronous processes. The struct ipoib_cm_tx
goes through four "states":
1) created, flags==0, and linked on the priv->cm.start_list.
2) not on the start_list, flags==0, and in the process of creating the RC QP.
3) not on the start_list, flags & IPOIB_FLAG_INITIALIZED, and RC QP created.
4) on the priv->cm.reap_task list or being destroyed by ipoib_cm_tx_reap().

Signed-off-by: Ralph Campbell 
---

I updated the description to be more detailed.
I stripped out as much non-functional code changes as I could.

 drivers/infiniband/ulp/ipoib/ipoib.h   |   14 +
 drivers/infiniband/ulp/ipoib/ipoib_cm.c|  108 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c  |  259 +++-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   76 ++-
 4 files changed, 215 insertions(+), 242 deletions(-)


diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983..5a842d7 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -415,9 +415,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
neighbour *neigh)
 INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
- struct net_device *dev);
-void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
+void ipoib_neigh_flush(struct ipoib_neigh *neigh);
 
 extern struct workqueue_struct *ipoib_workqueue;
 
@@ -464,7 +462,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
-void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+ struct ipoib_neigh *neigh);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -570,6 +569,7 @@ void ipoib_cm_dev_cleanup(struct net_device *dev);
 struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
struct ipoib_neigh *neigh);
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path);
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
   unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
@@ -659,6 +659,12 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
 }
 
 static inline
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
+{
+   return;
+}
+
+static inline
 int ipoib_cm_add_mode_attr(struct net_device *dev)
 {
return 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index bc65837..28c222b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -798,31 +798,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct 
ib_wc *wc)
 
if (wc->status != IB_WC_SUCCESS &&
wc->status != IB_WC_WR_FLUSH_ERR) {
-   struct ipoib_neigh *neigh;
-
ipoib_dbg(priv, "failed cm send event "
   "(status=%d, wrid=%d vend_err %x)\n",
   wc->status, wr_id, wc->vendor_err);
 
spin_lock_irqsave(&priv->lock, flags);
-   neigh = tx->neigh;
-
-   if (neigh) {
-   neigh->cm = NULL;
-   list_del(&neigh->list);
-   if (neigh->ah)
-   ipoib_put_ah(neigh->ah);
-   ipoib_neigh_free(dev, neigh);
-
-   

Re: [PATCH v2 01/51] IB/qib: Add Kconfig

2010-05-05 Thread Ralph Campbell
On Wed, 2010-05-05 at 15:21 -0700, Roland Dreier wrote:
> Ralph, I'd like to look at merging this for 2.6.35.  Could you send your
> latest code?
> 
>  - R.

I haven't switched all the debug printks to event tracing.
I guess I will need to strip those out to get something
ready anytime soon.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-12 Thread Ralph Campbell
On Fri, 2010-04-09 at 17:27 -0700, Jason Gunthorpe wrote:
> On Fri, Apr 09, 2010 at 05:13:24PM -0700, Ralph Campbell wrote:
> 
> > For the QSFP data, I hope I can leave it as is since it is
> > related to the link state that the other files contain.
> > It is a read-only file so no issue with trying to set a value.
> 
> There was some flack for other stuff like this a while back.
> 
> IMHO, it would be appropriate to have a hex dump of the entire QFSP
> EEPROM and leave parsing to userspace, or put the parsed version in
> debugfs..
> 
> Jason

OK. I will move it to our file system which is used
to export binary data.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-09 Thread Ralph Campbell
On Thu, 2010-04-08 at 14:33 -0700, Roland Dreier wrote:
> > This was for debugging and clearly could use a better method.
>  > Some stats are definitely useful and having files per value
>  > would make scripting easier too.
>  > I could add /sys/class/infiniband/qib0/ports/1/diag_counters/*
>  > 
>  > One other place that has multiple values is dumping the QSFP
>  > data from the IB cable.
> 
> You can stick debugging data under debugfs.  Or just kill it for now and
> figure out how to add it back later.

OK. I replaced the /sys/class/infiniband/qib0/stats file with

% ls /sys/class/infiniband/qib0/ports/1/diag_counters/
dmawait pkt_dropsrc_dupreq   rc_seqnakrnr_naks
loop_pkts   rc_acks  rc_qacksrc_timeouts  seq_naks
other_naks  rc_delayed_comp  rc_resends  rdma_seq unaligned

These are all simple counter values.

For the QSFP data, I hope I can leave it as is since it is
related to the link state that the other files contain.
It is a read-only file so no issue with trying to set a value.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-09 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:50 -0700, Jason Gunthorpe wrote:
> On Thu, Apr 08, 2010 at 03:26:41PM -0700, Ralph Campbell wrote:
> > On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
> > > On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
> > > 
> > > > One other place that has multiple values is dumping the QSFP
> > > > data from the IB cable.
> > > 
> > > I was going to comment that building your own I2C subsystem is kinda
> > > strange, can't the in-kernel stuff be used?
> 
> > It is a bit strange but we have had this discussion before with
> > the ib_ipath driver. Basically, the devices connected to the bus
> > weren't really I2C compliant. Since we had to support the
> > non-standard parts, it was easier to have only one set of code
> > that could handle both.
> 
> Is this still true on qib? I didn't notice anything too obviously
> weird, and QSFPs are clearly standard i2c..
> 
> The i2c layer has a pretty flexible definition of i2c these days..
> 
> Jason

I would be very reluctant to change this code.
One device we have doesn't have an i2c address, the "address" is the
address of memory within the chip, not the address of the chip on the
bus.

Reading some of the QSFP cable's EEPROM caused another EEPROM
on the bus to be erased. We had to put in defensive code to
check for this case.

I'm not the expert who wrote this code (he retired) so I would have
to do a lot of work making sure the older parts and cables with
these problems worked after a major rewrite of the code.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 26/51] IB/qib: Add qib_mr.c

2010-04-09 Thread Ralph Campbell
On Tue, 2010-04-06 at 21:15 -0700, Roland Dreier wrote:
> > +struct ib_fmr *qib_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
>  > +   struct ib_fmr_attr *fmr_attr)
> 
> Instead of the crufty old FMR API, I think it would be preferable to
> implement the real IB spec fast registration through a work queue
> stuff.  I understand that it might take some effort to do that but if we
> end up with our newest driver stuck with FMRs, we'll never be able to
> move away from that.

It looks like the IB_WR_FAST_REG_MR operation isn't too hard to
implement so I will add this support.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 16:29 -0700, Roland Dreier wrote:
> > I for one would rather not see this die.  We have debugged some critical
>  > issues using this data.  The sysfs entries above are what Mellanox uses.
>  > Should those also be changed?
> 
> Which sysfs entries?  I don't see any likely looking code in either of
> the Mellanox drivers.
> 
>  - R.

I think Ira means:

# ls /sys/class/infiniband/mlx4_0/diag_counters/
clear_diagrq_num_lqpoerq_num_udsdprd  sq_num_lqpoe   sq_num_rree
num_baddb rq_num_mce  rq_num_wrfe sq_num_mwbesq_num_rsync
num_cqovf rq_num_oos  sq_num_bre  sq_num_oos sq_num_tree
num_eqovf rq_num_rae  sq_num_ieecne   sq_num_rabrte  sq_num_wrfe
rq_num_laerq_num_rire sq_num_ieecse   sq_num_rae
rq_num_leeoe  rq_num_rnr  sq_num_leeoesq_num_rire
rq_num_llerq_num_rsyncsq_num_lle  sq_num_rnr
rq_num_lperq_num_ucsdprd  sq_num_lpe  sq_num_roe


I couldn't find where these entries are added in the kernel.org code.
It is in the OFED tree though.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] IB/core: allow HCAs to create IB port sysfs files

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 13:49 -0700, Roland Dreier wrote:
> Rather than have the device driver call a new function that then calls
> it back, how about if we just add a parameter to the
> ib_register_device() call that is the callback to add the sysfs stuff?
> This would let us avoid the race where the device is registered but not
> all the sysfs stuff is created yet.
> 
>  - R.

I'm not sure this is any less of a race than what I proposed
or the calls to device_create_file() that most IB device drivers
make after calling ib_register_device().

Is the following what you would like to see?
Note that all the hw/*/ drivers have to be changed to call
ib_register_device() with the new parameter.


diff --git a/drivers/infiniband/core/core_priv.h 
b/drivers/infiniband/core/core_priv.h
index 05ac36e..e70c809 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,7 +38,7 @@
 
 #include 
 
-int  ib_device_register_sysfs(struct ib_device *device);
+int  ib_device_register_sysfs(struct ib_device *device, sysfs_cb cb);
 void ib_device_unregister_sysfs(struct ib_device *device);
 
 int  ib_sysfs_setup(void);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index d1fba41..9ef8093 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -267,7 +267,7 @@ out:
  * callback for each device that is added. @device must be allocated
  * with ib_alloc_device().
  */
-int ib_register_device(struct ib_device *device)
+int ib_register_device(struct ib_device *device, sysfs_cb cb)
 {
int ret;
 
@@ -296,7 +296,7 @@ int ib_register_device(struct ib_device *device)
goto out;
}
 
-   ret = ib_device_register_sysfs(device);
+   ret = ib_device_register_sysfs(device, cb);
if (ret) {
printk(KERN_WARNING "Couldn't register device %s with driver 
model\n",
   device->name);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index f901957..a47bac8 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -754,7 +754,23 @@ static struct attribute_group iw_stats_group = {
.attrs  = iw_proto_stats_attrs,
 };
 
-int ib_device_register_sysfs(struct ib_device *device)
+static int sysfs_create_port_files(struct ib_device *device, sysfs_cb cb)
+{
+   struct kobject *p;
+   struct ib_port *port;
+   int ret = 0;
+
+   list_for_each_entry(p, &device->port_list, entry) {
+   port = container_of(p, struct ib_port, kobj);
+   ret = cb(device, port->port_num, &port->kobj);
+   if (ret)
+   break;
+   }
+
+   return ret;
+}
+
+int ib_device_register_sysfs(struct ib_device *device, sysfs_cb cb)
 {
struct device *class_dev = &device->dev;
int ret;
@@ -802,6 +818,12 @@ int ib_device_register_sysfs(struct ib_device *device)
goto err_put;
}
 
+   if (cb) {
+   ret = sysfs_create_port_files(device, cb);
+   if (ret)
+   goto err_put;
+   }
+
return 0;
 
 err_put:
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 6ecd85c..4e446e4 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1189,7 +1189,10 @@ struct ib_client {
 struct ib_device *ib_alloc_device(size_t size);
 void ib_dealloc_device(struct ib_device *device);
 
-int ib_register_device   (struct ib_device *device);
+typedef int (*sysfs_cb)(struct ib_device *dev, u8 port_num,
+   struct kobject *kobj);
+
+int ib_register_device   (struct ib_device *device, sysfs_cb cb);
 void ib_unregister_device(struct ib_device *device);
 
 int ib_register_client   (struct ib_client *client);


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:50 -0700, Jason Gunthorpe wrote:
> On Thu, Apr 08, 2010 at 03:26:41PM -0700, Ralph Campbell wrote:
> > On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
> > > On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
> > > 
> > > > One other place that has multiple values is dumping the QSFP
> > > > data from the IB cable.
> > > 
> > > I was going to comment that building your own I2C subsystem is kinda
> > > strange, can't the in-kernel stuff be used?
> 
> > It is a bit strange but we have had this discussion before with
> > the ib_ipath driver. Basically, the devices connected to the bus
> > weren't really I2C compliant. Since we had to support the
> > non-standard parts, it was easier to have only one set of code
> > that could handle both.
> 
> Is this still true on qib? I didn't notice anything too obviously
> weird, and QSFPs are clearly standard i2c..
> 
> The i2c layer has a pretty flexible definition of i2c these days..
> 
> Jason

I will take another look but don't be surprised if it takes me
awhile since I'm also working on addressing the other comments
too.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
> On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
> 
> > One other place that has multiple values is dumping the QSFP
> > data from the IB cable.
> 
> I was going to comment that building your own I2C subsystem is kinda
> strange, can't the in-kernel stuff be used?
> 
> Jason

It is a bit strange but we have had this discussion before with
the ib_ipath driver. Basically, the devices connected to the bus
weren't really I2C compliant. Since we had to support the
non-standard parts, it was easier to have only one set of code
that could handle both.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
This was for debugging and clearly could use a better method.
Some stats are definitely useful and having files per value
would make scripting easier too.
I could add /sys/class/infiniband/qib0/ports/1/diag_counters/*

One other place that has multiple values is dumping the QSFP
data from the IB cable.

On Thu, 2010-04-08 at 13:50 -0700, Roland Dreier wrote:
> I didn't audit everything (so there may be more problems here too), but
> certainly this violates the "one value per sysfs file" rule rather
> egregiously:
> 
>  > +static ssize_t show_stats(struct device *device, struct device_attribute 
> *attr,
>  > +char *buf)
>  > +{
>  > +  struct qib_ibdev *dev =
>  > +  container_of(device, struct qib_ibdev, ibdev.dev);
>  > +  struct qib_devdata *dd = dd_from_dev(dev);
>  > +  unsigned pidx;
>  > +  unsigned i;
>  > +  int len = 0;
>  > +  unsigned long flags;
>  > +
>  > +  for (pidx = 0; pidx < dd->num_pports; ++pidx) {
>  > +  struct qib_ibport *ibp = &dd->pport[pidx].ibport_data;
>  > +
>  > +  len += sprintf(buf + len,
>  > + "Port %d:\n"
>  > + "RC timeouts %d\n"
>  > + "RC resends  %d\n"
>  > + "RC QACKs%d\n"
>  > + "RC SEQ NAKs %d\n"
>  > + "RC RDMA seq %d\n"
>  > + "RC RNR NAKs %d\n"
>  > + "RC OTH NAKs %d\n"
>  > + "RC DComp%d\n"
>  > + "RCr dup req %d\n"
>  > + "RCr SEQ NAK %d\n"
>  > + "wait piobuf %d\n"
>  > + "wait DMA%d\n"
>  > + "wait TX %d\n"
>  > + "unaligned   %d\n"
>  > + "loop pkts   %d\n"
>  > + "PKT drops   %d\n",
>  > + dd->pport[pidx].port,
>  > + ibp->n_timeouts, ibp->n_rc_resends,
>  > + ibp->n_rc_qacks, ibp->n_seq_naks,
>  > + ibp->n_rdma_seq, ibp->n_rnr_naks,
>  > + ibp->n_other_naks, ibp->n_rc_delayed_comp,
>  > + ibp->n_rc_dupreq, ibp->n_rc_seqnak,
>  > + dev->n_piowait, ibp->n_dmawait, dev->n_txwait,
>  > + ibp->n_unaligned, ibp->n_loop_pkts,
>  > + ibp->n_pkt_drops);
>  > +  for (i = 0; i < ARRAY_SIZE(ibp->opstats); i++) {
>  > +  const struct qib_opcode_stats *si = &ibp->opstats[i];
>  > +
>  > +  if (!si->n_packets && !si->n_bytes)
>  > +  continue;
>  > +  len += sprintf(buf + len, "%02x %llu/%llu\n", i,
>  > + (unsigned long long) si->n_packets,
>  > + (unsigned long long) si->n_bytes);
>  > +  }
>  > +  }
>  > +  len += sprintf(buf + len, "Ctx:npkts");
>  > +  for (i = 0; i < dd->first_user_ctxt; i++) {
>  > +  if (!dd->rcd[i])
>  > +  continue;
>  > +  len += sprintf(buf + len, " %u:%u", i,
>  > + dd->rcd[i]->pkt_count);
>  > +  }
>  > +  len += sprintf(buf + len, "\n");
>  > +  spin_lock_irqsave(&dev->qpt_lock, flags);
>  > +  for (i = 0; i < dev->qp_table_size; i++) {
>  > +  struct qib_qp *qp;
>  > +  for (qp = dev->qp_table[i]; qp != NULL; qp = qp->next) {
>  > +  struct qib_swqe *wqe;
>  > +
>  > +  if (qp->s_last == qp->s_acked &&
>  > +  qp->s_acked == qp->s_cur &&
>  > +  qp->s_cur == qp->s_tail &&
>  > +  qp->s_tail == qp->s_head)
>  > +  continue;
>  > +  if (len + 128 >= PAGE_SIZE)
>  > +  break;
>  > +  wqe = get_swqe_ptr(qp, qp->s_last);
>  > +  len += sprintf(buf + len,
>  > + "QP%u %s %u %u %u f=%x %u %u %u %u %u "
>  > + "PSN %x %x %x %x %x "
>  > + "(%u %u %u %u %u %u) QP%u LID %x\n",
>  > + qp->ibqp.qp_num,
>  > + qp_type_str[qp->ibqp.qp_type],
>  > + qp->state,
>  > + wqe->wr.opcode,
>  > + qp->s_hdrwords,
>  > + qp->s_flags,
>  > + atomic_read(&qp->s_dma_busy),
>  > + !list_empty(&qp->iowait),
>  > + qp->timeout,
>  > + wqe->ssn,
>  > + qp->s_lsn,
>  > + qp->s_last_psn,
>  > + 

Re: [PATCH v2 12/51] IB/qib: Add qib_dma.c

2010-04-08 Thread Ralph Campbell
OK. This will be in v3.

On Wed, 2010-03-31 at 16:18 -0700, Roland Dreier wrote:
> > +struct ib_dma_mapping_ops qib_dma_mapping_ops = {
>  > +  qib_mapping_error,
>  > +  qib_dma_map_single,
>  > +  qib_dma_unmap_single,
>  > +  qib_dma_map_page,
>  > +  qib_dma_unmap_page,
>  > +  qib_map_sg,
>  > +  qib_unmap_sg,
>  > +  qib_sg_dma_address,
>  > +  qib_sg_dma_len,
>  > +  qib_sync_single_for_cpu,
>  > +  qib_sync_single_for_device,
>  > +  qib_dma_alloc_coherent,
>  > +  qib_dma_free_coherent
>  > +};
> 
> I think it would be better to use designated initializers (".xxx = yyy,")
> here to avoid problems if this struct ever changes layout.


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] IB/core: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
The way I understand the sequence of events w/o the
patch is:

ib_req_notify_cq(IB_CQ_NEXT_COMP)
CQE 1 added to queue
callback scheduled via tasklet
future callbacks disarmed
callback function calls ib_req_notify_cq(IB_CQ_NEXT_COMP)
callback function calls ib_poll_cq() and gets CQE 1
callback function calls ib_poll_cq() and gets none
CQE 2 added to queue via IRQ
callback scheduled via tasklet
future callbacks disarmed
callback function returns
some time later, tasklet runs and calls CQ callback function.
callback function calls ib_req_notify_cq(IB_CQ_NEXT_COMP)
callback function calls ib_poll_cq() and gets CQE 2

Since a tasklet or workqueue can be scheduled in the
callback function, the second CQE isn't "missed" but
there is a scheduling delay before the callback happens
and sees CQE 2.

I guess it is a minor optimization since either CQE 2
will be seen in the first callback while looping in ib_poll_cq()
and then getting a callback later with ib_poll_cq()==0 or
seen in the second callback.

I'm willing to withdraw the 1-3 patches.

I still don't understand why the timing difference matters
to RDS.

On Wed, 2010-03-31 at 11:17 -0700, Roland Dreier wrote:
> > ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
>  > a callback for the next completion entered since there is a race
>  > between arming the callback and another CQE being added to the queue.
>  > The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
>  > race and allow the verbs consumer to call ib_poll_cq() and
>  > ib_req_notify_cq() again to avoid delays in processing the CQE.
> 
> I'm not sure I understand the race you're fixing here... the existing
> code does the rearm before polling:
> 
>  > +  int ret;
>  >  
>  >port_priv = container_of(work, struct ib_mad_port_private, work);
>  > -  ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
>  >  
>  > +again:
>  >while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
>  >if (wc.status == IB_WC_SUCCESS) {
>  >switch (wc.opcode) {
>  > @@ -2246,6 +2247,10 @@ static void ib_mad_completion_handler(struct 
> work_struct *work)
>  >} else
>  >mad_error_handler(port_priv, &wc);
>  >}
>  > +  ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP |
>  > +IB_CQ_REPORT_MISSED_EVENTS);
>  > +  if (ret > 0)
>  > +  goto again;
> 
> The only issue with the existing code is that it may trigger extra
> events that will find the CQ empty when polling.
> 
> So this may be a valid optimization but I don't see it fixing any missed
> events.  Am I missing something?
> 
> Also for all these fixes, I think you only want to rearm the CQ once and
> go back and poll if you get a missed events warning; the next time the
> CQ is empty, then you know another event will happen.
> 
>  - R.


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] IB/iser: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/ulp/iser/iser_verbs.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c 
b/drivers/infiniband/ulp/iser/iser_verbs.c
index 308d17b..8cfd1c0 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -783,8 +783,11 @@ static void iser_cq_tasklet_fn(unsigned long data)
 unsigned long   xfer_len;
struct iser_conn *ib_conn;
int completed_tx, completed_rx;
+   int ret;
+
completed_tx = completed_rx = 0;
 
+again:
while (ib_poll_cq(cq, 1, &wc) == 1) {
desc = (struct iser_rx_desc *) (unsigned long) wc.wr_id;
BUG_ON(desc == NULL);
@@ -807,9 +810,10 @@ static void iser_cq_tasklet_fn(unsigned long data)
if (!(completed_rx & 63))
completed_tx += iser_drain_tx_cq(device);
}
-   /* #warning "it is assumed here that arming CQ only once its empty" *
-* " would not cause interrupts to be missed"   */
-   ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP |
+  IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret > 0)
+   goto again;
 
completed_tx += iser_drain_tx_cq(device);
iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx);

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] IB/srp: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/ulp/srp/ib_srp.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/ulp/srp/ib_srp.c 
b/drivers/infiniband/ulp/srp/ib_srp.c
index ed3f9eb..b0376f1 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -921,8 +921,9 @@ static void srp_recv_completion(struct ib_cq *cq, void 
*target_ptr)
 {
struct srp_target_port *target = target_ptr;
struct ib_wc wc;
+   int ret;
 
-   ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+again:
while (ib_poll_cq(cq, 1, &wc) > 0) {
if (wc.status) {
shost_printk(KERN_ERR, target->scsi_host,
@@ -934,6 +935,10 @@ static void srp_recv_completion(struct ib_cq *cq, void 
*target_ptr)
 
srp_handle_recv(target, &wc);
}
+   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP |
+  IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret > 0)
+   goto again;
 }
 
 static void srp_send_completion(struct ib_cq *cq, void *target_ptr)

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] IB/core: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/core/mad.c |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index e351b15..54c413e 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -2226,10 +2226,11 @@ static void ib_mad_completion_handler(struct 
work_struct *work)
 {
struct ib_mad_port_private *port_priv;
struct ib_wc wc;
+   int ret;
 
port_priv = container_of(work, struct ib_mad_port_private, work);
-   ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP);
 
+again:
while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) {
if (wc.status == IB_WC_SUCCESS) {
switch (wc.opcode) {
@@ -2246,6 +2247,10 @@ static void ib_mad_completion_handler(struct work_struct 
*work)
} else
mad_error_handler(port_priv, &wc);
}
+   ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP |
+ IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret > 0)
+   goto again;
 }
 
 static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv)

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] best practice for setting IB_CQ_REPORT_MISSED_EVENTS

2010-03-31 Thread Ralph Campbell
The following patches update ISER, SRP and core to use the
IB_CQ_REPORT_MISSED_EVENTS when calling ib_req_notify_cq()
similar to the patch I sent out for RDS.

Since the QLogic HCAs use a separate thread to generate the CQ callback,
it is important to make sure it isn't delayed more than necessary.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] IB/rds: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-30 Thread Ralph Campbell
On Tue, 2010-03-30 at 16:30 -0700, Roland Dreier wrote:
> > OpenFabrics added a IB_CQ_REPORT_MISSED_EVENTS flag to detect this
> 
> OpenFabrics?  Funny, I thought I added that flag.

You did. I can change the comment if you like.

> (This is not a serious objection ... I'm just being annoying.  Being
> serious, I'm happy to see this used outside of IPoIB and this looks like
> a good optimization)
> 
>  > This patch by itself should improve RDS performance over QLogic HCAs
> 
> Out of curiousity have you measured an improvement?

It is a great improvement over a bunch of printks and then
hitting BUG_ON() in __rds_ib_ring_used().

An actual performance difference will have to wait until
the underlying race is better understood. I thought this
patch might spark a discussion since the code in
rds_ib_send_cq_comp_handler() calls printk_ratelimit()
so the 0xdead message must have been seen before enough
to warrant adding the call and the comment:
/* In the error case, wc.opcode sometimes contains garbage */


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] IB/rds: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-30 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
OpenFabrics added a IB_CQ_REPORT_MISSED_EVENTS flag to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell 
---

This patch by itself should improve RDS performance over QLogic
HCAs.  I was running "qperf rds_bw" tests and would sometimes
see "unexpected opcode 0xdead" messages from
rds_ib_send_cq_comp_handler(). I have looked very closely at the
code and I didn't see any race conditions which would explain
why delaying the completion callback would cause the message but
with this patch, I don't see the error message.

 net/rds/ib_send.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index a10fab6..609ae66 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -187,10 +187,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void 
*context)
 
rdsdebug("cq %p conn %p\n", cq, conn);
rds_ib_stats_inc(s_ib_tx_cq_call);
-   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-   if (ret)
-   rdsdebug("ib_req_notify_cq send failed: %d\n", ret);
 
+again:
while (ib_poll_cq(cq, 1, &wc) > 0) {
rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n",
 (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
@@ -264,6 +262,12 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void 
*context)
&conn->c_faddr, wc.status);
}
}
+   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP |
+  IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret > 0)
+   goto again;
+   if (ret < 0)
+   rdsdebug("ib_req_notify_cq send failed: %d\n", ret);
 }
 
 /*
-- 
1.6.6.1



--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-29 Thread Ralph Campbell
On Sun, 2010-03-28 at 09:02 -0700, Eli Cohen wrote:
> On Thu, Mar 04, 2010 at 10:58:27AM -0800, Ralph Campbell wrote:
> > Subject: [PATCH v3] IB/ipoib: fix dangling pointer references to 
> > ipoib_neigh and ipoib_path
> > 
> > When using connected mode, ipoib_cm_create_tx() kmallocs a
> > struct ipoib_cm_tx which contains pointers to ipoib_neigh and
> > ipoib_path. If the paths are flushed or the struct neighbour is
> > destroyed, the pointers held by struct ipoib_cm_tx can reference
> > freed memory.
> > 
> I could use some more content here as this is quite a large patch.
> Anyway below are some comments. I think besides reviewing this patch
> we need to make sure it has been checked in real life.

Do you mean more details about how ipoib_cm_tx can be used after
being freed or more about how the changes fix the problem?

I have been waiting for our internal regression tests to finish
and to collect review feedback before sending out the final version
of the patch.

> > +/*
> > + * Search the list of connections to be started and remove any entries
> > + * which match the path being destroyed.
> > + *
> > + * This should be called with netif_tx_lock_bh() and priv->lock held.
> > + */
> > +void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
> > +{
> > +   struct ipoib_dev_priv *priv = netdev_priv(dev);
> > +   struct ipoib_cm_tx *tx;
> > +
> > +   list_for_each_entry(tx, &priv->cm.start_list, list) {
> > +   tx = list_entry(priv->cm.start_list.next, typeof(*tx), list);
> > +   if (tx->path == path) {
> > +   tx->path = NULL;
> > +   list_del_init(&tx->list);
> > +   break;
> > +   }
> > }
> >  }
> 
> Looks to me like we may find struct ipoib_cm_tx objects hanging and
> not freed. This could happen if they were just added to start_list and
> removed by ipoib_cm_flush_path() before being processed by
> ipoib_cm_tx_start().

Quite right. I should also use list_for_each_entry_safe().
I will fix this.

> > -static int __path_add(struct net_device *dev, struct ipoib_path *path)
> > +static void __path_add(struct net_device *dev, struct ipoib_path *path)
> >  {
> > struct ipoib_dev_priv *priv = netdev_priv(dev);
> > struct rb_node **n = &priv->path_tree.rb_node;
> > @@ -249,44 +252,26 @@ static int __path_add(struct net_device *dev, struct 
> > ipoib_path *path)
> > n = &pn->rb_left;
> > else if (ret > 0)
> > n = &pn->rb_right;
> > -   else
> > -   return -EEXIST;
> > +   else /* Should never happen since we always search first */
> > +   return;
> > }
> 
> Why not remove the last else and change the "else if" into else?

I don't understand. This is left, right, or return.
I'm only changing the return value to void since it is
never used.

> > }
> > @@ -460,19 +446,13 @@ static void path_rec_completion(int status,
> > memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
> >sizeof(union ib_gid));
> >  
> > -   if (ipoib_cm_enabled(dev, neigh->neighbour)) {
> > -   if (!ipoib_cm_get(neigh))
> > -   ipoib_cm_set(neigh, 
> > ipoib_cm_create_tx(dev,
> > -  
> > path,
> > -  
> > neigh));
> > -   if (!ipoib_cm_get(neigh)) {
> > -   list_del(&neigh->list);
> > -   if (neigh->ah)
> > -   ipoib_put_ah(neigh->ah);
> > -   ipoib_neigh_free(dev, neigh);
> > -   continue;
> > -   }
> > -   }
> ipoib_cm_set() is called only once in neigh_alloc(), setting neigh->cm
> to  NULL, and never again so all calls to ipoib_cm_get() will return
> NULL.

ipoib_cm_set() is only called once since I changed
ipoib_cm_create_tx() to initialize neigh->cm and return void.
To me, it is more clear to let ipoib_cm.c do as much of
the CM specific work as possible instead of defining two
versions of a function for when CM is compiled in or not.
I guess I could change neigh_alloc() to call kzmalloc()
and remove ip

Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
On Thu, 2010-03-11 at 13:52 -0800, Roland Dreier wrote:
> > Sorry, I was referring to my patch not Eli's.
> 
> Heh, I never would have said anything about your patch was "obvious".
> I skimmed yours once but I do want to read it more carefully.
> 
> Did you ever say what test case you are using to provoke the problem you're 
> fixing?

I think I did but it is just UDP stress tests in general.
Throwing in some link failures and switching between connected
and datagram modes helps too. netperf, qperf, etc. should work.
Anything which causes the connected mode QP to fail should
exercise the fix too.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
Sorry, I was referring to my patch not Eli's.

On Thu, 2010-03-11 at 13:41 -0800, Ralph Campbell wrote:
> On Thu, 2010-03-11 at 13:38 -0800, Roland Dreier wrote:
> > good debugging, applied thanks.
> > 
> > I do worry (as Moni mentioned) that this doesn't explain why you would
> > get send failures in this case, but the patch itself is well-explained
> > and looks "obviously correct" so I think we should apply it.
> 
> Well, after more testing it seems there may still be a problem.
> I haven't isolated it yet though. I could definitely use help
> reviewing the code changes.
> 
> ___
> ewg mailing list
> e...@lists.openfabrics.org
> http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
On Thu, 2010-03-11 at 13:38 -0800, Roland Dreier wrote:
> good debugging, applied thanks.
> 
> I do worry (as Moni mentioned) that this doesn't explain why you would
> get send failures in this case, but the patch itself is well-explained
> and looks "obviously correct" so I think we should apply it.

Well, after more testing it seems there may still be a problem.
I haven't isolated it yet though. I could definitely use help
reviewing the code changes.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-04 Thread Ralph Campbell
Subject: [PATCH v3] IB/ipoib: fix dangling pointer references to ipoib_neigh 
and ipoib_path

When using connected mode, ipoib_cm_create_tx() kmallocs a
struct ipoib_cm_tx which contains pointers to ipoib_neigh and
ipoib_path. If the paths are flushed or the struct neighbour is
destroyed, the pointers held by struct ipoib_cm_tx can reference
freed memory.

Signed-off-by: Ralph Campbell 
---

Changes from V1 were to remove the kref_t and avoid the extra locking.
Changes from V2 were to fix a race where a call to ipoib_cm_destroy_tx()
while the struct ipoib_cm_tx was being processed by ipoib_cm_tx_start()
could cause a use after free.

 drivers/infiniband/ulp/ipoib/ipoib.h   |   24 ++-
 drivers/infiniband/ulp/ipoib/ipoib_cm.c|  108 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c  |  267 +++-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   95 +++--
 4 files changed, 225 insertions(+), 269 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983..84bb561 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -415,9 +415,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
neighbour *neigh)
 INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
- struct net_device *dev);
-void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
+void ipoib_neigh_flush(struct ipoib_neigh *neigh);
 
 extern struct workqueue_struct *ipoib_workqueue;
 
@@ -464,7 +462,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
-void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+ struct ipoib_neigh *neigh);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -567,9 +566,10 @@ void ipoib_cm_dev_stop(struct net_device *dev);
 int ipoib_cm_dev_init(struct net_device *dev);
 int ipoib_cm_add_mode_attr(struct net_device *dev);
 void ipoib_cm_dev_cleanup(struct net_device *dev);
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh);
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh);
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path);
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
   unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
@@ -646,10 +646,10 @@ void ipoib_cm_dev_cleanup(struct net_device *dev)
 }
 
 static inline
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh)
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh)
 {
-   return NULL;
+   return;
 }
 
 static inline
@@ -659,6 +659,12 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
 }
 
 static inline
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
+{
+   return;
+}
+
+static inline
 int ipoib_cm_add_mode_attr(struct net_device *dev)
 {
return 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 30bdf42..27f494d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -794,31 +794,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct 
ib_wc *wc)
 
if (wc->status != IB_WC_SUCCESS &&
wc->status != IB_WC_WR_FLUSH_ERR) {
-   struct ipoib_neigh *neigh;
-
ipoib_dbg(priv, "failed cm send event "
   "(status=%d, wrid=%d vend_err %x)\n",
   wc->status, wr_id, wc->vendor_err);
 
spin_lock_irqsave(&priv->lock, flags);
-   neigh = tx->neigh;
-
-   if (neigh) {
-   neigh->cm = NULL;
-   list_del(&neigh->list);
-   if (neigh->ah)
-   ipoib_put_ah(neigh->ah);
-   ipoib_neigh_free(dev, neigh);
-
-   tx->neigh = NULL;
-   }
-
-   if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
-   list_move(&tx->list, &priv-

Re: [PATCH v2] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-02 Thread Ralph Campbell
In my zeal to remove reference counting, I missed a race between
ipoib_cm_destroy_tx() and ipoib_cm_tx_start().
I'm working on patch v3 and should have it ready in a day or two.

On Mon, 2010-03-01 at 17:50 -0800, Ralph Campbell wrote:
> When using connected mode, ipoib_cm_create_tx() kmallocs a
> struct ipoib_cm_tx which contains pointers to ipoib_neigh and
> ipoib_path. If the paths are flushed or the struct neighbour is
> destroyed, the pointers held by struct ipoib_cm_tx can reference
> freed memory.
> 
> Signed-off-by: Ralph Campbell 
> ---
> 
> I was able to remove the kref_t added to struct ipoib_path and ipoib_neigh.
> The key is to delete references to ipoib_neigh and ipoib_path
> when ipoib_neigh_cleanup() is called.
> 
>  drivers/infiniband/ulp/ipoib/ipoib.h   |   24 ++-
>  drivers/infiniband/ulp/ipoib/ipoib_cm.c|  105 +-
>  drivers/infiniband/ulp/ipoib/ipoib_main.c  |  267 
> +++-
>  drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   95 +++--
>  4 files changed, 222 insertions(+), 269 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
> b/drivers/infiniband/ulp/ipoib/ipoib.h
> index 753a983..84bb561 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib.h
> +++ b/drivers/infiniband/ulp/ipoib/ipoib.h
> @@ -415,9 +415,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
> neighbour *neigh)
>  INFINIBAND_ALEN, sizeof(void *));
>  }
> 
> -struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
> - struct net_device *dev);
> -void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
> +void ipoib_neigh_flush(struct ipoib_neigh *neigh);
> 
>  extern struct workqueue_struct *ipoib_workqueue;
> 
> @@ -464,7 +462,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
> 
>  void ipoib_mcast_join_task(struct work_struct *work);
>  void ipoib_mcast_carrier_on_task(struct work_struct *work);
> -void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff 
> *skb);
> +void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff 
> *skb,
> + struct ipoib_neigh *neigh);
> 
>  void ipoib_mcast_restart_task(struct work_struct *work);
>  int ipoib_mcast_start_thread(struct net_device *dev);
> @@ -567,9 +566,10 @@ void ipoib_cm_dev_stop(struct net_device *dev);
>  int ipoib_cm_dev_init(struct net_device *dev);
>  int ipoib_cm_add_mode_attr(struct net_device *dev);
>  void ipoib_cm_dev_cleanup(struct net_device *dev);
> -struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
> ipoib_path *path,
> -   struct ipoib_neigh *neigh);
> +void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
> +   struct ipoib_neigh *neigh);
>  void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
> +void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path);
>  void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
>unsigned int mtu);
>  void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
> @@ -646,10 +646,10 @@ void ipoib_cm_dev_cleanup(struct net_device *dev)
>  }
> 
>  static inline
> -struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
> ipoib_path *path,
> -   struct ipoib_neigh *neigh)
> +void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
> +   struct ipoib_neigh *neigh)
>  {
> -   return NULL;
> +   return;
>  }
> 
>  static inline
> @@ -659,6 +659,12 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
>  }
> 
>  static inline
> +void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
> +{
> +   return;
> +}
> +
> +static inline
>  int ipoib_cm_add_mode_attr(struct net_device *dev)
>  {
> return 0;
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
> b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> index 30bdf42..4ec4ebc 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
> @@ -794,31 +794,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, 
> struct ib_wc *wc)
> 
> if (wc->status != IB_WC_SUCCESS &&
> wc->status != IB_WC_WR_FLUSH_ERR) {
> -   struct ipoib_neigh *neigh;
> -
> ipoib_dbg(priv, "failed cm send event "
>"(status=%d, wrid=%d vend_err %x)\n",
>wc->status, wr_id, wc->vendor_err);
> 
>  

[PATCH v2] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-01 Thread Ralph Campbell
When using connected mode, ipoib_cm_create_tx() kmallocs a
struct ipoib_cm_tx which contains pointers to ipoib_neigh and
ipoib_path. If the paths are flushed or the struct neighbour is
destroyed, the pointers held by struct ipoib_cm_tx can reference
freed memory.

Signed-off-by: Ralph Campbell 
---

I was able to remove the kref_t added to struct ipoib_path and ipoib_neigh.
The key is to delete references to ipoib_neigh and ipoib_path
when ipoib_neigh_cleanup() is called.

 drivers/infiniband/ulp/ipoib/ipoib.h   |   24 ++-
 drivers/infiniband/ulp/ipoib/ipoib_cm.c|  105 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c  |  267 +++-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   95 +++--
 4 files changed, 222 insertions(+), 269 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983..84bb561 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -415,9 +415,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
neighbour *neigh)
 INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
- struct net_device *dev);
-void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
+void ipoib_neigh_flush(struct ipoib_neigh *neigh);
 
 extern struct workqueue_struct *ipoib_workqueue;
 
@@ -464,7 +462,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
-void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+ struct ipoib_neigh *neigh);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -567,9 +566,10 @@ void ipoib_cm_dev_stop(struct net_device *dev);
 int ipoib_cm_dev_init(struct net_device *dev);
 int ipoib_cm_add_mode_attr(struct net_device *dev);
 void ipoib_cm_dev_cleanup(struct net_device *dev);
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh);
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh);
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path);
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
   unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
@@ -646,10 +646,10 @@ void ipoib_cm_dev_cleanup(struct net_device *dev)
 }
 
 static inline
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh)
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh)
 {
-   return NULL;
+   return;
 }
 
 static inline
@@ -659,6 +659,12 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
 }
 
 static inline
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
+{
+   return;
+}
+
+static inline
 int ipoib_cm_add_mode_attr(struct net_device *dev)
 {
return 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 30bdf42..4ec4ebc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -794,31 +794,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct 
ib_wc *wc)
 
if (wc->status != IB_WC_SUCCESS &&
wc->status != IB_WC_WR_FLUSH_ERR) {
-   struct ipoib_neigh *neigh;
-
ipoib_dbg(priv, "failed cm send event "
   "(status=%d, wrid=%d vend_err %x)\n",
   wc->status, wr_id, wc->vendor_err);
 
spin_lock_irqsave(&priv->lock, flags);
-   neigh = tx->neigh;
-
-   if (neigh) {
-   neigh->cm = NULL;
-   list_del(&neigh->list);
-   if (neigh->ah)
-   ipoib_put_ah(neigh->ah);
-   ipoib_neigh_free(dev, neigh);
-
-   tx->neigh = NULL;
-   }
-
-   if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
-   list_move(&tx->list, &priv->cm.reap_list);
-   queue_work(ipoib_workqueue, &priv->cm.reap_task);
-   }
 
clear_bit(IPOIB_FLAG_OPER_UP, &tx->flag

Re: [PATCH] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-02-25 Thread Ralph Campbell
On Thu, 2010-02-25 at 12:15 -0800, Roland Dreier wrote:
> > When using connected mode, ipoib_cm_create_tx() kmallocs a
>  > struct ipoib_cm_tx which contains pointers to ipoib_neigh and
>  > ipoib_path. If the paths are flushed or the struct neighbour is
>  > destroyed, the pointers held by struct ipoib_cm_tx can reference
>  > freed memory. The fix is to add reference counts to struct
>  > ipoib_neigh and ipoib_path and to add locking when getting
>  > new references.
> 
> Good debugging.
> 
> First look at this patch is that it ends up being rather invasive.  I
> wonder if we could fix this in the other direction by keeping a list of
> the ipoib_cm_tx structures affected in the neigh and path structures,
> and clean the cm_tx stuff up when flushing?
> 
> Also I don't see any issues from a first read, but can you confirm that
> you're not adding more locking/atomic ops (via kref) to the main data path?
> 
>  - R.

I agree it is invasive. I thought it would be easier to discuss
an actual patch than me trying to hand wave about a solution.
Plus, now that I understand the problems better, I'm thinking
of new ways to fix them.

There is most definitely a new lock/unlock in the normal send path
because ipoib_start_xmit() now calls neighbour_priv() which
acquires the priv->lock() and does a kref_get(). I'm not really
sure what things can change while ipoib_start_xmit() is active so
I was being cautious. I guess at a minimum, ipoib_neigh_cleanup()
won't be called by the network stack while ipoib_start_xmit() is
active so the to_ipoib_neigh(neighbour) should be valid without
my added locking.

We could avoid adding a kref_t to struct ipoib_path by replacing
the pointer to ipoib_path in struct ipoib_cm_tx with a
struct ib_sa_path_rec. Otherwise, I think ipoib_flush_paths()
could call into ipoib_cm.c to make sure no ipoib_cm_tx is queued
on the priv->cm.start_list which points to the given struct ipoib_path
(and remove it from the list if found).

I will try these ideas out and send an updated patch based
on the results.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-02-25 Thread Ralph Campbell
On Thu, 2010-02-25 at 12:03 -0800, Arthur Kepner wrote:
> On Thu, Feb 25, 2010 at 11:29:02AM -0800, Ralph Campbell wrote:
> >  
> 
> I haven't looked carefully at the whole patch, but this bit 
> looks wrong:
> 
> > @@ -848,61 +823,112 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
> > struct ipoib_neigh *neigh;
> > struct ipoib_dev_priv *priv = netdev_priv(n->dev);
> > unsigned long flags;
> > -   struct ipoib_ah *ah = NULL;
> > +
> > +   spin_lock_irqsave(&priv->lock, flags);
> >  
> > neigh = *to_ipoib_neigh(n);
> > -   if (neigh)
> > -   priv = netdev_priv(neigh->dev);
> > -   else
> > +   if (neigh) {
> 
> Should this be "if (!neigh)" ?
> 
> > +   spin_unlock_irqrestore(&priv->lock, flags);
> > return;
> > +   }
> > +   *to_ipoib_neigh(n) = NULL;
> > +   neigh->neighbour = NULL;
> > +

You are correct.Homer Simpson Doh! :-)
I will send an updated patch after resolving Roland's questions.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-02-25 Thread Ralph Campbell
>From 4a2f3a9685fd82b57e75a31d04d6967d7d9b33c2 Mon Sep 17 00:00:00 2001
From: Ralph Campbell 
Date: Thu, 25 Feb 2010 11:22:02 -0800
Subject: [PATCH] IB/ipoib: fix dangling pointer references to ipoib_neigh and 
ipoib_path

When using connected mode, ipoib_cm_create_tx() kmallocs a
struct ipoib_cm_tx which contains pointers to ipoib_neigh and
ipoib_path. If the paths are flushed or the struct neighbour is
destroyed, the pointers held by struct ipoib_cm_tx can reference
freed memory. The fix is to add reference counts to struct
ipoib_neigh and ipoib_path and to add locking when getting
new references.

Signed-off-by: Ralph Campbell 
---
 drivers/infiniband/ulp/ipoib/ipoib.h   |   42 +++-
 drivers/infiniband/ulp/ipoib/ipoib_cm.c|   91 +++
 drivers/infiniband/ulp/ipoib/ipoib_main.c  |  322 +---
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   94 +++-
 4 files changed, 280 insertions(+), 269 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983..49c9097 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -379,6 +379,7 @@ struct ipoib_path {
struct rb_noderb_node;
struct list_head  list;
int   valid;
+   struct kref   ref;
 };
 
 struct ipoib_neigh {
@@ -393,6 +394,7 @@ struct ipoib_neigh {
struct net_device *dev;
 
struct list_headlist;
+   struct kref ref;
 };
 
 #define IPOIB_UD_MTU(ib_mtu)   (ib_mtu - IPOIB_ENCAP_LEN)
@@ -415,12 +417,33 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
neighbour *neigh)
 INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
- struct net_device *dev);
-void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
+void ipoib_neigh_flush(struct ipoib_neigh *neigh);
+void ipoib_neigh_free(struct kref *kref);
+void ipoib_path_free(struct kref *kref);
 
 extern struct workqueue_struct *ipoib_workqueue;
 
+static inline void ipoib_path_get(struct ipoib_path *path)
+{
+   kref_get(&path->ref);
+}
+
+/* This should not be called while holding priv->lock */
+static inline void ipoib_path_put(struct ipoib_path *path)
+{
+   kref_put(&path->ref, ipoib_path_free);
+}
+
+static inline void ipoib_neigh_get(struct ipoib_neigh *neigh)
+{
+   kref_get(&neigh->ref);
+}
+
+static inline void ipoib_neigh_put(struct ipoib_neigh *neigh)
+{
+   kref_put(&neigh->ref, ipoib_neigh_free);
+}
+
 /* functions */
 
 int ipoib_poll(struct napi_struct *napi, int budget);
@@ -464,7 +487,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
-void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+ struct ipoib_neigh *neigh);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -567,8 +591,8 @@ void ipoib_cm_dev_stop(struct net_device *dev);
 int ipoib_cm_dev_init(struct net_device *dev);
 int ipoib_cm_add_mode_attr(struct net_device *dev);
 void ipoib_cm_dev_cleanup(struct net_device *dev);
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh);
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh);
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
   unsigned int mtu);
@@ -646,10 +670,10 @@ void ipoib_cm_dev_cleanup(struct net_device *dev)
 }
 
 static inline
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh)
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh)
 {
-   return NULL;
+   return;
 }
 
 static inline
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 30bdf42..0a7343e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -794,31 +794,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct 
ib_wc *wc)
 
if (wc->status != IB_WC_SUCCESS &&
wc->status != IB_WC_WR_FLUSH_ERR) {
-   struct ipoib_neigh *neigh;
-
ipoib_dbg(priv, "failed cm send event "
   "(status=%d, wrid=%d vend_err %x)\n

Re: IPoIB memory use after free

2010-02-18 Thread Ralph Campbell
On Wed, 2010-02-17 at 12:08 -0800, Arthur Kepner wrote:
> On Wed, Feb 17, 2010 at 12:02:36PM -0800, Ralph Campbell wrote:
> > I have been tracking down a kernel panic while running qperf udp_bw
> > tests and it looks like ib_ipoib is using memory after freeing it.
> > 
> > The problem is with connected mode. I don't see the panic with
> > datagram mode. Looking at the source code, I see that the process
> > of creating the QP with the connection manager, ipoib_cm_create_tx(),
> > has pointers to struct ipoib_neigh and struct ipoib_path but there
> > doesn't seem to be a reference count or struct completion similar to
> > the way the SA path record look up process has to prevent this.
> > 
> > I'm working on a patch to test this theory but wanted to post
> > this before going too far in case others are already aware
> > of the problem and working on it.
> > 
> 
> Could what you're seeing be related to what's reported here:
> 
> http://lists.openfabrics.org/pipermail/general/2008-April/049629.html

It is related but it is not the same since I'm talking about
struct ipoib_cm_tx holding a stale pointer instead of in
ipoib_neigh_cleanup().

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


IPoIB memory use after free

2010-02-17 Thread Ralph Campbell
I have been tracking down a kernel panic while running qperf udp_bw
tests and it looks like ib_ipoib is using memory after freeing it.

The problem is with connected mode. I don't see the panic with
datagram mode. Looking at the source code, I see that the process
of creating the QP with the connection manager, ipoib_cm_create_tx(),
has pointers to struct ipoib_neigh and struct ipoib_path but there
doesn't seem to be a reference count or struct completion similar to
the way the SA path record look up process has to prevent this.

I'm working on a patch to test this theory but wanted to post
this before going too far in case others are already aware
of the problem and working on it.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] infiniband-diags/ibportstate: allow changes to CA portinfo parameters

2010-01-11 Thread Ralph Campbell
Its been 2 months since I posted this.
What is the current status? Last comment I saw was from Ira
saying either add this functionality to ibportstate or
rename ibportstate but don't split it off into a new command.
My preference is to go with the original patch. I haven't
seen any strong objection to it.

On Thu, 2009-11-05 at 11:56 -0800, Ralph Campbell wrote:
> This patch adds new commands to ibportstate to support initializing
> the link for CAs connected back-to-back. It also allows more than
> one field to be changed at the same time such as "lid 23 arm" or
> "width 1 speed 3 enable".
> 
> Signed-off-by: Ralph Campbell 
> ---
> 
> diff --git a/infiniband-diags/src/ibportstate.c 
> b/infiniband-diags/src/ibportstate.c
> index e631bfd..192b14e 100644
> --- a/infiniband-diags/src/ibportstate.c
> +++ b/infiniband-diags/src/ibportstate.c
> @@ -46,93 +46,133 @@
> 
>  #include "ibdiag_common.h"
> 
> +enum port_ops {
> +   QUERY,
> +   ENABLE,
> +   RESET,
> +   DISABLE,
> +   SPEED,
> +   WIDTH,
> +   DOWN,
> +   ARM,
> +   ACTIVE,
> +   VLS,
> +   MTU,
> +   LID,
> +   SMLID,
> +   LMC,
> +};
> +
>  struct ibmad_port *srcport;
> +int speed = 15;
> +int width = 255;
> +int lid;
> +int smlid;
> +int lmc;
> +int mtu;
> +int vls;
> +
> +struct {
> +   const char *name;
> +   int *val;
> +   int set;
> +} port_args[] = {
> +   { "query", NULL, 0 },   /* QUERY */
> +   { "enable", NULL, 0 },  /* ENABLE */
> +   { "reset", NULL, 0 },   /* RESET */
> +   { "disable", NULL, 0 }, /* DISABLE */
> +   { "speed", &speed, 0 }, /* SPEED */
> +   { "width", &width, 0 }, /* WIDTH */
> +   { "down", NULL, 0 },/* DOWN */
> +   { "arm", NULL, 0 }, /* ARM */
> +   { "active", NULL, 0 },  /* ACTIVE */
> +   { "vls", &vls, 0 }, /* VLS */
> +   { "mtu", &mtu, 0 }, /* MTU */
> +   { "lid", &lid, 0 }, /* LID */
> +   { "smlid", &smlid, 0 }, /* SMLID */
> +   { "lmc", &lmc, 0 }, /* LMC */
> +};
> +
> +#define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0]))
> 
>  /***/
> 
> +/*
> + * Return 1 if port is a switch, else zero.
> + */
>  static int get_node_info(ib_portid_t * dest, uint8_t * data)
>  {
> int node_type;
> 
> if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
> -   return -1;
> +   IBERROR("smp query nodeinfo failed");
> 
> node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
> if (node_type == IB_NODE_SWITCH)/* Switch NodeType ? */
> -   return 0;
> -   else
> return 1;
> +   else
> +   return 0;
>  }
> 
> -static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
> -int port_op)
> +static void get_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
> +{
> +   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, 
> srcport))
> +   IBERROR("smp query portinfo failed");
> +}
> +
> +static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
>  {
> char buf[2048];
> char val[64];
> 
> -   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, 
> srcport))
> -   return -1;
> -
> -   if (port_op != 4) {
> -   mad_dump_portstates(buf, sizeof buf, data, sizeof data);
> -   mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
> -   mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F,
> -  buf + strlen(buf), sizeof buf - strlen(buf),
> -  val);
> -   sprintf(buf + strlen(buf), "%s", "\n");
> -   mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
> -   mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + 
> strlen(buf),
> -  sizeof buf - strlen(buf), val);
> -   sprintf(buf + strlen(buf), "%s", "\n");
> -   mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
> -   mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
> -  sizeof buf - strlen(buf), val);
> -   sprintf(buf + strlen(buf), "%s", "

Re: InfiniBand/RDMA merge plans for 2.6.33

2009-12-14 Thread Ralph Campbell
On Mon, 2009-12-14 at 10:37 -0800, Roland Dreier wrote:

>  - New QLogic qib driver.  Needs at least one more iteration of
>cleanups; and I have not had time to look at the latest code in
>detail to see exactly what cleanups are needed.  I am concerned
>that QLogic chose to abandon the ipath driver as unmaintainable,
>and now wants to replace it with an even bigger driver (measured
>by lines of code) that does not support the HT device that ipath
>supported.  How can we make sure qib has a longer future?

I understand your frustration in having to deal with a large amount
of code. If you included all the Mellanox firmware in the mlx4
driver, it would be huge too. I'm limited in what I can do given
the complexity of the IBTA spec.

QLogic is not "abandoning the ipath driver as unmaintainable".
The thought was that trying to incrementally patch in all the changes
needed to support dual ports, QDR, chip register addresses, etc.
would result in larger patches than renaming the driver. It was a
chicken-and-egg problem because until the new code was fully
written and debugged, we couldn't post it and we couldn't patch
ipath until we knew all the places that needed to be changed.

We had a pretty strong business requirement to get support for 
our QDR product into OFED 1.5 and the IB interrop tests required
we get something into OFED. The chip schedule just didn't leave time
to debug everything, get it reviewed and then merge with OFED.
Also, I was out for 5 weeks and that delayed the submission to
linux-rdma.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/51] updated patches for adding QIB driver

2009-12-09 Thread Ralph Campbell
OK.
Done.

On Wed, 2009-12-09 at 14:47 -0800, Roland Dreier wrote:
> have not had a chance to look at the new submission yet but I think you
> need at least the following rolled in, to avoid calling __exit code that
> might have been thrown away from the error path of your init function.
> 
> Building with CONFIG_DEBUG_SECTION_MISMATCH=y when you see that the
> kernel build tells you that you introduced new section mismatches is
> probably a good idea.
> 
> diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c 
> b/drivers/infiniband/hw/qib/qib_file_ops.c
> index 781c87f..53c314f 100644
> --- a/drivers/infiniband/hw/qib/qib_file_ops.c
> +++ b/drivers/infiniband/hw/qib/qib_file_ops.c
> @@ -2450,7 +2450,7 @@ done:
>   return ret;
>  }
>  
> -void __exit qib_dev_cleanup(void)
> +void qib_dev_cleanup(void)
>  {
>   if (qib_class) {
>   class_destroy(qib_class);

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 51/51] IB/qib: Hooks for adding the QIB driver into the framework

2009-12-03 Thread Ralph Campbell
Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/Kconfig  |1 +
 drivers/infiniband/Makefile |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index dd0db67..c80f973 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -42,6 +42,7 @@ config INFINIBAND_ADDR_TRANS
 
 source "drivers/infiniband/hw/mthca/Kconfig"
 source "drivers/infiniband/hw/ipath/Kconfig"
+source "drivers/infiniband/hw/qib/Kconfig"
 source "drivers/infiniband/hw/ehca/Kconfig"
 source "drivers/infiniband/hw/amso1100/Kconfig"
 source "drivers/infiniband/hw/cxgb3/Kconfig"
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index ed35e44..27b66b1 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_INFINIBAND)   += core/
 obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/
 obj-$(CONFIG_INFINIBAND_IPATH) += hw/ipath/
+obj-$(CONFIG_INFINIBAND_QIB)   += hw/qib/
 obj-$(CONFIG_INFINIBAND_EHCA)  += hw/ehca/
 obj-$(CONFIG_INFINIBAND_AMSO1100)  += hw/amso1100/
 obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 50/51] IB/qib: Add qib_wc_x86_64.c

2009-12-03 Thread Ralph Campbell
creates the qib_wc_x86_64.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_wc_x86_64.c |  187 +
 1 files changed, 187 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_wc_x86_64.c

diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c 
b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
new file mode 100644
index 000..594c198
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+
+/*
+ * This file is conditionally built on x86_64 only.  Otherwise weak symbol
+ * versions of the functions exported from here are used.
+ */
+
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+/**
+ * qib_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: qlogic_ib device
+ *
+ * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable
+ * write combining.
+ */
+int qib_enable_wc(struct qib_devdata *dd)
+{
+   int ret = 0;
+   u64 pioaddr, piolen;
+   unsigned bits;
+   const unsigned long addr = pci_resource_start(dd->pcidev, 0);
+   const size_t len = pci_resource_len(dd->pcidev, 0);
+
+   /*
+* Set the PIO buffers to be WCCOMB, so we get HT bursts to the
+* chip.  Linux (possibly the hardware) requires it to be on a power
+* of 2 address matching the length (which has to be a power of 2).
+* For rev1, that means the base address, for rev2, it will be just
+* the PIO buffers themselves.
+* For chips with two sets of buffers, the calculations are
+* somewhat more complicated; we need to sum, and the piobufbase
+* register has both offsets, 2K in low 32 bits, 4K in high 32 bits.
+* The buffers are still packed, so a single range covers both.
+*/
+   if (dd->piobcnt2k && dd->piobcnt4k) {
+   /* 2 sizes for chip */
+   unsigned long pio2kbase, pio4kbase;
+   pio2kbase = dd->piobufbase & 0xUL;
+   pio4kbase = (dd->piobufbase >> 32) & 0xUL;
+   if (pio2kbase < pio4kbase) {
+   /* all current chips */
+   pioaddr = addr + pio2kbase;
+   piolen = pio4kbase - pio2kbase +
+   dd->piobcnt4k * dd->align4k;
+   } else {
+   pioaddr = addr + pio4kbase;
+   piolen = pio2kbase - pio4kbase +
+   dd->piobcnt2k * dd->palign;
+   }
+   } else {  /* single buffer size (2K, currently) */
+   pioaddr = addr + dd->piobufbase;
+   piolen = dd->piobcnt2k * dd->palign +
+   dd->piobcnt4k * dd->align4k;
+   }
+
+   for (bits = 0; !(piolen & (1ULL << bits)); bits++)
+   /* do nothing */ ;
+
+   if (piolen != (1ULL << bits)) {
+   piolen >>= bits;
+   while (piolen >>= 1)
+   bits++;
+   piolen = 1ULL << (bits + 1);
+   }
+   if (pioaddr & (piolen - 1)) {
+   u64 atmp;
+   qib_dbg("pioaddr %llx not on right boundary for size "
+ "%llx, fixing\n",
+ (unsigned lo

[PATCH v2 49/51] IB/qib: Add qib_wc_ppc64.c

2009-12-03 Thread Ralph Campbell
creates the qib_wc_ppc64.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_wc_ppc64.c |   62 ++
 1 files changed, 62 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_wc_ppc64.c

diff --git a/drivers/infiniband/hw/qib/qib_wc_ppc64.c 
b/drivers/infiniband/hw/qib/qib_wc_ppc64.c
new file mode 100644
index 000..673cf4c
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_wc_ppc64.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * This file is conditionally built on PowerPC only.  Otherwise weak symbol
+ * versions of the functions exported from here are used.
+ */
+
+#include "qib.h"
+
+/**
+ * qib_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: qlogic_ib device
+ *
+ * Nothing to do on PowerPC, so just return without error.
+ */
+int qib_enable_wc(struct qib_devdata *dd)
+{
+   return 0;
+}
+
+/**
+ * qib_unordered_wc - indicate whether write combining is unordered
+ *
+ * Because our performance depends on our ability to do write
+ * combining mmio writes in the most efficient way, we need to
+ * know if we are on a processor that may reorder stores when
+ * write combining.
+ */
+int qib_unordered_wc(void)
+{
+   return 1;
+}

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 48/51] IB/qib: Add qib_verbs_mcast.c

2009-12-03 Thread Ralph Campbell
creates the qib_verbs_mcast.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_verbs_mcast.c |  368 +++
 1 files changed, 368 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_verbs_mcast.c

diff --git a/drivers/infiniband/hw/qib/qib_verbs_mcast.c 
b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
new file mode 100644
index 000..dabb697
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+
+#include "qib.h"
+
+/**
+ * qib_mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct
+ * @qp: the QP to link
+ */
+static struct qib_mcast_qp *qib_mcast_qp_alloc(struct qib_qp *qp)
+{
+   struct qib_mcast_qp *mqp;
+
+   mqp = kmalloc(sizeof *mqp, GFP_KERNEL);
+   if (!mqp)
+   goto bail;
+
+   mqp->qp = qp;
+   atomic_inc(&qp->refcount);
+
+bail:
+   return mqp;
+}
+
+static void qib_mcast_qp_free(struct qib_mcast_qp *mqp)
+{
+   struct qib_qp *qp = mqp->qp;
+
+   /* Notify qib_destroy_qp() if it is waiting. */
+   if (atomic_dec_and_test(&qp->refcount))
+   wake_up(&qp->wait);
+
+   kfree(mqp);
+}
+
+/**
+ * qib_mcast_alloc - allocate the multicast GID structure
+ * @mgid: the multicast GID
+ *
+ * A list of QPs will be attached to this structure.
+ */
+static struct qib_mcast *qib_mcast_alloc(union ib_gid *mgid)
+{
+   struct qib_mcast *mcast;
+
+   mcast = kmalloc(sizeof *mcast, GFP_KERNEL);
+   if (!mcast)
+   goto bail;
+
+   mcast->mgid = *mgid;
+   INIT_LIST_HEAD(&mcast->qp_list);
+   init_waitqueue_head(&mcast->wait);
+   atomic_set(&mcast->refcount, 0);
+   mcast->n_attached = 0;
+
+bail:
+   return mcast;
+}
+
+static void qib_mcast_free(struct qib_mcast *mcast)
+{
+   struct qib_mcast_qp *p, *tmp;
+
+   list_for_each_entry_safe(p, tmp, &mcast->qp_list, list)
+   qib_mcast_qp_free(p);
+
+   kfree(mcast);
+}
+
+/**
+ * qib_mcast_find - search the global table for the given multicast GID
+ * @ibp: the IB port structure
+ * @mgid: the multicast GID to search for
+ *
+ * Returns NULL if not found.
+ *
+ * The caller is responsible for decrementing the reference count if found.
+ */
+struct qib_mcast *qib_mcast_find(struct qib_ibport *ibp, union ib_gid *mgid)
+{
+   struct rb_node *n;
+   unsigned long flags;
+   struct qib_mcast *mcast;
+
+   spin_lock_irqsave(&ibp->lock, flags);
+   n = ibp->mcast_tree.rb_node;
+   while (n) {
+   int ret;
+
+   mcast = rb_entry(n, struct qib_mcast, rb_node);
+
+   ret = memcmp(mgid->raw, mcast->mgid.raw,
+sizeof(union ib_gid));
+   if (ret < 0)
+   n = n->rb_left;
+   else if (ret > 0)
+   n = n->rb_right;
+   else {
+   atomic_inc(&mcast->refcount);
+   spin_unlock_irqrestore(&ibp->lock, flags);
+   goto bail;
+   }
+   }
+   spin_unlock_irqrestore(&ibp->lock, flags);
+
+   mcast = NULL;
+
+bail:
+   return mcast;
+}
+
+/**
+ * qib_mcast_add - insert mcast GID into table and attach QP struct
+ * @mcast: the mcast GID t

[PATCH v2 47/51] IB/qib: Add qib_verbs.h

2009-12-03 Thread Ralph Campbell
creates the qib_verbs.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_verbs.h | 1086 +
 1 files changed, 1086 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_verbs.h

diff --git a/drivers/infiniband/hw/qib/qib_verbs.h 
b/drivers/infiniband/hw/qib/qib_verbs.h
new file mode 100644
index 000..20c8ec1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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.
+ */
+
+#ifndef QIB_VERBS_H
+#define QIB_VERBS_H
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct qib_ctxtdata;
+struct qib_pportdata;
+struct qib_devdata;
+struct qib_verbs_txreq;
+
+#define QIB_MAX_RDMA_ATOMIC 16
+#define QIB_GUIDS_PER_PORT 5
+
+#define QPN_MAX (1 << 24)
+#define QPNMAP_ENTRIES  (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
+
+/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define QIB_UVERBS_ABI_VERSION   2
+
+/*
+ * Define an ib_cq_notify value that is not valid so we know when CQ
+ * notifications are armed.
+ */
+#define IB_CQ_NONE  (IB_CQ_NEXT_COMP + 1)
+
+#define IB_SEQ_NAK (3 << 29)
+
+/* AETH NAK opcode values */
+#define IB_RNR_NAK  0x20
+#define IB_NAK_PSN_ERROR0x60
+#define IB_NAK_INVALID_REQUEST  0x61
+#define IB_NAK_REMOTE_ACCESS_ERROR  0x62
+#define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63
+#define IB_NAK_INVALID_RD_REQUEST   0x64
+
+/* Flags for checking QP state (see ib_qib_state_ops[]) */
+#define QIB_POST_SEND_OK0x01
+#define QIB_POST_RECV_OK0x02
+#define QIB_PROCESS_RECV_OK 0x04
+#define QIB_PROCESS_SEND_OK 0x08
+#define QIB_PROCESS_NEXT_SEND_OK0x10
+#define QIB_FLUSH_SEND 0x20
+#define QIB_FLUSH_RECV 0x40
+#define QIB_PROCESS_OR_FLUSH_SEND \
+   (QIB_PROCESS_SEND_OK | QIB_FLUSH_SEND)
+
+/* IB Performance Manager status values */
+#define IB_PMA_SAMPLE_STATUS_DONE   0x00
+#define IB_PMA_SAMPLE_STATUS_STARTED0x01
+#define IB_PMA_SAMPLE_STATUS_RUNNING0x02
+
+/* Mandatory IB performance counter select values. */
+#define IB_PMA_PORT_XMIT_DATA   cpu_to_be16(0x0001)
+#define IB_PMA_PORT_RCV_DATAcpu_to_be16(0x0002)
+#define IB_PMA_PORT_XMIT_PKTS   cpu_to_be16(0x0003)
+#define IB_PMA_PORT_RCV_PKTScpu_to_be16(0x0004)
+#define IB_PMA_PORT_XMIT_WAIT   cpu_to_be16(0x0005)
+
+#define QIB_VENDOR_IPG cpu_to_be16(0xFFA0)
+
+#define IB_BTH_REQ_ACK (1 << 31)
+#define IB_BTH_SOLICITED   (1 << 23)
+#define IB_BTH_MIG_REQ (1 << 22)
+
+/* XXX Should be defined in ib_verbs.h enum ib_port_cap_flags */
+#define IB_PORT_OTHER_LOCAL_CHANGES_SUP (1 << 26)
+
+#define IB_GRH_VERSION 6
+#define IB_GRH_VERSION_MASK0xF
+#define IB_GRH_VERSION_SHIFT   28
+#define IB_GRH_TCLASS_MASK 0xFF
+#define IB_GRH_TCLASS_SHIFT20
+#define IB_GRH_FLOW_MASK   0xF
+#define IB_GRH_FLOW_SHIFT  0
+#define IB_GRH_NEXT_HDR0x1B
+
+#define IB_DEFAULT_GID_PREFIX  cpu_to_be64(0xfe80ULL)
+
+/* Values for set/get portinfo VLCap OperationalVLs */
+#define IB_VL_VL0   1
+#define IB_VL_VL0_1 2
+#define IB_VL_VL0_3 3
+#define IB_VL_VL0_7 4
+#define IB_VL_VL0_145
+
+static inline int qib_num_vls(int 

[PATCH v2 45/51] IB/qib: Add qib_user_sdma.h

2009-12-03 Thread Ralph Campbell
creates the qib_user_sdma.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_user_sdma.h |   52 +
 1 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.h

diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.h 
b/drivers/infiniband/hw/qib/qib_user_sdma.h
new file mode 100644
index 000..ce8cbaf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include 
+
+struct qib_user_sdma_queue;
+
+struct qib_user_sdma_queue *
+qib_user_sdma_queue_create(struct device *dev, int unit, int port, int sport);
+void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq);
+
+int qib_user_sdma_writev(struct qib_ctxtdata *pd,
+struct qib_user_sdma_queue *pq,
+const struct iovec *iov,
+unsigned long dim);
+
+int qib_user_sdma_make_progress(struct qib_pportdata *ppd,
+   struct qib_user_sdma_queue *pq);
+
+void qib_user_sdma_queue_drain(struct qib_pportdata *ppd,
+  struct qib_user_sdma_queue *pq);
+
+u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq);
+u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq);

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 44/51] IB/qib: Add qib_user_sdma.c

2009-12-03 Thread Ralph Campbell
creates the qib_user_sdma.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_user_sdma.c |  909 +
 1 files changed, 909 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.c

diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c 
b/drivers/infiniband/hw/qib/qib_user_sdma.c
new file mode 100644
index 000..869244e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 2007, 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_user_sdma.h"
+
+/* minimum size of header */
+#define QIB_USER_SDMA_MIN_HEADER_LENGTH 64
+/* expected size of headers (for dma_pool) */
+#define QIB_USER_SDMA_EXP_HEADER_LENGTH 64
+
+struct qib_user_sdma_pkt {
+   u8 naddr;   /* dimension of addr (1..3) ... */
+   u32 counter;/* sdma pkts queued counter for this entry */
+   u64 added;  /* global descq number of entries */
+
+   struct {
+   u32 offset; /* offset for kvaddr, addr */
+   u32 length; /* length in page */
+   u8  put_page;   /* should we put_page? */
+   u8  dma_mapped; /* is page dma_mapped? */
+   struct page *page;  /* may be NULL (coherent mem) */
+   void *kvaddr;   /* FIXME: only for pio hack */
+   dma_addr_t addr;
+   } addr[4];   /* max pages, any more and we coalesce */
+   struct list_head list;  /* list element */
+};
+
+struct qib_user_sdma_queue {
+   /*
+* pkts sent to dma engine are queued on this
+* list head.  the type of the elements of this
+* list are struct qib_user_sdma_pkt...
+*/
+   struct list_head sent;
+
+   /* headers with expected length are allocated from here... */
+   char header_cache_name[64];
+   struct dma_pool *header_cache;
+
+   /* packets are allocated from the slab cache... */
+   char pkt_slab_name[64];
+   struct kmem_cache *pkt_slab;
+
+   /* as packets go on the queued queue, they are counted... */
+   u32 counter;
+   u32 sent_counter;
+
+   /* dma page table */
+   struct rb_root dma_pages_root;
+
+   /* protect everything above... */
+   struct mutex lock;
+};
+
+struct qib_user_sdma_queue *
+qib_user_sdma_queue_create(struct device *dev, int unit, int ctxt, int sctxt)
+{
+   struct qib_user_sdma_queue *pq =
+   kmalloc(sizeof(struct qib_user_sdma_queue), GFP_KERNEL);
+
+   if (!pq)
+   goto done;
+
+   pq->counter = 0;
+   pq->sent_counter = 0;
+   INIT_LIST_HEAD(&pq->sent);
+
+   mutex_init(&pq->lock);
+
+   snprintf(pq->pkt_slab_name, sizeof(pq->pkt_slab_name),
+"qib-user-sdma-pkts-%u-%02u.%02u", unit, ctxt, sctxt);
+   pq->pkt_slab = kmem_cache_create(pq->pkt_slab_name,
+sizeof(struct qib_user_sdma_pkt),
+0, 0, NULL);
+
+   if (!pq->pkt_slab)
+   goto err_kfree;
+
+   snprintf(pq->header_cache_name, sizeof(pq->header_cache_name),
+"qib-user-sdma-headers-%u-%02u.%02u&

[PATCH v2 43/51] IB/qib: Add qib_user_pages.c

2009-12-03 Thread Ralph Campbell
creates the qib_user_pages.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_user_pages.c |  163 
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_pages.c

diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c 
b/drivers/infiniband/hw/qib/qib_user_pages.c
new file mode 100644
index 000..a0406a2
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_pages.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+
+#include "qib.h"
+
+static void __qib_release_user_pages(struct page **p, size_t num_pages,
+int dirty)
+{
+   size_t i;
+
+   for (i = 0; i < num_pages; i++) {
+   qib_cdbg(MM, "%lu/%lu put_page %p\n", (unsigned long) i,
+(unsigned long) num_pages, p[i]);
+   if (dirty)
+   set_page_dirty_lock(p[i]);
+   put_page(p[i]);
+   }
+}
+
+/*
+ * Call with current->mm->mmap_sem held.
+ */
+static int __get_user_pages(unsigned long start_page, size_t num_pages,
+   struct page **p, struct vm_area_struct **vma)
+{
+   unsigned long lock_limit;
+   size_t got;
+   int ret;
+
+   lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
+   PAGE_SHIFT;
+
+   if (num_pages > lock_limit) {
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   qib_cdbg(VERBOSE, "pin %lx pages from vaddr %lx\n",
+(unsigned long) num_pages, start_page);
+
+   for (got = 0; got < num_pages; got += ret) {
+   ret = get_user_pages(current, current->mm,
+start_page + got * PAGE_SIZE,
+num_pages - got, 1, 1,
+p + got, vma);
+   if (ret < 0)
+   goto bail_release;
+   }
+
+   current->mm->locked_vm += num_pages;
+
+   ret = 0;
+   goto bail;
+
+bail_release:
+   __qib_release_user_pages(p, got, 0);
+bail:
+   return ret;
+}
+
+/**
+ * qib_map_page - a safety wrapper around pci_map_page()
+ *
+ * A dma_addr of all 0's is interpreted by the chip as "disabled".
+ * Unfortunately, it can also be a valid dma_addr returned on some
+ * architectures.
+ *
+ * The powerpc iommu assigns dma_addrs in ascending order, so we don't
+ * have to bother with retries or mapping a dummy page to insure we
+ * don't just get the same mapping again.
+ *
+ * I'm sure we won't be so lucky with other iommu's, so FIXME.
+ */
+dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page,
+   unsigned long offset, size_t size, int direction)
+{
+   dma_addr_t phys;
+
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+
+   if (phys == 0) {
+   pci_unmap_page(hwdev, phys, size, direction);
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+   /*
+* FIXME: If we get 0 again, we should keep this page,
+* map another, then free the 0 page.
+*/
+   }
+
+   return phys;
+}
+
+/**
+ * qib_get_user_pages - lock user pages into memory
+ * @start_page: the start page
+ * 

[PATCH v2 42/51] IB/qib: Add qib_ud.c

2009-12-03 Thread Ralph Campbell
creates the qib_ud.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_ud.c |  607 
 1 files changed, 607 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ud.c

diff --git a/drivers/infiniband/hw/qib/qib_ud.c 
b/drivers/infiniband/hw/qib/qib_ud.c
new file mode 100644
index 000..c838cda
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+
+#include "qib.h"
+#include "qib_mad.h"
+
+/**
+ * qib_ud_loopback - handle send on loopback QPs
+ * @sqp: the sending QP
+ * @swqe: the send work request
+ *
+ * This is called from qib_make_ud_req() to forward a WQE addressed
+ * to the same HCA.
+ * Note that the receive interrupt handler may be calling qib_ud_rcv()
+ * while this is being called.
+ */
+static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe)
+{
+   struct qib_ibport *ibp = to_iport(sqp->ibqp.device, sqp->port_num);
+   struct qib_pportdata *ppd;
+   struct qib_qp *qp;
+   struct ib_ah_attr *ah_attr;
+   unsigned long flags;
+   struct qib_sge_state ssge;
+   struct qib_sge *sge;
+   struct ib_wc wc;
+   u32 length;
+
+   qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn);
+   if (!qp) {
+   ibp->n_pkt_drops++;
+   return;
+   }
+   if (qp->ibqp.qp_type != sqp->ibqp.qp_type ||
+   !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) {
+   ibp->n_pkt_drops++;
+   goto drop;
+   }
+
+   ah_attr = &to_iah(swqe->wr.wr.ud.ah)->attr;
+   ppd = ppd_from_ibp(ibp);
+
+   if (qp->ibqp.qp_num > 1) {
+   u16 pkey1;
+   u16 pkey2;
+   u16 lid;
+
+   pkey1 = qib_get_pkey(ibp, sqp->s_pkey_index);
+   pkey2 = qib_get_pkey(ibp, qp->s_pkey_index);
+   if (unlikely(!qib_pkey_ok(pkey1, pkey2))) {
+   lid = ppd->lid | (ah_attr->src_path_bits &
+ ((1 << ppd->lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey1,
+ ah_attr->sl,
+ sqp->ibqp.qp_num, qp->ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(ah_attr->dlid));
+   goto drop;
+   }
+   }
+
+   /*
+* Check that the qkey matches (except for QP0, see 9.6.1.4.1).
+* Qkeys with the high order bit set mean use the
+* qkey from the QP context instead of the WR (see 10.2.5).
+*/
+   if (qp->ibqp.qp_num) {
+   u32 qkey;
+
+   qkey = (int)swqe->wr.wr.ud.remote_qkey < 0 ?
+   sqp->qkey : swqe->wr.wr.ud.remote_qkey;
+   if (unlikely(qkey != qp->qkey)) {
+   u16 lid;
+
+   lid = ppd->lid | (ah_attr->src_path_bits &
+ ((1 << ppd->lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
+ ah_attr->sl,
+ sqp->ibqp.qp_num, qp->ibqp.qp_num,

[PATCH v2 41/51] IB/qib: Add qib_uc.c

2009-12-03 Thread Ralph Campbell
creates the qib_uc.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_uc.c |  586 
 1 files changed, 586 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_uc.c

diff --git a/drivers/infiniband/hw/qib/qib_uc.c 
b/drivers/infiniband/hw/qib/qib_uc.c
new file mode 100644
index 000..f077489
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_uc.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 "qib.h"
+
+/* cut down ridiculously long IB macro names */
+#define OP(x) IB_OPCODE_UC_##x
+
+/**
+ * qib_make_uc_req - construct a request packet (SEND, RDMA write)
+ * @qp: a pointer to the QP
+ *
+ * Return 1 if constructed; otherwise, return 0.
+ */
+int qib_make_uc_req(struct qib_qp *qp)
+{
+   struct qib_other_headers *ohdr;
+   struct qib_swqe *wqe;
+   unsigned long flags;
+   u32 hwords;
+   u32 bth0;
+   u32 len;
+   u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu);
+   int ret = 0;
+
+   spin_lock_irqsave(&qp->s_lock, flags);
+
+   if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_SEND_OK)) {
+   if (!(ib_qib_state_ops[qp->state] & QIB_FLUSH_SEND))
+   goto bail;
+   /* We are in the error state, flush the work request. */
+   if (qp->s_last == qp->s_head)
+   goto bail;
+   /* If DMAs are in progress, we can't flush immediately. */
+   if (atomic_read(&qp->s_dma_busy)) {
+   qp->s_flags |= QIB_S_WAIT_DMA;
+   goto bail;
+   }
+   wqe = get_swqe_ptr(qp, qp->s_last);
+   qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+   goto done;
+   }
+
+   ohdr = &qp->s_hdr.u.oth;
+   if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
+   ohdr = &qp->s_hdr.u.l.oth;
+
+   /* header size in 32-bit words LRH+BTH = (8+12)/4. */
+   hwords = 5;
+   bth0 = 1 << 22; /* Set M bit */
+
+   /* Get the next send request. */
+   wqe = get_swqe_ptr(qp, qp->s_cur);
+   qp->s_wqe = NULL;
+   switch (qp->s_state) {
+   default:
+   if (!(ib_qib_state_ops[qp->state] &
+   QIB_PROCESS_NEXT_SEND_OK))
+   goto bail;
+   /* Check if send work queue is empty. */
+   if (qp->s_cur == qp->s_head)
+   goto bail;
+   /*
+* Start a new request.
+*/
+   wqe->psn = qp->s_next_psn;
+   qp->s_psn = qp->s_next_psn;
+   qp->s_sge.sge = wqe->sg_list[0];
+   qp->s_sge.sg_list = wqe->sg_list + 1;
+   qp->s_sge.num_sge = wqe->wr.num_sge;
+   qp->s_sge.total_len = wqe->length;
+   len = wqe->length;
+   qp->s_len = len;
+   switch (wqe->wr.opcode) {
+   case IB_WR_SEND:
+   case IB_WR_SEND_WITH_IMM:
+   if (len > pmtu) {
+   qp->s_state = OP(SEND_FIRST);
+   len = pmtu;
+   break;
+   }
+   if (wqe->wr.opcode == IB_WR_SEND)
+

[PATCH v2 40/51] IB/qib: Add qib_tx.c

2009-12-03 Thread Ralph Campbell
creates the qib_tx.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_tx.c |  585 
 1 files changed, 585 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_tx.c

diff --git a/drivers/infiniband/hw/qib/qib_tx.c 
b/drivers/infiniband/hw/qib/qib_tx.c
new file mode 100644
index 000..7d77f29
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_tx.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+static unsigned qib_hol_timeout_ms = 3000;
+module_param_named(hol_timeout_ms, qib_hol_timeout_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(hol_timeout_ms,
+"duration of user app suspension after link failure");
+
+unsigned qib_sdma_fetch_arb = 1;
+module_param_named(fetch_arb, qib_sdma_fetch_arb, uint, S_IRUGO);
+MODULE_PARM_DESC(fetch_arb, "IBA7220: change SDMA descriptor arbitration");
+
+/**
+ * qib_disarm_piobufs - cancel a range of PIO buffers
+ * @dd: the qlogic_ib device
+ * @first: the first PIO buffer to cancel
+ * @cnt: the number of PIO buffers to cancel
+ *
+ * Cancel a range of PIO buffers. Used at user process close,
+ * in case it died while writing to a PIO buffer.
+ */
+void qib_disarm_piobufs(struct qib_devdata *dd, unsigned first, unsigned cnt)
+{
+   unsigned long flags;
+   unsigned i;
+   unsigned last;
+
+   qib_cdbg(ERRPKT, "disarm %u PIObufs first=%u\n", cnt, first);
+   last = first + cnt;
+   spin_lock_irqsave(&dd->pioavail_lock, flags);
+   for (i = first; i < last; i++) {
+   __clear_bit(i, dd->pio_need_disarm);
+   dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   spin_unlock_irqrestore(&dd->pioavail_lock, flags);
+}
+
+/*
+ * This is called by a user process when it sees the DISARM_BUFS event
+ * bit is set.
+ */
+int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd)
+{
+   struct qib_devdata *dd = rcd->dd;
+   unsigned i;
+   unsigned last;
+   unsigned n = 0;
+
+   last = rcd->pio_base + rcd->piocnt;
+   /*
+* Don't need uctxt_lock here, since user has called in to us.
+* Clear at start in case more interrupts set bits while we
+* are disarming
+*/
+   if (rcd->user_event_mask) {
+   /*
+* subctxt_cnt is 0 if not shared, so do base
+* separately, first, then remaining subctxt, if any
+*/
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT, &rcd->user_event_mask[0]);
+   for (i = 1; i < rcd->subctxt_cnt; i++)
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT,
+ &rcd->user_event_mask[i]);
+   }
+   spin_lock_irq(&dd->pioavail_lock);
+   for (i = rcd->pio_base; i < last; i++) {
+   if (__test_and_clear_bit(i, dd->pio_need_disarm)) {
+   n++;
+   dd->f_sendctrl(rcd->ppd, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   }
+   spin_unlock_irq(&dd->pioavail_lock);
+   qib_cdbg(ERRPKT, "Ctxt%u, User disarm (%u bufs (%u-%u)) done\n",
+   rcd->ctxt, n, rcd->pio_base, last);
+   return 0;
+}
+
+static struct qib_pportdata *is_sdma_buf(struct qib_devdata *dd, unsigned i)
+{
+   struct qib_pportda

[PATCH v2 39/51] IB/qib: Add qib_twsi.c

2009-12-03 Thread Ralph Campbell
creates the qib_twsi.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_twsi.c |  521 ++
 1 files changed, 521 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_twsi.c

diff --git a/drivers/infiniband/hw/qib/qib_twsi.c 
b/drivers/infiniband/hw/qib/qib_twsi.c
new file mode 100644
index 000..a9a1c92
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_twsi.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * QLogic_IB "Two Wire Serial Interface" driver.
+ * Originally written for a not-quite-i2c serial eeprom, which is
+ * still used on some supported boards. Later boards have added a
+ * variety of other uses, most board-specific, so teh bit-boffing
+ * part has been split off to this file, while the other parts
+ * have been moved to chip-specific files.
+ *
+ * We have also dropped all pretense of fully generic (e.g. pretend
+ * we don't know whether '1' is the higher voltage) interface, as
+ * the restrictions of the generic i2c interface (e.g. no access from
+ * driver itself) make it unsuitable for this use.
+ */
+
+#define READ_CMD 1
+#define WRITE_CMD 0
+
+/**
+ * i2c_wait_for_writes - wait for a write
+ * @dd: the qlogic_ib device
+ *
+ * We use this instead of udelay directly, so we can make sure
+ * that previous register writes have been flushed all the way
+ * to the chip.  Since we are delaying anyway, the cost doesn't
+ * hurt, and makes the bit twiddling more regular
+ */
+static void i2c_wait_for_writes(struct qib_devdata *dd)
+{
+   /*
+* implicit read of EXTStatus is as good as explicit
+* read of scratch, if all we want to do is flush
+* writes.
+*/
+   dd->f_gpio_mod(dd, 0, 0, 0);
+   rmb(); /* inlined, so prevent compiler reordering */
+}
+
+/*
+ * QSFP modules are allowed to hold SCL low for 500uSec. Allow twice that
+ * for "almost compliant" modules
+ */
+#define SCL_WAIT_USEC 1000
+
+/* BUF_WAIT is time bus must be free between STOP or ACK and to next START.
+ * Should be 20, but some chips need more.
+ */
+#define TWSI_BUF_WAIT_USEC 60
+
+static void scl_out(struct qib_devdata *dd, u8 bit)
+{
+   u32 mask;
+
+   udelay(1);
+
+   mask = 1UL << dd->gpio_scl_num;
+
+   /* SCL is meant to be bare-drain, so never set "OUT", just DIR */
+   dd->f_gpio_mod(dd, 0, bit ? 0 : mask, mask);
+
+   /*
+* Allow for slow slaves by simple
+* delay for falling edge, sampling on rise.
+*/
+   if (!bit)
+   udelay(2);
+   else {
+   int rise_usec;
+   for (rise_usec = SCL_WAIT_USEC; rise_usec > 0; rise_usec -= 2) {
+   if (mask & dd->f_gpio_mod(dd, 0, 0, 0))
+   break;
+   udelay(2);
+   }
+   if (rise_usec <= 0)
+   qib_dev_err(dd, "TWSI SCL stuck low > %d uSec\n",
+   SCL_WAIT_USEC);
+   }
+   i2c_wait_for_writes(dd);
+}
+
+static void sda_out(struct qib_devdata *dd, u8 bit)
+{
+   u32 mask;
+
+   mask = 1UL << dd->gpio_sda_num;
+
+   /* SDA is meant to be bare-drain, so never set "OUT", just DIR */
+   dd->f_gpio_mod(dd, 0,

[PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2009-12-03 Thread Ralph Campbell
creates the qib_sysfs.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_sysfs.c |  736 +
 1 files changed, 736 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sysfs.c

diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c 
b/drivers/infiniband/hw/qib/qib_sysfs.c
new file mode 100644
index 000..747005a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sysfs.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+
+#include "qib.h"
+
+/**
+ * qib_parse_ushort - parse an unsigned short value in an arbitrary base
+ * @str: the string containing the number
+ * @valp: where to put the result
+ *
+ * Returns the number of bytes consumed, or negative value on error.
+ */
+static int qib_parse_ushort(const char *str, unsigned short *valp)
+{
+   unsigned long val;
+   char *end;
+   int ret;
+
+   if (!isdigit(str[0])) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   val = simple_strtoul(str, &end, 0);
+
+   if (val > 0x) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   *valp = val;
+
+   ret = end + 1 - str;
+   if (ret == 0)
+   ret = -EINVAL;
+
+bail:
+   return ret;
+}
+
+/* start of per-port functions */
+/*
+ * Get/Set heartbeat enable. OR of 1=enabled, 2=auto
+ */
+static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf)
+{
+   struct qib_devdata *dd = ppd->dd;
+   int ret;
+
+   ret = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT);
+   ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret);
+   return ret;
+}
+
+static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf,
+  size_t count)
+{
+   struct qib_devdata *dd = ppd->dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, &val);
+
+   /*
+* Set the "intentional" heartbeat enable per either of
+* "Enable" and "Auto", as these are normally set together.
+* This bit is consulted when leaving loopback mode,
+* because entering loopback mode overrides it and automatically
+* disables heartbeat.
+*/
+   if (ret >= 0)
+   ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val);
+   if (ret < 0)
+   qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n");
+   return ret < 0 ? ret : count;
+}
+
+static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd->dd;
+   int ret = count, r;
+
+   r = dd->f_set_ib_loopback(ppd, buf);
+   if (r < 0)
+   ret = r;
+
+   return ret;
+}
+
+static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd->dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, &val);
+   if (ret > 0)
+   qib_set_led_override(ppd, val);
+   else
+   qib_dev_err(dd, "attempt to set invalid LED override\n");
+   return ret < 0 ? ret : count;
+}
+
+static ssize_t show_qsfp(struct qib_pportdata *ppd, char *buf)
+{
+   ssize_t ret;
+
+   ret = qib_qsfp_dump(ppd, buf, PAGE_SIZE);

[PATCH v2 37/51] IB/qib: Add qib_srq.c

2009-12-03 Thread Ralph Campbell
creates the qib_srq.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_srq.c |  374 +++
 1 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_srq.c

diff --git a/drivers/infiniband/hw/qib/qib_srq.c 
b/drivers/infiniband/hw/qib/qib_srq.c
new file mode 100644
index 000..d79ae33
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_srq.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib_verbs.h"
+
+/**
+ * qib_post_srq_receive - post a receive on a shared receive queue
+ * @ibsrq: the SRQ to post the receive on
+ * @wr: the list of work requests to post
+ * @bad_wr: A pointer to the first WR to cause a problem is put here
+ *
+ * This may be called from interrupt context.
+ */
+int qib_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+struct ib_recv_wr **bad_wr)
+{
+   struct qib_srq *srq = to_isrq(ibsrq);
+   struct qib_rwq *wq;
+   unsigned long flags;
+   int ret;
+
+   for (; wr; wr = wr->next) {
+   struct qib_rwqe *wqe;
+   u32 next;
+   int i;
+
+   if ((unsigned) wr->num_sge > srq->rq.max_sge) {
+   *bad_wr = wr;
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   spin_lock_irqsave(&srq->rq.lock, flags);
+   wq = srq->rq.wq;
+   next = wq->head + 1;
+   if (next >= srq->rq.size)
+   next = 0;
+   if (next == wq->tail) {
+   spin_unlock_irqrestore(&srq->rq.lock, flags);
+   *bad_wr = wr;
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   wqe = get_rwqe_ptr(&srq->rq, wq->head);
+   wqe->wr_id = wr->wr_id;
+   wqe->num_sge = wr->num_sge;
+   for (i = 0; i < wr->num_sge; i++)
+   wqe->sg_list[i] = wr->sg_list[i];
+   /* Make sure queue entry is written before the head index. */
+   smp_wmb();
+   wq->head = next;
+   spin_unlock_irqrestore(&srq->rq.lock, flags);
+   }
+   ret = 0;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_create_srq - create a shared receive queue
+ * @ibpd: the protection domain of the SRQ to create
+ * @srq_init_attr: the attributes of the SRQ
+ * @udata: data from libibverbs when creating a user SRQ
+ */
+struct ib_srq *qib_create_srq(struct ib_pd *ibpd,
+ struct ib_srq_init_attr *srq_init_attr,
+ struct ib_udata *udata)
+{
+   struct qib_ibdev *dev = to_idev(ibpd->device);
+   struct qib_srq *srq;
+   u32 sz;
+   struct ib_srq *ret;
+
+   if (srq_init_attr->attr.max_sge == 0 ||
+   srq_init_attr->attr.max_sge > ib_qib_max_srq_sges ||
+   srq_init_attr->attr.max_wr == 0 ||
+   srq_init_attr->attr.max_wr > ib_qib_max_srq_wrs) {
+   ret = ERR_PTR(-EINVAL);
+   goto done;
+   }
+
+   srq = kmalloc(sizeof(*srq), GFP_KERNEL);
+   if (!srq) {
+   ret = ERR_PTR(-ENOMEM);
+   goto done;
+   }
+
+   /*
+* Need

[PATCH v2 36/51] IB/qib: Add qib_sdma.c

2009-12-03 Thread Ralph Campbell
creates the qib_sdma.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_sdma.c | 1037 ++
 1 files changed, 1037 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sdma.c

diff --git a/drivers/infiniband/hw/qib/qib_sdma.c 
b/drivers/infiniband/hw/qib/qib_sdma.c
new file mode 100644
index 000..4b58f26
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sdma.c
@@ -0,0 +1,1037 @@
+/*
+ * Copyright (c) 2007, 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/* default pio off, sdma on */
+static ushort sdma_descq_cnt = 256;
+module_param_named(sdma_descq_cnt, sdma_descq_cnt, ushort, S_IRUGO);
+MODULE_PARM_DESC(sdma_descq_cnt, "Number of SDMA descq entries");
+
+/*
+ * Bits defined in the send DMA descriptor.
+ */
+#define SDMA_DESC_LAST  (1ULL << 11)
+#define SDMA_DESC_FIRST (1ULL << 12)
+#define SDMA_DESC_DMA_HEAD  (1ULL << 13)
+#define SDMA_DESC_USE_LARGE_BUF (1ULL << 14)
+#define SDMA_DESC_INTR  (1ULL << 15)
+#define SDMA_DESC_COUNT_LSB 16
+#define SDMA_DESC_GEN_LSB   30
+
+char *qib_sdma_state_names[] = {
+   [qib_sdma_state_s00_hw_down]  = "s00_HwDown",
+   [qib_sdma_state_s10_hw_start_up_wait] = "s10_HwStartUpWait",
+   [qib_sdma_state_s20_idle] = "s20_Idle",
+   [qib_sdma_state_s30_sw_clean_up_wait] = "s30_SwCleanUpWait",
+   [qib_sdma_state_s40_hw_clean_up_wait] = "s40_HwCleanUpWait",
+   [qib_sdma_state_s50_hw_halt_wait] = "s50_HwHaltWait",
+   [qib_sdma_state_s99_running]  = "s99_Running",
+};
+
+char *qib_sdma_event_names[] = {
+   [qib_sdma_event_e00_go_hw_down]   = "e00_GoHwDown",
+   [qib_sdma_event_e10_go_hw_start]  = "e10_GoHwStart",
+   [qib_sdma_event_e20_hw_started]   = "e20_HwStarted",
+   [qib_sdma_event_e30_go_running]   = "e30_GoRunning",
+   [qib_sdma_event_e40_sw_cleaned]   = "e40_SwCleaned",
+   [qib_sdma_event_e50_hw_cleaned]   = "e50_HwCleaned",
+   [qib_sdma_event_e60_hw_halted]= "e60_HwHalted",
+   [qib_sdma_event_e70_go_idle]  = "e70_GoIdle",
+   [qib_sdma_event_e7220_err_halted] = "e7220_ErrHalted",
+   [qib_sdma_event_e7322_err_halted] = "e7322_ErrHalted",
+   [qib_sdma_event_e90_timer_tick]   = "e90_TimerTick",
+};
+
+/* declare all statics here rather than keep sorting */
+static int alloc_sdma(struct qib_pportdata *);
+static void sdma_complete(struct kref *);
+static void sdma_finalput(struct qib_sdma_state *);
+static void sdma_get(struct qib_sdma_state *);
+static void sdma_put(struct qib_sdma_state *);
+static void sdma_set_state(struct qib_pportdata *, enum qib_sdma_states);
+static void sdma_start_sw_clean_up(struct qib_pportdata *);
+static void sdma_sw_clean_up_task(unsigned long);
+static void unmap_desc(struct qib_pportdata *, unsigned);
+
+static void sdma_get(struct qib_sdma_state *ss)
+{
+   kref_get(&ss->kref);
+}
+
+static void sdma_complete(struct kref *kref)
+{
+   struct qib_sdma_state *ss =
+   container_of(kref, struct qib_sdma_state, kref);
+
+   complete(&ss->comp);
+}
+
+static void sdma_put(struct qib_sdma_state *ss)
+{
+   kref_put(&ss->kref, sdma_complete);
+}
+
+static void sdma_fi

[PATCH v2 35/51] IB/qib: Add qib_sd7220_img.c

2009-12-03 Thread Ralph Campbell
creates the qib_sd7220_img.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_sd7220_img.c | 1081 
 1 files changed, 1081 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220_img.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220_img.c 
b/drivers/infiniband/hw/qib/qib_sd7220_img.c
new file mode 100644
index 000..a1118fb
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220_img.c
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * This file contains the memory image from the vendor, to be copied into
+ * the IB SERDES of the IBA7220 during initialization.
+ * The file also includes the two functions which use this image.
+ */
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_7220.h"
+
+static unsigned char qib_sd7220_ib_img[] = {
+/**/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6,
+   0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01,
+   0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08,
+/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08,
+   0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2,
+/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7,
+   0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00,
+/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75,
+   0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5,
+/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38,
+   0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94,
+/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36,
+   0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74,
+/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90,
+   0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20,
+/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3,
+   0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12,
+/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04,
+   0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09,
+/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+   0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2,
+/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09,
+   0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24,
+/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83,
+   0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3,
+/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0,
+   0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03,
+/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4,
+   0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E,
+/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82,
+   0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44,
+/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40,
+   0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54,
+/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44,
+   0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08,
+/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF,
+   0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40,
+/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75,
+   0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E,
+/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD,
+   0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81,
+/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED,
+   0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF,
+/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0,
+   0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12,
+/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32,
+   0x02, 0x03, 0xF6

[PATCH v2 34/51] IB/qib: Add qib_sd7220.c

2009-12-03 Thread Ralph Campbell
creates the qib_sd7220.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_sd7220.c | 1442 
 1 files changed, 1442 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c 
b/drivers/infiniband/hw/qib/qib_sd7220.c
new file mode 100644
index 000..2230a09
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220.c
@@ -0,0 +1,1442 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+/*
+ * This file contains all of the code that is specific to the SerDes
+ * on the QLogic_IB 7220 chip.
+ */
+
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_7220.h"
+
+/*
+ * Same as in qib_iba7220.c, but just the registers needed here.
+ * Could move whole set to qib_7220.h, but decided better to keep
+ * local.
+ */
+#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64))
+#define kr_hwerrclear KREG_IDX(HwErrClear)
+#define kr_hwerrmask KREG_IDX(HwErrMask)
+#define kr_hwerrstatus KREG_IDX(HwErrStatus)
+#define kr_ibcstatus KREG_IDX(IBCStatus)
+#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl)
+#define kr_scratch KREG_IDX(Scratch)
+#define kr_xgxs_cfg KREG_IDX(XGXSCfg)
+/* these are used only here, not in qib_iba7220.c */
+#define kr_ibsd_epb_access_ctrl KREG_IDX(ibsd_epb_access_ctrl)
+#define kr_ibsd_epb_transaction_reg KREG_IDX(ibsd_epb_transaction_reg)
+#define kr_pciesd_epb_transaction_reg KREG_IDX(pciesd_epb_transaction_reg)
+#define kr_pciesd_epb_access_ctrl KREG_IDX(pciesd_epb_access_ctrl)
+#define kr_serdes_ddsrxeq0 KREG_IDX(SerDes_DDSRXEQ0)
+
+/*
+ * The IBSerDesMappTable is a memory that holds values to be stored in
+ * various SerDes registers by IBC.
+ */
+#define kr_serdes_maptable KREG_IDX(IBSerDesMappTable)
+
+/*
+ * Below used for sdnum parameter, selecting one of the two sections
+ * used for PCIe, or the single SerDes used for IB.
+ */
+#define PCIE_SERDES0 0
+#define PCIE_SERDES1 1
+
+/*
+ * The EPB requires addressing in a particular form. EPB_LOC() is intended
+ * to make #definitions a little more readable.
+ */
+#define EPB_ADDR_SHF 8
+#define EPB_LOC(chn, elt, reg) \
+   (((elt & 0xf) | ((chn & 7) << 4) | ((reg & 0x3f) << 9)) << \
+EPB_ADDR_SHF)
+#define EPB_IB_QUAD0_CS_SHF (25)
+#define EPB_IB_QUAD0_CS (1U <<  EPB_IB_QUAD0_CS_SHF)
+#define EPB_IB_UC_CS_SHF (26)
+#define EPB_PCIE_UC_CS_SHF (27)
+#define EPB_GLOBAL_WR (1U << (EPB_ADDR_SHF + 8))
+
+/* Forward declarations. */
+static int qib_sd7220_reg_mod(struct qib_devdata *dd, int sdnum, u32 loc,
+ u32 data, u32 mask);
+static int ibsd_mod_allchnls(struct qib_devdata *dd, int loc, int val,
+int mask);
+static int qib_sd_trimdone_poll(struct qib_devdata *dd);
+static void qib_sd_trimdone_monitor(struct qib_devdata *dd, const char *where);
+static int qib_sd_setvals(struct qib_devdata *dd);
+static int qib_sd_early(struct qib_devdata *dd);
+static int qib_sd_dactrim(struct qib_devdata *dd);
+static int qib_internal_presets(struct qib_devdata *dd);
+/* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */
+static int qib_sd_trimself(struct qib_devdata *dd, int val);
+static int epb_access(struct qib_devdata *dd, int sdnum, int claim);
+
+/*
+ * Below keeps track of whether the "once per power-on" initialization has
+ * been done, because uC c

[PATCH v2 33/51] IB/qib: Add qib_ruc.c

2009-12-03 Thread Ralph Campbell
creates the qib_ruc.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_ruc.c |  817 +++
 1 files changed, 817 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ruc.c

diff --git a/drivers/infiniband/hw/qib/qib_ruc.c 
b/drivers/infiniband/hw/qib/qib_ruc.c
new file mode 100644
index 000..eb78d93
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ruc.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+
+#include "qib.h"
+#include "qib_mad.h"
+
+/*
+ * Convert the AETH RNR timeout code into the number of microseconds.
+ */
+const u32 ib_qib_rnr_table[32] = {
+   655360, /* 00: 655.36 */
+   10, /* 01:.01 */
+   20, /* 02 .02 */
+   30, /* 03:.03 */
+   40, /* 04:.04 */
+   60, /* 05:.06 */
+   80, /* 06:.08 */
+   120,/* 07:.12 */
+   160,/* 08:.16 */
+   240,/* 09:.24 */
+   320,/* 0A:.32 */
+   480,/* 0B:.48 */
+   640,/* 0C:.64 */
+   960,/* 0D:.96 */
+   1280,   /* 0E:   1.28 */
+   1920,   /* 0F:   1.92 */
+   2560,   /* 10:   2.56 */
+   3840,   /* 11:   3.84 */
+   5120,   /* 12:   5.12 */
+   7680,   /* 13:   7.68 */
+   10240,  /* 14:  10.24 */
+   15360,  /* 15:  15.36 */
+   20480,  /* 16:  20.48 */
+   30720,  /* 17:  30.72 */
+   40960,  /* 18:  40.96 */
+   61440,  /* 19:  61.44 */
+   81920,  /* 1A:  81.92 */
+   122880, /* 1B: 122.88 */
+   163840, /* 1C: 163.84 */
+   245760, /* 1D: 245.76 */
+   327680, /* 1E: 327.68 */
+   491520  /* 1F: 491.52 */
+};
+
+/*
+ * Validate a RWQE and fill in the SGE state.
+ * Return 1 if OK.
+ */
+static int qib_init_sge(struct qib_qp *qp, struct qib_rwqe *wqe)
+{
+   int i, j, ret;
+   struct ib_wc wc;
+   struct qib_lkey_table *rkt;
+   struct qib_pd *pd;
+   struct qib_sge_state *ss;
+
+   rkt = &to_idev(qp->ibqp.device)->lk_table;
+   pd = to_ipd(qp->ibqp.srq ? qp->ibqp.srq->pd : qp->ibqp.pd);
+   ss = &qp->r_sge;
+   ss->sg_list = qp->r_sg_list;
+   qp->r_len = 0;
+   for (i = j = 0; i < wqe->num_sge; i++) {
+   if (wqe->sg_list[i].length == 0)
+   continue;
+   /* Check LKEY */
+   if (!qib_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
+&wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE))
+   goto bad_lkey;
+   qp->r_len += wqe->sg_list[i].length;
+   j++;
+   }
+   ss->num_sge = j;
+   ss->total_len = qp->r_len;
+   ret = 1;
+   goto bail;
+
+bad_lkey:
+   while (j) {
+   struct qib_sge *sge = --j ? &ss->sg_list[j - 1] : &ss->sge;
+
+   atomic_dec(&sge->mr->refcount);
+   }
+   ss->num_sge = 0;
+   memset(&wc, 0, sizeof(wc));
+   wc.wr_id = wqe->wr_id;
+   wc.status = IB_WC_LOC_PROT_ERR;
+   wc.opcode = IB_WC_RECV;
+   wc.qp = &qp->ibqp;
+   /* Signal solicited completion event. */
+   qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
+   ret = 0;
+bail:
+   return ret;
+}
+
+/**
+ * qib_get_rwqe - copy the next RWQE 

[PATCH v2 31/51] IB/qib: Add qib_qsfp.h

2009-12-03 Thread Ralph Campbell
creates the qib_qsfp.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qsfp.h |  183 ++
 1 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.h

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h 
b/drivers/infiniband/hw/qib/qib_qsfp.h
new file mode 100644
index 000..01ea507
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+/* QSFP support common definitions, for ib_qib driver */
+
+#define QSFP_DEV 0xA0
+#define QSFP_PWR_LAG_MSEC 2000
+
+/*
+ * Below are masks for various QSFP signals, for Port 1.
+ * Port2 equivalents are shifted by QSFP_GPIO_PORT2_SHIFT.
+ * _N means asserted low
+ */
+#define QSFP_GPIO_MOD_SEL_N (4)
+#define QSFP_GPIO_MOD_PRS_N (8)
+#define QSFP_GPIO_INT_N (0x10)
+#define QSFP_GPIO_MOD_RST_N (0x20)
+#define QSFP_GPIO_LP_MODE (0x40)
+#define QSFP_GPIO_PORT2_SHIFT 5
+
+#define QSFP_PAGESIZE 128
+/* Defined fields that QLogic requires of qualified cables */
+/* Byte 0 is Identifier, not checked */
+/* Byte 1 is reserved "status MSB" */
+/* Byte 2 is "status LSB" We only care that D2 "Flat Mem" is set. */
+/*
+ * Rest of first 128 not used, although 127 is reserved for page select
+ * if module is not "Flat memory".
+ */
+/* Byte 128 is Identifier: must be 0x0c for QSFP, or 0x0d for QSFP+ */
+#define QSFP_MOD_ID_OFFS 128
+/*
+ * Byte 129 is "Extended Identifier". We only care about D7,D6: Power class
+ *  0:1.5W, 1:2.0W, 2:2.5W, 3:3.5W
+ */
+#define QSFP_MOD_PWR_OFFS 129
+/* Byte 130 is Connector type. Not QLogic req'd */
+/* Bytes 131..138 are Transceiver types, bit maps for various tech, none IB */
+/* Byte 139 is encoding. code 0x01 is 8b10b. Not QLogic req'd */
+/* byte 140 is nominal bit-rate, in units of 100Mbits/sec Not QLogic req'd */
+/* Byte 141 is Extended Rate Select. Not QLogic req'd */
+/* Bytes 142..145 are lengths for various fiber types. Not QLogic req'd */
+/* Byte 146 is length for Copper. Units of 1 meter */
+#define QSFP_MOD_LEN_OFFS 146
+/*
+ * Byte 147 is Device technology. D0..3 not Qlogc req'd
+ * D4..7 select from 15 choices, translated by table:
+ */
+#define QSFP_MOD_TECH_OFFS 147
+extern const char *const qib_qsfp_devtech[16];
+/* Length is only valid if technology is "copper" */
+#define QSFP_IS_CU(tech) ((0xED00 >> ((tech) >> 4)) & 1)
+#define QSFP_TECH_1490 9
+
+#define QSFP_OUI(oui) (((unsigned)oui[0] << 16) | ((unsigned)oui[1] << 8) | \
+   oui[2])
+#define QSFP_OUI_AMPHENOL 0x415048
+#define QSFP_OUI_FINISAR  0x009065
+#define QSFP_OUI_GORE 0x002177
+
+/* Bytes 148..163 are Vendor Name, Left-justified Blank-filled */
+#define QSFP_VEND_OFFS 148
+#define QSFP_VEND_LEN 16
+/* Byte 164 is IB Extended tranceiver codes Bits D0..3 are SDR,DDR,QDR,EDR */
+#define QSFP_IBXCV_OFFS 164
+/* Bytes 165..167 are Vendor OUI number */
+#define QSFP_VOUI_OFFS 165
+#define QSFP_VOUI_LEN 3
+/* Bytes 168..183 are Vendor Part Number, string */
+#define QSFP_PN_OFFS 168
+#define QSFP_PN_LEN 16
+/* Bytes 184,185 are Vendor Rev. Left Justified, Blank-filled */
+#define QSFP_REV_OFFS 184
+#define QSFP_REV_LEN 2
+/*
+ * Bytes 186,187 are Wavelength, if Optical. Not Qlogic req'd
+ *  If copper, they are attenuation in dB:
+ * Byte 186 is at 2.5Gb/sec (SDR), By

[PATCH v2 30/51] IB/qib: Add qib_qsfp.c

2009-12-03 Thread Ralph Campbell
creates the qib_qsfp.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qsfp.c |  593 ++
 1 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.c

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c 
b/drivers/infiniband/hw/qib/qib_qsfp.c
new file mode 100644
index 000..5ffeddf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_qsfp.h"
+
+/*
+ * QSFP support for ib_qib driver, using "Two Wire Serial Interface" driver
+ * in qib_twsi.c
+ */
+#define QSFP_MAX_RETRY 4
+
+static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
+{
+   struct qib_devdata *dd = ppd->dd;
+   u32 out, mask;
+   int ret, cnt, pass = 0;
+   int stuck = 0;
+   u8 *buff = bp;
+
+   qib_cdbg(VERBOSE, "Grabbing Mutex for QSFP in %d:%d\n", dd->unit,
+ppd->port);
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (ret)
+   goto no_unlock;
+
+   if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
+   qib_dbg("QSFP read on board without QSFP\n");
+   ret = -ENXIO;
+   goto bail;
+   }
+
+   /*
+* We presume, if we are called at all, that this board has
+* QSFP. This is on the same i2c chain as the legacy parts,
+* but only responds if the module is selected via GPIO pins.
+* Further, there are very long setup and hold requirements
+* on MODSEL.
+*/
+   mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   if (ppd->hw_pidx) {
+   mask <<= QSFP_GPIO_PORT2_SHIFT;
+   out <<= QSFP_GPIO_PORT2_SHIFT;
+   }
+
+   dd->f_gpio_mod(dd, out, mask, mask);
+
+   /*
+* Module could take up to 2 Msec to respond to MOD_SEL, and there
+* is no way to tell if it is ready, so we must wait.
+*/
+   msleep(2);
+
+   /* Make sure TWSI bus is in sane state. */
+   ret = qib_twsi_reset(dd);
+   if (ret) {
+   qib_dev_porterr(dd, ppd->port, "TWSI Reset failed, QSFP Rd\n");
+   ret = -EIO;
+   stuck = 1;
+   goto deselect;
+   }
+
+   /* All QSFP modules are at A0 */
+
+   cnt = 0;
+   while (cnt < len) {
+   unsigned in_page;
+   int wlen = len - cnt;
+   in_page = addr % QSFP_PAGESIZE;
+   if ((in_page + wlen) > QSFP_PAGESIZE)
+   wlen = QSFP_PAGESIZE - in_page;
+   ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
+   /* Some QSFP's fail first try. Retry as experiment */
+   if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY)
+   continue;
+   if (ret) {
+   /* qib_twsi_blk_rd() 1 for error, else 0 */
+   ret = -EIO;
+   goto deselect;
+   }
+   addr += wlen;
+   cnt += wlen;
+   }
+   ret = cnt;
+
+deselect:
+   /*
+* Module could take up to 10 u

[PATCH v2 28/51] IB/qib: Add qib_pio_copy.c

2009-12-03 Thread Ralph Campbell
creates the qib_pio_copy.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_pio_copy.c |   64 ++
 1 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pio_copy.c

diff --git a/drivers/infiniband/hw/qib/qib_pio_copy.c 
b/drivers/infiniband/hw/qib/qib_pio_copy.c
new file mode 100644
index 000..10b8c44
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pio_copy.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "qib.h"
+
+/**
+ * qib_pio_copy - copy data to MMIO space, in multiples of 32-bits
+ * @to: destination, in MMIO space (must be 64-bit aligned)
+ * @from: source (must be 64-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from kernel space to MMIO space, in multiples of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void qib_pio_copy(void __iomem *to, const void *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+   u64 __iomem *dst = to;
+   const u64 *src = from;
+   const u64 *end = src + (count >> 1);
+
+   while (src < end)
+   __raw_writeq(*src++, dst++);
+   if (count & 1)
+   __raw_writel(*(const u32 *)src, dst);
+#else
+   u32 __iomem *dst = to;
+   const u32 *src = from;
+   const u32 *end = src + count;
+
+   while (src < end)
+   __raw_writel(*src++, dst++);
+#endif
+}

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 29/51] IB/qib: Add qib_qp.c

2009-12-03 Thread Ralph Campbell
creates the qib_qp.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_qp.c | 1241 
 1 files changed, 1241 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qp.c

diff --git a/drivers/infiniband/hw/qib/qib_qp.c 
b/drivers/infiniband/hw/qib/qib_qp.c
new file mode 100644
index 000..d0ccbf5
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -0,0 +1,1241 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib.h"
+
+#define BITS_PER_PAGE   (PAGE_SIZE*BITS_PER_BYTE)
+#define BITS_PER_PAGE_MASK  (BITS_PER_PAGE-1)
+
+static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
+ struct qpn_map *map, unsigned off)
+{
+   return (map - qpt->map) * BITS_PER_PAGE + off;
+}
+
+static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
+   struct qpn_map *map, unsigned off,
+   unsigned r)
+{
+   if (qpt->mask) {
+   off++;
+   if ((off & qpt->mask) >> 1 != r)
+   off = ((off & qpt->mask) ?
+   (off | qpt->mask) + 1 : off) | (r << 1);
+   } else
+   off = find_next_zero_bit(map->page, BITS_PER_PAGE, off);
+   return off;
+}
+
+/*
+ * Convert the AETH credit code into the number of credits.
+ */
+static u32 credit_table[31] = {
+   0,  /* 0 */
+   1,  /* 1 */
+   2,  /* 2 */
+   3,  /* 3 */
+   4,  /* 4 */
+   6,  /* 5 */
+   8,  /* 6 */
+   12, /* 7 */
+   16, /* 8 */
+   24, /* 9 */
+   32, /* A */
+   48, /* B */
+   64, /* C */
+   96, /* D */
+   128,/* E */
+   192,/* F */
+   256,/* 10 */
+   384,/* 11 */
+   512,/* 12 */
+   768,/* 13 */
+   1024,   /* 14 */
+   1536,   /* 15 */
+   2048,   /* 16 */
+   3072,   /* 17 */
+   4096,   /* 18 */
+   6144,   /* 19 */
+   8192,   /* 1A */
+   12288,  /* 1B */
+   16384,  /* 1C */
+   24576,  /* 1D */
+   32768   /* 1E */
+};
+
+static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
+{
+   unsigned long page = get_zeroed_page(GFP_KERNEL);
+
+   /*
+* Free the page if someone raced with us installing it.
+*/
+
+   spin_lock(&qpt->lock);
+   if (map->page)
+   free_page(page);
+   else
+   map->page = (void *)page;
+   spin_unlock(&qpt->lock);
+}
+
+/*
+ * Allocate the next available QPN or
+ * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
+ */
+static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
+enum ib_qp_type type, u8 port)
+{
+   u32 i, offset, max_scan, qpn;
+

[PATCH v2 27/51] IB/qib: Add qib_pcie.c

2009-12-03 Thread Ralph Campbell
creates the qib_pcie.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_pcie.c |  810 ++
 1 files changed, 810 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pcie.c

diff --git a/drivers/infiniband/hw/qib/qib_pcie.c 
b/drivers/infiniband/hw/qib/qib_pcie.c
new file mode 100644
index 000..714cad4
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * This file contains PCIe utility routines that are common to the
+ * various QLogic InfiniPath adapters
+ */
+
+/*
+ * Code to adjust PCIe capabilities.
+ * To minimize the change footprint, we call it
+ * from qib_pcie_params, which every chip-specific
+ * file calls, even though this violates some
+ * expectations of harmlessness.
+ */
+static int qib_tune_pcie_caps(struct qib_devdata *);
+static int qib_tune_pcie_coalesce(struct qib_devdata *);
+
+/*
+ * Do all the common PCIe setup and initialization.
+ * devdata is not yet allocated, and is not allocated until after this
+ * routine returns success.  Therefore qib_dev_err() can't be used for error
+ * printing.
+ */
+int qib_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+   int ret;
+
+   ret = pci_enable_device(pdev);
+   if (ret) {
+   /*
+* This can happen (in theory) iff:
+* We did a chip reset, and then failed to reprogram the
+* BAR, or the chip reset due to an internal error.  We then
+* unloaded the driver and reloaded it.
+*
+* Both reset cases set the BAR back to initial state.  For
+* the latter case, the AER sticky error bit at offset 0x718
+* should be set, but the Linux kernel doesn't yet know
+* about that, it appears.  If the original BAR was retained
+* in the kernel data structures, this may be OK.
+*/
+   qib_early_err(&pdev->dev, "pci enable failed: error %d\n",
+ -ret);
+   goto done;
+   }
+
+   ret = pci_request_regions(pdev, QIB_DRV_NAME);
+   if (ret) {
+   qib_devinfo(pdev, "pci_request_regions fails: err %d\n", -ret);
+   goto bail;
+   }
+
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret) {
+   /*
+* If the 64 bit setup fails, try 32 bit.  Some systems
+* do not setup 64 bit maps on systems with 2GB or less
+* memory installed.
+*/
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (ret) {
+   qib_devinfo(pdev, "Unable to set DMA mask: %d\n", ret);
+   goto bail;
+   }
+   qib_dbg("No 64bit DMA mask, used 32 bit mask\n");
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+   } else
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret)
+   qib_early_err(&pdev->dev,
+ "Unable to set DMA consistent mask: %d\n", ret);
+
+   pci_set_master(pdev);
+   ret = pci_enable_pcie_error_reporting(pdev);
+   if (ret)
+   qib_ea

[PATCH v2 26/51] IB/qib: Add qib_mr.c

2009-12-03 Thread Ralph Campbell
creates the qib_mr.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mr.c |  455 
 1 files changed, 455 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mr.c

diff --git a/drivers/infiniband/hw/qib/qib_mr.c 
b/drivers/infiniband/hw/qib/qib_mr.c
new file mode 100644
index 000..f283c3b
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib.h"
+
+/* Fast memory region */
+struct qib_fmr {
+   struct ib_fmr ibfmr;
+   u8 page_shift;
+   struct qib_mregion mr;/* must be last */
+};
+
+static inline struct qib_fmr *to_ifmr(struct ib_fmr *ibfmr)
+{
+   return container_of(ibfmr, struct qib_fmr, ibfmr);
+}
+
+/**
+ * qib_get_dma_mr - get a DMA memory region
+ * @pd: protection domain for this memory region
+ * @acc: access flags
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ * Note that all DMA addresses should be created via the
+ * struct ib_dma_mapping_ops functions (see qib_dma.c).
+ */
+struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc)
+{
+   struct qib_ibdev *dev = to_idev(pd->device);
+   struct qib_mr *mr;
+   struct ib_mr *ret;
+   unsigned long flags;
+
+   if (to_ipd(pd)->user) {
+   ret = ERR_PTR(-EPERM);
+   goto bail;
+   }
+
+   mr = kzalloc(sizeof *mr, GFP_KERNEL);
+   if (!mr) {
+   ret = ERR_PTR(-ENOMEM);
+   goto bail;
+   }
+
+   mr->mr.access_flags = acc;
+   atomic_set(&mr->mr.refcount, 0);
+
+   spin_lock_irqsave(&dev->lk_table.lock, flags);
+   if (!dev->dma_mr)
+   dev->dma_mr = &mr->mr;
+   spin_unlock_irqrestore(&dev->lk_table.lock, flags);
+
+   ret = &mr->ibmr;
+
+bail:
+   return ret;
+}
+
+static struct qib_mr *alloc_mr(int count, struct qib_lkey_table *lk_table)
+{
+   struct qib_mr *mr;
+   int m, i = 0;
+
+   /* Allocate struct plus pointers to first level page tables. */
+   m = (count + QIB_SEGSZ - 1) / QIB_SEGSZ;
+   mr = kmalloc(sizeof *mr + m * sizeof mr->mr.map[0], GFP_KERNEL);
+   if (!mr)
+   goto done;
+
+   /* Allocate first level page tables. */
+   for (; i < m; i++) {
+   mr->mr.map[i] = kmalloc(sizeof *mr->mr.map[0], GFP_KERNEL);
+   if (!mr->mr.map[i])
+   goto bail;
+   }
+   mr->mr.mapsz = m;
+
+   /*
+* ib_reg_phys_mr() will initialize mr->ibmr except for
+* lkey and rkey.
+*/
+   if (!qib_alloc_lkey(lk_table, &mr->mr))
+   goto bail;
+   mr->ibmr.lkey = mr->mr.lkey;
+   mr->ibmr.rkey = mr->mr.lkey;
+
+   atomic_set(&mr->mr.refcount, 0);
+   goto done;
+
+bail:
+   while (i)
+   kfree(mr->mr.map[--i]);
+   kfree(mr);
+   mr = NULL;
+
+done:
+   return mr;
+}
+
+/**
+ * qib_reg_phys_mr - register a physical memory region
+ * @pd: protection domain for this memory region
+ * @buffer_list: pointer to the list of physical buffers to register
+ * @num_phys_buf: the number of physical buffers to register
+ * @iova_start: the starting address passed over IB which maps to this MR
+ *
+ * Returns the memory region on success

[PATCH v2 25/51] IB/qib: Add qib_mmap.c

2009-12-03 Thread Ralph Campbell
creates the qib_mmap.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mmap.c |  173 ++
 1 files changed, 173 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mmap.c

diff --git a/drivers/infiniband/hw/qib/qib_mmap.c 
b/drivers/infiniband/hw/qib/qib_mmap.c
new file mode 100644
index 000..ae15d38
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mmap.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib_verbs.h"
+
+/**
+ * qib_release_mmap_info - free mmap info structure
+ * @ref: a pointer to the kref within struct qib_mmap_info
+ */
+void qib_release_mmap_info(struct kref *ref)
+{
+   struct qib_mmap_info *ip =
+   container_of(ref, struct qib_mmap_info, ref);
+   struct qib_ibdev *dev = to_idev(ip->context->device);
+
+   spin_lock_irq(&dev->pending_lock);
+   list_del(&ip->pending_mmaps);
+   spin_unlock_irq(&dev->pending_lock);
+
+   vfree(ip->obj);
+   kfree(ip);
+}
+
+/*
+ * open and close keep track of how many times the CQ is mapped,
+ * to avoid releasing it.
+ */
+static void qib_vma_open(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma->vm_private_data;
+
+   kref_get(&ip->ref);
+}
+
+static void qib_vma_close(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma->vm_private_data;
+
+   kref_put(&ip->ref, qib_release_mmap_info);
+}
+
+static struct vm_operations_struct qib_vm_ops = {
+   .open = qib_vma_open,
+   .close =qib_vma_close,
+};
+
+/**
+ * qib_mmap - create a new mmap region
+ * @context: the IB user context of the process making the mmap() call
+ * @vma: the VMA to be initialized
+ * Return zero if the mmap is OK. Otherwise, return an errno.
+ */
+int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
+{
+   struct qib_ibdev *dev = to_idev(context->device);
+   unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+   unsigned long size = vma->vm_end - vma->vm_start;
+   struct qib_mmap_info *ip, *pp;
+   int ret = -EINVAL;
+
+   /*
+* Search the device's list of objects waiting for a mmap call.
+* Normally, this list is very short since a call to create a
+* CQ, QP, or SRQ is soon followed by a call to mmap().
+*/
+   spin_lock_irq(&dev->pending_lock);
+   list_for_each_entry_safe(ip, pp, &dev->pending_mmaps,
+pending_mmaps) {
+   /* Only the creator is allowed to mmap the object */
+   if (context != ip->context || (__u64) offset != ip->offset)
+   continue;
+   /* Don't allow a mmap larger than the object. */
+   if (size > ip->size)
+   break;
+
+   list_del_init(&ip->pending_mmaps);
+   spin_unlock_irq(&dev->pending_lock);
+
+   ret = remap_vmalloc_range(vma, ip->obj, 0);
+   if (ret)
+   goto done;
+   vma->vm_ops = &qib_vm_ops;
+   vma->vm_private_data = ip;
+   qib_vma_open(vma);
+   goto done;
+   }
+   spin_unlock_irq(&dev->pending_lock);
+done:
+   return ret;
+}
+
+/*
+ *

[PATCH v2 24/51] IB/qib: Add qib_mad.h

2009-12-03 Thread Ralph Campbell
creates the qib_mad.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mad.h |  333 +++
 1 files changed, 333 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.h

diff --git a/drivers/infiniband/hw/qib/qib_mad.h 
b/drivers/infiniband/hw/qib/qib_mad.h
new file mode 100644
index 000..57cab0d
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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.
+ */
+
+#define IB_SMP_UNSUP_VERSIONcpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR  cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELDcpu_to_be16(0x001C)
+
+struct ib_node_info {
+   u8 base_version;
+   u8 class_version;
+   u8 node_type;
+   u8 num_ports;
+   __be64 sys_guid;
+   __be64 node_guid;
+   __be64 port_guid;
+   __be16 partition_cap;
+   __be16 device_id;
+   __be32 revision;
+   u8 local_port_num;
+   u8 vendor_id[3];
+} __attribute__ ((packed));
+
+struct ib_mad_notice_attr {
+   u8 generic_type;
+   u8 prod_type_msb;
+   __be16 prod_type_lsb;
+   __be16 trap_num;
+   __be16 issuer_lid;
+   __be16 toggle_count;
+
+   union {
+   struct {
+   u8  details[54];
+   } raw_data;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* where violation happened */
+   u8  port_num;   /* where violation happened */
+   } __attribute__ ((packed)) ntc_129_131;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* LID where change occured */
+   u8  reserved2;
+   u8  local_changes;  /* low bit - local changes */
+   __be32  new_cap_mask;   /* new capability mask */
+   u8  reserved3;
+   u8  change_flags;   /* low 3 bits only */
+   } __attribute__ ((packed)) ntc_144;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* lid where sys guid changed */
+   __be16  reserved2;
+   __be64  new_sys_guid;
+   } __attribute__ ((packed)) ntc_145;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;
+   __be16  dr_slid;
+   u8  method;
+   u8  reserved2;
+   __be16  attr_id;
+   __be32  attr_mod;
+   __be64  mkey;
+   u8  reserved3;
+   u8  dr_trunc_hop;
+   u8  dr_rtn_path[30];
+   } __attribute__ ((packed)) ntc_256;
+
+   struct {
+   __be16  reserved;
+   __be16  lid1;
+   __be16  lid2;
+   __be32  key;
+   __be32  sl_qp1; /* SL: high 4 bits */
+   __be32  qp2;/* high 8 bits reserved */
+   union ib_gidgid1;
+   union ib_gidgid2;
+   } __a

[PATCH v2 23/51] IB/qib: Add qib_mad.c

2009-12-03 Thread Ralph Campbell
creates the qib_mad.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_mad.c | 1867 +++
 1 files changed, 1867 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.c

diff --git a/drivers/infiniband/hw/qib/qib_mad.c 
b/drivers/infiniband/hw/qib/qib_mad.c
new file mode 100644
index 000..d6fd6e1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -0,0 +1,1867 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+
+#include "qib.h"
+#include "qib_mad.h"
+
+static int reply(struct ib_smp *smp)
+{
+   /*
+* The verbs framework will handle the directed/LID route
+* packet changes.
+*/
+   smp->method = IB_MGMT_METHOD_GET_RESP;
+   if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+   smp->status |= IB_SMP_DIRECTION;
+   return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
+{
+   struct ib_mad_send_buf *send_buf;
+   struct ib_mad_agent *agent;
+   struct ib_smp *smp;
+   int ret;
+   unsigned long flags;
+   unsigned long timeout;
+
+   agent = ibp->send_agent;
+   if (!agent)
+   return;
+
+   /* o14-3.2.1 */
+   if (!(ppd_from_ibp(ibp)->lflags & QIBL_LINKACTIVE))
+   return;
+
+   /* o14-2 */
+   if (ibp->trap_timeout && time_before(jiffies, ibp->trap_timeout))
+   return;
+
+   send_buf = ib_create_send_mad(agent, 0, 0, 0, IB_MGMT_MAD_HDR,
+ IB_MGMT_MAD_DATA, GFP_ATOMIC);
+   if (IS_ERR(send_buf))
+   return;
+
+   smp = send_buf->mad;
+   smp->base_version = IB_MGMT_BASE_VERSION;
+   smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+   smp->class_version = 1;
+   smp->method = IB_MGMT_METHOD_TRAP;
+   ibp->tid++;
+   smp->tid = cpu_to_be64(ibp->tid);
+   smp->attr_id = IB_SMP_ATTR_NOTICE;
+   /* o14-1: smp->mkey = 0; */
+   memcpy(smp->data, data, len);
+
+   spin_lock_irqsave(&ibp->lock, flags);
+   if (!ibp->sm_ah) {
+   if (ibp->sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
+   struct ib_ah *ah;
+   struct ib_ah_attr attr;
+
+   memset(&attr, 0, sizeof attr);
+   attr.dlid = ibp->sm_lid;
+   attr.port_num = ppd_from_ibp(ibp)->port;
+   ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr);
+   if (IS_ERR(ah))
+   ret = -EINVAL;
+   else {
+   send_buf->ah = ah;
+   ibp->sm_ah = to_iah(ah);
+   ret = 0;
+   }
+   } else
+   ret = -EINVAL;
+   } else {
+   send_buf->ah = &ibp->sm_ah->ibah;
+   ret = 0;
+   }
+   spin_unlock_irqrestore(&ibp->lock, flags);
+
+   if (!ret)
+   ret = ib_post_send_mad(send_buf, NULL);
+   if (!ret) {
+   /* 4.096 usec. */
+   timeout = (4096 * (1UL << ibp->subnet_timeout)) / 1000;
+   ibp->trap_timeout =

[PATCH v2 22/51] IB/qib: Add qib_keys.c

2009-12-03 Thread Ralph Campbell
creates the qib_keys.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_keys.c |  278 ++
 1 files changed, 278 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_keys.c

diff --git a/drivers/infiniband/hw/qib/qib_keys.c 
b/drivers/infiniband/hw/qib/qib_keys.c
new file mode 100644
index 000..e2b42e5
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_keys.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved.
+ * Copyright (c) 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 "qib.h"
+
+/**
+ * qib_alloc_lkey - allocate an lkey
+ * @rkt: lkey table in which to allocate the lkey
+ * @mr: memory region that this lkey protects
+ *
+ * Returns 1 if successful, otherwise returns 0.
+ */
+
+int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 r;
+   u32 n;
+   int ret;
+
+   spin_lock_irqsave(&rkt->lock, flags);
+
+   /* Find the next available LKEY */
+   r = rkt->next;
+   n = r;
+   for (;;) {
+   if (rkt->table[r] == NULL)
+   break;
+   r = (r + 1) & (rkt->max - 1);
+   if (r == n) {
+   spin_unlock_irqrestore(&rkt->lock, flags);
+   qib_dbg("LKEY table full\n");
+   ret = 0;
+   goto bail;
+   }
+   }
+   rkt->next = (r + 1) & (rkt->max - 1);
+   /*
+* Make sure lkey is never zero which is reserved to indicate an
+* unrestricted LKEY.
+*/
+   rkt->gen++;
+   mr->lkey = (r << (32 - ib_qib_lkey_table_size)) |
+   1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen)
+<< 8);
+   if (mr->lkey == 0) {
+   mr->lkey |= 1 << 8;
+   rkt->gen++;
+   }
+   rkt->table[r] = mr;
+   spin_unlock_irqrestore(&rkt->lock, flags);
+
+   ret = 1;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_free_lkey - free an lkey
+ * @rkt: table from which to free the lkey
+ * @lkey: lkey id to free
+ */
+int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 lkey = mr->lkey;
+   u32 r;
+   int ret;
+
+   spin_lock_irqsave(&dev->lk_table.lock, flags);
+   if (lkey == 0) {
+   if (dev->dma_mr && dev->dma_mr == mr) {
+   ret = atomic_read(&dev->dma_mr->refcount);
+   if (!ret)
+   dev->dma_mr = NULL;
+   } else
+   ret = 0;
+   } else {
+   r = lkey >> (32 - ib_qib_lkey_table_size);
+   ret = atomic_read(&dev->lk_table.table[r]->refcount);
+   if (!ret)
+   dev->lk_table.table[r] = NULL;
+   }
+   spin_unlock_irqrestore(&dev->lk_table.lock, flags);
+
+   if (ret) {
+   qib_dbg("MR busy (LKEY %x cnt %u)\n", lkey, ret);
+   ret = -EBUSY;
+   }
+   return ret;
+}
+
+/**
+ * qib_lkey_ok - check IB SGE for validity and initialize
+ * @rkt: table containing lkey to check SGE against
+ * @isge: outgoing internal SGE
+ * @sge: SGE to check
+ * @acc: access flags
+ *
+ * Return 1 if valid and successful, otherwise retur

[PATCH v2 21/51] IB/qib: Add qib_intr.c

2009-12-03 Thread Ralph Campbell
creates the qib_intr.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_intr.c |  217 ++
 1 files changed, 217 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_intr.c

diff --git a/drivers/infiniband/hw/qib/qib_intr.c 
b/drivers/infiniband/hw/qib/qib_intr.c
new file mode 100644
index 000..46e128a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_intr.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/**
+ * qib_format_hwmsg - format a single hwerror message
+ * @msg message buffer
+ * @msgl length of message buffer
+ * @hwmsg message to add to message buffer
+ */
+static void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
+{
+   strlcat(msg, "[", msgl);
+   strlcat(msg, hwmsg, msgl);
+   strlcat(msg, "]", msgl);
+}
+
+/**
+ * qib_format_hwerrors - format hardware error messages for display
+ * @hwerrs hardware errors bit vector
+ * @hwerrmsgs hardware error descriptions
+ * @nhwerrmsgs number of hwerrmsgs
+ * @msg message buffer
+ * @msgl message buffer length
+ */
+void qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs,
+size_t nhwerrmsgs, char *msg, size_t msgl)
+{
+   int i;
+
+   for (i = 0; i < nhwerrmsgs; i++)
+   if (hwerrs & hwerrmsgs[i].mask)
+   qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
+}
+
+static void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev)
+{
+   struct ib_event event;
+   struct qib_devdata *dd = ppd->dd;
+
+   event.device = &dd->verbs_dev.ibdev;
+   event.element.port_num = ppd->port;
+   event.event = ev;
+   ib_dispatch_event(&event);
+}
+
+void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs)
+{
+   struct qib_devdata *dd = ppd->dd;
+   unsigned long flags;
+   u32 lstate;
+   u8 ltstate;
+
+   lstate = dd->f_iblink_state(ibcs); /* linkstate */
+   ltstate = dd->f_ibphys_portstate(ibcs);
+
+   /*
+* If linkstate transitions into INIT from any of the various down
+* states, or if it transitions from any of the up (INIT or better)
+* states into any of the down states (except link recovery), then
+* call the chip-specific code to take appropriate actions.
+*/
+   if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) &&
+   ltstate == IB_PHYSPORTSTATE_LINKUP) {
+   /* transitioned to UP */
+   if (dd->f_ib_updown(ppd, 1, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   } else if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED |
+  QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) {
+   if (ltstate != IB_PHYSPORTSTATE_LINKUP &&
+   ltstate <= IB_PHYSPORTSTATE_CFG_TRAIN &&
+   dd->f_ib_updown(ppd, 0, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT);
+   }
+
+   if (lstate != IB_PORT_DOWN) {
+   /* lstate is INIT, ARMED, or ACTIVE */
+   if (lstate != IB_PORT_ACTIVE) {
+   *ppd->

[PATCH v2 20/51] IB/qib: Add qib_init.c

2009-12-03 Thread Ralph Campbell
creates the qib_init.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_init.c | 1618 ++
 1 files changed, 1618 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_init.c

diff --git a/drivers/infiniband/hw/qib/qib_init.c 
b/drivers/infiniband/hw/qib/qib_init.c
new file mode 100644
index 000..6ce1128
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -0,0 +1,1618 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/*
+ * min buffers we want to have per context, after driver
+ */
+#define QIB_MIN_USER_CTXT_BUFCNT 7
+
+#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF
+#define QLOGIC_IB_R_SOFTWARE_SHIFT 24
+#define QLOGIC_IB_R_EMULATOR_MASK (1ULL<<62)
+
+/*
+ * Number of ctxts we are configured to use (to allow for more pio
+ * buffers per ctxt, etc.)  Zero means use chip value.
+ */
+ushort qib_cfgctxts;
+module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
+MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use");
+
+/*
+ * If set, do not write to any regs if avoidable, hack to allow
+ * check for deranged default register values.
+ */
+ushort qib_mini_init;
+module_param_named(mini_init, qib_mini_init, ushort, S_IRUGO);
+MODULE_PARM_DESC(mini_init, "If set, do minimal diag init");
+
+unsigned qib_n_krcv_queues;
+module_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO);
+MODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port");
+
+/*
+ * qib_wc_pat parameter:
+ *  0 is WC via MTRR
+ *  1 is WC via PAT
+ *  If PAT initialization fails, code reverts back to MTRR
+ */
+unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */
+module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
+MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism");
+
+static void verify_interrupt(unsigned long);
+
+static struct idr qib_unit_table;
+
+/* set number of contexts we'll actually use */
+void qib_set_ctxtcnt(struct qib_devdata *dd)
+{
+   if (!qib_cfgctxts)
+   dd->cfgctxts = dd->ctxtcnt;
+   else if (qib_cfgctxts < dd->num_pports) {
+   dd->cfgctxts = dd->ctxtcnt;
+   qib_dbg("Configured to use too few ctxts (%u); using %u\n",
+   qib_cfgctxts, dd->cfgctxts);
+   } else if (qib_cfgctxts <= dd->ctxtcnt) {
+   dd->cfgctxts = qib_cfgctxts;
+   qib_cdbg(INIT, "Configured to use %u ctxts\n", dd->cfgctxts);
+   } else {
+   dd->cfgctxts = dd->ctxtcnt;
+   qib_dbg("Configured to use too many ctxts (%u); using %u\n",
+   qib_cfgctxts, dd->cfgctxts);
+   }
+}
+
+/*
+ * Common code for creating the receive context array.
+ */
+int qib_create_ctxts(struct qib_devdata *dd)
+{
+   unsigned i;
+   int ret;
+
+   /*
+* Allocate full ctxtcnt array, rather than just cfgctxts, because
+* cleanup iterates across all possible ctxts.
+*/
+   dd->rcd = kzalloc(sizeof(*dd->rcd) * dd->ctxtcnt, GFP_KERNEL);
+   if (!dd->rcd) {
+   qib_dev_err(dd, "Unable to allocate ctxtdata array, "
+   "failing\n");

[PATCH v2 16/51] IB/qib: Add qib_fs.c

2009-12-03 Thread Ralph Campbell
creates the qib_fs.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_fs.c |  549 
 1 files changed, 549 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_fs.c

diff --git a/drivers/infiniband/hw/qib/qib_fs.c 
b/drivers/infiniband/hw/qib/qib_fs.c
new file mode 100644
index 000..629ff7e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+#define QIBFS_MAGIC 0x726a77
+
+static struct super_block *qib_super;
+
+#define private2dd(file) ((file)->f_dentry->d_inode->i_private)
+
+static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
+  int mode, const struct file_operations *fops,
+  void *data)
+{
+   int error;
+   struct inode *inode = new_inode(dir->i_sb);
+
+   if (!inode) {
+   error = -EPERM;
+   goto bail;
+   }
+
+   inode->i_mode = mode;
+   inode->i_uid = 0;
+   inode->i_gid = 0;
+   inode->i_blocks = 0;
+   inode->i_atime = CURRENT_TIME;
+   inode->i_mtime = inode->i_atime;
+   inode->i_ctime = inode->i_atime;
+   inode->i_private = data;
+   if ((mode & S_IFMT) == S_IFDIR) {
+   inode->i_op = &simple_dir_inode_operations;
+   inc_nlink(inode);
+   inc_nlink(dir);
+   }
+
+   inode->i_fop = fops;
+
+   d_instantiate(dentry, inode);
+   error = 0;
+
+bail:
+   return error;
+}
+
+static int create_file(const char *name, mode_t mode,
+  struct dentry *parent, struct dentry **dentry,
+  const struct file_operations *fops, void *data)
+{
+   int error;
+
+   *dentry = NULL;
+   mutex_lock(&parent->d_inode->i_mutex);
+   *dentry = lookup_one_len(name, parent, strlen(name));
+   if (!IS_ERR(*dentry))
+   error = qibfs_mknod(parent->d_inode, *dentry,
+   mode, fops, data);
+   else
+   error = PTR_ERR(*dentry);
+   mutex_unlock(&parent->d_inode->i_mutex);
+
+   return error;
+}
+
+static ssize_t driver_stats_read(struct file *file, char __user *buf,
+size_t count, loff_t *ppos)
+{
+   return simple_read_from_buffer(buf, count, ppos, &qib_stats,
+  sizeof qib_stats);
+}
+
+/*
+ * driver stats field names, one line per stat, single string.  Used by
+ * programs like ipathstats to print the stats in a way which works for
+ * different versions of drivers, without changing program source.
+ * if qlogic_ib_stats changes, this needs to change.  Names need to be
+ * 12 chars or less (w/o newline), for proper display by ipathstats utility.
+ */
+static const char qib_statnames[] =
+   "KernIntr\n"
+   "ErrorIntr\n"
+   "Tx_Errs\n"
+   "Rcv_Errs\n"
+   "H/W_Errs\n"
+   "NoPIOBufs\n"
+   "CtxtsOpen\n"
+   "RcvLen_Errs\n"
+   "EgrBufFull\n"
+   "EgrHdrFull\n"
+   ;
+
+static ssize_t driver_names_read(struct file *file, char __user *buf,
+size_t co

[PATCH v2 14/51] IB/qib: Add qib_eeprom.c

2009-12-03 Thread Ralph Campbell
creates the qib_eeprom.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_eeprom.c |  460 
 1 files changed, 460 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_eeprom.c

diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c 
b/drivers/infiniband/hw/qib/qib_eeprom.c
new file mode 100644
index 000..7a6fe41
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_eeprom.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * Functions specific to the serial EEPROM on cards handled by ib_qib.
+ * The actual serail interface code is in qib_twsi.c. This file is a client
+ */
+
+/**
+ * qib_eeprom_read - receives bytes from the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: address to read from
+ * @buffer: where to store result
+ * @len: number of bytes to receive
+ */
+int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset,
+   void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (!ret) {
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, "TWSI Reset failed, EEPROM Rd\n");
+   else
+   ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev,
+ eeprom_offset, buff, len);
+   mutex_unlock(&dd->eep_lock);
+   }
+
+   return ret;
+}
+
+/*
+ * Actually update the eeprom, first doing write enable if
+ * needed, then restoring write enable state.
+ * Must be called with eep_lock held
+ */
+static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset,
+const void *buf, int len)
+{
+   int ret, pwen;
+
+   pwen = dd->f_eeprom_wen(dd, 1);
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, "TWSI Reset failed, EEPROM Wr\n");
+   else
+   ret = qib_twsi_blk_wr(dd, dd->twsi_eeprom_dev,
+ offset, buf, len);
+   dd->f_eeprom_wen(dd, pwen);
+   return ret;
+}
+
+/**
+ * qib_eeprom_write - writes data to the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: where to place data
+ * @buffer: data to write
+ * @len: number of bytes to write
+ */
+int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset,
+const void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(&dd->eep_lock);
+   if (!ret) {
+   ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len);
+   mutex_unlock(&dd->eep_lock);
+   }
+
+   return ret;
+}
+
+static u8 flash_csum(struct qib_flash *ifp, int adjust)
+{
+   u8 *ip = (u8 *) ifp;
+   u8 csum = 0, len;
+
+   /*
+* Limit length checksummed to max length of actual data.
+* Checksum of erased eeprom will still be bad, but we avoid
+* reading past the end of the buffer we were passed.
+*/
+   len = ifp->if_length;
+   if (len > sizeof(struct qib_flash))
+   len = sizeof(struct qib_flash);
+   while (len--)
+   csum += *ip++;
+   csum -= ifp->if_csum;
+   csum = ~csum;
+   if (adjust)
+   ifp->if_csum = csum;
+
+   

[PATCH v2 13/51] IB/qib: Add qib_driver.c

2009-12-03 Thread Ralph Campbell
creates the qib_driver.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_driver.c |  793 
 1 files changed, 793 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_driver.c

diff --git a/drivers/infiniband/hw/qib/qib_driver.c 
b/drivers/infiniband/hw/qib/qib_driver.c
new file mode 100644
index 000..a9a9896
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -0,0 +1,793 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+
+/*
+ * The size has to be longer than this string, so we can append
+ * board/chip information to it in the init code.
+ */
+const char ib_qib_version[] = QIB_IDSTR "\n";
+
+DEFINE_SPINLOCK(qib_devs_lock);
+LIST_HEAD(qib_dev_list);
+DEFINE_MUTEX(qib_mutex);   /* general driver use */
+
+unsigned qib_debug;
+module_param_named(debug, qib_debug, uint, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(debug, "mask for debug prints");
+
+unsigned qib_ibmtu;
+module_param_named(ibmtu, qib_ibmtu, uint, S_IRUGO);
+MODULE_PARM_DESC(ibmtu, "Set max IB MTU (0=2KB, 1=256, 2=512, ... 5=4096");
+
+unsigned qib_compat_ddr_negotiate = 1;
+module_param_named(compat_ddr_negotiate, qib_compat_ddr_negotiate, uint,
+  S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(compat_ddr_negotiate,
+"Attempt pre-IBTA 1.2 DDR speed negotiation");
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("QLogic ");
+MODULE_DESCRIPTION("QLogic IB driver");
+
+/*
+ * QIB_PIO_MAXIBHDR is the max IB header size allowed for in our
+ * PIO send buffers.  This is well beyond anything currently
+ * defined in the InfiniBand spec.
+ */
+#define QIB_PIO_MAXIBHDR 128
+
+struct qlogic_ib_stats qib_stats;
+
+const char *qib_get_unit_name(int unit)
+{
+   static char iname[16];
+
+   snprintf(iname, sizeof iname, "infinipath%u", unit);
+   return iname;
+}
+
+/*
+ * Return count of units with at least one port ACTIVE.
+ */
+int qib_count_active_units(void)
+{
+   struct qib_devdata *dd;
+   struct qib_pportdata *ppd;
+   unsigned long flags;
+   int pidx, nunits_active = 0;
+
+   spin_lock_irqsave(&qib_devs_lock, flags);
+   list_for_each_entry(dd, &qib_dev_list, list) {
+   if (!(dd->flags & QIB_PRESENT) || !dd->kregbase)
+   continue;
+   for (pidx = 0; pidx < dd->num_pports; ++pidx) {
+   ppd = dd->pport + pidx;
+   if (ppd->lid && (ppd->lflags & (QIBL_LINKINIT |
+QIBL_LINKARMED | QIBL_LINKACTIVE))) {
+   nunits_active++;
+   break;
+   }
+   }
+   }
+   spin_unlock_irqrestore(&qib_devs_lock, flags);
+   return nunits_active;
+}
+
+/*
+ * Return count of all units, optionally return in arguments
+ * the number of usable (present) units, and the number of
+ * ports that are up.
+ */
+int qib_count_units(int *npresentp, int *nupp)
+{
+   int nunits = 0, npresent = 0, nup = 0;
+   struct qib_devdata *dd;
+   unsigned long flags;
+   int pidx;
+   struct qib_pportdata *ppd;
+
+   spin_lock_irqsave(&qib_devs_lock,

[PATCH v2 12/51] IB/qib: Add qib_dma.c

2009-12-03 Thread Ralph Campbell
creates the qib_dma.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_dma.c |  182 +++
 1 files changed, 182 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_dma.c

diff --git a/drivers/infiniband/hw/qib/qib_dma.c 
b/drivers/infiniband/hw/qib/qib_dma.c
new file mode 100644
index 000..f84085e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_dma.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006, 2009 QLogic, Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include 
+#include 
+
+#include "qib_verbs.h"
+
+#define BAD_DMA_ADDRESS ((u64) 0)
+
+/*
+ * The following functions implement driver specific replacements
+ * for the ib_dma_*() functions.
+ *
+ * These functions return kernel virtual addresses instead of
+ * device bus addresses since the driver uses the CPU to copy
+ * data instead of using hardware DMA.
+ */
+
+static int qib_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+   return dma_addr == BAD_DMA_ADDRESS;
+}
+
+static u64 qib_dma_map_single(struct ib_device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+   return (u64) cpu_addr;
+}
+
+static void qib_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_dma_map_page(struct ib_device *dev, struct page *page,
+   unsigned long offset, size_t size,
+   enum dma_data_direction direction)
+{
+   u64 addr;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   if (offset + size > PAGE_SIZE) {
+   addr = BAD_DMA_ADDRESS;
+   goto done;
+   }
+
+   addr = (u64) page_address(page);
+   if (addr)
+   addr += offset;
+   /* TODO: handle highmem pages */
+
+done:
+   return addr;
+}
+
+static void qib_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size,
+  enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static int qib_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction)
+{
+   struct scatterlist *sg;
+   u64 addr;
+   int i;
+   int ret = nents;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   for_each_sg(sgl, sg, nents, i) {
+   addr = (u64) page_address(sg_page(sg));
+   /* TODO: handle highmem pages */
+   if (!addr) {
+   ret = 0;
+   break;
+   }
+   }
+   return ret;
+}
+
+static void qib_unmap_sg(struct ib_device *dev,
+struct scatterlist *sg, int nents,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
+{
+   u64 addr = (u64) page_address(sg_page(sg));
+
+   if (addr)
+   addr += sg->offset;
+   return addr;
+}
+
+static unsigned int qib_sg_dma_len(struct ib_device *dev,
+  struct scatterlist *sg)
+{
+   return sg->length;
+}
+
+static void qib_sync_single_for_cpu(struct ib_device *dev, u64 addr,
+   size_t size, enum dma_data_direction dir)
+{
+}
+
+static void qib_

[PATCH v2 11/51] IB/qib: Add qib_diag.c

2009-12-03 Thread Ralph Campbell
creates the qib_diag.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_diag.c |  908 ++
 1 files changed, 908 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_diag.c

diff --git a/drivers/infiniband/hw/qib/qib_diag.c 
b/drivers/infiniband/hw/qib/qib_diag.c
new file mode 100644
index 000..f5cb4cc
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_diag.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+
+/*
+ * This file contains support for diagnostic functions.  It is accessed by
+ * opening the qib_diag device, normally minor number 129.  Diagnostic use
+ * of the QLogic_IB chip may render the chip or board unusable until the
+ * driver is unloaded, or in some cases, until the system is rebooted.
+ *
+ * Accesses to the chip through this interface are not similar to going
+ * through the /sys/bus/pci resource mmap interface.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib.h"
+#include "qib_common.h"
+
+/*
+ * Each client that opens the diag device must read then write
+ * offset 0, to prevent lossage from random cat or od. diag_state
+ * sequences this "handshake".
+ */
+enum diag_state { UNUSED = 0, OPENED, INIT, READY };
+
+/* State for an individual client. PID so children cannot abuse handshake */
+static struct qib_diag_client {
+   struct qib_diag_client *next;
+   struct qib_devdata *dd;
+   pid_t pid;
+   enum diag_state state;
+} *client_pool;
+
+/*
+ * Get a client struct. Recycled if possible, else kmalloc.
+ * Must be called with qib_mutex held
+ */
+static struct qib_diag_client *get_client(struct qib_devdata *dd)
+{
+   struct qib_diag_client *dc;
+
+   dc = client_pool;
+   if (dc)
+   /* got from pool remove it and use */
+   client_pool = dc->next;
+   else
+   /* None in pool, alloc and init */
+   dc = kmalloc(sizeof *dc, GFP_KERNEL);
+
+   if (dc) {
+   dc->next = NULL;
+   dc->dd = dd;
+   dc->pid = current->pid;
+   dc->state = OPENED;
+   }
+   return dc;
+}
+
+/*
+ * Return to pool. Must be called with qib_mutex held
+ */
+static void return_client(struct qib_diag_client *dc)
+{
+   struct qib_devdata *dd = dc->dd;
+   struct qib_diag_client *tdc, *rdc;
+
+   rdc = NULL;
+   if (dc == dd->diag_client) {
+   dd->diag_client = dc->next;
+   rdc = dc;
+   } else {
+   tdc = dc->dd->diag_client;
+   while (tdc) {
+   if (dc == tdc->next) {
+   tdc->next = dc->next;
+   rdc = dc;
+   break;
+   }
+   tdc = tdc->next;
+   }
+   }
+   if (rdc) {
+   rdc->state = UNUSED;
+   rdc->dd = NULL;
+   rdc->pid = 0;
+   rdc->next = client_pool;
+   client_pool = rdc;
+   }
+}
+
+static int qib_diag_open(struct inode *in, struct file *fp);
+static int qib_diag_release(struct inode *in, struct file *fp);
+static ssize_t qib_diag_read(struct file *fp, char __user *data,
+size_t count, loff_t *off);
+static ssize_t

[PATCH v2 10/51] IB/qib: Add qib_debug.h

2009-12-03 Thread Ralph Campbell
creates the qib_debug.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_debug.h |   85 +
 1 files changed, 85 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_debug.h

diff --git a/drivers/infiniband/hw/qib/qib_debug.h 
b/drivers/infiniband/hw/qib/qib_debug.h
new file mode 100644
index 000..e6a77cd
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_debug.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006, 2007, 2009 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.
+ */
+
+#ifndef _QIB_DEBUG_H
+#define _QIB_DEBUG_H
+
+#ifndef _QIB_DEBUGGING  /* debugging enabled or not */
+#define _QIB_DEBUGGING 1
+#endif
+
+#if _QIB_DEBUGGING
+
+/*
+ * Mask values for debugging.  The scheme allows us to compile out any
+ * of the debug tracing stuff, and if compiled in, to enable or disable
+ * dynamically.  This can be set at modprobe time also:
+ *  modprobe qlogic_ib.ko qlogic_ib_debug=7
+ */
+
+#define __QIB_INFO0x1   /* logging of dev_info and dev_err */
+#define __QIB_DBG 0x2   /* generic debug */
+/* leave some low verbosity spots open */
+#define __QIB_RVPKTDBG0x10  /* verbose pktrcv debug */
+#define __QIB_INITDBG 0x20  /* init-level debug */
+#define __QIB_VERBDBG 0x40  /* very verbose debug */
+#define __QIB_PKTDBG  0x80  /* print packet data */
+#define __QIB_PROCDBG 0x100 /* process init/exit debug */
+#define __QIB_MMDBG   0x200 /* mmap, etc debug */
+#define __QIB_ERRPKTDBG   0x400 /* packet error debugging */
+#define __QIB_SDMADBG 0x800 /* Send DMA */
+#define __QIB_VPKTDBG 0x1000 /* Dump IB contents being copied to send buf 
*/
+#define __QIB_LINKVERBDBG 0x20  /* very verbose linkchange debug */
+
+#else   /* _QIB_DEBUGGING */
+
+/*
+ * define all of these even with debugging off, for the few places that do
+ * if(qlogic_ib_debug & _QIB_xyzzy), but in a way that will make the
+ * compiler eliminate the code
+ */
+
+#define __QIB_DBG   0x0 /* generic debug */
+#define __QIB_VERBDBG   0x0 /* very verbose debug */
+#define __QIB_PKTDBG0x0 /* print packet data */
+#define __QIB_PROCDBG   0x0  /* process init/exit debug */
+#define __QIB_MMDBG 0x0 /* mmap, etc debug */
+#define __QIB_ERRPKTDBG 0x0 /* packet error debugging */
+#define __QIB_SDMADBG   0x0 /* Send DMA */
+#define __QIB_LINKVERBDBG 0x0   /* very verbose linkchange debug */
+
+#endif  /* _QIB_DEBUGGING */
+
+#define __QIB_VERBOSEDBG __QIB_VERBDBG
+
+#endif  /* _QIB_DEBUG_H */

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 09/51] IB/qib: Add qib_cq.c

2009-12-03 Thread Ralph Campbell
creates the qib_cq.c file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_cq.c |  475 
 1 files changed, 475 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_cq.c

diff --git a/drivers/infiniband/hw/qib/qib_cq.c 
b/drivers/infiniband/hw/qib/qib_cq.c
new file mode 100644
index 000..4aed485
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_cq.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.
+ * Copyright (c) 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 
+#include 
+
+#include "qib_verbs.h"
+
+/**
+ * qib_cq_enter - add a new entry to the completion queue
+ * @cq: completion queue
+ * @entry: work completion entry to add
+ * @sig: true if @entry is a solicitated entry
+ *
+ * This may be called with qp->s_lock held.
+ */
+void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int solicited)
+{
+   struct qib_cq_wc *wc;
+   unsigned long flags;
+   u32 head;
+   u32 next;
+
+   spin_lock_irqsave(&cq->lock, flags);
+
+   /*
+* Note that the head pointer might be writable by user processes.
+* Take care to verify it is a sane value.
+*/
+   wc = cq->queue;
+   head = wc->head;
+   if (head >= (unsigned) cq->ibcq.cqe) {
+   head = cq->ibcq.cqe;
+   next = 0;
+   } else
+   next = head + 1;
+   if (unlikely(next == wc->tail)) {
+   spin_unlock_irqrestore(&cq->lock, flags);
+   if (cq->ibcq.event_handler) {
+   struct ib_event ev;
+
+   ev.device = cq->ibcq.device;
+   ev.element.cq = &cq->ibcq;
+   ev.event = IB_EVENT_CQ_ERR;
+   cq->ibcq.event_handler(&ev, cq->ibcq.cq_context);
+   }
+   return;
+   }
+   if (cq->ip) {
+   wc->uqueue[head].wr_id = entry->wr_id;
+   wc->uqueue[head].status = entry->status;
+   wc->uqueue[head].opcode = entry->opcode;
+   wc->uqueue[head].vendor_err = entry->vendor_err;
+   wc->uqueue[head].byte_len = entry->byte_len;
+   wc->uqueue[head].ex.imm_data =
+   (__u32 __force)entry->ex.imm_data;
+   wc->uqueue[head].qp_num = entry->qp->qp_num;
+   wc->uqueue[head].src_qp = entry->src_qp;
+   wc->uqueue[head].wc_flags = entry->wc_flags;
+   wc->uqueue[head].pkey_index = entry->pkey_index;
+   wc->uqueue[head].slid = entry->slid;
+   wc->uqueue[head].sl = entry->sl;
+   wc->uqueue[head].dlid_path_bits = entry->dlid_path_bits;
+   wc->uqueue[head].port_num = entry->port_num;
+   /* Make sure entry is written before the head index. */
+   smp_wmb();
+   } else
+   wc->kqueue[head] = *entry;
+   wc->head = next;
+
+   if (cq->notify == IB_CQ_NEXT_COMP ||
+   (cq->notify == IB_CQ_SOLICITED && solicited)) {
+   cq->notify = IB_CQ_NONE;
+   cq->triggered++;
+   /*
+* This will cause send_complete() to be called in
+* another thread.
+*/
+   tasklet_hi_schedule(&cq->comptask);
+

[PATCH v2 08/51] IB/qib: Add qib_common.h

2009-12-03 Thread Ralph Campbell
creates the qib_common.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_common.h |  755 
 1 files changed, 755 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_common.h

diff --git a/drivers/infiniband/hw/qib/qib_common.h 
b/drivers/infiniband/hw/qib/qib_common.h
new file mode 100644
index 000..51239aa
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_common.h
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+
+#ifndef _QIB_COMMON_H
+#define _QIB_COMMON_H
+
+/*
+ * This file contains defines, structures, etc. that are used
+ * to communicate between kernel and user code.
+ */
+
+/* This is the IEEE-assigned OUI for QLogic Inc. QLogic_IB */
+#define QIB_SRC_OUI_1 0x00
+#define QIB_SRC_OUI_2 0x11
+#define QIB_SRC_OUI_3 0x75
+
+/* version of protocol header (known to chip also). In the long run,
+ * we should be able to generate and accept a range of version numbers;
+ * for now we only accept one, and it's compiled in.
+ */
+#define IPS_PROTO_VERSION 2
+
+/*
+ * These are compile time constants that you may want to enable or disable
+ * if you are trying to debug problems with code or performance.
+ * QIB_VERBOSE_TRACING define as 1 if you want additional tracing in
+ * fastpath code
+ * QIB_TRACE_REGWRITES define as 1 if you want register writes to be
+ * traced in faspath code
+ * _QIB_TRACING define as 0 if you want to remove all tracing in a
+ * compilation unit
+ * _QIB_DEBUGGING define as 0 if you want to remove debug prints
+ */
+
+/*
+ * The value in the BTH QP field that QLogic_IB uses to differentiate
+ * an qlogic_ib protocol IB packet vs standard IB transport
+ * This it needs to be even (0x656b78), because the LSB is sometimes
+ * used for the MSB of context. The change may cause a problem
+ * interoperating with older software.
+ */
+#define QIB_KD_QP 0x656b78
+
+/*
+ * These are the status bits readable (in ascii form, 64bit value)
+ * from the "status" sysfs file.  For binary compatibility, values
+ * must remain as is; removed states can be reused for different
+ * purposes.
+ */
+#define QIB_STATUS_INITTED   0x1/* basic initialization done */
+/* Chip has been found and initted */
+#define QIB_STATUS_CHIP_PRESENT 0x20
+/* IB link is at ACTIVE, usable for data traffic */
+#define QIB_STATUS_IB_READY 0x40
+/* link is configured, LID, MTU, etc. have been set */
+#define QIB_STATUS_IB_CONF  0x80
+/* A Fatal hardware error has occurred. */
+#define QIB_STATUS_HWERROR 0x200
+
+/*
+ * The list of usermode accessible registers.  Also see Reg_* later in file.
+ */
+enum qib_ureg {
+   /* (RO)  DMA RcvHdr to be used next. */
+   ur_rcvhdrtail = 0,
+   /* (RW)  RcvHdr entry to be processed next by host. */
+   ur_rcvhdrhead = 1,
+   /* (RO)  Index of next Eager index to use. */
+   ur_rcvegrindextail = 2,
+   /* (RW)  Eager TID to be processed next */
+   ur_rcvegrindexhead = 3,
+   /* For internal use only; max register number. */
+   _QIB_UregMax
+};
+
+/* bit values for spi_runtime_flags */
+#define QIB_RUNTIME_PCIE0x0002
+#define QIB_RUNTIME_FORCE_WC_ORDER  0x0004
+#define QIB_RUNTIME_RCVHDR_COPY 0x0008
+#define QIB_RUNTIME_MASTER  0x0010
+#define QIB_RUNTIME_NODMA_RTAIL 0x0080
+#define QIB_RUNTIME_SPECIAL_TRIGGER 0x0100
+#define QIB_RUNTIME_SDMA  

[PATCH v2 05/51] IB/qib: Add qib_7220.h

2009-12-03 Thread Ralph Campbell
creates the qib_7220.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_7220.h |  158 ++
 1 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_7220.h

diff --git a/drivers/infiniband/hw/qib/qib_7220.h 
b/drivers/infiniband/hw/qib/qib_7220.h
new file mode 100644
index 000..a68230e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_7220.h
@@ -0,0 +1,158 @@
+#ifndef _QIB_7220_H
+#define _QIB_7220_H
+/*
+ * Copyright (c) 2007, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* grab register-defs auto-generated by HW */
+#include "qib_7220_regs.h"
+
+/* The number of eager receive TIDs for context zero. */
+#define IBA7220_KRCVEGRCNT  2048U
+
+#define IB_7220_LT_STATE_CFGRCVFCFG  0x09
+#define IB_7220_LT_STATE_CFGWAITRMT  0x0a
+#define IB_7220_LT_STATE_TXREVLANES  0x0d
+#define IB_7220_LT_STATE_CFGENH  0x10
+
+struct qib_chip_specific {
+   u64 __iomem *cregbase;
+   u64 *cntrs;
+   u64 *portcntrs;
+   spinlock_t sdepb_lock; /* serdes EPB bus */
+   spinlock_t rcvmod_lock; /* protect rcvctrl shadow changes */
+   spinlock_t gpio_lock; /* RMW of shadows/regs for ExtCtrl and GPIO */
+   u64 hwerrmask;
+   u64 errormask;
+   u64 gpio_out; /* shadow of kr_gpio_out, for rmw ops */
+   u64 gpio_mask; /* shadow the gpio mask register */
+   u64 extctrl; /* shadow the gpio output enable, etc... */
+   u32 ncntrs;
+   u32 nportcntrs;
+   u32 cntrnamelen;
+   u32 portcntrnamelen;
+   u32 numctxts;
+   u32 rcvegrcnt;
+   u32 autoneg_tries;
+   u32 serdes_first_init_done;
+   u32 sdmabufcnt;
+   u32 lastbuf_for_pio;
+   u32 updthresh; /* current AvailUpdThld */
+   u32 updthresh_dflt; /* default AvailUpdThld */
+   int irq;
+   u8 presets_needed;
+   char emsgbuf[128];
+   char sdmamsgbuf[192];
+   char bitsmsgbuf[64];
+   struct qib_relock {
+   atomic_t relock_timer_active;
+   struct timer_list relock_timer;
+   unsigned int relock_interval; /* in jiffies */
+   } relock_st;
+};
+
+struct qib_chippport_specific {
+   struct qib_pportdata pportdata;
+   wait_queue_head_t autoneg_wait;
+   struct delayed_work autoneg_work;
+   struct timer_list chase_timer;
+   /*
+* these 5 fields are used to establish deltas for IB symbol
+* errors and linkrecovery errors.  They can be reported on
+* some chips during link negotiation prior to INIT, and with
+* DDR when faking DDR negotiations with non-IBTA switches.
+* The chip counters are adjusted at driver unload if there is
+* a non-zero delta.
+*/
+   u64 ibdeltainprog;
+   u64 ibsymdelta;
+   u64 ibsymsnap;
+   u64 iblnkerrdelta;
+   u64 iblnkerrsnap;
+   u64 ibcctrl; /* kr_ibcctrl shadow */
+   u64 ibcddrctrl; /* kr_ibcddrctrl shadow */
+   u64 chase_end;
+   u32 last_delay_mult;
+};
+
+/*
+ * This header file provides the declarations and common definitions
+ * for (mostly) manipulation of the SerDes blocks within the IBA7220.
+ * the functions declared should only be called from within other
+ * 7220-related files such as qib_iba7220.c or qib_sd7220.c.
+ */
+int qib_sd7220_presets(struct qib_devdata *dd);
+int qib_sd7220_init(struct qib_devdata *dd);
+int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, u8 *img,
+  int len, int offset);
+int qib_sd7220_prog_vfy(struct 

[PATCH v2 04/51] IB/qib: Add qib_6120_regs.h

2009-12-03 Thread Ralph Campbell
This creates the qib_6120_regs.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib_6120_regs.h |  977 +
 1 files changed, 977 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_6120_regs.h

diff --git a/drivers/infiniband/hw/qib/qib_6120_regs.h 
b/drivers/infiniband/hw/qib/qib_6120_regs.h
new file mode 100644
index 000..8108b89
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_6120_regs.h
@@ -0,0 +1,977 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *  - Redistributions of source code must retain the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer.
+ *
+ *  - Redistributions in binary form must reproduce the above
+ *copyright notice, this list of conditions and the following
+ *disclaimer in the documentation and/or other materials
+ *provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* This file is mechanically generated from RTL. Any hand-edits will be lost! 
*/
+
+#define QIB_6120_Revision_OFFS 0x0
+#define QIB_6120_Revision_R_Simulator_LSB 0x3F
+#define QIB_6120_Revision_R_Simulator_RMASK 0x1
+#define QIB_6120_Revision_Reserved_LSB 0x28
+#define QIB_6120_Revision_Reserved_RMASK 0x7F
+#define QIB_6120_Revision_BoardID_LSB 0x20
+#define QIB_6120_Revision_BoardID_RMASK 0xFF
+#define QIB_6120_Revision_R_SW_LSB 0x18
+#define QIB_6120_Revision_R_SW_RMASK 0xFF
+#define QIB_6120_Revision_R_Arch_LSB 0x10
+#define QIB_6120_Revision_R_Arch_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMajor_LSB 0x8
+#define QIB_6120_Revision_R_ChipRevMajor_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMinor_LSB 0x0
+#define QIB_6120_Revision_R_ChipRevMinor_RMASK 0xFF
+
+#define QIB_6120_Control_OFFS 0x8
+#define QIB_6120_Control_TxLatency_LSB 0x4
+#define QIB_6120_Control_TxLatency_RMASK 0x1
+#define QIB_6120_Control_PCIERetryBufDiagEn_LSB 0x3
+#define QIB_6120_Control_PCIERetryBufDiagEn_RMASK 0x1
+#define QIB_6120_Control_LinkEn_LSB 0x2
+#define QIB_6120_Control_LinkEn_RMASK 0x1
+#define QIB_6120_Control_FreezeMode_LSB 0x1
+#define QIB_6120_Control_FreezeMode_RMASK 0x1
+#define QIB_6120_Control_SyncReset_LSB 0x0
+#define QIB_6120_Control_SyncReset_RMASK 0x1
+
+#define QIB_6120_PageAlign_OFFS 0x10
+
+#define QIB_6120_PortCnt_OFFS 0x18
+
+#define QIB_6120_SendRegBase_OFFS 0x30
+
+#define QIB_6120_UserRegBase_OFFS 0x38
+
+#define QIB_6120_CntrRegBase_OFFS 0x40
+
+#define QIB_6120_Scratch_OFFS 0x48
+#define QIB_6120_Scratch_TopHalf_LSB 0x20
+#define QIB_6120_Scratch_TopHalf_RMASK 0x
+#define QIB_6120_Scratch_BottomHalf_LSB 0x0
+#define QIB_6120_Scratch_BottomHalf_RMASK 0x
+
+#define QIB_6120_IntBlocked_OFFS 0x60
+#define QIB_6120_IntBlocked_ErrorIntBlocked_LSB 0x1F
+#define QIB_6120_IntBlocked_ErrorIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioSetIntBlocked_LSB 0x1E
+#define QIB_6120_IntBlocked_PioSetIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_LSB 0x1D
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_LSB 0x1C
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved_LSB 0xF
+#define QIB_6120_IntBlocked_Reserved_RMASK 0x1FFF
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_LSB 0x10
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_LSB 0xF
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_LSB 0xE
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_LSB 0xD
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_LSB 0xC
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved1_LSB 0x5
+#define QIB_6120_IntBlocked_Reserved1_RMASK 0x7

[PATCH v2 03/51] IB/qib: Add qib.h

2009-12-03 Thread Ralph Campbell
This creates the qib.h file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/qib.h | 1437 +++
 1 files changed, 1437 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib.h

diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
new file mode 100644
index 000..d715eeb
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib.h
@@ -0,0 +1,1437 @@
+#ifndef _QIB_KERNEL_H
+#define _QIB_KERNEL_H
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 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.
+ */
+
+/*
+ * This header file is the base header file for qlogic_ib kernel code
+ * qib_user.h serves a similar purpose for user code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "qib_common.h"
+#include "qib_debug.h"
+#include "qib_verbs.h"
+
+/* only s/w major version of QLogic_IB we can handle */
+#define QIB_CHIP_VERS_MAJ 2U
+
+/* don't care about this except printing */
+#define QIB_CHIP_VERS_MIN 0U
+
+/* The Organization Unique Identifier (Mfg code), and its position in GUID */
+#define QIB_OUI 0x001175
+#define QIB_OUI_LSB 40
+
+/*
+ * per driver stats, either not device nor port-specific, or
+ * summed over all of the devices and ports.
+ * They are described by name via ipathfs filesystem, so layout
+ * and number of elements can change without breaking compatibility.
+ * If members are added or deleted qib_statnames[] in qib_fs.c must
+ * change to match.
+ */
+struct qlogic_ib_stats {
+   __u64 sps_ints; /* number of interrupts handled */
+   __u64 sps_errints; /* number of error interrupts */
+   __u64 sps_txerrs; /* tx-related packet errors */
+   __u64 sps_rcverrs; /* non-crc rcv packet errors */
+   __u64 sps_hwerrs; /* hardware errors reported (parity, etc.) */
+   __u64 sps_nopiobufs; /* no pio bufs avail from kernel */
+   __u64 sps_ctxts; /* number of contexts currently open */
+   __u64 sps_lenerrs; /* number of kernel packets where RHF != LRH len */
+   __u64 sps_buffull;
+   __u64 sps_hdrfull;
+};
+
+extern struct qlogic_ib_stats qib_stats;
+extern struct pci_error_handlers qib_pci_err_handler;
+extern struct pci_driver qib_driver;
+
+#define QIB_CHIP_SWVERSION QIB_CHIP_VERS_MAJ
+/*
+ * First-cut critierion for "device is active" is
+ * two thousand dwords combined Tx, Rx traffic per
+ * 5-second interval. SMA packets are 64 dwords,
+ * and occur "a few per second", presumably each way.
+ */
+#define QIB_TRAFFIC_ACTIVE_THRESHOLD (2000)
+
+/*
+ * Struct used to indicate which errors are logged in each of the
+ * error-counters that are logged to EEPROM. A counter is incremented
+ * _once_ (saturating at 255) for each event with any bits set in
+ * the error or hwerror register masks below.
+ */
+#define QIB_EEP_LOG_CNT (4)
+struct qib_eep_log_mask {
+   u64 errs_to_log;
+   u64 hwerrs_to_log;
+};
+
+/*
+ * Below contains all data related to a single context (formerly called port).
+ */
+struct qib_ctxtdata {
+   void **rcvegrbuf;
+   dma_addr_t *rcvegrbuf_phys;
+   /* rcvhdrq base, needs mmap before useful */
+   void *rcvhdrq;
+   /* kernel virtual address where hdrqtail is updated */
+   void *rcvhdrtail_kvaddr;
+   /*
+* temp buffer for expected send setup, allocated at open, instead
+* of each setup call
+*/
+   v

[PATCH v2 02/51] IB/qib: Add Makefile

2009-12-03 Thread Ralph Campbell
This creates the Makefile file.

Signed-off-by: Ralph Campbell 
---

 drivers/infiniband/hw/qib/Makefile |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Makefile

diff --git a/drivers/infiniband/hw/qib/Makefile 
b/drivers/infiniband/hw/qib/Makefile
new file mode 100644
index 000..c6515a1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_INFINIBAND_QIB) += ib_qib.o
+
+ib_qib-y := qib_cq.o qib_diag.o qib_dma.o qib_driver.o qib_eeprom.o \
+   qib_file_ops.o qib_fs.o qib_init.o qib_intr.o qib_keys.o \
+   qib_mad.o qib_mmap.o qib_mr.o qib_pcie.o qib_pio_copy.o \
+   qib_qp.o qib_qsfp.o qib_rc.o qib_ruc.o qib_sdma.o qib_srq.o \
+   qib_sysfs.o qib_twsi.o qib_tx.o qib_uc.o qib_ud.o \
+   qib_user_pages.o qib_user_sdma.o qib_verbs_mcast.o qib_iba7220.o \
+   qib_sd7220.o qib_sd7220_img.o qib_iba7322.o qib_verbs.o
+
+# 6120 has no fallback if no MSI interrupts, others can do INTx
+ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o
+
+ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
+ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


<    1   2   3   >