From 9c2185f11303ea173785923159f5814164022748 Mon Sep 17 00:00:00 2001 From: Adam Madsen Date: Sun, 1 Nov 2020 16:14:11 -0600 Subject: [PATCH] Add structure for common pre- and post-reset tasks --- Kbuild | 10 +++ Makefile | 15 +---- src/Makefile | 2 + src/amd/Makefile | 5 ++ src/amd/common.c | 46 +++++++++++++ src/amd/common.h | 87 +++++++++++++++++++++++++ src/amd/navi10.c | 2 +- src/amd/soc15_common.h | 135 +++++++++++++++++++++++++++++++++++++++ src/amd/vega10.c | 14 ++-- src/amd/vega20.c | 2 +- src/device-db.h | 72 ++++++++++----------- src/vendor-reset-dev.h | 21 ++++-- src/vendor-reset.c | 38 ++++++++++- userspace/Makefile | 3 + userspace/vendor-reset | Bin 21456 -> 0 bytes userspace/vendor-reset.c | 2 +- 16 files changed, 391 insertions(+), 63 deletions(-) create mode 100644 Kbuild create mode 100644 src/Makefile create mode 100644 src/amd/Makefile create mode 100644 src/amd/common.c create mode 100644 src/amd/common.h create mode 100644 src/amd/soc15_common.h create mode 100644 userspace/Makefile delete mode 100755 userspace/vendor-reset diff --git a/Kbuild b/Kbuild new file mode 100644 index 0000000..a7a7301 --- /dev/null +++ b/Kbuild @@ -0,0 +1,10 @@ +obj-m += vendor-reset.o + +include $(src)/src/Makefile +include $(src)/src/amd/Makefile + +ccflags-y += \ + -I$(src)/include -g +ldflags-$(CONFIG_DEBUG) += -g + +subdir-y += userspace/ \ No newline at end of file diff --git a/Makefile b/Makefile index 5218135..8aea118 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,3 @@ -obj-m := vendor-reset.o -vendor-reset-y := src/vendor-reset.o - -vendor-reset-y += src/amd/vega10.o -vendor-reset-y += src/amd/vega20.o -vendor-reset-y += src/amd/navi10.o - - -ccflags-y := -I$(src)/src -ccflags-y += -I$(src)/include - USER := $(shell whoami) KVER ?= $(shell uname -r) KDIR ?= /lib/modules/$(KVER)/build @@ -23,7 +12,7 @@ userspace: gcc userspace/vendor-reset.c -Wall -Werror -g -Og -o userspace/vendor-reset load: all - grep -q '^vendor-reset' /proc/modules && sudo rmmod vendor-reset || true + grep -q '^vendor_reset' /proc/modules && sudo rmmod vendor_reset || true sudo insmod ./vendor-reset.ko -.PHONY: userspace +.PHONY: userspace load diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..6b8aff8 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,2 @@ +vendor-reset-y += src/vendor-reset.o +ccflags-y += -I$(src)/src \ No newline at end of file diff --git a/src/amd/Makefile b/src/amd/Makefile new file mode 100644 index 0000000..176d9d9 --- /dev/null +++ b/src/amd/Makefile @@ -0,0 +1,5 @@ +vendor-reset-y += \ + src/amd/common.o \ + src/amd/vega10.o \ + src/amd/vega20.o \ + src/amd/navi10.o \ No newline at end of file diff --git a/src/amd/common.c b/src/amd/common.c new file mode 100644 index 0000000..85ac437 --- /dev/null +++ b/src/amd/common.c @@ -0,0 +1,46 @@ +#include +#include +#include "vendor-reset-dev.h" +#include "common.h" + +int amd_common_pre_reset(struct vendor_reset_dev *dev) +{ + struct amd_vendor_private *priv; + struct pci_dev *pdev = dev->pdev; + + priv = kzalloc(sizeof *priv, GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev->vendor_private = priv; + + spin_lock_init(&priv->pcie_lock); + + pci_set_power_state(pdev, PCI_D0); + pci_clear_master(pdev); + pci_save_state(pdev); + priv->saved_state = pci_store_saved_state(pdev); + pci_read_config_word(pdev, PCI_COMMAND, &priv->cfg); + pci_write_config_word(pdev, PCI_COMMAND, priv->cfg | PCI_COMMAND_MEMORY | PCI_COMMAND_INTX_DISABLE); + + return 0; +} + +int amd_common_post_reset(struct vendor_reset_dev *dev) +{ + struct amd_vendor_private *priv = amd_private(dev); + struct pci_dev *pdev = dev->pdev; + + if (priv->saved_state) + { + pci_load_and_free_saved_state(pdev, &priv->saved_state); + pci_restore_state(pdev); + } + pci_write_config_word(pdev, PCI_COMMAND, priv->cfg); + + /* don't try to go to low power if reset failed */ + if (!dev->reset_ret) + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} diff --git a/src/amd/common.h b/src/amd/common.h new file mode 100644 index 0000000..7ffa13c --- /dev/null +++ b/src/amd/common.h @@ -0,0 +1,87 @@ +/* +Vendor Reset - Vendor Specific Reset +Copyright (C) 2020 Geoffrey McRae + +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. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __VENDOR_RESET_COMMON_H__ +#define __VENDOR_RESET_COMMON_H__ + +#include "vendor-reset-dev.h" + +#define RREG32(reg) \ + ({ \ + u32 out; \ + if ((reg) < mmio_size) \ + out = readl(mmio + (reg)); \ + else \ + { \ + writel((reg), mmio + mmMM_INDEX); \ + out = readl(mmio + mmMM_DATA); \ + } \ + out; \ + }) + +#define WREG32(reg, v) \ + do \ + { \ + if ((reg) < mmio_size) \ + writel(v, mmio + (reg)); \ + else \ + { \ + writel((reg), mmio + mmMM_INDEX); \ + writel(v, mmio + mmMM_DATA); \ + } \ + } while (0) + +#define WREG32_PCIE(reg, v) \ + do \ + { \ + unsigned long __flags; \ + spin_lock_irqsave(&pcie_lock, __flags); \ + WREG32(mmPCIE_INDEX2, reg); \ + (void)RREG32(mmPCIE_INDEX2); \ + WREG32(mmPCIE_DATA2, v); \ + (void)RREG32(mmPCIE_DATA2); \ + spin_unlock_irqrestore(&pcie_lock, __flags); \ + } while (0) + +#define RREG32_PCIE(reg) \ + ({ \ + unsigned long __flags; \ + u32 __tmp_read; \ + spin_lock_irqsave(&pcie_lock, __flags); \ + WREG32(mmPCIE_INDEX2, reg); \ + (void)RREG32(mmPCIE_INDEX2); \ + __tmp_read = RREG32(mmPCIE_DATA2); \ + spin_unlock_irqrestore(&pcie_lock, __flags); \ + __tmp_read; \ + }) + +struct amd_vendor_private +{ + u16 cfg; + + struct pci_saved_state *saved_state; + + spinlock_t pcie_lock; +}; + +#define amd_private(vdev) ((struct amd_vendor_private *)(vdev->vendor_private)) + +int amd_common_pre_reset(struct vendor_reset_dev *); +int amd_common_post_reset(struct vendor_reset_dev *); + +#endif \ No newline at end of file diff --git a/src/amd/navi10.c b/src/amd/navi10.c index 194f877..cb95883 100644 --- a/src/amd/navi10.c +++ b/src/amd/navi10.c @@ -18,7 +18,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "vendor-reset-dev.h" -static int amd_navi10_reset(struct pci_dev * dev) +static int amd_navi10_reset(struct vendor_reset_dev *dev) { return 0; } diff --git a/src/amd/soc15_common.h b/src/amd/soc15_common.h new file mode 100644 index 0000000..a5c00ab --- /dev/null +++ b/src/amd/soc15_common.h @@ -0,0 +1,135 @@ +/* + * Copyright 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __SOC15_COMMON_H__ +#define __SOC15_COMMON_H__ + +/* Register Access Macros */ +#define SOC15_REG_OFFSET(ip, inst, reg) (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + +#define WREG32_FIELD15(ip, idx, reg, field, val) \ + WREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \ + (RREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \ + & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field)) + +#define RREG32_SOC15(ip, inst, reg) \ + RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + +#define RREG32_SOC15_NO_KIQ(ip, inst, reg) \ + RREG32_NO_KIQ(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + +#define RREG32_SOC15_OFFSET(ip, inst, reg, offset) \ + RREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset) + +#define WREG32_SOC15(ip, inst, reg, value) \ + WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value) + +#define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \ + WREG32_NO_KIQ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg), value) + +#define WREG32_SOC15_OFFSET(ip, inst, reg, offset, value) \ + WREG32((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset, value) + +#define SOC15_WAIT_ON_RREG(ip, inst, reg, expected_value, mask) \ +({ int ret = 0; \ + do { \ + uint32_t old_ = 0; \ + uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ + uint32_t loop = adev->usec_timeout; \ + ret = 0; \ + while ((tmp_ & (mask)) != (expected_value)) { \ + if (old_ != tmp_) { \ + loop = adev->usec_timeout; \ + old_ = tmp_; \ + } else \ + udelay(1); \ + tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ + loop--; \ + if (!loop) { \ + DRM_WARN("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ + inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ + ret = -ETIMEDOUT; \ + break; \ + } \ + } \ + } while (0); \ + ret; \ +}) + +#define WREG32_RLC(reg, value) \ + do { \ + if (amdgpu_sriov_fullaccess(adev)) { \ + uint32_t i = 0; \ + uint32_t retries = 50000; \ + uint32_t r0 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0; \ + uint32_t r1 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1; \ + uint32_t spare_int = adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT; \ + WREG32(r0, value); \ + WREG32(r1, (reg | 0x80000000)); \ + WREG32(spare_int, 0x1); \ + for (i = 0; i < retries; i++) { \ + u32 tmp = RREG32(r1); \ + if (!(tmp & 0x80000000)) \ + break; \ + udelay(10); \ + } \ + if (i >= retries) \ + pr_err("timeout: rlcg program reg:0x%05x failed !\n", reg); \ + } else { \ + WREG32(reg, value); \ + } \ + } while (0) + +#define WREG32_SOC15_RLC_SHADOW(ip, inst, reg, value) \ + do { \ + uint32_t target_reg = adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg;\ + if (amdgpu_sriov_fullaccess(adev)) { \ + uint32_t r2 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG2; \ + uint32_t r3 = adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3; \ + uint32_t grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL; \ + uint32_t grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX; \ + if (target_reg == grbm_cntl) \ + WREG32(r2, value); \ + else if (target_reg == grbm_idx) \ + WREG32(r3, value); \ + WREG32(target_reg, value); \ + } else { \ + WREG32(target_reg, value); \ + } \ + } while (0) + +#define WREG32_SOC15_RLC(ip, inst, reg, value) \ + do { \ + uint32_t target_reg = adev->reg_offset[GC_HWIP][0][reg##_BASE_IDX] + reg;\ + WREG32_RLC(target_reg, value); \ + } while (0) + +#define WREG32_FIELD15_RLC(ip, idx, reg, field, val) \ + WREG32_RLC((adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg), \ + (RREG32(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg) \ + & ~REG_FIELD_MASK(reg, field)) | (val) << REG_FIELD_SHIFT(reg, field)) + +#define WREG32_SOC15_OFFSET_RLC(ip, inst, reg, offset, value) \ + WREG32_RLC(((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) + offset), value) + +#endif diff --git a/src/amd/vega10.c b/src/amd/vega10.c index c576992..5ab7816 100644 --- a/src/amd/vega10.c +++ b/src/amd/vega10.c @@ -16,14 +16,18 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "soc15_common.h" #include "vendor-reset-dev.h" +#include "common.h" -static int amd_vega10_reset(struct pci_dev * dev) +static int amd_vega10_reset(struct vendor_reset_dev *dev) { - return 0; + + return 0; } -const struct vendor_reset_ops amd_vega10_ops = -{ - .reset = amd_vega10_reset +const struct vendor_reset_ops amd_vega10_ops = { + .pre_reset = amd_common_pre_reset, + .reset = amd_vega10_reset, + .post_reset = amd_common_post_reset, }; diff --git a/src/amd/vega20.c b/src/amd/vega20.c index 17d61c5..4a945f6 100644 --- a/src/amd/vega20.c +++ b/src/amd/vega20.c @@ -18,7 +18,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "vendor-reset-dev.h" -static int amd_vega20_reset(struct pci_dev * dev) +static int amd_vega20_reset(struct vendor_reset_dev *dev) { return 0; } diff --git a/src/device-db.h b/src/device-db.h index 02224a1..ecfeeac 100644 --- a/src/device-db.h +++ b/src/device-db.h @@ -18,42 +18,42 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "amd/amd.h" -static struct vendor_reset_device vendor_reset_devices[] = -{ - /* AMD Vega 10 */ - { PCI_VENDOR_ID_ATI, 0x6860, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6861, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6862, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6863, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6864, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6867, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6868, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x6869, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686a, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686b, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686c, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686d, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686e, &amd_vega10_ops }, - { PCI_VENDOR_ID_ATI, 0x686f, &amd_vega10_ops }, +static struct vendor_reset_cfg vendor_reset_devices[] = + { + /* AMD Vega 10 */ + {PCI_VENDOR_ID_ATI, 0x6860, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6861, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6862, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6863, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6864, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6867, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6868, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x6869, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686a, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686b, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686c, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686d, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686e, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x686f, &amd_vega10_ops}, + {PCI_VENDOR_ID_ATI, 0x687f, &amd_vega10_ops}, - /* AMD Vega 20 */ - { PCI_VENDOR_ID_ATI, 0x66a0, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66a1, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66a2, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66a3, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66a4, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66a7, &amd_vega20_ops }, - { PCI_VENDOR_ID_ATI, 0x66af, &amd_vega20_ops }, + /* AMD Vega 20 */ + {PCI_VENDOR_ID_ATI, 0x66a0, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66a1, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66a2, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66a3, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66a4, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66a7, &amd_vega20_ops}, + {PCI_VENDOR_ID_ATI, 0x66af, &amd_vega20_ops}, - /* AMD Navi 10 */ - { PCI_VENDOR_ID_ATI, 0x7310, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x7312, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x7318, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x7319, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x731a, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x731b, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x731e, &amd_navi10_ops }, - { PCI_VENDOR_ID_ATI, 0x731f, &amd_navi10_ops }, + /* AMD Navi 10 */ + {PCI_VENDOR_ID_ATI, 0x7310, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x7312, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x7318, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x7319, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x731a, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x731b, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x731e, &amd_navi10_ops}, + {PCI_VENDOR_ID_ATI, 0x731f, &amd_navi10_ops}, - { 0 } -}; + {0}}; diff --git a/src/vendor-reset-dev.h b/src/vendor-reset-dev.h index 1445daf..24b9f0f 100644 --- a/src/vendor-reset-dev.h +++ b/src/vendor-reset-dev.h @@ -23,13 +23,26 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include -struct vendor_reset_ops +struct vendor_reset_dev { - /* the reset method for the device at the specified address */ - int (*reset)(struct pci_dev *dev); + struct pci_dev *pdev; + + int reset_ret; + + void *vendor_private; }; -struct vendor_reset_device +struct vendor_reset_ops +{ + /* any pre-reset ops to do, i.e., common code between devices */ + int (*pre_reset)(struct vendor_reset_dev *); + /* the reset method for the device at the specified address */ + int (*reset)(struct vendor_reset_dev *); + /* any post-reset ops to do, i.e., common code between devices */ + int (*post_reset)(struct vendor_reset_dev *); +}; + +struct vendor_reset_cfg { /* the vendor ID */ unsigned int vendor; diff --git a/src/vendor-reset.c b/src/vendor-reset.c index c78e8aa..9d15232 100644 --- a/src/vendor-reset.c +++ b/src/vendor-reset.c @@ -32,9 +32,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA static long vendor_reset_ioctl_reset(struct file * filp, unsigned long arg) { struct vendor_reset_ioctl dev; - struct vendor_reset_device *entry = vendor_reset_devices; + struct vendor_reset_cfg *entry = vendor_reset_devices; struct pci_dev * pcidev; int ret; + struct vendor_reset_dev vdev; if (copy_from_user(&dev, (void __user *)arg, sizeof(dev))) return -EFAULT; @@ -43,6 +44,8 @@ static long vendor_reset_ioctl_reset(struct file * filp, unsigned long arg) if (!pcidev) return -ENODEV; + pci_printk(KERN_INFO, pcidev, "Found device\n"); + for(entry = vendor_reset_devices; entry->vendor; ++entry) { if (entry->vendor != pcidev->vendor) @@ -59,7 +62,38 @@ static long vendor_reset_ioctl_reset(struct file * filp, unsigned long arg) goto err; } - ret = entry->ops->reset(pcidev); + vdev.pdev = pcidev; + + /* we probably always want to lock the device */ + if (!pci_cfg_access_trylock(pcidev)) + goto err; + else + { + if (!device_trylock(&pcidev->dev)) + { + pci_cfg_access_unlock(pcidev); + goto err; + } + } + + if (entry->ops->pre_reset) + { + ret = entry->ops->pre_reset(&vdev); + if (ret) + goto unlock; + } + + /* expose return code to cleanup */ + ret = vdev.reset_ret = entry->ops->reset(&vdev); + if (ret) + pci_warn(pcidev, "Failed to reset device\n"); + + if (entry->ops->post_reset) + ret = entry->ops->post_reset(&vdev); + +unlock: + device_unlock(&pcidev->dev); + pci_cfg_access_unlock(pcidev); err: pci_dev_put(pcidev); diff --git a/userspace/Makefile b/userspace/Makefile new file mode 100644 index 0000000..1c3e3fe --- /dev/null +++ b/userspace/Makefile @@ -0,0 +1,3 @@ +userccflags += -I$(src)/../include +userprogs-always-y += vendor-reset +vendor-reset-objs += vendor-reset.o \ No newline at end of file diff --git a/userspace/vendor-reset b/userspace/vendor-reset deleted file mode 100755 index a90b65f8e6500ec4d131977add1c23070dcdec50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21456 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 diff --git a/userspace/vendor-reset.c b/userspace/vendor-reset.c index 0ea500e..bafb5d6 100644 --- a/userspace/vendor-reset.c +++ b/userspace/vendor-reset.c @@ -16,12 +16,12 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../include/vendor-reset.h" #include #include #include #include #include +#include "vendor-reset.h" int main(int argc, char * argv[]) {