#define IPATH_CMD_UNUSED_2     26
 #define IPATH_CMD_PIOAVAILUPD  27      /* force an update of PIOAvail reg */
 #define IPATH_CMD_POLL_TYPE    28      /* set the kind of polling we want */
+#define IPATH_CMD_ARMLAUNCH_CTRL       29 /* armlaunch detection control */
 
-#define IPATH_CMD_MAX          28
+#define IPATH_CMD_MAX          29
 
 /*
  * Poll types
                __u64 port_info;
                /* enable/disable receipt of packets */
                __u32 recv_ctrl;
+               /* enable/disable armlaunch errors (non-zero to enable) */
+               __u32 armlaunch_ctrl;
                /* partition key to set */
                __u16 part_key;
                /* user address of __u32 bitmask of active slaves */
 
                udelay(1);
        }
 
+       ipath_disable_armlaunch(dd);
+
        writeq(0, piobuf); /* length 0, no dwords actually sent */
        ipath_flush_wc();
 
 done:
        /* disarm piobuf, so it's available again */
        ipath_disarm_piobufs(dd, pbnum, 1);
+       ipath_enable_armlaunch(dd);
 }
 
 static int __devinit ipath_init_one(struct pci_dev *pdev,
        }
        return 0;
 }
+
+/*
+ * Disable and enable the armlaunch error.  Used for PIO bandwidth testing on
+ * the 7220, which is count-based, rather than trigger-based.  Safe for the
+ * driver check, since it's at init.   Not completely safe when used for
+ * user-mode checking, since some error checking can be lost, but not
+ * particularly risky, and only has problematic side-effects in the face of
+ * very buggy user code.  There is no reference counting, but that's also
+ * fine, given the intended use.
+ */
+void ipath_enable_armlaunch(struct ipath_devdata *dd)
+{
+       dd->ipath_lasterror &= ~INFINIPATH_E_SPIOARMLAUNCH;
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear,
+               INFINIPATH_E_SPIOARMLAUNCH);
+       dd->ipath_errormask |= INFINIPATH_E_SPIOARMLAUNCH;
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
+               dd->ipath_errormask);
+}
+
+void ipath_disable_armlaunch(struct ipath_devdata *dd)
+{
+       /* so don't re-enable if already set */
+       dd->ipath_maskederrs &= ~INFINIPATH_E_SPIOARMLAUNCH;
+       dd->ipath_errormask &= ~INFINIPATH_E_SPIOARMLAUNCH;
+       ipath_write_kreg(dd, dd->ipath_kregs->kr_errormask,
+               dd->ipath_errormask);
+}
+
 module_init(infinipath_init);
 module_exit(infinipath_cleanup);
 
                dest = &cmd.cmd.poll_type;
                src = &ucmd->cmd.poll_type;
                break;
+       case IPATH_CMD_ARMLAUNCH_CTRL:
+               copy = sizeof(cmd.cmd.armlaunch_ctrl);
+               dest = &cmd.cmd.armlaunch_ctrl;
+               src = &ucmd->cmd.armlaunch_ctrl;
+               break;
        default:
                ret = -EINVAL;
                goto bail;
        case IPATH_CMD_POLL_TYPE:
                pd->poll_type = cmd.cmd.poll_type;
                break;
+       case IPATH_CMD_ARMLAUNCH_CTRL:
+               if (cmd.cmd.armlaunch_ctrl)
+                       ipath_enable_armlaunch(pd->port_dd);
+               else
+                       ipath_disable_armlaunch(pd->port_dd);
+               break;
        }
 
        if (ret >= 0)
 
 int ipath_set_mtu(struct ipath_devdata *, u16);
 int ipath_set_lid(struct ipath_devdata *, u32, u8);
 int ipath_set_rx_pol_inv(struct ipath_devdata *dd, u8 new_pol_inv);
+void ipath_enable_armlaunch(struct ipath_devdata *);
+void ipath_disable_armlaunch(struct ipath_devdata *);
 
 /* for use in system calls, where we want to know device type, etc. */
 #define port_fp(fp) ((struct ipath_filedata *)(fp)->private_data)->pd