IB/ipath: Force PIOAvail update entry point
authorArthur Jones <arthur.jones@qlogic.com>
Thu, 15 Mar 2007 21:45:05 +0000 (14:45 -0700)
committerRoland Dreier <rolandd@cisco.com>
Thu, 19 Apr 2007 03:20:58 +0000 (20:20 -0700)
Due to a chip bug, the PIOAvail register is not always updated to
memory.  This patch allows userspace to force an update.

Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ipath/ipath_common.h
drivers/infiniband/hw/ipath/ipath_file_ops.c

index 048b928bb4bf2fbda7ffffe186b95ed6853092d5..10c008f22ba6947b9a5cf9c9d75f5cb976651452 100644 (file)
@@ -352,7 +352,7 @@ struct ipath_base_info {
  * may not be implemented; the user code must deal with this if it
  * cares, or it must abort after initialization reports the difference.
  */
-#define IPATH_USER_SWMINOR 4
+#define IPATH_USER_SWMINOR 5
 
 #define IPATH_USER_SWVERSION ((IPATH_USER_SWMAJOR<<16) | IPATH_USER_SWMINOR)
 
@@ -429,8 +429,11 @@ struct ipath_user_info {
 #define __IPATH_CMD_SLAVE_INFO 22      /* return info on slave processes (for old user code) */
 #define IPATH_CMD_ASSIGN_PORT  23      /* allocate HCA and port */
 #define IPATH_CMD_USER_INIT    24      /* set up userspace */
+#define IPATH_CMD_UNUSED_1     25
+#define IPATH_CMD_UNUSED_2     26
+#define IPATH_CMD_PIOAVAILUPD  27      /* force an update of PIOAvail reg */
 
-#define IPATH_CMD_MAX          24
+#define IPATH_CMD_MAX          27
 
 struct ipath_port_info {
        __u32 num_active;       /* number of active units */
index bb53bde80ee8a9ec12908766ebc0190cdb6f6261..9ca582b65fe98dd420a4e4e21d8fccb400cd897e 100644 (file)
@@ -2047,6 +2047,17 @@ static int ipath_get_slave_info(struct ipath_portdata *pd,
        return ret;
 }
 
+static int ipath_force_pio_avail_update(struct ipath_devdata *dd)
+{
+       u64 reg = dd->ipath_sendctrl;
+
+       clear_bit(IPATH_S_PIOBUFAVAILUPD, &reg);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, reg);
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, dd->ipath_sendctrl);
+
+       return 0;
+}
+
 static ssize_t ipath_write(struct file *fp, const char __user *data,
                           size_t count, loff_t *off)
 {
@@ -2106,22 +2117,30 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
                dest = &cmd.cmd.slave_mask_addr;
                src = &ucmd->cmd.slave_mask_addr;
                break;
+       case IPATH_CMD_PIOAVAILUPD:     // force an update of PIOAvail reg
+               copy = 0;
+               src = NULL;
+               dest = NULL;
+               break;
        default:
                ret = -EINVAL;
                goto bail;
        }
 
-       if ((count - consumed) < copy) {
-               ret = -EINVAL;
-               goto bail;
-       }
+       if (copy) {
+               if ((count - consumed) < copy) {
+                       ret = -EINVAL;
+                       goto bail;
+               }
 
-       if (copy_from_user(dest, src, copy)) {
-               ret = -EFAULT;
-               goto bail;
+               if (copy_from_user(dest, src, copy)) {
+                       ret = -EFAULT;
+                       goto bail;
+               }
+
+               consumed += copy;
        }
 
-       consumed += copy;
        pd = port_fp(fp);
        if (!pd && cmd.type != __IPATH_CMD_USER_INIT &&
                cmd.type != IPATH_CMD_ASSIGN_PORT) {
@@ -2172,6 +2191,9 @@ static ssize_t ipath_write(struct file *fp, const char __user *data,
                                           (void __user *) (unsigned long)
                                           cmd.cmd.slave_mask_addr);
                break;
+       case IPATH_CMD_PIOAVAILUPD:
+               ret = ipath_force_pio_avail_update(pd->port_dd);
+               break;
        }
 
        if (ret >= 0)