Re: [PATCH 06/13] ocxl: Driver code for 'generic' opencapi devices

2018-01-02 Thread Andrew Donnellan

On 19/12/17 02:21, Frederic Barrat wrote:

Add an ocxl driver to handle generic opencapi devices. Of course, it's
not meant to be the only opencapi driver, any device is free to
implement its own. But if a host application only needs basic services
like attaching to an opencapi adapter, have translation faults handled
or allocate AFU interrupts, it should suffice.

The AFU config space must follow the opencapi specification and use
the expected vendor/device ID to be seen by the generic driver.

The driver exposes the device AFUs as a char device in /dev/ocxl/

Note that the driver currently doesn't handle memory attached to the
opencapi device.

Signed-off-by: Frederic Barrat 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Alastair D'Silva 


A bunch of sparse warnings we should look at. (there's a few more that 
appear in later patches too)



---
  drivers/misc/ocxl/config.c| 718 ++
  drivers/misc/ocxl/context.c   | 237 +
  drivers/misc/ocxl/file.c  | 405 +
  drivers/misc/ocxl/link.c  | 610 
  drivers/misc/ocxl/main.c  |  40 +++
  drivers/misc/ocxl/ocxl_internal.h | 200 +++
  drivers/misc/ocxl/pasid.c | 114 ++
  drivers/misc/ocxl/pci.c   | 592 +++
  drivers/misc/ocxl/sysfs.c | 150 
  include/uapi/misc/ocxl.h  |  47 +++
  10 files changed, 3113 insertions(+)
  create mode 100644 drivers/misc/ocxl/config.c
  create mode 100644 drivers/misc/ocxl/context.c
  create mode 100644 drivers/misc/ocxl/file.c
  create mode 100644 drivers/misc/ocxl/link.c
  create mode 100644 drivers/misc/ocxl/main.c
  create mode 100644 drivers/misc/ocxl/ocxl_internal.h
  create mode 100644 drivers/misc/ocxl/pasid.c
  create mode 100644 drivers/misc/ocxl/pci.c
  create mode 100644 drivers/misc/ocxl/sysfs.c
  create mode 100644 include/uapi/misc/ocxl.h

diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
new file mode 100644
index ..bb2fde5967e2
--- /dev/null
+++ b/drivers/misc/ocxl/config.c
@@ -0,0 +1,718 @@
+/*
+ * Copyright 2017 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include "ocxl_internal.h"
+
+#define EXTRACT_BIT(val, bit) (!!(val & BIT(bit)))
+#define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s)
+
+#define OCXL_DVSEC_AFU_IDX_MASK  GENMASK(5, 0)
+#define OCXL_DVSEC_ACTAG_MASKGENMASK(11, 0)
+#define OCXL_DVSEC_PASID_MASKGENMASK(19, 0)
+#define OCXL_DVSEC_PASID_LOG_MASKGENMASK(4, 0)
+
+#define OCXL_DVSEC_TEMPL_VERSION 0x0
+#define OCXL_DVSEC_TEMPL_NAME0x4
+#define OCXL_DVSEC_TEMPL_AFU_VERSION 0x1C
+#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL 0x20
+#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ  0x28
+#define OCXL_DVSEC_TEMPL_MMIO_PP 0x30
+#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ  0x38
+#define OCXL_DVSEC_TEMPL_MEM_SZ  0x3C
+#define OCXL_DVSEC_TEMPL_WWID0x40
+
+#define OCXL_MAX_AFU_PER_FUNCTION 64
+#define OCXL_TEMPL_LEN0x58
+#define OCXL_TEMPL_NAME_LEN   24
+#define OCXL_CFG_TIMEOUT 3
+
+static int find_dvsec(struct pci_dev *dev, int dvsec_id)
+{
+   int vsec = 0;
+   u16 vendor, id;
+
+   while ((vsec = pci_find_next_ext_capability(dev, vsec,
+   OCXL_EXT_CAP_ID_DVSEC))) {
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
+   &vendor);
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
+   if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
+   return vsec;
+   }
+   return 0;
+}
+
+static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
+{
+   int vsec = 0;
+   u16 vendor, id;
+   u8 idx;
+
+   while ((vsec = pci_find_next_ext_capability(dev, vsec,
+   OCXL_EXT_CAP_ID_DVSEC))) {
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
+   &vendor);
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
+
+   if (vendor == PCI_VENDOR_ID_IBM &&
+   id == OCXL_DVSEC_AFU_CTRL_ID) {
+   pci_read_config_byte(dev,
+   vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
+   &idx);
+   if (idx == afu_idx)
+   return vsec;
+   }
+   }
+   return 0;
+}
+
+static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *f

[PATCH 06/13] ocxl: Driver code for 'generic' opencapi devices

2017-12-18 Thread Frederic Barrat
Add an ocxl driver to handle generic opencapi devices. Of course, it's
not meant to be the only opencapi driver, any device is free to
implement its own. But if a host application only needs basic services
like attaching to an opencapi adapter, have translation faults handled
or allocate AFU interrupts, it should suffice.

The AFU config space must follow the opencapi specification and use
the expected vendor/device ID to be seen by the generic driver.

The driver exposes the device AFUs as a char device in /dev/ocxl/

Note that the driver currently doesn't handle memory attached to the
opencapi device.

Signed-off-by: Frederic Barrat 
Signed-off-by: Andrew Donnellan 
Signed-off-by: Alastair D'Silva 
---
 drivers/misc/ocxl/config.c| 718 ++
 drivers/misc/ocxl/context.c   | 237 +
 drivers/misc/ocxl/file.c  | 405 +
 drivers/misc/ocxl/link.c  | 610 
 drivers/misc/ocxl/main.c  |  40 +++
 drivers/misc/ocxl/ocxl_internal.h | 200 +++
 drivers/misc/ocxl/pasid.c | 114 ++
 drivers/misc/ocxl/pci.c   | 592 +++
 drivers/misc/ocxl/sysfs.c | 150 
 include/uapi/misc/ocxl.h  |  47 +++
 10 files changed, 3113 insertions(+)
 create mode 100644 drivers/misc/ocxl/config.c
 create mode 100644 drivers/misc/ocxl/context.c
 create mode 100644 drivers/misc/ocxl/file.c
 create mode 100644 drivers/misc/ocxl/link.c
 create mode 100644 drivers/misc/ocxl/main.c
 create mode 100644 drivers/misc/ocxl/ocxl_internal.h
 create mode 100644 drivers/misc/ocxl/pasid.c
 create mode 100644 drivers/misc/ocxl/pci.c
 create mode 100644 drivers/misc/ocxl/sysfs.c
 create mode 100644 include/uapi/misc/ocxl.h

diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
new file mode 100644
index ..bb2fde5967e2
--- /dev/null
+++ b/drivers/misc/ocxl/config.c
@@ -0,0 +1,718 @@
+/*
+ * Copyright 2017 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include "ocxl_internal.h"
+
+#define EXTRACT_BIT(val, bit) (!!(val & BIT(bit)))
+#define EXTRACT_BITS(val, s, e) ((val & GENMASK(e, s)) >> s)
+
+#define OCXL_DVSEC_AFU_IDX_MASK  GENMASK(5, 0)
+#define OCXL_DVSEC_ACTAG_MASKGENMASK(11, 0)
+#define OCXL_DVSEC_PASID_MASKGENMASK(19, 0)
+#define OCXL_DVSEC_PASID_LOG_MASKGENMASK(4, 0)
+
+#define OCXL_DVSEC_TEMPL_VERSION 0x0
+#define OCXL_DVSEC_TEMPL_NAME0x4
+#define OCXL_DVSEC_TEMPL_AFU_VERSION 0x1C
+#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL 0x20
+#define OCXL_DVSEC_TEMPL_MMIO_GLOBAL_SZ  0x28
+#define OCXL_DVSEC_TEMPL_MMIO_PP 0x30
+#define OCXL_DVSEC_TEMPL_MMIO_PP_SZ  0x38
+#define OCXL_DVSEC_TEMPL_MEM_SZ  0x3C
+#define OCXL_DVSEC_TEMPL_WWID0x40
+
+#define OCXL_MAX_AFU_PER_FUNCTION 64
+#define OCXL_TEMPL_LEN0x58
+#define OCXL_TEMPL_NAME_LEN   24
+#define OCXL_CFG_TIMEOUT 3
+
+static int find_dvsec(struct pci_dev *dev, int dvsec_id)
+{
+   int vsec = 0;
+   u16 vendor, id;
+
+   while ((vsec = pci_find_next_ext_capability(dev, vsec,
+   OCXL_EXT_CAP_ID_DVSEC))) {
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
+   &vendor);
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
+   if (vendor == PCI_VENDOR_ID_IBM && id == dvsec_id)
+   return vsec;
+   }
+   return 0;
+}
+
+static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
+{
+   int vsec = 0;
+   u16 vendor, id;
+   u8 idx;
+
+   while ((vsec = pci_find_next_ext_capability(dev, vsec,
+   OCXL_EXT_CAP_ID_DVSEC))) {
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_VENDOR_OFFSET,
+   &vendor);
+   pci_read_config_word(dev, vsec + OCXL_DVSEC_ID_OFFSET, &id);
+
+   if (vendor == PCI_VENDOR_ID_IBM &&
+   id == OCXL_DVSEC_AFU_CTRL_ID) {
+   pci_read_config_byte(dev,
+   vsec + OCXL_DVSEC_AFU_CTRL_AFU_IDX,
+   &idx);
+   if (idx == afu_idx)
+   return vsec;
+   }
+   }
+   return 0;
+}
+
+static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
+{
+   u16 val;
+   int pos;
+
+   pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PASID);
+   if (!pos) {
+   /*
+* PASID