Fix r8169 link detection with Xenomai
``` [ 741.073012] IRQ pipeline: some code running in oob context 'Xenomai' [ 741.073013] called an in-band only routine [ 741.073013] CPU: 1 PID: 22419 Comm: my_task Tainted: G O 5.10.179-lp154.3-0510xenomai3 #1 [ 741.073014] Hardware name: ICP / iEi IMBA-9454ISA/IMBA-9454ISA(E168), BIOS 080014 02/20/2009 [ 741.073015] IRQ stage: Xenomai [ 741.073015] Call Trace: [ 741.073015] dump_stack+0x86/0xa6 [ 741.073016] check_inband_stage+0x8c/0xa0 [ 741.073017] inband_irq_save+0xe/0x30 [ 741.073017] try_to_grab_pending+0x1e/0x180 [ 741.073018] mod_delayed_work_on+0x42/0xa0 [ 741.073018] phy_trigger_machine+0x23/0x30 [ 741.073019] phy_mac_interrupt+0xe/0x20 [ 741.073019] ec_poll+0x105/0x110 [ec_r8169] [ 741.073020] ec_device_poll+0x24/0x30 [ec_master] [ 741.073020] ecrt_master_receive+0x21/0x160 [ec_master] [ 741.073021] ec_ioctl_rtdm_rt+0x430/0x4c0 [ec_master] [ 741.073021] ? rtdm_fd_get+0x11d/0x210 [ 741.073022] ec_rtdm_ioctl_rt_handler+0x26/0x40 [ec_master] [ 741.073022] rtdm_fd_ioctl+0xdc/0x240 [ 741.073023] ? xnlock_dbg_release+0x21/0xf0 [ 741.073023] CoBaLt_ioctl+0xe/0x20 [ 741.073024] handle_head_syscall+0x10f/0x4d0 [ 741.073025] ? CoBaLt_fcntl+0x20/0x20 [ 741.073025] ? handle_pipelined_syscall+0x39/0x40 [ 741.073026] handle_oob_syscall+0x13/0x20 [ 741.073026] pipeline_syscall+0x8c/0x130 [ 741.073027] syscall_enter_from_user_mode+0x26/0x90 [ 741.073027] do_syscall_64+0x13/0x60 [ 741.073028] entry_SYSCALL_64_after_hwframe+0x61/0xc6 [ 741.073029] RIP: 0033:0x7fac8da13c8f [ 741.073029] Code: Unable to access opcode bytes at RIP 0x7fac8da13c65. [ 741.073030] RSP: 002b:00007fac8e864c90 EFLAGS: 00000206 ORIG_RAX: 0000000010000050 [ 741.073031] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fac8da13c8f [ 741.073032] RDX: 0000000000000000 RSI: 000000000000a426 RDI: 0000000000000003 [ 741.073032] RBP: 000000000000a426 R08: 00007fac8e865700 R09: 0000000000000000 [ 741.073033] R10: 0000000000000113 R11: 0000000000000206 R12: 0000000000000000 [ 741.073033] R13: 0000000000000000 R14: 0000000000000000 R15: 00007fac8e864e80 ```
This commit is contained in:
parent
0c1e2bc397
commit
bdd7d1f8f7
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/in.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
|
@ -633,6 +634,7 @@ struct rtl8169_private {
|
|||
|
||||
ec_device_t *ecdev;
|
||||
unsigned long ec_watchdog_jiffies;
|
||||
struct irq_work ec_watchdog_kicker;
|
||||
};
|
||||
|
||||
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
|
||||
|
|
@ -5079,6 +5081,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
|||
|
||||
if (tp->ecdev) {
|
||||
ecdev_close(tp->ecdev);
|
||||
irq_work_sync(&tp->ec_watchdog_kicker);
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
} else {
|
||||
unregister_netdev(tp->dev);
|
||||
|
|
@ -5369,6 +5372,14 @@ done:
|
|||
rtl_rar_set(tp, mac_addr);
|
||||
}
|
||||
|
||||
static void ec_kick_watchdog(struct irq_work *work)
|
||||
{
|
||||
struct rtl8169_private *tp =
|
||||
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
|
||||
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
}
|
||||
|
||||
static void ec_poll(struct net_device *dev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
|
@ -5387,8 +5398,7 @@ static void ec_poll(struct net_device *dev)
|
|||
rtl_rx(dev, tp, 100);
|
||||
|
||||
if (status & LinkChg)
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
|
||||
irq_work_queue(&tp->ec_watchdog_kicker);
|
||||
|
||||
rtl_ack_events(tp, status);
|
||||
}
|
||||
|
|
@ -5588,6 +5598,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
if (tp->ecdev) {
|
||||
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
|
||||
rc = ecdev_open(tp->ecdev);
|
||||
if (rc) {
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/in.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
|
@ -653,6 +654,7 @@ struct rtl8169_private {
|
|||
|
||||
ec_device_t *ecdev;
|
||||
unsigned long ec_watchdog_jiffies;
|
||||
struct irq_work ec_watchdog_kicker;
|
||||
};
|
||||
|
||||
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
|
||||
|
|
@ -5048,6 +5050,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
|||
|
||||
if (tp->ecdev) {
|
||||
ecdev_close(tp->ecdev);
|
||||
irq_work_sync(&tp->ec_watchdog_kicker);
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
} else {
|
||||
unregister_netdev(tp->dev);
|
||||
|
|
@ -5338,6 +5341,14 @@ done:
|
|||
rtl_rar_set(tp, mac_addr);
|
||||
}
|
||||
|
||||
static void ec_kick_watchdog(struct irq_work *work)
|
||||
{
|
||||
struct rtl8169_private *tp =
|
||||
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
|
||||
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
}
|
||||
|
||||
static void ec_poll(struct net_device *dev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
|
@ -5356,7 +5367,7 @@ static void ec_poll(struct net_device *dev)
|
|||
rtl_rx(dev, tp, 100);
|
||||
|
||||
if (status & LinkChg)
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
irq_work_queue(&tp->ec_watchdog_kicker);
|
||||
|
||||
rtl_ack_events(tp, status);
|
||||
}
|
||||
|
|
@ -5560,6 +5571,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
if (tp->ecdev) {
|
||||
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
|
||||
rc = ecdev_open(tp->ecdev);
|
||||
if (rc) {
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/in.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
|
@ -641,6 +642,7 @@ struct rtl8169_private {
|
|||
|
||||
ec_device_t *ecdev;
|
||||
unsigned long ec_watchdog_jiffies;
|
||||
struct irq_work ec_watchdog_kicker;
|
||||
};
|
||||
|
||||
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
|
||||
|
|
@ -5041,6 +5043,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
|||
|
||||
if (tp->ecdev) {
|
||||
ecdev_close(tp->ecdev);
|
||||
irq_work_sync(&tp->ec_watchdog_kicker);
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
} else {
|
||||
unregister_netdev(tp->dev);
|
||||
|
|
@ -5331,6 +5334,14 @@ done:
|
|||
rtl_rar_set(tp, mac_addr);
|
||||
}
|
||||
|
||||
static void ec_kick_watchdog(struct irq_work *work)
|
||||
{
|
||||
struct rtl8169_private *tp =
|
||||
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
|
||||
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
}
|
||||
|
||||
static void ec_poll(struct net_device *dev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
|
@ -5349,7 +5360,7 @@ static void ec_poll(struct net_device *dev)
|
|||
rtl_rx(dev, tp, 100);
|
||||
|
||||
if (status & LinkChg)
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
irq_work_queue(&tp->ec_watchdog_kicker);
|
||||
|
||||
rtl_ack_events(tp, status);
|
||||
}
|
||||
|
|
@ -5552,6 +5563,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
if (tp->ecdev) {
|
||||
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
|
||||
rc = ecdev_open(tp->ecdev);
|
||||
if (rc) {
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/in.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
|
@ -630,6 +631,7 @@ struct rtl8169_private {
|
|||
|
||||
ec_device_t *ecdev;
|
||||
unsigned long ec_watchdog_jiffies;
|
||||
struct irq_work ec_watchdog_kicker;
|
||||
};
|
||||
|
||||
typedef void (*rtl_generic_fct)(struct rtl8169_private *tp);
|
||||
|
|
@ -4919,6 +4921,7 @@ static void rtl_remove_one(struct pci_dev *pdev)
|
|||
|
||||
if (tp->ecdev) {
|
||||
ecdev_close(tp->ecdev);
|
||||
irq_work_sync(&tp->ec_watchdog_kicker);
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
} else {
|
||||
unregister_netdev(tp->dev);
|
||||
|
|
@ -5189,6 +5192,14 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
|
|||
return false;
|
||||
}
|
||||
|
||||
static void ec_kick_watchdog(struct irq_work *work)
|
||||
{
|
||||
struct rtl8169_private *tp =
|
||||
container_of(work, struct rtl8169_private, ec_watchdog_kicker);
|
||||
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
}
|
||||
|
||||
static void ec_poll(struct net_device *dev)
|
||||
{
|
||||
struct rtl8169_private *tp = netdev_priv(dev);
|
||||
|
|
@ -5207,7 +5218,7 @@ static void ec_poll(struct net_device *dev)
|
|||
rtl_rx(dev, tp, 100);
|
||||
|
||||
if (status & LinkChg)
|
||||
phy_mac_interrupt(tp->phydev);
|
||||
irq_work_queue(&tp->ec_watchdog_kicker);
|
||||
|
||||
rtl_ack_events(tp, status);
|
||||
}
|
||||
|
|
@ -5416,6 +5427,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
if (tp->ecdev) {
|
||||
init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog);
|
||||
rc = ecdev_open(tp->ecdev);
|
||||
if (rc) {
|
||||
ecdev_withdraw(tp->ecdev);
|
||||
|
|
|
|||
Loading…
Reference in New Issue