cxl: Implement an ioctl to fetch afu card-id, offset-id and mode
authorVaibhav Jain <vaibhav@linux.vnet.ibm.com>
Wed, 29 Apr 2015 10:17:23 +0000 (15:47 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 3 Jun 2015 03:27:15 +0000 (13:27 +1000)
Given a file descriptor on an afu device, libcxl currently uses the
major/minor number obtained from fstat on the fd to construct path to
the afu's sysfs directory. However it is possible that rather than using
one of the device in /dev/cxl, a kernel driver creates its own device
which export generic cxl interface to the userspace. This causes
problems with libcxl as it tries to use a wrong major/minor number to
construct the sysfs path and fail.

So this patch introduces a new ioctl called CXL_IOCTL_GET_AFU_ID on the
afu file descriptor to fetch the cxl_afu_id struct that holds the
card/offset-id and mode information. These info is then used by libcxl to
construct the correct path to the afu sysfs directory.

Testing:
- Build against pseries be/le configs
- Testing with corresponding libcxl changes to verify that it constructs
  right sysfs path to the afu.

Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
drivers/misc/cxl/cxl.h
drivers/misc/cxl/file.c
include/uapi/misc/cxl.h

index a1cee4767ec6c571344e93ca874e8bdac83ed3a5..9f280e3e742e4a67c9915d87dbeb987e09322f21 100644 (file)
@@ -315,8 +315,6 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};
 #define CXL_MAX_SLICES 4
 #define MAX_AFU_MMIO_REGS 3
 
-#define CXL_MODE_DEDICATED   0x1
-#define CXL_MODE_DIRECTED    0x2
 #define CXL_MODE_TIME_SLICED 0x4
 #define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)
 
index 2364bcadb9a94c195abc6398a77c734f45a7e468..98552344382956eeae3021772fc42bc2ef050b03 100644 (file)
@@ -212,6 +212,25 @@ static long afu_ioctl_process_element(struct cxl_context *ctx,
        return 0;
 }
 
+static long afu_ioctl_get_afu_id(struct cxl_context *ctx,
+                                struct cxl_afu_id __user *upafuid)
+{
+       struct cxl_afu_id afuid = { 0 };
+
+       afuid.card_id = ctx->afu->adapter->adapter_num;
+       afuid.afu_offset = ctx->afu->slice;
+       afuid.afu_mode = ctx->afu->current_mode;
+
+       /* set the flag bit in case the afu is a slave */
+       if (ctx->afu->current_mode == CXL_MODE_DIRECTED && !ctx->master)
+               afuid.flags |= CXL_AFUID_FLAG_SLAVE;
+
+       if (copy_to_user(upafuid, &afuid, sizeof(afuid)))
+               return -EFAULT;
+
+       return 0;
+}
+
 static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct cxl_context *ctx = file->private_data;
@@ -225,6 +244,9 @@ static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return afu_ioctl_start_work(ctx, (struct cxl_ioctl_start_work __user *)arg);
        case CXL_IOCTL_GET_PROCESS_ELEMENT:
                return afu_ioctl_process_element(ctx, (__u32 __user *)arg);
+       case CXL_IOCTL_GET_AFU_ID:
+               return afu_ioctl_get_afu_id(ctx, (struct cxl_afu_id __user *)
+                                           arg);
        }
        return -EINVAL;
 }
index cd6d789b73ec4cd15c116f2302c305db845f9385..99a8ca15fe648c9d176325eb2ed9c952a5ac7088 100644 (file)
@@ -32,10 +32,32 @@ struct cxl_ioctl_start_work {
 #define CXL_START_WORK_ALL             (CXL_START_WORK_AMR |\
                                         CXL_START_WORK_NUM_IRQS)
 
+
+/* Possible modes that an afu can be in */
+#define CXL_MODE_DEDICATED   0x1
+#define CXL_MODE_DIRECTED    0x2
+
+/* possible flags for the cxl_afu_id flags field */
+#define CXL_AFUID_FLAG_SLAVE    0x1  /* In directed-mode afu is in slave mode */
+
+struct cxl_afu_id {
+       __u64 flags;     /* One of CXL_AFUID_FLAG_X */
+       __u32 card_id;
+       __u32 afu_offset;
+       __u32 afu_mode;  /* one of the CXL_MODE_X */
+       __u32 reserved1;
+       __u64 reserved2;
+       __u64 reserved3;
+       __u64 reserved4;
+       __u64 reserved5;
+       __u64 reserved6;
+};
+
 /* ioctl numbers */
 #define CXL_MAGIC 0xCA
 #define CXL_IOCTL_START_WORK           _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
 #define CXL_IOCTL_GET_PROCESS_ELEMENT  _IOR(CXL_MAGIC, 0x01, __u32)
+#define CXL_IOCTL_GET_AFU_ID            _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
 
 #define CXL_READ_MIN_SIZE 0x1000 /* 4K */