From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR03-AM5-obe.outbound.protection.outlook.com (mail-eopbgr30040.outbound.protection.outlook.com [40.107.3.40]) by dpdk.org (Postfix) with ESMTP id 414031B3D5 for ; Mon, 12 Feb 2018 19:20:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=iY4K2fcgxvldiTX/lBdHuqri5Y3OlRnomKK7Hozq5XQ=; b=hLAJ8gG45BIgGAcQi/mQY5uH8PYzSDQcB7C7kRj0bgWjJnxX4B3oh75BF7F5hoOJ0DMnjfPwNopT6Xlu/ePtVg1mk/sG2q5U6Tn2ss7blELgMDcgDRF5VRqjYJ8Fx6DL/06Omr/NZLsI5lEG6N1aKd7T8R2/yN0Aiwq/8ZqYjW0= Received: from mellanox.com (209.116.155.178) by AM5PR0501MB2036.eurprd05.prod.outlook.com (2603:10a6:203:1a::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.485.10; Mon, 12 Feb 2018 18:20:55 +0000 From: Yongseok Koh To: stable@dpdk.org Cc: Yongseok Koh Date: Mon, 12 Feb 2018 10:20:22 -0800 Message-Id: <20180212182022.36466-1-yskoh@mellanox.com> X-Mailer: git-send-email 2.11.0 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [209.116.155.178] X-ClientProxiedBy: CY4PR15CA0011.namprd15.prod.outlook.com (2603:10b6:910:14::21) To AM5PR0501MB2036.eurprd05.prod.outlook.com (2603:10a6:203:1a::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 33270ebb-378e-4ee5-e2a9-08d572455bad X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603307)(7153060)(7193020); SRVR:AM5PR0501MB2036; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 3:c0L8zKa4TtdvZHs0D/t7jVKYJBYCT0mOC8OhwvuiseWC/8plY/gLr+lC5dNYfXTR5YMaCG9RVcwXa1CXOf+KgRb1v0I0pResm5hreutq1SBUQtf3vzVFGHAuS0hxB+i2T65zQ1/I1aLMSVqygAUKEjeaCrhVg3m7Qpva8tRQLWdxJPg4ZvLDo1kdQXvSzJPwRY1Rh/uUYD4UVIiUWoNeFLPrS4pOBd+YLa1FCwVZvgJRtm2Bgo/gQt5baUHNLGfy; 25:tdxFZV8HI6/2nw39V0r1Z1xj0ZD0jpiZIRI0/UAZCj2OTW7T8IhRjDYdAtbwvn1aL+6UtcU0pAKSflp43Ro0Rswgy7uQaGTvlPwQFd9oq2kJelFuxPgu2+hR8d2d43yAjNNJU8AxewHu1acRh9ZxddJv/rGgBNhBzpqtmDWvhCzVyy54ycOgmqNpBR6vclCiGmVE4+z0byizNGuOQBQ0U4Y2v8EqnlCvKgOunVNsp/2ZPHO2ycJFliG5Qp48b0xCU+htyvRDnQm4YP/if4MslIQlFJvxUN5a2OKfDfcQICLZSMMnTo7wpWBcPclgBagoysQTBO8TTy+YifgcFng9tQ==; 31:207su6g98OQd60VKPYb16cP7C8zPwHJZroZ/iqXJ4ZxWU2K7CmjH4+pAl516ctSNZpfj7kMpJH9CzNZtHo9EBKIE+6HySfk6dQOzSHDFlnY//uVKAsMVbQVKhVMg2YgWCzp/zzILOW8M8ySdRr8urOcbCozlXYbKAcqf7dKSXphJAu4VHER+8JLKIoThwgZx/NRE9LyVXXEoo3NxAZrQkdDzykLzrkC9igkHZOyvb8g= X-MS-TrafficTypeDiagnostic: AM5PR0501MB2036: X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 20:gPAUym7RMTbyP3QyvUCKe4UIMDfzxlnW+9vwsO6nyefCkIAveWXFVPI2g0cxDMOcOMFvA0cDp/S8SECa7TyxLsgUos8U2E8Uw0tWqrt5QgahuHYlXRHI81qwzN0USP4pMyX91x4/f+GM71m0ru3rPETQ/WJsVOFV0ju5r6e+XDX4Vj9HE5a5fRSADiV+ggmENmvVlMA1AKd13m85/uJFwOUVOwbT6QpVln1rFbrocbk1pxg6ivcJ7Q4H5/Y+SjOwb6To0zD3el7axQVnOVizfyMPzjEJPEuZ2RXFJxcaPDAZTdsHiN5gs/TxbJuDVXuTyyac/cSJF+NkOO6lpnruJKmfh1yL2eGN89ZfMOknQ9TRYGu8rEl3ukyaa67vL1eHE8bgbRpiF9fCZosT9jPtzeApzllJPS6JJWvlULFvSnxClWYWwOjq0EozUVp2tdFfUIHYW046gbd2KL08DpprEzpr5vuABCFaLf/L3M3Q+koPSzMwqSHmEDVvON4KNiGl; 4:VvYQloIC3MKpzUAq1OaKPgTiabPNxwDnwLntb7DDLBNS6/hdCj9gDOc73SIKGx0SrqLe0ZWQax+HX8MLqCORoMD6NI4JpdlGBWVNCnybL5wNLyyYVlAuS37BCOih/L8tdPT1EtvE8j3DzHg6UMX9e1TaQtmEe1pkAf1F9Ow2dxRshginvUxuD4MkkenuvGnlJKXwkdI993oP85EnJHUvkRp73FgqNBUwDuxVAtwdI3EWWkeYlUmqCcNXPEuVTYdtVfwNTPnb3qwp7p7LetMjcA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(5005006)(8121501046)(3231101)(2400082)(944501161)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041288)(20161123564045)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(6072148)(201708071742011); SRVR:AM5PR0501MB2036; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0501MB2036; X-Forefront-PRVS: 0581B5AB35 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(39860400002)(39380400002)(346002)(376002)(396003)(366004)(199004)(189003)(386003)(186003)(107886003)(4326008)(7696005)(52116002)(51416003)(2361001)(3846002)(6116002)(8676002)(7736002)(105586002)(81156014)(1076002)(305945005)(8936002)(48376002)(478600001)(16526019)(2906002)(50466002)(36756003)(81166006)(59450400001)(6346003)(2351001)(1857600001)(6666003)(69596002)(21086003)(16586007)(26005)(5660300001)(53936002)(66066001)(316002)(106356001)(55016002)(25786009)(86362001)(6916009)(575784001)(50226002)(47776003)(68736007)(97736004); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0501MB2036; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0501MB2036; 23:bPrsFbvhFOLp+Bpnpj2Pi/Fwd6+bdoajrC2f21d?= =?us-ascii?Q?ZDfoNEGkZxj3+fXRub64txBrFyqmL62jL30n/rlNm4r/tLmyLWBUR9DtHNLy?= =?us-ascii?Q?86MI5QRo0o3cO3TtebetikzBE5lJQbN4q043Zlokdtr3B1rNvaV87n8imjzt?= =?us-ascii?Q?IjuHbz6RRargeo7rkm7E6DrctugWFfx2V5KQo8zsilgOmUhv4BJkRHOVOhA3?= =?us-ascii?Q?LPj8egyIdxEEAW6xlGt9GUEA0TvbNWJFFUUgJRRphTyViqNfdOjyZn6dc+pP?= =?us-ascii?Q?Lmxc/4TQUh/FsUMkYRhEamnZHY3Hl3l6rN1IPv8ILCUIlu/S8DyEQ6f1Hl/S?= =?us-ascii?Q?vzYV0278CApTo42KIRt9dfjssWAPqdxMPp1nw3aGThb+D1F1XaPgUTuK7PFI?= =?us-ascii?Q?4qPlBtSwkbO3yZFTUFXvmTYoysyYaXI+XL9FVMtkONcmNGc4U+JGqjkLGvfZ?= =?us-ascii?Q?AAVCloSSUDCbaAx4gisIT7+0ynoGjS2wre6r3atGWqvRSKGyHxjzPav79KwD?= =?us-ascii?Q?BG4uEU2qm8z8CdLo29LrWk5A1t/33b+GBvNfFuNbC5a10mcLdoufeiuZbE9e?= =?us-ascii?Q?LzBUUNnzNpkFrP5iwK+olRcOkHYm6UHemnlhmoelAXuTJiOtklJZcz9eVnII?= =?us-ascii?Q?K8QXg1ssoC+LF9zz5dZp9oKlj47nZRlzxu+1zUUCtPMcHGBQefSgalOiJHFW?= =?us-ascii?Q?8NIqTNQygbxZfHprvxXztaKVhYaYANSddJuBXuHU5DrGwt/5JS9j1ZscBaJJ?= =?us-ascii?Q?TAHV9f7t94fD4k8KCi+mvk5BbO77VMMZwe2d5FuT6Qsn5dcoIZIulPtFD27T?= =?us-ascii?Q?4i1k4PML19ID2pS+M+D7EspMumBpPBz7Ng5OZtYBGukTc/rcCJLINyu9AAqd?= =?us-ascii?Q?kdjARWkDEefNqx/jb+rvvMnTEZQ2vRTg0v/irss5R6+K1gSfefQQkzV7TnuK?= =?us-ascii?Q?KNsO0rx+9f3gtnL0VlFA7UuuoQMYnTDxUQJ3Pz2q7UKkLAQ/hmCcZyVXRP9p?= =?us-ascii?Q?u/D047U9Y6QdJEoycnSD5KNtxDsRg1Y+h5zhad71buxj+9TfNnvmruizstGl?= =?us-ascii?Q?0svy5z7qcsQ7ESjn+b7JZaxmsZ6EOdDZvmQg6y9cEs4BRENKuDGIUPCG4uw5?= =?us-ascii?Q?hut7Yj/pjbEHlO09gI0ntR65qi0PtLj2yR2kGQ8bZykmijmwGggFTFh5Ait3?= =?us-ascii?Q?ClQ3UBCtAeck1gEzVFPMQYBND2hVihumC3luJoOQ3kBx7EY4MHhhb3SYV041?= =?us-ascii?Q?mSgWMphLy27NfJjn3gIE=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0501MB2036; 6:aR017gfPLjjruGgh+dWobx0PgOgxuCEd1x+plsDFDf/XIT4OkhRv6HdJLE7ykx18BPNVpN9I4/cTLXCRtr1ZXfpgxt2d1GsaEsIs/8IATKX0TolDey7XGeV9Viv8qnW/jMBa1moZlNYFNLErTh1Xf6AynKstnizue019ZnWZmLUawBaGMhIYZm6mdTzlUZiNFd9gUoZOkr607cnEp7u0VcRmPQSRM/TGgnLyFLJye0V9lXvouGTTirH8HfeM8kAYfp1YsR8ETnrfVQxXKYwnVR5dU4a+Jz1G1aBQN5j9nxhgHxxFBoqAVJZ6p/pOqWOLEnc2gKz91TA5p58NOOwrzOaJ7ZWoO2C4IRAXzTYKDAk=; 5:1olyj16tE9KMjpc/TZvrsz1QQvqThrQjvl58v7bLXw4C7w+W3DW4JDTtJzNOvLKdNq2/uMT7cxSnBvTrQQvK18s2pp0iaKyTd1yPfT7kxpJ1ic17zxagkOLuEginj1kuKsy3XM7LliI4YqUorJWDkUdfUjZPjM8Kko3scTVCa94=; 24:rw1G2Fn0oUq0ehkvkx98x9byv4Ec3prDB6qjG4aRGwLSSOjnOxr3X9a8I8hgBIM15X4CPA36/ki6XOpsy4BSonBrmxs0NfVaZJ1n/1Dwxn4=; 7:H4dRpfJbT+X0SLGPlIL7h9XKQajeMMvQxyKnsizbtWqiWFSGzGn8PDBXwFg8l/ZUROiIFNf311tILegRYvJIYW/JsITuzizagvwjOIX3krWxeT852Yhs0grTa+KOmjSIlsl6i8Wq+NxaoilJey5POfADvCXNZUpWyf08SlPx1E2IWKcQxNdYm0eZ3BDr87hh8VV3w8J22mUwQRNTJjkY9qK735tHSA9hLDAi8KBCN0iRaQFWlhdz7dip/v6AZ3U0 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Feb 2018 18:20:55.2662 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 33270ebb-378e-4ee5-e2a9-08d572455bad X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0501MB2036 Subject: [dpdk-stable] [PATCH] net/mlx5: fix handling link status event X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Feb 2018 18:20:58 -0000 [ backported from upstream commit c7bf62255edf ] Even though link of a port gets down, device still can receive traffic. That is the reason why mlx5_set_link_up/down() switches rx/tx_pkt_burst(). However, if link gets down by an external command (e.g. ifconfig), it isn't effective. It is better to change burst functions when link status change is detected. Fixes: 62072098b54e ("mlx5: support setting link up or down") Cc: stable@dpdk.org Signed-off-by: Yongseok Koh Acked-by: Nelio Laranjeiro --- drivers/net/mlx5/mlx5.c | 1 - drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_ethdev.c | 118 ++++++++++++++++++++++++++++++---------- drivers/net/mlx5/mlx5_trigger.c | 23 ++------ 4 files changed, 95 insertions(+), 48 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index eba674269..40804b3e6 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -932,7 +932,6 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) /* Bring Ethernet device up. */ DEBUG("forcing Ethernet interface up"); priv_set_flags(priv, ~IFF_UP, IFF_UP); - mlx5_link_update(priv->dev, 1); continue; port_error: diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 1a4f444c7..de9071f5d 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -210,6 +210,7 @@ int priv_set_flags(struct priv *, unsigned int, unsigned int); int mlx5_dev_configure(struct rte_eth_dev *); void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *); const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev); +int priv_link_update(struct priv *, int); int mlx5_link_update(struct rte_eth_dev *, int); int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t); int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *); diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c index e91c0f633..25f84e9bc 100644 --- a/drivers/net/mlx5/mlx5_ethdev.c +++ b/drivers/net/mlx5/mlx5_ethdev.c @@ -914,25 +914,104 @@ mlx5_link_update_unlocked_gs(struct rte_eth_dev *dev, int wait_to_complete) } /** - * DPDK callback to retrieve physical link information. + * Enable receiving and transmitting traffic. * - * @param dev - * Pointer to Ethernet device structure. + * @param priv + * Pointer to private structure. + */ +static void +priv_link_start(struct priv *priv) +{ + struct rte_eth_dev *dev = priv->dev; + int err; + + priv_dev_select_tx_function(priv, dev); + priv_dev_select_rx_function(priv, dev); + err = priv_dev_traffic_enable(priv, dev); + if (err) + ERROR("%p: error occurred while configuring control flows: %s", + (void *)priv, strerror(err)); + err = priv_flow_start(priv, &priv->flows); + if (err) + ERROR("%p: error occurred while configuring flows: %s", + (void *)priv, strerror(err)); +} + +/** + * Disable receiving and transmitting traffic. + * + * @param priv + * Pointer to private structure. + */ +static void +priv_link_stop(struct priv *priv) +{ + struct rte_eth_dev *dev = priv->dev; + + priv_flow_stop(priv, &priv->flows); + priv_dev_traffic_disable(priv, dev); + dev->rx_pkt_burst = removed_rx_burst; + dev->tx_pkt_burst = removed_tx_burst; +} + +/** + * Retrieve physical link information and update rx/tx_pkt_burst callbacks + * accordingly. + * + * @param priv + * Pointer to private structure. * @param wait_to_complete * Wait for request completion (ignored). */ int -mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) +priv_link_update(struct priv *priv, int wait_to_complete) { + struct rte_eth_dev *dev = priv->dev; struct utsname utsname; int ver[3]; + int ret; + struct rte_eth_link dev_link = dev->data->dev_link; if (uname(&utsname) == -1 || sscanf(utsname.release, "%d.%d.%d", &ver[0], &ver[1], &ver[2]) != 3 || KERNEL_VERSION(ver[0], ver[1], ver[2]) < KERNEL_VERSION(4, 9, 0)) - return mlx5_link_update_unlocked_gset(dev, wait_to_complete); - return mlx5_link_update_unlocked_gs(dev, wait_to_complete); + ret = mlx5_link_update_unlocked_gset(dev, wait_to_complete); + else + ret = mlx5_link_update_unlocked_gs(dev, wait_to_complete); + /* If lsc interrupt is disabled, should always be ready for traffic. */ + if (!dev->data->dev_conf.intr_conf.lsc) { + priv_link_start(priv); + return ret; + } + /* Re-select burst callbacks only if link status has been changed. */ + if (!ret && dev_link.link_status != dev->data->dev_link.link_status) { + if (dev->data->dev_link.link_status == ETH_LINK_UP) + priv_link_start(priv); + else + priv_link_stop(priv); + } + return ret; +} + +/** + * DPDK callback to retrieve physical link information. + * + * @param dev + * Pointer to Ethernet device structure. + * @param wait_to_complete + * Wait for request completion (ignored). + */ +int +mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete) +{ + struct priv *priv = dev->data->dev_private; + int ret; + + priv_lock(priv); + ret = priv_link_update(priv, wait_to_complete); + priv_unlock(priv); + return ret; } /** @@ -1151,7 +1230,7 @@ priv_link_status_update(struct priv *priv) { struct rte_eth_link *link = &priv->dev->data->dev_link; - mlx5_link_update(priv->dev, 0); + priv_link_update(priv, 0); if (((link->link_speed == 0) && link->link_status) || ((link->link_speed != 0) && !link->link_status)) { /* @@ -1354,8 +1433,6 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev) * * @param priv * Pointer to private data structure. - * @param dev - * Pointer to rte_eth_dev structure. * @param up * Nonzero for link up, otherwise link down. * @@ -1363,24 +1440,9 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev) * 0 on success, errno value on failure. */ static int -priv_dev_set_link(struct priv *priv, struct rte_eth_dev *dev, int up) +priv_dev_set_link(struct priv *priv, int up) { - int err; - - if (up) { - err = priv_set_flags(priv, ~IFF_UP, IFF_UP); - if (err) - return err; - priv_dev_select_tx_function(priv, dev); - priv_dev_select_rx_function(priv, dev); - } else { - err = priv_set_flags(priv, ~IFF_UP, ~IFF_UP); - if (err) - return err; - dev->rx_pkt_burst = removed_rx_burst; - dev->tx_pkt_burst = removed_tx_burst; - } - return 0; + return priv_set_flags(priv, ~IFF_UP, up ? IFF_UP : ~IFF_UP); } /** @@ -1399,7 +1461,7 @@ mlx5_set_link_down(struct rte_eth_dev *dev) int err; priv_lock(priv); - err = priv_dev_set_link(priv, dev, 0); + err = priv_dev_set_link(priv, 0); priv_unlock(priv); return err; } @@ -1420,7 +1482,7 @@ mlx5_set_link_up(struct rte_eth_dev *dev) int err; priv_lock(priv); - err = priv_dev_set_link(priv, dev, 1); + err = priv_dev_set_link(priv, 1); priv_unlock(priv); return err; } diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index 39c5ec5d2..01780ef18 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -154,38 +154,23 @@ mlx5_dev_start(struct rte_eth_dev *dev) (void *)dev, strerror(err)); goto error; } - /* Update send callback. */ - priv_dev_select_tx_function(priv, dev); err = priv_rxq_start(priv); if (err) { ERROR("%p: RXQ allocation failed: %s", (void *)dev, strerror(err)); goto error; } - /* Update receive callback. */ - priv_dev_select_rx_function(priv, dev); - err = priv_dev_traffic_enable(priv, dev); - if (err) { - ERROR("%p: an error occurred while configuring control flows:" - " %s", - (void *)priv, strerror(err)); - goto error; - } - err = priv_flow_start(priv, &priv->flows); - if (err) { - ERROR("%p: an error occurred while configuring flows:" - " %s", - (void *)priv, strerror(err)); - goto error; - } err = priv_rx_intr_vec_enable(priv); if (err) { ERROR("%p: RX interrupt vector creation failed", (void *)priv); goto error; } - priv_dev_interrupt_handler_install(priv, dev); priv_xstats_init(priv); + /* Update link status and Tx/Rx callbacks for the first time. */ + memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link)); + priv_link_update(priv, 1); + priv_dev_interrupt_handler_install(priv, dev); priv_unlock(priv); return 0; error: -- 2.11.0