30
30
#include <linux/smp.h>
31
31
#include <linux/init.h>
32
32
#include <linux/vmalloc.h>
33
+ #include <asm/firmware.h>
33
34
#include <asm/eeh.h> /* for eeh_add_device() */
34
35
#include <asm/rtas.h> /* rtas_call */
35
36
#include <asm/pci-bridge.h> /* for pci_controller */
@@ -196,25 +197,21 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes,
196
197
return 0 ;
197
198
}
198
199
199
- /* To get the DRC props describing the current node, first obtain it's
200
- * my-drc-index property. Next obtain the DRC list from it's parent. Use
201
- * the my-drc-index for correlation, and obtain the requested properties.
200
+
201
+ /* Verify the existence of 'drc_name' and/or 'drc_type' within the
202
+ * current node. First obtain it's my-drc-index property. Next,
203
+ * obtain the DRC info from it's parent. Use the my-drc-index for
204
+ * correlation, and obtain/validate the requested properties.
202
205
*/
203
- int rpaphp_get_drc_props (struct device_node * dn , int * drc_index ,
204
- char * * drc_name , char * * drc_type , int * drc_power_domain )
206
+
207
+ static int rpaphp_check_drc_props_v1 (struct device_node * dn , char * drc_name ,
208
+ char * drc_type , unsigned int my_index )
205
209
{
210
+ char * name_tmp , * type_tmp ;
206
211
const int * indexes , * names ;
207
212
const int * types , * domains ;
208
- const unsigned int * my_index ;
209
- char * name_tmp , * type_tmp ;
210
213
int i , rc ;
211
214
212
- my_index = of_get_property (dn , "ibm,my-drc-index" , NULL );
213
- if (!my_index ) {
214
- /* Node isn't DLPAR/hotplug capable */
215
- return - EINVAL ;
216
- }
217
-
218
215
rc = get_children_props (dn -> parent , & indexes , & names , & types , & domains );
219
216
if (rc < 0 ) {
220
217
return - EINVAL ;
@@ -225,24 +222,84 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
225
222
226
223
/* Iterate through parent properties, looking for my-drc-index */
227
224
for (i = 0 ; i < be32_to_cpu (indexes [0 ]); i ++ ) {
228
- if ((unsigned int ) indexes [i + 1 ] == * my_index ) {
229
- if (drc_name )
230
- * drc_name = name_tmp ;
231
- if (drc_type )
232
- * drc_type = type_tmp ;
233
- if (drc_index )
234
- * drc_index = be32_to_cpu (* my_index );
235
- if (drc_power_domain )
236
- * drc_power_domain = be32_to_cpu (domains [i + 1 ]);
237
- return 0 ;
238
- }
225
+ if ((unsigned int ) indexes [i + 1 ] == my_index )
226
+ break ;
227
+
239
228
name_tmp += (strlen (name_tmp ) + 1 );
240
229
type_tmp += (strlen (type_tmp ) + 1 );
241
230
}
242
231
232
+ if (((drc_name == NULL ) || (drc_name && !strcmp (drc_name , name_tmp ))) &&
233
+ ((drc_type == NULL ) || (drc_type && !strcmp (drc_type , type_tmp ))))
234
+ return 0 ;
235
+
243
236
return - EINVAL ;
244
237
}
245
- EXPORT_SYMBOL_GPL (rpaphp_get_drc_props );
238
+
239
+ static int rpaphp_check_drc_props_v2 (struct device_node * dn , char * drc_name ,
240
+ char * drc_type , unsigned int my_index )
241
+ {
242
+ struct property * info ;
243
+ unsigned int entries ;
244
+ struct of_drc_info drc ;
245
+ const __be32 * value ;
246
+ char cell_drc_name [MAX_DRC_NAME_LEN ];
247
+ int j , fndit ;
248
+
249
+ info = of_find_property (dn -> parent , "ibm,drc-info" , NULL );
250
+ if (info == NULL )
251
+ return - EINVAL ;
252
+
253
+ value = of_prop_next_u32 (info , NULL , & entries );
254
+ if (!value )
255
+ return - EINVAL ;
256
+
257
+ for (j = 0 ; j < entries ; j ++ ) {
258
+ of_read_drc_info_cell (& info , & value , & drc );
259
+
260
+ /* Should now know end of current entry */
261
+
262
+ if (my_index > drc .last_drc_index )
263
+ continue ;
264
+
265
+ fndit = 1 ;
266
+ break ;
267
+ }
268
+ /* Found it */
269
+
270
+ if (fndit )
271
+ sprintf (cell_drc_name , "%s%d" , drc .drc_name_prefix ,
272
+ my_index );
273
+
274
+ if (((drc_name == NULL ) ||
275
+ (drc_name && !strcmp (drc_name , cell_drc_name ))) &&
276
+ ((drc_type == NULL ) ||
277
+ (drc_type && !strcmp (drc_type , drc .drc_type ))))
278
+ return 0 ;
279
+
280
+ return - EINVAL ;
281
+ }
282
+
283
+ int rpaphp_check_drc_props (struct device_node * dn , char * drc_name ,
284
+ char * drc_type )
285
+ {
286
+ const unsigned int * my_index ;
287
+
288
+ my_index = of_get_property (dn , "ibm,my-drc-index" , NULL );
289
+ if (!my_index ) {
290
+ /* Node isn't DLPAR/hotplug capable */
291
+ return - EINVAL ;
292
+ }
293
+
294
+ if (firmware_has_feature (FW_FEATURE_DRC_INFO ))
295
+ return rpaphp_check_drc_props_v2 (dn , drc_name , drc_type ,
296
+ * my_index );
297
+ else
298
+ return rpaphp_check_drc_props_v1 (dn , drc_name , drc_type ,
299
+ * my_index );
300
+ }
301
+ EXPORT_SYMBOL_GPL (rpaphp_check_drc_props );
302
+
246
303
247
304
static int is_php_type (char * drc_type )
248
305
{
0 commit comments