1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2017 6WIND S.A. 5 * Copyright 2017 Mellanox. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of 6WIND S.A. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <rte_malloc.h> 35 36 #include "failsafe_private.h" 37 38 static int 39 fs_bus_init(struct rte_eth_dev *dev) 40 { 41 struct sub_device *sdev; 42 struct rte_devargs *da; 43 uint8_t i; 44 int ret; 45 46 FOREACH_SUBDEV(sdev, i, dev) { 47 if (sdev->state != DEV_PARSED) 48 continue; 49 da = &sdev->devargs; 50 ret = rte_eal_hotplug_add(da->bus->name, 51 da->name, 52 da->args); 53 if (ret) { 54 ERROR("sub_device %d probe failed %s%s%s", i, 55 rte_errno ? "(" : "", 56 rte_errno ? strerror(rte_errno) : "", 57 rte_errno ? ")" : ""); 58 continue; 59 } 60 ETH(sdev) = rte_eth_dev_allocated(da->name); 61 if (ETH(sdev) == NULL) { 62 ERROR("sub_device %d init went wrong", i); 63 return -ENODEV; 64 } 65 SUB_ID(sdev) = i; 66 sdev->fs_dev = dev; 67 sdev->dev = ETH(sdev)->device; 68 ETH(sdev)->state = RTE_ETH_DEV_DEFERRED; 69 sdev->state = DEV_PROBED; 70 } 71 return 0; 72 } 73 74 int 75 failsafe_eal_init(struct rte_eth_dev *dev) 76 { 77 int ret; 78 79 ret = fs_bus_init(dev); 80 if (ret) 81 return ret; 82 if (PRIV(dev)->state < DEV_PROBED) 83 PRIV(dev)->state = DEV_PROBED; 84 fs_switch_dev(dev, NULL); 85 return 0; 86 } 87 88 static int 89 fs_bus_uninit(struct rte_eth_dev *dev) 90 { 91 struct sub_device *sdev = NULL; 92 uint8_t i; 93 int sdev_ret; 94 int ret = 0; 95 96 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) { 97 sdev_ret = rte_eal_hotplug_remove(sdev->bus->name, 98 sdev->dev->name); 99 if (sdev_ret) { 100 ERROR("Failed to remove requested device %s (err: %d)", 101 sdev->dev->name, sdev_ret); 102 continue; 103 } 104 sdev->state = DEV_PROBED - 1; 105 } 106 return ret; 107 } 108 109 int 110 failsafe_eal_uninit(struct rte_eth_dev *dev) 111 { 112 int ret; 113 114 ret = fs_bus_uninit(dev); 115 PRIV(dev)->state = DEV_PROBED - 1; 116 return ret; 117 } 118