@@ -62,13 +62,20 @@ EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
62
62
*/
63
63
void pci_epf_unbind (struct pci_epf * epf )
64
64
{
65
+ struct pci_epf * epf_vf ;
66
+
65
67
if (!epf -> driver ) {
66
68
dev_WARN (& epf -> dev , "epf device not bound to driver\n" );
67
69
return ;
68
70
}
69
71
70
72
mutex_lock (& epf -> lock );
71
- epf -> driver -> ops -> unbind (epf );
73
+ list_for_each_entry (epf_vf , & epf -> pci_vepf , list ) {
74
+ if (epf_vf -> is_bound )
75
+ epf_vf -> driver -> ops -> unbind (epf_vf );
76
+ }
77
+ if (epf -> is_bound )
78
+ epf -> driver -> ops -> unbind (epf );
72
79
mutex_unlock (& epf -> lock );
73
80
module_put (epf -> driver -> owner );
74
81
}
@@ -83,6 +90,7 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
83
90
*/
84
91
int pci_epf_bind (struct pci_epf * epf )
85
92
{
93
+ struct pci_epf * epf_vf ;
86
94
int ret ;
87
95
88
96
if (!epf -> driver ) {
@@ -94,13 +102,97 @@ int pci_epf_bind(struct pci_epf *epf)
94
102
return - EAGAIN ;
95
103
96
104
mutex_lock (& epf -> lock );
105
+ list_for_each_entry (epf_vf , & epf -> pci_vepf , list ) {
106
+ epf_vf -> func_no = epf -> func_no ;
107
+ epf_vf -> epc = epf -> epc ;
108
+ epf_vf -> sec_epc = epf -> sec_epc ;
109
+ ret = epf_vf -> driver -> ops -> bind (epf_vf );
110
+ if (ret )
111
+ goto ret ;
112
+ epf_vf -> is_bound = true;
113
+ }
114
+
97
115
ret = epf -> driver -> ops -> bind (epf );
116
+ if (ret )
117
+ goto ret ;
118
+ epf -> is_bound = true;
119
+
120
+ mutex_unlock (& epf -> lock );
121
+ return 0 ;
122
+
123
+ ret :
98
124
mutex_unlock (& epf -> lock );
125
+ pci_epf_unbind (epf );
99
126
100
127
return ret ;
101
128
}
102
129
EXPORT_SYMBOL_GPL (pci_epf_bind );
103
130
131
+ /**
132
+ * pci_epf_add_vepf() - associate virtual EP function to physical EP function
133
+ * @epf_pf: the physical EP function to which the virtual EP function should be
134
+ * associated
135
+ * @epf_vf: the virtual EP function to be added
136
+ *
137
+ * A physical endpoint function can be associated with multiple virtual
138
+ * endpoint functions. Invoke pci_epf_add_epf() to add a virtual PCI endpoint
139
+ * function to a physical PCI endpoint function.
140
+ */
141
+ int pci_epf_add_vepf (struct pci_epf * epf_pf , struct pci_epf * epf_vf )
142
+ {
143
+ u32 vfunc_no ;
144
+
145
+ if (IS_ERR_OR_NULL (epf_pf ) || IS_ERR_OR_NULL (epf_vf ))
146
+ return - EINVAL ;
147
+
148
+ if (epf_pf -> epc || epf_vf -> epc || epf_vf -> epf_pf )
149
+ return - EBUSY ;
150
+
151
+ if (epf_pf -> sec_epc || epf_vf -> sec_epc )
152
+ return - EBUSY ;
153
+
154
+ mutex_lock (& epf_pf -> lock );
155
+ vfunc_no = find_first_zero_bit (& epf_pf -> vfunction_num_map ,
156
+ BITS_PER_LONG );
157
+ if (vfunc_no >= BITS_PER_LONG ) {
158
+ mutex_unlock (& epf_pf -> lock );
159
+ return - EINVAL ;
160
+ }
161
+
162
+ set_bit (vfunc_no , & epf_pf -> vfunction_num_map );
163
+ epf_vf -> vfunc_no = vfunc_no ;
164
+
165
+ epf_vf -> epf_pf = epf_pf ;
166
+ epf_vf -> is_vf = true;
167
+
168
+ list_add_tail (& epf_vf -> list , & epf_pf -> pci_vepf );
169
+ mutex_unlock (& epf_pf -> lock );
170
+
171
+ return 0 ;
172
+ }
173
+ EXPORT_SYMBOL_GPL (pci_epf_add_vepf );
174
+
175
+ /**
176
+ * pci_epf_remove_vepf() - remove virtual EP function from physical EP function
177
+ * @epf_pf: the physical EP function from which the virtual EP function should
178
+ * be removed
179
+ * @epf_vf: the virtual EP function to be removed
180
+ *
181
+ * Invoke to remove a virtual endpoint function from the physcial endpoint
182
+ * function.
183
+ */
184
+ void pci_epf_remove_vepf (struct pci_epf * epf_pf , struct pci_epf * epf_vf )
185
+ {
186
+ if (IS_ERR_OR_NULL (epf_pf ) || IS_ERR_OR_NULL (epf_vf ))
187
+ return ;
188
+
189
+ mutex_lock (& epf_pf -> lock );
190
+ clear_bit (epf_vf -> vfunc_no , & epf_pf -> vfunction_num_map );
191
+ list_del (& epf_vf -> list );
192
+ mutex_unlock (& epf_pf -> lock );
193
+ }
194
+ EXPORT_SYMBOL_GPL (pci_epf_remove_vepf );
195
+
104
196
/**
105
197
* pci_epf_free_space() - free the allocated PCI EPF register space
106
198
* @epf: the EPF device from whom to free the memory
@@ -317,6 +409,10 @@ struct pci_epf *pci_epf_create(const char *name)
317
409
return ERR_PTR (- ENOMEM );
318
410
}
319
411
412
+ /* VFs are numbered starting with 1. So set BIT(0) by default */
413
+ epf -> vfunction_num_map = 1 ;
414
+ INIT_LIST_HEAD (& epf -> pci_vepf );
415
+
320
416
dev = & epf -> dev ;
321
417
device_initialize (dev );
322
418
dev -> bus = & pci_epf_bus_type ;
0 commit comments