* split up a pci address into its constituent parts. */
| 394 | * split up a pci address into its constituent parts. |
| 395 | */ |
| 396 | static int |
| 397 | parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr) |
| 398 | { |
| 399 | /* first split on ':' */ |
| 400 | union splitaddr { |
| 401 | struct { |
| 402 | char *domain; |
| 403 | char *bus; |
| 404 | char *devid; |
| 405 | char *function; |
| 406 | }; |
| 407 | char *str[PCI_FMT_NVAL]; /* last element-separator is "." not ":" */ |
| 408 | } splitaddr; |
| 409 | |
| 410 | char *buf_copy = strndup(buf, bufsize); |
| 411 | if (buf_copy == NULL) |
| 412 | return -1; |
| 413 | |
| 414 | if (rte_strsplit(buf_copy, bufsize, splitaddr.str, PCI_FMT_NVAL, ':') |
| 415 | != PCI_FMT_NVAL - 1) |
| 416 | goto error; |
| 417 | /* final split is on '.' between devid and function */ |
| 418 | splitaddr.function = strchr(splitaddr.devid,'.'); |
| 419 | if (splitaddr.function == NULL) |
| 420 | goto error; |
| 421 | *splitaddr.function++ = '\0'; |
| 422 | |
| 423 | /* now convert to int values */ |
| 424 | errno = 0; |
| 425 | addr->domain = strtoul(splitaddr.domain, NULL, 16); |
| 426 | addr->bus = strtoul(splitaddr.bus, NULL, 16); |
| 427 | addr->devid = strtoul(splitaddr.devid, NULL, 16); |
| 428 | addr->function = strtoul(splitaddr.function, NULL, 10); |
| 429 | if (errno != 0) |
| 430 | goto error; |
| 431 | |
| 432 | free(buf_copy); /* free the copy made with strdup */ |
| 433 | return 0; |
| 434 | error: |
| 435 | free(buf_copy); |
| 436 | return -1; |
| 437 | } |
| 438 | |
| 439 | /* |
| 440 | * Scan the content of the PCI bus, and the devices in the devices |
no test coverage detected