diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/eeh.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/pci-bridge.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_dev.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 137 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 4 |
6 files changed, 127 insertions, 26 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index b5b5f45dfb0a..fb9f376ae27b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -140,9 +140,11 @@ struct eeh_dev { | |||
140 | int af_cap; /* Saved AF capability */ | 140 | int af_cap; /* Saved AF capability */ |
141 | struct eeh_pe *pe; /* Associated PE */ | 141 | struct eeh_pe *pe; /* Associated PE */ |
142 | struct list_head list; /* Form link list in the PE */ | 142 | struct list_head list; /* Form link list in the PE */ |
143 | struct list_head rmv_list; /* Record the removed edevs */ | ||
143 | struct pci_controller *phb; /* Associated PHB */ | 144 | struct pci_controller *phb; /* Associated PHB */ |
144 | struct pci_dn *pdn; /* Associated PCI device node */ | 145 | struct pci_dn *pdn; /* Associated PCI device node */ |
145 | struct pci_dev *pdev; /* Associated PCI device */ | 146 | struct pci_dev *pdev; /* Associated PCI device */ |
147 | bool in_error; /* Error flag for edev */ | ||
146 | struct pci_dev *physfn; /* Associated SRIOV PF */ | 148 | struct pci_dev *physfn; /* Associated SRIOV PF */ |
147 | struct pci_bus *bus; /* PCI bus for partial hotplug */ | 149 | struct pci_bus *bus; /* PCI bus for partial hotplug */ |
148 | }; | 150 | }; |
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index f4d17587fa31..9f165e8a77bf 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h | |||
@@ -212,6 +212,7 @@ struct pci_dn { | |||
212 | #define IODA_INVALID_PE (-1) | 212 | #define IODA_INVALID_PE (-1) |
213 | #ifdef CONFIG_PPC_POWERNV | 213 | #ifdef CONFIG_PPC_POWERNV |
214 | int pe_number; | 214 | int pe_number; |
215 | int vf_index; /* VF index in the PF */ | ||
215 | #ifdef CONFIG_PCI_IOV | 216 | #ifdef CONFIG_PCI_IOV |
216 | u16 vfs_expanded; /* number of VFs IOV BAR expanded */ | 217 | u16 vfs_expanded; /* number of VFs IOV BAR expanded */ |
217 | u16 num_vfs; /* number of VFs enabled*/ | 218 | u16 num_vfs; /* number of VFs enabled*/ |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 0d724625662f..b7338a9426df 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -1246,6 +1246,14 @@ void eeh_remove_device(struct pci_dev *dev) | |||
1246 | * from the parent PE during the BAR resotre. | 1246 | * from the parent PE during the BAR resotre. |
1247 | */ | 1247 | */ |
1248 | edev->pdev = NULL; | 1248 | edev->pdev = NULL; |
1249 | |||
1250 | /* | ||
1251 | * The flag "in_error" is used to trace EEH devices for VFs | ||
1252 | * in error state or not. It's set in eeh_report_error(). If | ||
1253 | * it's not set, eeh_report_{reset,resume}() won't be called | ||
1254 | * for the VF EEH device. | ||
1255 | */ | ||
1256 | edev->in_error = false; | ||
1249 | dev->dev.archdata.edev = NULL; | 1257 | dev->dev.archdata.edev = NULL; |
1250 | if (!(edev->pe->state & EEH_PE_KEEP)) | 1258 | if (!(edev->pe->state & EEH_PE_KEEP)) |
1251 | eeh_rmv_from_parent_pe(edev); | 1259 | eeh_rmv_from_parent_pe(edev); |
diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index aabba94ff9cb..7815095fe3d8 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c | |||
@@ -67,6 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data) | |||
67 | edev->pdn = pdn; | 67 | edev->pdn = pdn; |
68 | edev->phb = phb; | 68 | edev->phb = phb; |
69 | INIT_LIST_HEAD(&edev->list); | 69 | INIT_LIST_HEAD(&edev->list); |
70 | INIT_LIST_HEAD(&edev->rmv_list); | ||
70 | 71 | ||
71 | return NULL; | 72 | return NULL; |
72 | } | 73 | } |
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 650cfb31ea3d..c0fe7a6be2c9 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c | |||
@@ -34,6 +34,11 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/rtas.h> | 35 | #include <asm/rtas.h> |
36 | 36 | ||
37 | struct eeh_rmv_data { | ||
38 | struct list_head edev_list; | ||
39 | int removed; | ||
40 | }; | ||
41 | |||
37 | /** | 42 | /** |
38 | * eeh_pcid_name - Retrieve name of PCI device driver | 43 | * eeh_pcid_name - Retrieve name of PCI device driver |
39 | * @pdev: PCI device | 44 | * @pdev: PCI device |
@@ -211,6 +216,7 @@ static void *eeh_report_error(void *data, void *userdata) | |||
211 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; | 216 | if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; |
212 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; | 217 | if (*res == PCI_ERS_RESULT_NONE) *res = rc; |
213 | 218 | ||
219 | edev->in_error = true; | ||
214 | eeh_pcid_put(dev); | 220 | eeh_pcid_put(dev); |
215 | return NULL; | 221 | return NULL; |
216 | } | 222 | } |
@@ -282,7 +288,8 @@ static void *eeh_report_reset(void *data, void *userdata) | |||
282 | 288 | ||
283 | if (!driver->err_handler || | 289 | if (!driver->err_handler || |
284 | !driver->err_handler->slot_reset || | 290 | !driver->err_handler->slot_reset || |
285 | (edev->mode & EEH_DEV_NO_HANDLER)) { | 291 | (edev->mode & EEH_DEV_NO_HANDLER) || |
292 | (!edev->in_error)) { | ||
286 | eeh_pcid_put(dev); | 293 | eeh_pcid_put(dev); |
287 | return NULL; | 294 | return NULL; |
288 | } | 295 | } |
@@ -326,6 +333,7 @@ static void *eeh_report_resume(void *data, void *userdata) | |||
326 | { | 333 | { |
327 | struct eeh_dev *edev = (struct eeh_dev *)data; | 334 | struct eeh_dev *edev = (struct eeh_dev *)data; |
328 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 335 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
336 | bool was_in_error; | ||
329 | struct pci_driver *driver; | 337 | struct pci_driver *driver; |
330 | 338 | ||
331 | if (!dev || eeh_dev_removed(edev)) | 339 | if (!dev || eeh_dev_removed(edev)) |
@@ -335,11 +343,13 @@ static void *eeh_report_resume(void *data, void *userdata) | |||
335 | driver = eeh_pcid_get(dev); | 343 | driver = eeh_pcid_get(dev); |
336 | if (!driver) return NULL; | 344 | if (!driver) return NULL; |
337 | 345 | ||
346 | was_in_error = edev->in_error; | ||
347 | edev->in_error = false; | ||
338 | eeh_enable_irq(dev); | 348 | eeh_enable_irq(dev); |
339 | 349 | ||
340 | if (!driver->err_handler || | 350 | if (!driver->err_handler || |
341 | !driver->err_handler->resume || | 351 | !driver->err_handler->resume || |
342 | (edev->mode & EEH_DEV_NO_HANDLER)) { | 352 | (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) { |
343 | edev->mode &= ~EEH_DEV_NO_HANDLER; | 353 | edev->mode &= ~EEH_DEV_NO_HANDLER; |
344 | eeh_pcid_put(dev); | 354 | eeh_pcid_put(dev); |
345 | return NULL; | 355 | return NULL; |
@@ -386,12 +396,40 @@ static void *eeh_report_failure(void *data, void *userdata) | |||
386 | return NULL; | 396 | return NULL; |
387 | } | 397 | } |
388 | 398 | ||
399 | static void *eeh_add_virt_device(void *data, void *userdata) | ||
400 | { | ||
401 | struct pci_driver *driver; | ||
402 | struct eeh_dev *edev = (struct eeh_dev *)data; | ||
403 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | ||
404 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); | ||
405 | |||
406 | if (!(edev->physfn)) { | ||
407 | pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n", | ||
408 | __func__, edev->phb->global_number, pdn->busno, | ||
409 | PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); | ||
410 | return NULL; | ||
411 | } | ||
412 | |||
413 | driver = eeh_pcid_get(dev); | ||
414 | if (driver) { | ||
415 | eeh_pcid_put(dev); | ||
416 | if (driver->err_handler) | ||
417 | return NULL; | ||
418 | } | ||
419 | |||
420 | #ifdef CONFIG_PPC_POWERNV | ||
421 | pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0); | ||
422 | #endif | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
389 | static void *eeh_rmv_device(void *data, void *userdata) | 426 | static void *eeh_rmv_device(void *data, void *userdata) |
390 | { | 427 | { |
391 | struct pci_driver *driver; | 428 | struct pci_driver *driver; |
392 | struct eeh_dev *edev = (struct eeh_dev *)data; | 429 | struct eeh_dev *edev = (struct eeh_dev *)data; |
393 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); | 430 | struct pci_dev *dev = eeh_dev_to_pci_dev(edev); |
394 | int *removed = (int *)userdata; | 431 | struct eeh_rmv_data *rmv_data = (struct eeh_rmv_data *)userdata; |
432 | int *removed = rmv_data ? &rmv_data->removed : NULL; | ||
395 | 433 | ||
396 | /* | 434 | /* |
397 | * Actually, we should remove the PCI bridges as well. | 435 | * Actually, we should remove the PCI bridges as well. |
@@ -416,7 +454,8 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
416 | driver = eeh_pcid_get(dev); | 454 | driver = eeh_pcid_get(dev); |
417 | if (driver) { | 455 | if (driver) { |
418 | eeh_pcid_put(dev); | 456 | eeh_pcid_put(dev); |
419 | if (driver->err_handler && | 457 | if (removed && |
458 | driver->err_handler && | ||
420 | driver->err_handler->error_detected && | 459 | driver->err_handler->error_detected && |
421 | driver->err_handler->slot_reset) | 460 | driver->err_handler->slot_reset) |
422 | return NULL; | 461 | return NULL; |
@@ -427,11 +466,29 @@ static void *eeh_rmv_device(void *data, void *userdata) | |||
427 | pci_name(dev)); | 466 | pci_name(dev)); |
428 | edev->bus = dev->bus; | 467 | edev->bus = dev->bus; |
429 | edev->mode |= EEH_DEV_DISCONNECTED; | 468 | edev->mode |= EEH_DEV_DISCONNECTED; |
430 | (*removed)++; | 469 | if (removed) |
470 | (*removed)++; | ||
431 | 471 | ||
432 | pci_lock_rescan_remove(); | 472 | if (edev->physfn) { |
433 | pci_stop_and_remove_bus_device(dev); | 473 | #ifdef CONFIG_PPC_POWERNV |
434 | pci_unlock_rescan_remove(); | 474 | struct pci_dn *pdn = eeh_dev_to_pdn(edev); |
475 | |||
476 | pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0); | ||
477 | edev->pdev = NULL; | ||
478 | |||
479 | /* | ||
480 | * We have to set the VF PE number to invalid one, which is | ||
481 | * required to plug the VF successfully. | ||
482 | */ | ||
483 | pdn->pe_number = IODA_INVALID_PE; | ||
484 | #endif | ||
485 | if (rmv_data) | ||
486 | list_add(&edev->rmv_list, &rmv_data->edev_list); | ||
487 | } else { | ||
488 | pci_lock_rescan_remove(); | ||
489 | pci_stop_and_remove_bus_device(dev); | ||
490 | pci_unlock_rescan_remove(); | ||
491 | } | ||
435 | 492 | ||
436 | return NULL; | 493 | return NULL; |
437 | } | 494 | } |
@@ -545,11 +602,13 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe) | |||
545 | * During the reset, udev might be invoked because those affected | 602 | * During the reset, udev might be invoked because those affected |
546 | * PCI devices will be removed and then added. | 603 | * PCI devices will be removed and then added. |
547 | */ | 604 | */ |
548 | static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | 605 | static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, |
606 | struct eeh_rmv_data *rmv_data) | ||
549 | { | 607 | { |
550 | struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); | 608 | struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); |
551 | struct timeval tstamp; | 609 | struct timeval tstamp; |
552 | int cnt, rc, removed = 0; | 610 | int cnt, rc; |
611 | struct eeh_dev *edev; | ||
553 | 612 | ||
554 | /* pcibios will clear the counter; save the value */ | 613 | /* pcibios will clear the counter; save the value */ |
555 | cnt = pe->freeze_count; | 614 | cnt = pe->freeze_count; |
@@ -563,12 +622,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
563 | */ | 622 | */ |
564 | eeh_pe_state_mark(pe, EEH_PE_KEEP); | 623 | eeh_pe_state_mark(pe, EEH_PE_KEEP); |
565 | if (bus) { | 624 | if (bus) { |
566 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | 625 | if (pe->type & EEH_PE_VF) { |
567 | pci_lock_rescan_remove(); | 626 | eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); |
568 | pcibios_remove_pci_devices(bus); | 627 | } else { |
569 | pci_unlock_rescan_remove(); | 628 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); |
629 | pci_lock_rescan_remove(); | ||
630 | pcibios_remove_pci_devices(bus); | ||
631 | pci_unlock_rescan_remove(); | ||
632 | } | ||
570 | } else if (frozen_bus) { | 633 | } else if (frozen_bus) { |
571 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); | 634 | eeh_pe_dev_traverse(pe, eeh_rmv_device, &rmv_data); |
572 | } | 635 | } |
573 | 636 | ||
574 | /* | 637 | /* |
@@ -610,14 +673,22 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
610 | * PE. We should disconnect it so the binding can be | 673 | * PE. We should disconnect it so the binding can be |
611 | * rebuilt when adding PCI devices. | 674 | * rebuilt when adding PCI devices. |
612 | */ | 675 | */ |
676 | edev = list_first_entry(&pe->edevs, struct eeh_dev, list); | ||
613 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); | 677 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); |
614 | pcibios_add_pci_devices(bus); | 678 | if (pe->type & EEH_PE_VF) |
615 | } else if (frozen_bus && removed) { | 679 | eeh_add_virt_device(edev, NULL); |
680 | else | ||
681 | pcibios_add_pci_devices(bus); | ||
682 | } else if (frozen_bus && rmv_data->removed) { | ||
616 | pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); | 683 | pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); |
617 | ssleep(5); | 684 | ssleep(5); |
618 | 685 | ||
686 | edev = list_first_entry(&pe->edevs, struct eeh_dev, list); | ||
619 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); | 687 | eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); |
620 | pcibios_add_pci_devices(frozen_bus); | 688 | if (pe->type & EEH_PE_VF) |
689 | eeh_add_virt_device(edev, NULL); | ||
690 | else | ||
691 | pcibios_add_pci_devices(frozen_bus); | ||
621 | } | 692 | } |
622 | eeh_pe_state_clear(pe, EEH_PE_KEEP); | 693 | eeh_pe_state_clear(pe, EEH_PE_KEEP); |
623 | 694 | ||
@@ -636,8 +707,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) | |||
636 | static void eeh_handle_normal_event(struct eeh_pe *pe) | 707 | static void eeh_handle_normal_event(struct eeh_pe *pe) |
637 | { | 708 | { |
638 | struct pci_bus *frozen_bus; | 709 | struct pci_bus *frozen_bus; |
710 | struct eeh_dev *edev, *tmp; | ||
639 | int rc = 0; | 711 | int rc = 0; |
640 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; | 712 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; |
713 | struct eeh_rmv_data rmv_data = {LIST_HEAD_INIT(rmv_data.edev_list), 0}; | ||
641 | 714 | ||
642 | frozen_bus = eeh_pe_bus_get(pe); | 715 | frozen_bus = eeh_pe_bus_get(pe); |
643 | if (!frozen_bus) { | 716 | if (!frozen_bus) { |
@@ -692,7 +765,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
692 | */ | 765 | */ |
693 | if (result == PCI_ERS_RESULT_NONE) { | 766 | if (result == PCI_ERS_RESULT_NONE) { |
694 | pr_info("EEH: Reset with hotplug activity\n"); | 767 | pr_info("EEH: Reset with hotplug activity\n"); |
695 | rc = eeh_reset_device(pe, frozen_bus); | 768 | rc = eeh_reset_device(pe, frozen_bus, NULL); |
696 | if (rc) { | 769 | if (rc) { |
697 | pr_warn("%s: Unable to reset, err=%d\n", | 770 | pr_warn("%s: Unable to reset, err=%d\n", |
698 | __func__, rc); | 771 | __func__, rc); |
@@ -744,7 +817,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
744 | /* If any device called out for a reset, then reset the slot */ | 817 | /* If any device called out for a reset, then reset the slot */ |
745 | if (result == PCI_ERS_RESULT_NEED_RESET) { | 818 | if (result == PCI_ERS_RESULT_NEED_RESET) { |
746 | pr_info("EEH: Reset without hotplug activity\n"); | 819 | pr_info("EEH: Reset without hotplug activity\n"); |
747 | rc = eeh_reset_device(pe, NULL); | 820 | rc = eeh_reset_device(pe, NULL, &rmv_data); |
748 | if (rc) { | 821 | if (rc) { |
749 | pr_warn("%s: Cannot reset, err=%d\n", | 822 | pr_warn("%s: Cannot reset, err=%d\n", |
750 | __func__, rc); | 823 | __func__, rc); |
@@ -764,6 +837,15 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) | |||
764 | goto hard_fail; | 837 | goto hard_fail; |
765 | } | 838 | } |
766 | 839 | ||
840 | /* | ||
841 | * For those hot removed VFs, we should add back them after PF get | ||
842 | * recovered properly. | ||
843 | */ | ||
844 | list_for_each_entry_safe(edev, tmp, &rmv_data.edev_list, rmv_list) { | ||
845 | eeh_add_virt_device(edev, NULL); | ||
846 | list_del(&edev->rmv_list); | ||
847 | } | ||
848 | |||
767 | /* Tell all device drivers that they can resume operations */ | 849 | /* Tell all device drivers that they can resume operations */ |
768 | pr_info("EEH: Notify device driver to resume\n"); | 850 | pr_info("EEH: Notify device driver to resume\n"); |
769 | eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); | 851 | eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); |
@@ -803,12 +885,17 @@ perm_error: | |||
803 | * the their PCI config any more. | 885 | * the their PCI config any more. |
804 | */ | 886 | */ |
805 | if (frozen_bus) { | 887 | if (frozen_bus) { |
806 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | 888 | if (pe->type & EEH_PE_VF) { |
807 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | 889 | eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); |
890 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | ||
891 | } else { | ||
892 | eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); | ||
893 | eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); | ||
808 | 894 | ||
809 | pci_lock_rescan_remove(); | 895 | pci_lock_rescan_remove(); |
810 | pcibios_remove_pci_devices(frozen_bus); | 896 | pcibios_remove_pci_devices(frozen_bus); |
811 | pci_unlock_rescan_remove(); | 897 | pci_unlock_rescan_remove(); |
898 | } | ||
812 | } | 899 | } |
813 | } | 900 | } |
814 | 901 | ||
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index e23bdf786dab..38102cb9baa9 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c | |||
@@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev) | |||
139 | #ifdef CONFIG_PCI_IOV | 139 | #ifdef CONFIG_PCI_IOV |
140 | static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, | 140 | static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, |
141 | struct pci_dev *pdev, | 141 | struct pci_dev *pdev, |
142 | int vf_index, | ||
142 | int busno, int devfn) | 143 | int busno, int devfn) |
143 | { | 144 | { |
144 | struct pci_dn *pdn; | 145 | struct pci_dn *pdn; |
@@ -158,6 +159,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, | |||
158 | pdn->busno = busno; | 159 | pdn->busno = busno; |
159 | pdn->devfn = devfn; | 160 | pdn->devfn = devfn; |
160 | #ifdef CONFIG_PPC_POWERNV | 161 | #ifdef CONFIG_PPC_POWERNV |
162 | pdn->vf_index = vf_index; | ||
161 | pdn->pe_number = IODA_INVALID_PE; | 163 | pdn->pe_number = IODA_INVALID_PE; |
162 | #endif | 164 | #endif |
163 | INIT_LIST_HEAD(&pdn->child_list); | 165 | INIT_LIST_HEAD(&pdn->child_list); |
@@ -197,7 +199,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) | |||
197 | return NULL; | 199 | return NULL; |
198 | 200 | ||
199 | for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { | 201 | for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { |
200 | pdn = add_one_dev_pci_data(parent, NULL, | 202 | pdn = add_one_dev_pci_data(parent, NULL, i, |
201 | pci_iov_virtfn_bus(pdev, i), | 203 | pci_iov_virtfn_bus(pdev, i), |
202 | pci_iov_virtfn_devfn(pdev, i)); | 204 | pci_iov_virtfn_devfn(pdev, i)); |
203 | if (!pdn) { | 205 | if (!pdn) { |