#define IPATH_CMD_MIN          16
 
-#define IPATH_CMD_USER_INIT    16      /* set up userspace */
+#define __IPATH_CMD_USER_INIT  16      /* old set up userspace (for old user code) */
 #define IPATH_CMD_PORT_INFO    17      /* find out what resources we got */
 #define IPATH_CMD_RECV_CTRL    18      /* control receipt of packets */
 #define IPATH_CMD_TID_UPDATE   19      /* update expected TID entries */
 #define IPATH_CMD_TID_FREE     20      /* free expected TID entries */
 #define IPATH_CMD_SET_PART_KEY 21      /* add partition key */
 #define IPATH_CMD_SLAVE_INFO   22      /* return info on slave processes */
+#define IPATH_CMD_ASSIGN_PORT  23      /* allocate HCA and port */
+#define IPATH_CMD_USER_INIT    24      /* set up userspace */
 
-#define IPATH_CMD_MAX          22
+#define IPATH_CMD_MAX          24
 
 struct ipath_port_info {
        __u32 num_active;       /* number of active units */
 
 
 static int ipath_open(struct inode *in, struct file *fp)
 {
-       /* The real work is performed later in ipath_do_user_init() */
+       /* The real work is performed later in ipath_assign_port() */
        fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
        return fp->private_data ? 0 : -ENOMEM;
 }
 
-static int ipath_do_user_init(struct file *fp,
+
+/* Get port early, so can set affinity prior to memory allocation */
+static int ipath_assign_port(struct file *fp,
                              const struct ipath_user_info *uinfo)
 {
        int ret;
-       struct ipath_portdata *pd;
-       struct ipath_devdata *dd;
-       u32 head32;
        int i_minor;
        unsigned swminor;
 
 
        mutex_unlock(&ipath_mutex);
 
-       if (ret)
-               goto done;
+done:
+       return ret;
+}
+
+
+static int ipath_do_user_init(struct file *fp,
+                             const struct ipath_user_info *uinfo)
+{
+       int ret;
+       struct ipath_portdata *pd;
+       struct ipath_devdata *dd;
+       u32 head32;
 
        pd = port_fp(fp);
        dd = pd->port_dd;
        consumed = sizeof(cmd.type);
 
        switch (cmd.type) {
+       case IPATH_CMD_ASSIGN_PORT:
+       case __IPATH_CMD_USER_INIT:
        case IPATH_CMD_USER_INIT:
                copy = sizeof(cmd.cmd.user_info);
                dest = &cmd.cmd.user_info;
 
        consumed += copy;
        pd = port_fp(fp);
-       if (!pd && cmd.type != IPATH_CMD_USER_INIT) {
+       if (!pd && cmd.type != __IPATH_CMD_USER_INIT &&
+               cmd.type != IPATH_CMD_ASSIGN_PORT) {
                ret = -EINVAL;
                goto bail;
        }
 
        switch (cmd.type) {
+       case IPATH_CMD_ASSIGN_PORT:
+               ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+               if (ret)
+                       goto bail;
+               break;
+       case __IPATH_CMD_USER_INIT:
+               /* backwards compatibility, get port first */
+               ret = ipath_assign_port(fp, &cmd.cmd.user_info);
+               if (ret)
+                       goto bail;
+               /* and fall through to current version. */
        case IPATH_CMD_USER_INIT:
                ret = ipath_do_user_init(fp, &cmd.cmd.user_info);
                if (ret)