178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */ 278ee8d1cSJulian Grajkowski /* Copyright(c) 2007-2022 Intel Corporation */ 378ee8d1cSJulian Grajkowski #include "qat_freebsd.h" 478ee8d1cSJulian Grajkowski #include "adf_cfg.h" 578ee8d1cSJulian Grajkowski #include "adf_common_drv.h" 678ee8d1cSJulian Grajkowski #include "adf_accel_devices.h" 778ee8d1cSJulian Grajkowski #include "icp_qat_uclo.h" 878ee8d1cSJulian Grajkowski #include "icp_qat_fw.h" 978ee8d1cSJulian Grajkowski #include "icp_qat_fw_init_admin.h" 1078ee8d1cSJulian Grajkowski #include "adf_cfg_strings.h" 1178ee8d1cSJulian Grajkowski #include "adf_transport_access_macros.h" 1278ee8d1cSJulian Grajkowski #include "adf_transport_internal.h" 1378ee8d1cSJulian Grajkowski #include <sys/bus.h> 1478ee8d1cSJulian Grajkowski #include <dev/pci/pcireg.h> 1578ee8d1cSJulian Grajkowski #include <dev/pci/pcivar.h> 1678ee8d1cSJulian Grajkowski #include <sys/systm.h> 1778ee8d1cSJulian Grajkowski 1878ee8d1cSJulian Grajkowski #define ADF_PPAERUCM_MASK (BIT(14) | BIT(20) | BIT(22)) 1978ee8d1cSJulian Grajkowski 2078ee8d1cSJulian Grajkowski static struct workqueue_struct *fatal_error_wq; 2178ee8d1cSJulian Grajkowski struct adf_fatal_error_data { 2278ee8d1cSJulian Grajkowski struct adf_accel_dev *accel_dev; 2378ee8d1cSJulian Grajkowski struct work_struct work; 2478ee8d1cSJulian Grajkowski }; 2578ee8d1cSJulian Grajkowski 2678ee8d1cSJulian Grajkowski static struct workqueue_struct *device_reset_wq; 2778ee8d1cSJulian Grajkowski 2878ee8d1cSJulian Grajkowski void 2978ee8d1cSJulian Grajkowski linux_complete_common(struct completion *c, int all) 3078ee8d1cSJulian Grajkowski { 3178ee8d1cSJulian Grajkowski sleepq_lock(c); 3278ee8d1cSJulian Grajkowski c->done++; 3378ee8d1cSJulian Grajkowski if (all) 34*01518f5eSMark Johnston sleepq_broadcast(c, SLEEPQ_SLEEP, 0, 0); 3578ee8d1cSJulian Grajkowski else 36*01518f5eSMark Johnston sleepq_signal(c, SLEEPQ_SLEEP, 0, 0); 3778ee8d1cSJulian Grajkowski sleepq_release(c); 3878ee8d1cSJulian Grajkowski } 3978ee8d1cSJulian Grajkowski 4078ee8d1cSJulian Grajkowski /* reset dev data */ 4178ee8d1cSJulian Grajkowski struct adf_reset_dev_data { 4278ee8d1cSJulian Grajkowski int mode; 4378ee8d1cSJulian Grajkowski struct adf_accel_dev *accel_dev; 4478ee8d1cSJulian Grajkowski struct completion compl; 4578ee8d1cSJulian Grajkowski struct work_struct reset_work; 4678ee8d1cSJulian Grajkowski }; 4778ee8d1cSJulian Grajkowski 4878ee8d1cSJulian Grajkowski int 4978ee8d1cSJulian Grajkowski adf_aer_store_ppaerucm_reg(device_t dev, struct adf_hw_device_data *hw_data) 5078ee8d1cSJulian Grajkowski { 5178ee8d1cSJulian Grajkowski unsigned int aer_offset, reg_val = 0; 5278ee8d1cSJulian Grajkowski 5378ee8d1cSJulian Grajkowski if (!hw_data) 5478ee8d1cSJulian Grajkowski return -EINVAL; 5578ee8d1cSJulian Grajkowski 5678ee8d1cSJulian Grajkowski if (pci_find_extcap(dev, PCIZ_AER, &aer_offset) == 0) { 5778ee8d1cSJulian Grajkowski reg_val = 5878ee8d1cSJulian Grajkowski pci_read_config(dev, aer_offset + PCIR_AER_UC_MASK, 4); 5978ee8d1cSJulian Grajkowski 6078ee8d1cSJulian Grajkowski hw_data->aerucm_mask = reg_val; 6178ee8d1cSJulian Grajkowski } else { 6278ee8d1cSJulian Grajkowski device_printf(dev, 6378ee8d1cSJulian Grajkowski "Unable to find AER capability of the device\n"); 6478ee8d1cSJulian Grajkowski return -ENODEV; 6578ee8d1cSJulian Grajkowski } 6678ee8d1cSJulian Grajkowski 6778ee8d1cSJulian Grajkowski return 0; 6878ee8d1cSJulian Grajkowski } 6978ee8d1cSJulian Grajkowski 7078ee8d1cSJulian Grajkowski void 7178ee8d1cSJulian Grajkowski adf_reset_sbr(struct adf_accel_dev *accel_dev) 7278ee8d1cSJulian Grajkowski { 7378ee8d1cSJulian Grajkowski device_t pdev = accel_to_pci_dev(accel_dev); 7478ee8d1cSJulian Grajkowski device_t parent = device_get_parent(device_get_parent(pdev)); 7578ee8d1cSJulian Grajkowski uint16_t bridge_ctl = 0; 7678ee8d1cSJulian Grajkowski 7778ee8d1cSJulian Grajkowski if (accel_dev->is_vf) 7878ee8d1cSJulian Grajkowski return; 7978ee8d1cSJulian Grajkowski 8078ee8d1cSJulian Grajkowski if (!parent) 8178ee8d1cSJulian Grajkowski parent = pdev; 8278ee8d1cSJulian Grajkowski 8378ee8d1cSJulian Grajkowski if (!pcie_wait_for_pending_transactions(pdev, 0)) 8478ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 8578ee8d1cSJulian Grajkowski "Transaction still in progress. Proceeding\n"); 8678ee8d1cSJulian Grajkowski 8778ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), "Secondary bus reset\n"); 8878ee8d1cSJulian Grajkowski 8978ee8d1cSJulian Grajkowski pci_save_state(pdev); 9078ee8d1cSJulian Grajkowski bridge_ctl = pci_read_config(parent, PCIR_BRIDGECTL_1, 2); 9178ee8d1cSJulian Grajkowski bridge_ctl |= PCIB_BCR_SECBUS_RESET; 9278ee8d1cSJulian Grajkowski pci_write_config(parent, PCIR_BRIDGECTL_1, bridge_ctl, 2); 9378ee8d1cSJulian Grajkowski pause_ms("adfrst", 100); 9478ee8d1cSJulian Grajkowski bridge_ctl &= ~PCIB_BCR_SECBUS_RESET; 9578ee8d1cSJulian Grajkowski pci_write_config(parent, PCIR_BRIDGECTL_1, bridge_ctl, 2); 9678ee8d1cSJulian Grajkowski pause_ms("adfrst", 100); 9778ee8d1cSJulian Grajkowski pci_restore_state(pdev); 9878ee8d1cSJulian Grajkowski } 9978ee8d1cSJulian Grajkowski 10078ee8d1cSJulian Grajkowski void 10178ee8d1cSJulian Grajkowski adf_reset_flr(struct adf_accel_dev *accel_dev) 10278ee8d1cSJulian Grajkowski { 10378ee8d1cSJulian Grajkowski device_t pdev = accel_to_pci_dev(accel_dev); 10478ee8d1cSJulian Grajkowski 10578ee8d1cSJulian Grajkowski pci_save_state(pdev); 10678ee8d1cSJulian Grajkowski if (pcie_flr(pdev, 10778ee8d1cSJulian Grajkowski max(pcie_get_max_completion_timeout(pdev) / 1000, 10), 10878ee8d1cSJulian Grajkowski true)) { 10978ee8d1cSJulian Grajkowski pci_restore_state(pdev); 11078ee8d1cSJulian Grajkowski return; 11178ee8d1cSJulian Grajkowski } 11278ee8d1cSJulian Grajkowski pci_restore_state(pdev); 11378ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 11478ee8d1cSJulian Grajkowski "FLR qat_dev%d failed trying secondary bus reset\n", 11578ee8d1cSJulian Grajkowski accel_dev->accel_id); 11678ee8d1cSJulian Grajkowski adf_reset_sbr(accel_dev); 11778ee8d1cSJulian Grajkowski } 11878ee8d1cSJulian Grajkowski 11978ee8d1cSJulian Grajkowski void 12078ee8d1cSJulian Grajkowski adf_dev_pre_reset(struct adf_accel_dev *accel_dev) 12178ee8d1cSJulian Grajkowski { 12278ee8d1cSJulian Grajkowski struct adf_hw_device_data *hw_device = accel_dev->hw_device; 12378ee8d1cSJulian Grajkowski device_t pdev = accel_to_pci_dev(accel_dev); 12478ee8d1cSJulian Grajkowski u32 aer_offset, reg_val = 0; 12578ee8d1cSJulian Grajkowski 12678ee8d1cSJulian Grajkowski if (pci_find_extcap(pdev, PCIZ_AER, &aer_offset) == 0) { 12778ee8d1cSJulian Grajkowski reg_val = 12878ee8d1cSJulian Grajkowski pci_read_config(pdev, aer_offset + PCIR_AER_UC_MASK, 4); 12978ee8d1cSJulian Grajkowski reg_val |= ADF_PPAERUCM_MASK; 13078ee8d1cSJulian Grajkowski pci_write_config(pdev, 13178ee8d1cSJulian Grajkowski aer_offset + PCIR_AER_UC_MASK, 13278ee8d1cSJulian Grajkowski reg_val, 13378ee8d1cSJulian Grajkowski 4); 13478ee8d1cSJulian Grajkowski } else { 13578ee8d1cSJulian Grajkowski device_printf(pdev, 13678ee8d1cSJulian Grajkowski "Unable to find AER capability of the device\n"); 13778ee8d1cSJulian Grajkowski } 13878ee8d1cSJulian Grajkowski 13978ee8d1cSJulian Grajkowski if (hw_device->disable_arb) { 14078ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), "Disable arbiter.\n"); 14178ee8d1cSJulian Grajkowski hw_device->disable_arb(accel_dev); 14278ee8d1cSJulian Grajkowski } 14378ee8d1cSJulian Grajkowski } 14478ee8d1cSJulian Grajkowski 14578ee8d1cSJulian Grajkowski void 14678ee8d1cSJulian Grajkowski adf_dev_post_reset(struct adf_accel_dev *accel_dev) 14778ee8d1cSJulian Grajkowski { 14878ee8d1cSJulian Grajkowski struct adf_hw_device_data *hw_device = accel_dev->hw_device; 14978ee8d1cSJulian Grajkowski device_t pdev = accel_to_pci_dev(accel_dev); 15078ee8d1cSJulian Grajkowski u32 aer_offset; 15178ee8d1cSJulian Grajkowski 15278ee8d1cSJulian Grajkowski if (pci_find_extcap(pdev, PCIZ_AER, &aer_offset) == 0) { 15378ee8d1cSJulian Grajkowski pci_write_config(pdev, 15478ee8d1cSJulian Grajkowski aer_offset + PCIR_AER_UC_MASK, 15578ee8d1cSJulian Grajkowski hw_device->aerucm_mask, 15678ee8d1cSJulian Grajkowski 4); 15778ee8d1cSJulian Grajkowski } else { 15878ee8d1cSJulian Grajkowski device_printf(pdev, 15978ee8d1cSJulian Grajkowski "Unable to find AER capability of the device\n"); 16078ee8d1cSJulian Grajkowski } 16178ee8d1cSJulian Grajkowski } 16278ee8d1cSJulian Grajkowski 16378ee8d1cSJulian Grajkowski void 16478ee8d1cSJulian Grajkowski adf_dev_restore(struct adf_accel_dev *accel_dev) 16578ee8d1cSJulian Grajkowski { 16678ee8d1cSJulian Grajkowski struct adf_hw_device_data *hw_device = accel_dev->hw_device; 16778ee8d1cSJulian Grajkowski device_t pdev = accel_to_pci_dev(accel_dev); 16878ee8d1cSJulian Grajkowski 16978ee8d1cSJulian Grajkowski if (hw_device->pre_reset) { 17078ee8d1cSJulian Grajkowski dev_dbg(GET_DEV(accel_dev), "Performing pre reset save\n"); 17178ee8d1cSJulian Grajkowski hw_device->pre_reset(accel_dev); 17278ee8d1cSJulian Grajkowski } 17378ee8d1cSJulian Grajkowski 17478ee8d1cSJulian Grajkowski if (hw_device->reset_device) { 17578ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 17678ee8d1cSJulian Grajkowski "Resetting device qat_dev%d\n", 17778ee8d1cSJulian Grajkowski accel_dev->accel_id); 17878ee8d1cSJulian Grajkowski hw_device->reset_device(accel_dev); 17978ee8d1cSJulian Grajkowski pci_restore_state(pdev); 18078ee8d1cSJulian Grajkowski pci_save_state(pdev); 18178ee8d1cSJulian Grajkowski } 18278ee8d1cSJulian Grajkowski 18378ee8d1cSJulian Grajkowski if (hw_device->post_reset) { 18478ee8d1cSJulian Grajkowski dev_dbg(GET_DEV(accel_dev), "Performing post reset restore\n"); 18578ee8d1cSJulian Grajkowski hw_device->post_reset(accel_dev); 18678ee8d1cSJulian Grajkowski } 18778ee8d1cSJulian Grajkowski } 18878ee8d1cSJulian Grajkowski 18978ee8d1cSJulian Grajkowski static void 19078ee8d1cSJulian Grajkowski adf_device_reset_worker(struct work_struct *work) 19178ee8d1cSJulian Grajkowski { 19278ee8d1cSJulian Grajkowski struct adf_reset_dev_data *reset_data = 19378ee8d1cSJulian Grajkowski container_of(work, struct adf_reset_dev_data, reset_work); 19478ee8d1cSJulian Grajkowski struct adf_accel_dev *accel_dev = reset_data->accel_dev; 19578ee8d1cSJulian Grajkowski 19678ee8d1cSJulian Grajkowski if (adf_dev_restarting_notify(accel_dev)) { 19778ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 19878ee8d1cSJulian Grajkowski "Unable to send RESTARTING notification.\n"); 19978ee8d1cSJulian Grajkowski return; 20078ee8d1cSJulian Grajkowski } 20178ee8d1cSJulian Grajkowski 20278ee8d1cSJulian Grajkowski if (adf_dev_stop(accel_dev)) { 20378ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), "Stopping device failed.\n"); 20478ee8d1cSJulian Grajkowski return; 20578ee8d1cSJulian Grajkowski } 20678ee8d1cSJulian Grajkowski 20778ee8d1cSJulian Grajkowski adf_dev_shutdown(accel_dev); 20878ee8d1cSJulian Grajkowski 20978ee8d1cSJulian Grajkowski if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) { 21078ee8d1cSJulian Grajkowski /* The device hanged and we can't restart it */ 21178ee8d1cSJulian Grajkowski /* so stop here */ 21278ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), "Restart device failed\n"); 21378ee8d1cSJulian Grajkowski if (reset_data->mode == ADF_DEV_RESET_ASYNC) 21478ee8d1cSJulian Grajkowski kfree(reset_data); 21578ee8d1cSJulian Grajkowski WARN(1, "QAT: device restart failed. Device is unusable\n"); 21678ee8d1cSJulian Grajkowski return; 21778ee8d1cSJulian Grajkowski } 21878ee8d1cSJulian Grajkowski 21978ee8d1cSJulian Grajkowski adf_dev_restarted_notify(accel_dev); 22078ee8d1cSJulian Grajkowski clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); 22178ee8d1cSJulian Grajkowski 22278ee8d1cSJulian Grajkowski /* The dev is back alive. Notify the caller if in sync mode */ 22378ee8d1cSJulian Grajkowski if (reset_data->mode == ADF_DEV_RESET_SYNC) 22478ee8d1cSJulian Grajkowski complete(&reset_data->compl); 22578ee8d1cSJulian Grajkowski else 22678ee8d1cSJulian Grajkowski kfree(reset_data); 22778ee8d1cSJulian Grajkowski } 22878ee8d1cSJulian Grajkowski 22978ee8d1cSJulian Grajkowski int 23078ee8d1cSJulian Grajkowski adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, 23178ee8d1cSJulian Grajkowski enum adf_dev_reset_mode mode) 23278ee8d1cSJulian Grajkowski { 23378ee8d1cSJulian Grajkowski struct adf_reset_dev_data *reset_data; 23478ee8d1cSJulian Grajkowski if (!adf_dev_started(accel_dev) || 23578ee8d1cSJulian Grajkowski test_bit(ADF_STATUS_RESTARTING, &accel_dev->status)) 23678ee8d1cSJulian Grajkowski return 0; 23778ee8d1cSJulian Grajkowski set_bit(ADF_STATUS_RESTARTING, &accel_dev->status); 23878ee8d1cSJulian Grajkowski reset_data = kzalloc(sizeof(*reset_data), GFP_ATOMIC); 23978ee8d1cSJulian Grajkowski if (!reset_data) 24078ee8d1cSJulian Grajkowski return -ENOMEM; 24178ee8d1cSJulian Grajkowski reset_data->accel_dev = accel_dev; 24278ee8d1cSJulian Grajkowski init_completion(&reset_data->compl); 24378ee8d1cSJulian Grajkowski reset_data->mode = mode; 24478ee8d1cSJulian Grajkowski INIT_WORK(&reset_data->reset_work, adf_device_reset_worker); 24578ee8d1cSJulian Grajkowski queue_work(device_reset_wq, &reset_data->reset_work); 24678ee8d1cSJulian Grajkowski /* If in sync mode wait for the result */ 24778ee8d1cSJulian Grajkowski if (mode == ADF_DEV_RESET_SYNC) { 24878ee8d1cSJulian Grajkowski int ret = 0; 24978ee8d1cSJulian Grajkowski /* Maximum device reset time is 10 seconds */ 25078ee8d1cSJulian Grajkowski unsigned long wait_jiffies = msecs_to_jiffies(10000); 25178ee8d1cSJulian Grajkowski unsigned long timeout = 25278ee8d1cSJulian Grajkowski wait_for_completion_timeout(&reset_data->compl, 25378ee8d1cSJulian Grajkowski wait_jiffies); 25478ee8d1cSJulian Grajkowski if (!timeout) { 25578ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 25678ee8d1cSJulian Grajkowski "Reset device timeout expired\n"); 25778ee8d1cSJulian Grajkowski ret = -EFAULT; 25878ee8d1cSJulian Grajkowski } 25978ee8d1cSJulian Grajkowski kfree(reset_data); 26078ee8d1cSJulian Grajkowski return ret; 26178ee8d1cSJulian Grajkowski } 26278ee8d1cSJulian Grajkowski return 0; 26378ee8d1cSJulian Grajkowski } 26478ee8d1cSJulian Grajkowski 26578ee8d1cSJulian Grajkowski int 26678ee8d1cSJulian Grajkowski adf_dev_autoreset(struct adf_accel_dev *accel_dev) 26778ee8d1cSJulian Grajkowski { 26878ee8d1cSJulian Grajkowski if (accel_dev->autoreset_on_error) 26978ee8d1cSJulian Grajkowski return adf_dev_reset(accel_dev, ADF_DEV_RESET_ASYNC); 27078ee8d1cSJulian Grajkowski return 0; 27178ee8d1cSJulian Grajkowski } 27278ee8d1cSJulian Grajkowski 27378ee8d1cSJulian Grajkowski static void 27478ee8d1cSJulian Grajkowski adf_notify_fatal_error_work(struct work_struct *work) 27578ee8d1cSJulian Grajkowski { 27678ee8d1cSJulian Grajkowski struct adf_fatal_error_data *wq_data = 27778ee8d1cSJulian Grajkowski container_of(work, struct adf_fatal_error_data, work); 27878ee8d1cSJulian Grajkowski struct adf_accel_dev *accel_dev = wq_data->accel_dev; 27978ee8d1cSJulian Grajkowski 28078ee8d1cSJulian Grajkowski adf_error_notifier((uintptr_t)accel_dev); 28178ee8d1cSJulian Grajkowski if (!accel_dev->is_vf) { 28278ee8d1cSJulian Grajkowski adf_dev_autoreset(accel_dev); 28378ee8d1cSJulian Grajkowski } 28478ee8d1cSJulian Grajkowski 28578ee8d1cSJulian Grajkowski kfree(wq_data); 28678ee8d1cSJulian Grajkowski } 28778ee8d1cSJulian Grajkowski 28878ee8d1cSJulian Grajkowski int 28978ee8d1cSJulian Grajkowski adf_notify_fatal_error(struct adf_accel_dev *accel_dev) 29078ee8d1cSJulian Grajkowski { 29178ee8d1cSJulian Grajkowski struct adf_fatal_error_data *wq_data; 29278ee8d1cSJulian Grajkowski 29378ee8d1cSJulian Grajkowski wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC); 29478ee8d1cSJulian Grajkowski if (!wq_data) { 29578ee8d1cSJulian Grajkowski device_printf(GET_DEV(accel_dev), 29678ee8d1cSJulian Grajkowski "Failed to allocate memory\n"); 29778ee8d1cSJulian Grajkowski return ENOMEM; 29878ee8d1cSJulian Grajkowski } 29978ee8d1cSJulian Grajkowski wq_data->accel_dev = accel_dev; 30078ee8d1cSJulian Grajkowski 30178ee8d1cSJulian Grajkowski INIT_WORK(&wq_data->work, adf_notify_fatal_error_work); 30278ee8d1cSJulian Grajkowski queue_work(fatal_error_wq, &wq_data->work); 30378ee8d1cSJulian Grajkowski 30478ee8d1cSJulian Grajkowski return 0; 30578ee8d1cSJulian Grajkowski } 30678ee8d1cSJulian Grajkowski 30778ee8d1cSJulian Grajkowski int __init 30878ee8d1cSJulian Grajkowski adf_init_fatal_error_wq(void) 30978ee8d1cSJulian Grajkowski { 31078ee8d1cSJulian Grajkowski fatal_error_wq = create_workqueue("qat_fatal_error_wq"); 31178ee8d1cSJulian Grajkowski return !fatal_error_wq ? EFAULT : 0; 31278ee8d1cSJulian Grajkowski } 31378ee8d1cSJulian Grajkowski 31478ee8d1cSJulian Grajkowski void 31578ee8d1cSJulian Grajkowski adf_exit_fatal_error_wq(void) 31678ee8d1cSJulian Grajkowski { 31778ee8d1cSJulian Grajkowski if (fatal_error_wq) 31878ee8d1cSJulian Grajkowski destroy_workqueue(fatal_error_wq); 31978ee8d1cSJulian Grajkowski fatal_error_wq = NULL; 32078ee8d1cSJulian Grajkowski } 32178ee8d1cSJulian Grajkowski 32278ee8d1cSJulian Grajkowski int 32378ee8d1cSJulian Grajkowski adf_init_aer(void) 32478ee8d1cSJulian Grajkowski { 32578ee8d1cSJulian Grajkowski device_reset_wq = create_workqueue("qat_device_reset_wq"); 32678ee8d1cSJulian Grajkowski return !device_reset_wq ? -EFAULT : 0; 32778ee8d1cSJulian Grajkowski } 32878ee8d1cSJulian Grajkowski 32978ee8d1cSJulian Grajkowski void 33078ee8d1cSJulian Grajkowski adf_exit_aer(void) 33178ee8d1cSJulian Grajkowski { 33278ee8d1cSJulian Grajkowski if (device_reset_wq) 33378ee8d1cSJulian Grajkowski destroy_workqueue(device_reset_wq); 33478ee8d1cSJulian Grajkowski device_reset_wq = NULL; 33578ee8d1cSJulian Grajkowski } 336