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 uint16_t j; 45 int ret; 46 47 FOREACH_SUBDEV(sdev, i, dev) { 48 if (sdev->state != DEV_PARSED) 49 continue; 50 da = &sdev->devargs; 51 ret = rte_eal_hotplug_add(da->bus->name, 52 da->name, 53 da->args); 54 if (ret) { 55 ERROR("sub_device %d probe failed %s%s%s", i, 56 rte_errno ? "(" : "", 57 rte_errno ? strerror(rte_errno) : "", 58 rte_errno ? ")" : ""); 59 continue; 60 } 61 RTE_ETH_FOREACH_DEV(j) { 62 if (strcmp(rte_eth_devices[j].device->name, 63 da->name) == 0) { 64 ETH(sdev) = &rte_eth_devices[j]; 65 break; 66 } 67 } 68 if (ETH(sdev) == NULL) { 69 ERROR("sub_device %d init went wrong", i); 70 return -ENODEV; 71 } 72 SUB_ID(sdev) = i; 73 sdev->fs_dev = dev; 74 sdev->dev = ETH(sdev)->device; 75 ETH(sdev)->state = RTE_ETH_DEV_DEFERRED; 76 sdev->state = DEV_PROBED; 77 } 78 return 0; 79 } 80 81 int 82 failsafe_eal_init(struct rte_eth_dev *dev) 83 { 84 int ret; 85 86 ret = fs_bus_init(dev); 87 if (ret) 88 return ret; 89 if (PRIV(dev)->state < DEV_PROBED) 90 PRIV(dev)->state = DEV_PROBED; 91 fs_switch_dev(dev, NULL); 92 return 0; 93 } 94 95 static int 96 fs_bus_uninit(struct rte_eth_dev *dev) 97 { 98 struct sub_device *sdev = NULL; 99 uint8_t i; 100 int sdev_ret; 101 int ret = 0; 102 103 FOREACH_SUBDEV_STATE(sdev, i, dev, DEV_PROBED) { 104 sdev_ret = rte_eal_hotplug_remove(sdev->bus->name, 105 sdev->dev->name); 106 if (sdev_ret) { 107 ERROR("Failed to remove requested device %s (err: %d)", 108 sdev->dev->name, sdev_ret); 109 continue; 110 } 111 sdev->state = DEV_PROBED - 1; 112 } 113 return ret; 114 } 115 116 int 117 failsafe_eal_uninit(struct rte_eth_dev *dev) 118 { 119 int ret; 120 121 ret = fs_bus_uninit(dev); 122 PRIV(dev)->state = DEV_PROBED - 1; 123 return ret; 124 } 125