| 367 | } |
| 368 | |
| 369 | int |
| 370 | rte_dev_remove(struct rte_device *dev) |
| 371 | { |
| 372 | struct eal_dev_mp_req req; |
| 373 | char *devargs; |
| 374 | int ret; |
| 375 | |
| 376 | if (!rte_dev_is_probed(dev)) { |
| 377 | RTE_LOG(ERR, EAL, "Device is not probed\n"); |
| 378 | return -ENOENT; |
| 379 | } |
| 380 | |
| 381 | ret = build_devargs(dev->bus->name, dev->name, "", &devargs); |
| 382 | if (ret != 0) |
| 383 | return ret; |
| 384 | |
| 385 | memset(&req, 0, sizeof(req)); |
| 386 | req.t = EAL_DEV_REQ_TYPE_DETACH; |
| 387 | strlcpy(req.devargs, devargs, EAL_DEV_MP_DEV_ARGS_MAX_LEN); |
| 388 | free(devargs); |
| 389 | |
| 390 | if (rte_eal_process_type() != RTE_PROC_PRIMARY) { |
| 391 | /** |
| 392 | * If in secondary process, just send IPC request to |
| 393 | * primary process. |
| 394 | */ |
| 395 | ret = eal_dev_hotplug_request_to_primary(&req); |
| 396 | if (ret != 0) { |
| 397 | RTE_LOG(ERR, EAL, |
| 398 | "Failed to send hotplug request to primary\n"); |
| 399 | return -ENOMSG; |
| 400 | } |
| 401 | if (req.result != 0) |
| 402 | RTE_LOG(ERR, EAL, |
| 403 | "Failed to hotplug remove device\n"); |
| 404 | return req.result; |
| 405 | } |
| 406 | |
| 407 | /* detach a device from primary start from here: */ |
| 408 | |
| 409 | /* primary send detach sync request to secondary */ |
| 410 | ret = eal_dev_hotplug_request_to_secondary(&req); |
| 411 | |
| 412 | /** |
| 413 | * if communication error, we need to rollback, because it is possible |
| 414 | * part of the secondary processes still detached it successfully. |
| 415 | */ |
| 416 | if (ret != 0) { |
| 417 | RTE_LOG(ERR, EAL, |
| 418 | "Failed to send device detach request to secondary\n"); |
| 419 | ret = -ENOMSG; |
| 420 | goto rollback; |
| 421 | } |
| 422 | |
| 423 | /** |
| 424 | * if any secondary failed to detach, we need to consider if rollback |
| 425 | * is necessary. |
| 426 | */ |