| 231 | } |
| 232 | |
| 233 | int |
| 234 | rte_dev_probe(const char *devargs) |
| 235 | { |
| 236 | struct eal_dev_mp_req req; |
| 237 | struct rte_device *dev; |
| 238 | int ret; |
| 239 | |
| 240 | memset(&req, 0, sizeof(req)); |
| 241 | req.t = EAL_DEV_REQ_TYPE_ATTACH; |
| 242 | strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN); |
| 243 | |
| 244 | if (rte_eal_process_type() != RTE_PROC_PRIMARY) { |
| 245 | /** |
| 246 | * If in secondary process, just send IPC request to |
| 247 | * primary process. |
| 248 | */ |
| 249 | ret = eal_dev_hotplug_request_to_primary(&req); |
| 250 | if (ret != 0) { |
| 251 | RTE_LOG(ERR, EAL, |
| 252 | "Failed to send hotplug request to primary\n"); |
| 253 | return -ENOMSG; |
| 254 | } |
| 255 | if (req.result != 0) |
| 256 | RTE_LOG(ERR, EAL, |
| 257 | "Failed to hotplug add device\n"); |
| 258 | return req.result; |
| 259 | } |
| 260 | |
| 261 | /* attach a shared device from primary start from here: */ |
| 262 | |
| 263 | /* primary attach the new device itself. */ |
| 264 | ret = local_dev_probe(devargs, &dev); |
| 265 | |
| 266 | if (ret != 0) { |
| 267 | RTE_LOG(ERR, EAL, |
| 268 | "Failed to attach device on primary process\n"); |
| 269 | |
| 270 | /** |
| 271 | * it is possible that secondary process failed to attached a |
| 272 | * device that primary process have during initialization, |
| 273 | * so for -EEXIST case, we still need to sync with secondary |
| 274 | * process. |
| 275 | */ |
| 276 | if (ret != -EEXIST) |
| 277 | return ret; |
| 278 | } |
| 279 | |
| 280 | /* primary send attach sync request to secondary. */ |
| 281 | ret = eal_dev_hotplug_request_to_secondary(&req); |
| 282 | |
| 283 | /* if any communication error, we need to rollback. */ |
| 284 | if (ret != 0) { |
| 285 | RTE_LOG(ERR, EAL, |
| 286 | "Failed to send hotplug add request to secondary\n"); |
| 287 | ret = -ENOMSG; |
| 288 | goto rollback; |
| 289 | } |
| 290 | |