get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/63008/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 63008,
    "url": "http://patches.dpdk.org/api/patches/63008/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1573722187-148846-12-git-send-email-rosen.xu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1573722187-148846-12-git-send-email-rosen.xu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1573722187-148846-12-git-send-email-rosen.xu@intel.com",
    "date": "2019-11-14T09:02:59",
    "name": "[v18,11/19] raw/ifpga: add PCIe BDF devices tree scan",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "789be774535a1c3a8962be2247210b66a1ef0be8",
    "submitter": {
        "id": 946,
        "url": "http://patches.dpdk.org/api/people/946/?format=api",
        "name": "Xu, Rosen",
        "email": "rosen.xu@intel.com"
    },
    "delegate": {
        "id": 31221,
        "url": "http://patches.dpdk.org/api/users/31221/?format=api",
        "username": "yexl",
        "first_name": "xiaolong",
        "last_name": "ye",
        "email": "xiaolong.ye@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1573722187-148846-12-git-send-email-rosen.xu@intel.com/mbox/",
    "series": [
        {
            "id": 7455,
            "url": "http://patches.dpdk.org/api/series/7455/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=7455",
            "date": "2019-11-14T09:02:48",
            "name": "add PCIe AER disable and IRQ support for ipn3ke",
            "version": 18,
            "mbox": "http://patches.dpdk.org/series/7455/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/63008/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/63008/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 56324A04C2;\n\tThu, 14 Nov 2019 10:06:11 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 85B461BED5;\n\tThu, 14 Nov 2019 10:04:54 +0100 (CET)",
            "from mga17.intel.com (mga17.intel.com [192.55.52.151])\n by dpdk.org (Postfix) with ESMTP id 0336A1BEBF\n for <dev@dpdk.org>; Thu, 14 Nov 2019 10:04:46 +0100 (CET)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n 14 Nov 2019 01:04:46 -0800",
            "from dpdk-rosen-02.sh.intel.com ([10.67.110.156])\n by fmsmga006.fm.intel.com with ESMTP; 14 Nov 2019 01:04:45 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.68,302,1569308400\"; d=\"scan'208\";a=\"406259576\"",
        "From": "Rosen Xu <rosen.xu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "rosen.xu@intel.com, tianfei.zhang@intel.com, andy.pei@intel.com,\n xiaolong.ye@intel.com, ferruh.yigit@intel.com",
        "Date": "Thu, 14 Nov 2019 17:02:59 +0800",
        "Message-Id": "<1573722187-148846-12-git-send-email-rosen.xu@intel.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1573722187-148846-1-git-send-email-rosen.xu@intel.com>",
        "References": "<1571917119-149534-2-git-send-email-andy.pei@intel.com>\n <1573722187-148846-1-git-send-email-rosen.xu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v18 11/19] raw/ifpga: add PCIe BDF devices tree\n\tscan",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add PCIe BDF devices tree scan for ipn3ke.\n\nSigned-off-by: Rosen Xu <rosen.xu@intel.com>\nSigned-off-by: Andy Pei <andy.pei@intel.com>\n---\n drivers/raw/ifpga/ifpga_rawdev.c | 551 ++++++++++++++++++++++++++++++++++++++-\n drivers/raw/ifpga/ifpga_rawdev.h |  16 ++\n 2 files changed, 562 insertions(+), 5 deletions(-)",
    "diff": "diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c\nindex 977dfcf..8d633e0 100644\n--- a/drivers/raw/ifpga/ifpga_rawdev.c\n+++ b/drivers/raw/ifpga/ifpga_rawdev.c\n@@ -8,6 +8,8 @@\n #include <unistd.h>\n #include <sys/types.h>\n #include <fcntl.h>\n+#include <sys/ioctl.h>\n+#include <sys/epoll.h>\n #include <rte_log.h>\n #include <rte_bus.h>\n #include <rte_malloc.h>\n@@ -17,7 +19,7 @@\n #include <rte_bus_pci.h>\n #include <rte_kvargs.h>\n #include <rte_alarm.h>\n-\n+#include <rte_interrupts.h>\n #include <rte_errno.h>\n #include <rte_per_lcore.h>\n #include <rte_memory.h>\n@@ -25,6 +27,7 @@\n #include <rte_eal.h>\n #include <rte_common.h>\n #include <rte_bus_vdev.h>\n+#include <rte_string_fns.h>\n \n #include \"base/opae_hw_api.h\"\n #include \"base/opae_ifpga_hw_api.h\"\n@@ -37,6 +40,12 @@\n #include \"ifpga_rawdev.h\"\n #include \"ipn3ke_rawdev_api.h\"\n \n+#define RTE_PCI_EXT_CAP_ID_ERR           0x01\t/* Advanced Error Reporting */\n+#define RTE_PCI_CFG_SPACE_SIZE           256\n+#define RTE_PCI_CFG_SPACE_EXP_SIZE       4096\n+#define RTE_PCI_EXT_CAP_ID(header)       (int)(header & 0x0000ffff)\n+#define RTE_PCI_EXT_CAP_NEXT(header)     ((header >> 20) & 0xffc)\n+\n int ifpga_rawdev_logtype;\n \n #define PCI_VENDOR_ID_INTEL          0x8086\n@@ -64,6 +73,494 @@\n \t{ .vendor_id = 0, /* sentinel */ },\n };\n \n+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];\n+\n+static int ifpga_monitor_start;\n+static pthread_t ifpga_monitor_start_thread;\n+\n+static struct ifpga_rawdev *\n+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);\n+static int set_surprise_link_check_aer(\n+\t\tstruct ifpga_rawdev *ifpga_rdev, int force_disable);\n+static int ifpga_pci_find_next_ext_capability(unsigned int fd,\n+\t\tint start, int cap);\n+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);\n+\n+struct ifpga_rawdev *\n+ifpga_rawdev_get(const struct rte_rawdev *rawdev)\n+{\n+\tstruct ifpga_rawdev *dev;\n+\tunsigned int i;\n+\n+\tif (rawdev == NULL)\n+\t\treturn NULL;\n+\n+\tfor (i = 0; i < IFPGA_RAWDEV_NUM; i++) {\n+\t\tdev = &ifpga_rawdevices[i];\n+\t\tif (dev->rawdev == rawdev)\n+\t\t\treturn dev;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static inline uint8_t\n+ifpga_rawdev_find_free_device_index(void)\n+{\n+\tuint16_t dev_id;\n+\n+\tfor (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {\n+\t\tif (ifpga_rawdevices[dev_id].rawdev == NULL)\n+\t\t\treturn dev_id;\n+\t}\n+\n+\treturn IFPGA_RAWDEV_NUM;\n+}\n+static struct ifpga_rawdev *\n+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)\n+{\n+\tstruct ifpga_rawdev *dev;\n+\tuint16_t dev_id;\n+\n+\tdev = ifpga_rawdev_get(rawdev);\n+\tif (dev != NULL) {\n+\t\tIFPGA_RAWDEV_PMD_ERR(\"Event device already allocated!\");\n+\t\treturn NULL;\n+\t}\n+\n+\tdev_id = ifpga_rawdev_find_free_device_index();\n+\tif (dev_id == IFPGA_RAWDEV_NUM) {\n+\t\tIFPGA_RAWDEV_PMD_ERR(\"Reached maximum number of raw devices\");\n+\t\treturn NULL;\n+\t}\n+\n+\tdev = &ifpga_rawdevices[dev_id];\n+\tdev->rawdev = rawdev;\n+\tdev->dev_id = dev_id;\n+\n+\treturn dev;\n+}\n+\n+static int ifpga_pci_find_next_ext_capability(unsigned int fd,\n+int start, int cap)\n+{\n+\tuint32_t header;\n+\tint ttl;\n+\tint pos = RTE_PCI_CFG_SPACE_SIZE;\n+\tint ret;\n+\n+\t/* minimum 8 bytes per capability */\n+\tttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;\n+\n+\tif (start)\n+\t\tpos = start;\n+\tret = pread(fd, &header, sizeof(header), pos);\n+\tif (ret == -1)\n+\t\treturn -1;\n+\n+\t/*\n+\t * If we have no capabilities, this is indicated by cap ID,\n+\t * cap version and next pointer all being 0.\n+\t */\n+\tif (header == 0)\n+\t\treturn 0;\n+\n+\twhile (ttl-- > 0) {\n+\t\tif (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)\n+\t\t\treturn pos;\n+\n+\t\tpos = RTE_PCI_EXT_CAP_NEXT(header);\n+\t\tif (pos < RTE_PCI_CFG_SPACE_SIZE)\n+\t\t\tbreak;\n+\t\tret = pread(fd, &header, sizeof(header), pos);\n+\t\tif (ret == -1)\n+\t\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)\n+{\n+\treturn ifpga_pci_find_next_ext_capability(fd, 0, cap);\n+}\n+\n+static int ifpga_get_dev_vendor_id(const char *bdf,\n+\tuint32_t *dev_id, uint32_t *vendor_id)\n+{\n+\tint fd;\n+\tchar path[1024];\n+\tint ret;\n+\tuint32_t header;\n+\n+\tstrlcpy(path, \"/sys/bus/pci/devices/\", sizeof(path));\n+\tstrlcat(path, bdf, sizeof(path));\n+\tstrlcat(path, \"/config\", sizeof(path));\n+\tfd = open(path, O_RDWR);\n+\tif (fd < 0)\n+\t\treturn -1;\n+\tret = pread(fd, &header, sizeof(header), 0);\n+\tif (ret == -1) {\n+\t\tclose(fd);\n+\t\treturn -1;\n+\t}\n+\t(*vendor_id) = header & 0xffff;\n+\t(*dev_id) = (header >> 16) & 0xffff;\n+\tclose(fd);\n+\n+\treturn 0;\n+}\n+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,\n+\tconst char *bdf)\n+{\n+\tchar path[1024] = \"/sys/bus/pci/devices/0000:\";\n+\tchar link[1024], link1[1024];\n+\tchar dir[1024] = \"/sys/devices/\";\n+\tchar *c;\n+\tint ret;\n+\tchar sub_brg_bdf[4][16];\n+\tint point;\n+\tDIR *dp = NULL;\n+\tstruct dirent *entry;\n+\tint i, j;\n+\n+\tunsigned int dom, bus, dev;\n+\tint func;\n+\tuint32_t dev_id, vendor_id;\n+\n+\tstrlcat(path, bdf, sizeof(path));\n+\tmemset(link, 0, sizeof(link));\n+\tmemset(link1, 0, sizeof(link1));\n+\tret = readlink(path, link, (sizeof(link)-1));\n+\tif (ret == -1)\n+\t\treturn -1;\n+\tstrlcpy(link1, link, sizeof(link1));\n+\tmemset(ifpga_dev->parent_bdf, 0, 16);\n+\tpoint = strlen(link);\n+\tif (point < 39)\n+\t\treturn -1;\n+\tpoint -= 39;\n+\tlink[point] = 0;\n+\tif (point < 12)\n+\t\treturn -1;\n+\tpoint -= 12;\n+\trte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);\n+\n+\tpoint = strlen(link1);\n+\tif (point < 26)\n+\t\treturn -1;\n+\tpoint -= 26;\n+\tlink1[point] = 0;\n+\tif (point < 12)\n+\t\treturn -1;\n+\tpoint -= 12;\n+\tc = strchr(link1, 'p');\n+\tif (!c)\n+\t\treturn -1;\n+\tstrlcat(dir, c, sizeof(dir));\n+\n+\t/* scan folder */\n+\tdp = opendir(dir);\n+\tif (dp == NULL)\n+\t\treturn -1;\n+\ti = 0;\n+\twhile ((entry = readdir(dp)) != NULL) {\n+\t\tif (i >= 4)\n+\t\t\tbreak;\n+\t\tif (entry->d_name[0] == '.')\n+\t\t\tcontinue;\n+\t\tif (strlen(entry->d_name) > 12)\n+\t\t\tcontinue;\n+\t\tif (sscanf(entry->d_name, \"%x:%x:%x.%d\",\n+\t\t\t&dom, &bus, &dev, &func) < 4)\n+\t\t\tcontinue;\n+\t\telse {\n+\t\t\tstrlcpy(sub_brg_bdf[i],\n+\t\t\t\tentry->d_name,\n+\t\t\t\tsizeof(sub_brg_bdf[i]));\n+\t\t\ti++;\n+\t\t}\n+\t}\n+\tclosedir(dp);\n+\n+\t/* get fpga and fvl */\n+\tj = 0;\n+\tfor (i = 0; i < 4; i++) {\n+\t\tstrlcpy(link, dir, sizeof(link));\n+\t\tstrlcat(link, \"/\", sizeof(link));\n+\t\tstrlcat(link, sub_brg_bdf[i], sizeof(link));\n+\t\tdp = opendir(link);\n+\t\tif (dp == NULL)\n+\t\t\treturn -1;\n+\t\twhile ((entry = readdir(dp)) != NULL) {\n+\t\t\tif (j >= 8)\n+\t\t\t\tbreak;\n+\t\t\tif (entry->d_name[0] == '.')\n+\t\t\t\tcontinue;\n+\n+\t\t\tif (strlen(entry->d_name) > 12)\n+\t\t\t\tcontinue;\n+\t\t\tif (sscanf(entry->d_name, \"%x:%x:%x.%d\",\n+\t\t\t\t&dom, &bus, &dev, &func) < 4)\n+\t\t\t\tcontinue;\n+\t\t\telse {\n+\t\t\t\tif (ifpga_get_dev_vendor_id(entry->d_name,\n+\t\t\t\t\t&dev_id, &vendor_id))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tif (vendor_id == 0x8086 &&\n+\t\t\t\t\t(dev_id == 0x0CF8 ||\n+\t\t\t\t\tdev_id == 0x0D58 ||\n+\t\t\t\t\tdev_id == 0x1580)) {\n+\t\t\t\t\tstrlcpy(ifpga_dev->fvl_bdf[j],\n+\t\t\t\t\t\tentry->d_name,\n+\t\t\t\t\t\tsizeof(ifpga_dev->fvl_bdf[j]));\n+\t\t\t\t\tj++;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t\tclosedir(dp);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+#define HIGH_FATAL(_sens, value)\\\n+\t(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\\\n+\t (value > (_sens)->high_fatal))\n+\n+#define HIGH_WARN(_sens, value)\\\n+\t(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\\\n+\t (value > (_sens)->high_warn))\n+\n+#define LOW_FATAL(_sens, value)\\\n+\t(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\\\n+\t (value > (_sens)->low_fatal))\n+\n+#define LOW_WARN(_sens, value)\\\n+\t(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\\\n+\t (value > (_sens)->low_warn))\n+\n+#define AUX_VOLTAGE_WARN 11400\n+\n+static int\n+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,\n+\t       bool *gsd_start)\n+{\n+\tstruct opae_adapter *adapter;\n+\tstruct opae_manager *mgr;\n+\tstruct opae_sensor_info *sensor;\n+\tunsigned int value;\n+\tint ret;\n+\n+\tadapter = ifpga_rawdev_get_priv(raw_dev);\n+\tif (!adapter)\n+\t\treturn -ENODEV;\n+\n+\tmgr = opae_adapter_get_mgr(adapter);\n+\tif (!mgr)\n+\t\treturn -ENODEV;\n+\n+\topae_mgr_for_each_sensor(sensor) {\n+\t\tif (!(sensor->flags & OPAE_SENSOR_VALID))\n+\t\t\tgoto fail;\n+\n+\t\tret = opae_mgr_get_sensor_value(mgr, sensor, &value);\n+\t\tif (ret)\n+\t\t\tgoto fail;\n+\n+\t\tif (value == 0xdeadbeef) {\n+\t\t\tIFPGA_RAWDEV_PMD_ERR(\"sensor %s is invalid value %x\\n\",\n+\t\t\t\t\tsensor->name, value);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* monitor temperature sensors */\n+\t\tif (!strcmp(sensor->name, \"Board Temperature\") ||\n+\t\t\t\t!strcmp(sensor->name, \"FPGA Die Temperature\")) {\n+\t\t\tIFPGA_RAWDEV_PMD_INFO(\"read sensor %s %d %d %d\\n\",\n+\t\t\t\t\tsensor->name, value, sensor->high_warn,\n+\t\t\t\t\tsensor->high_fatal);\n+\n+\t\t\tif (HIGH_WARN(sensor, value) ||\n+\t\t\t\tLOW_WARN(sensor, value)) {\n+\t\t\t\tIFPGA_RAWDEV_PMD_INFO(\"%s reach theshold %d\\n\",\n+\t\t\t\t\tsensor->name, value);\n+\t\t\t\t*gsd_start = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* monitor 12V AUX sensor */\n+\t\tif (!strcmp(sensor->name, \"12V AUX Voltage\")) {\n+\t\t\tif (value < AUX_VOLTAGE_WARN) {\n+\t\t\t\tIFPGA_RAWDEV_PMD_INFO(\"%s reach theshold %d\\n\",\n+\t\t\t\t\t\tsensor->name, value);\n+\t\t\t\t*gsd_start = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+fail:\n+\treturn -EFAULT;\n+}\n+\n+static int set_surprise_link_check_aer(\n+\tstruct ifpga_rawdev *ifpga_rdev, int force_disable)\n+{\n+\tstruct rte_rawdev *rdev;\n+\tint fd = -1;\n+\tchar path[1024];\n+\tint pos;\n+\tint ret;\n+\tuint32_t data;\n+\tbool enable = 0;\n+\tuint32_t aer_new0, aer_new1;\n+\n+\tif (!ifpga_rdev) {\n+\t\tprintf(\"\\n device does not exist\\n\");\n+\t\treturn -EFAULT;\n+\t}\n+\n+\trdev = ifpga_rdev->rawdev;\n+\tif (ifpga_rdev->aer_enable)\n+\t\treturn -EFAULT;\n+\tif (ifpga_monitor_sensor(rdev, &enable))\n+\t\treturn -EFAULT;\n+\tif (enable || force_disable) {\n+\t\tIFPGA_RAWDEV_PMD_ERR(\"Set AER, pls graceful shutdown\\n\");\n+\t\tifpga_rdev->aer_enable = 1;\n+\t\t/* get bridge fd */\n+\t\tstrlcpy(path, \"/sys/bus/pci/devices/\", sizeof(path));\n+\t\tstrlcat(path, ifpga_rdev->parent_bdf, sizeof(path));\n+\t\tstrlcat(path, \"/config\", sizeof(path));\n+\t\tfd = open(path, O_RDWR);\n+\t\tif (fd < 0)\n+\t\t\tgoto end;\n+\t\tpos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);\n+\t\tif (!pos)\n+\t\t\tgoto end;\n+\t\t/* save previout ECAP_AER+0x08 */\n+\t\tret = pread(fd, &data, sizeof(data), pos+0x08);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\t\tifpga_rdev->aer_old[0] = data;\n+\t\t/* save previout ECAP_AER+0x14 */\n+\t\tret = pread(fd, &data, sizeof(data), pos+0x14);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\t\tifpga_rdev->aer_old[1] = data;\n+\n+\t\t/* set ECAP_AER+0x08 to 0xFFFFFFFF */\n+\t\tdata = 0xffffffff;\n+\t\tret = pwrite(fd, &data, 4, pos+0x08);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\t\t/* set ECAP_AER+0x14 to 0xFFFFFFFF */\n+\t\tret = pwrite(fd, &data, 4, pos+0x14);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\n+\t\t/* read current ECAP_AER+0x08 */\n+\t\tret = pread(fd, &data, sizeof(data), pos+0x08);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\t\taer_new0 = data;\n+\t\t/* read current ECAP_AER+0x14 */\n+\t\tret = pread(fd, &data, sizeof(data), pos+0x14);\n+\t\tif (ret == -1)\n+\t\t\tgoto end;\n+\t\taer_new1 = data;\n+\n+\t\tif (fd != -1)\n+\t\t\tclose(fd);\n+\n+\t\tprintf(\">>>>>>Set AER %x,%x %x,%x\\n\",\n+\t\t\tifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],\n+\t\t\taer_new0, aer_new1);\n+\n+\t\treturn 1;\n+\t\t}\n+\n+end:\n+\tif (fd != -1)\n+\t\tclose(fd);\n+\treturn -EFAULT;\n+}\n+\n+static void *\n+ifpga_rawdev_gsd_handle(__rte_unused void *param)\n+{\n+\tstruct ifpga_rawdev *ifpga_rdev;\n+\tint i;\n+\tint gsd_enable, ret;\n+#define MS 1000\n+\n+\twhile (1) {\n+\t\tgsd_enable = 0;\n+\t\tfor (i = 0; i < IFPGA_RAWDEV_NUM; i++) {\n+\t\t\tifpga_rdev = &ifpga_rawdevices[i];\n+\t\t\tif (ifpga_rdev->rawdev) {\n+\t\t\t\tret = set_surprise_link_check_aer(ifpga_rdev,\n+\t\t\t\t\tgsd_enable);\n+\t\t\t\tif (ret == 1 && !gsd_enable) {\n+\t\t\t\t\tgsd_enable = 1;\n+\t\t\t\t\ti = -1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (gsd_enable)\n+\t\t\tprintf(\">>>>>>Pls Shutdown APP\\n\");\n+\n+\t\trte_delay_us(100 * MS);\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static int\n+ifpga_monitor_start_func(void)\n+{\n+\tint ret;\n+\n+\tif (ifpga_monitor_start == 0) {\n+\t\tret = pthread_create(&ifpga_monitor_start_thread,\n+\t\t\tNULL,\n+\t\t\tifpga_rawdev_gsd_handle, NULL);\n+\t\tif (ret) {\n+\t\t\tIFPGA_RAWDEV_PMD_ERR(\n+\t\t\t\t\"Fail to create ifpga nonitor thread\");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tifpga_monitor_start = 1;\n+\t}\n+\n+\treturn 0;\n+}\n+static int\n+ifpga_monitor_stop_func(void)\n+{\n+\tint ret;\n+\n+\tif (ifpga_monitor_start == 1) {\n+\t\tret = pthread_cancel(ifpga_monitor_start_thread);\n+\t\tif (ret)\n+\t\t\tIFPGA_RAWDEV_PMD_ERR(\"Can't cancel the thread\");\n+\n+\t\tret = pthread_join(ifpga_monitor_start_thread, NULL);\n+\t\tif (ret)\n+\t\t\tIFPGA_RAWDEV_PMD_ERR(\"Can't join the thread\");\n+\n+\t\tifpga_monitor_start = 0;\n+\n+\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n ifpga_fill_afu_dev(struct opae_accelerator *acc,\n \t\tstruct rte_afu_device *afu_dev)\n@@ -372,8 +869,9 @@\n \tif (ret)\n \t\treturn ret;\n \n-\tmemcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));\n-\tmemcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));\n+\trte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));\n+\trte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,\n+\t\tuuid.b + 8, sizeof(u64));\n \n \tIFPGA_RAWDEV_PMD_INFO(\"%s: uuid_l=0x%lx, uuid_h=0x%lx\\n\", __func__,\n \t\t(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,\n@@ -838,6 +1336,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n {\n \tint ret = 0;\n \tstruct rte_rawdev *rawdev = NULL;\n+\tstruct ifpga_rawdev *dev = NULL;\n \tstruct opae_adapter *adapter = NULL;\n \tstruct opae_manager *mgr = NULL;\n \tstruct opae_adapter_data_pci *data = NULL;\n@@ -851,7 +1350,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n \t}\n \n \tmemset(name, 0, sizeof(name));\n-\tsnprintf(name, RTE_RAWDEV_NAME_MAX_LEN, \"IFPGA:%x:%02x.%x\",\n+\tsnprintf(name, RTE_RAWDEV_NAME_MAX_LEN, \"IFPGA:%02x:%02x.%x\",\n \t\tpci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);\n \n \tIFPGA_RAWDEV_PMD_INFO(\"Init %s on NUMA node %d\", name, rte_socket_id());\n@@ -865,6 +1364,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n \t\tgoto cleanup;\n \t}\n \n+\tdev = ifpga_rawdev_allocate(rawdev);\n+\tif (dev == NULL) {\n+\t\tIFPGA_RAWDEV_PMD_ERR(\"Unable to allocate ifpga_rawdevice\");\n+\t\tret = -EINVAL;\n+\t\tgoto cleanup;\n+\t}\n+\tdev->aer_enable = 0;\n+\n \t/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */\n \tdata = opae_adapter_data_alloc(OPAE_FPGA_PCI);\n \tif (!data) {\n@@ -983,6 +1490,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n static int\n ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)\n {\n+\tifpga_monitor_stop_func();\n \treturn ifpga_rawdev_destroy(pci_dev);\n }\n \n@@ -1014,13 +1522,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n \tNULL\n };\n \n+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,\n+\tconst char *value, void *extra_args)\n+{\n+\tint size;\n+\tif (!value || !extra_args)\n+\t\treturn -EINVAL;\n+\n+\tsize = strlen(value) + 1;\n+\t*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);\n+\tif (!*(char **)extra_args)\n+\t\treturn -ENOMEM;\n+\n+\tstrlcpy(*(char **)extra_args, value, size);\n+\n+\treturn 0;\n+}\n static int\n ifpga_cfg_probe(struct rte_vdev_device *dev)\n {\n \tstruct rte_devargs *devargs;\n \tstruct rte_kvargs *kvlist = NULL;\n+\tstruct rte_rawdev *rawdev = NULL;\n+\tstruct ifpga_rawdev *ifpga_dev;\n \tint port;\n \tchar *name = NULL;\n+\tconst char *bdf;\n \tchar dev_name[RTE_RAWDEV_NAME_MAX_LEN];\n \tint ret = -1;\n \n@@ -1034,7 +1561,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n \n \tif (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {\n \t\tif (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,\n-\t\t\t\t       &rte_ifpga_get_string_arg, &name) < 0) {\n+\t\t\t\t       &ifpga_rawdev_get_string_arg,\n+\t\t\t\t       &name) < 0) {\n \t\t\tIFPGA_RAWDEV_PMD_ERR(\"error to parse %s\",\n \t\t\t\t     IFPGA_ARG_NAME);\n \t\t\tgoto end;\n@@ -1061,6 +1589,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)\n \t}\n \n \tmemset(dev_name, 0, sizeof(dev_name));\n+\tsnprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, \"IFPGA:%s\", name);\n+\trawdev = rte_rawdev_pmd_get_named_dev(dev_name);\n+\tif (!rawdev)\n+\t\tgoto end;\n+\tifpga_dev = ifpga_rawdev_get(rawdev);\n+\tif (!ifpga_dev)\n+\t\tgoto end;\n+\tbdf = name;\n+\tifpga_rawdev_fill_info(ifpga_dev, bdf);\n+\n+\tifpga_monitor_start_func();\n+\n+\tmemset(dev_name, 0, sizeof(dev_name));\n \tsnprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, \"%d|%s\",\n \tport, name);\n \ndiff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h\nindex e153dba..bd42083 100644\n--- a/drivers/raw/ifpga/ifpga_rawdev.h\n+++ b/drivers/raw/ifpga/ifpga_rawdev.h\n@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {\n \treturn rawdev->dev_private;\n }\n \n+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7\n+#define IFPGA_RAWDEV_NUM 32\n+\n+struct ifpga_rawdev {\n+\tint dev_id;\n+\tstruct rte_rawdev *rawdev;\n+\tint aer_enable;\n+\tint intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];\n+\tuint32_t aer_old[2];\n+\tchar fvl_bdf[8][16];\n+\tchar parent_bdf[16];\n+};\n+\n+struct ifpga_rawdev *\n+ifpga_rawdev_get(const struct rte_rawdev *rawdev);\n+\n #endif /* _IFPGA_RAWDEV_H_ */\n",
    "prefixes": [
        "v18",
        "11/19"
    ]
}