| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/** |
|---|
| 2 | +/* |
|---|
| 3 | 3 | * configfs to configure the PCI endpoint |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * Copyright (C) 2017 Texas Instruments |
|---|
| .. | .. |
|---|
| 29 | 29 | struct config_group group; |
|---|
| 30 | 30 | struct pci_epc *epc; |
|---|
| 31 | 31 | bool start; |
|---|
| 32 | | - unsigned long function_num_map; |
|---|
| 33 | 32 | }; |
|---|
| 34 | 33 | |
|---|
| 35 | 34 | static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item) |
|---|
| .. | .. |
|---|
| 58 | 57 | |
|---|
| 59 | 58 | if (!start) { |
|---|
| 60 | 59 | pci_epc_stop(epc); |
|---|
| 60 | + epc_group->start = 0; |
|---|
| 61 | 61 | return len; |
|---|
| 62 | 62 | } |
|---|
| 63 | 63 | |
|---|
| .. | .. |
|---|
| 89 | 89 | struct config_item *epf_item) |
|---|
| 90 | 90 | { |
|---|
| 91 | 91 | int ret; |
|---|
| 92 | | - u32 func_no = 0; |
|---|
| 93 | 92 | struct pci_epf_group *epf_group = to_pci_epf_group(epf_item); |
|---|
| 94 | 93 | struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); |
|---|
| 95 | 94 | struct pci_epc *epc = epc_group->epc; |
|---|
| 96 | 95 | struct pci_epf *epf = epf_group->epf; |
|---|
| 97 | 96 | |
|---|
| 98 | | - func_no = find_first_zero_bit(&epc_group->function_num_map, |
|---|
| 99 | | - BITS_PER_LONG); |
|---|
| 100 | | - if (func_no >= BITS_PER_LONG) |
|---|
| 101 | | - return -EINVAL; |
|---|
| 102 | | - |
|---|
| 103 | | - set_bit(func_no, &epc_group->function_num_map); |
|---|
| 104 | | - epf->func_no = func_no; |
|---|
| 105 | | - |
|---|
| 106 | 97 | ret = pci_epc_add_epf(epc, epf); |
|---|
| 107 | 98 | if (ret) |
|---|
| 108 | | - goto err_add_epf; |
|---|
| 99 | + return ret; |
|---|
| 109 | 100 | |
|---|
| 110 | 101 | ret = pci_epf_bind(epf); |
|---|
| 111 | | - if (ret) |
|---|
| 112 | | - goto err_epf_bind; |
|---|
| 102 | + if (ret) { |
|---|
| 103 | + pci_epc_remove_epf(epc, epf); |
|---|
| 104 | + return ret; |
|---|
| 105 | + } |
|---|
| 113 | 106 | |
|---|
| 114 | 107 | return 0; |
|---|
| 115 | | - |
|---|
| 116 | | -err_epf_bind: |
|---|
| 117 | | - pci_epc_remove_epf(epc, epf); |
|---|
| 118 | | - |
|---|
| 119 | | -err_add_epf: |
|---|
| 120 | | - clear_bit(func_no, &epc_group->function_num_map); |
|---|
| 121 | | - |
|---|
| 122 | | - return ret; |
|---|
| 123 | 108 | } |
|---|
| 124 | 109 | |
|---|
| 125 | 110 | static void pci_epc_epf_unlink(struct config_item *epc_item, |
|---|
| .. | .. |
|---|
| 134 | 119 | |
|---|
| 135 | 120 | epc = epc_group->epc; |
|---|
| 136 | 121 | epf = epf_group->epf; |
|---|
| 137 | | - clear_bit(epf->func_no, &epc_group->function_num_map); |
|---|
| 138 | 122 | pci_epf_unbind(epf); |
|---|
| 139 | 123 | pci_epc_remove_epf(epc, epf); |
|---|
| 140 | 124 | } |
|---|