xref: /linux/arch/powerpc/platforms/ps3/repository.c (revision 5acbae5f7eb3d5275120abfe698c394b7325dcec)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  PS3 repository routines.
4  *
5  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
6  *  Copyright 2006 Sony Corp.
7  */
8 
9 #include <linux/minmax.h>
10 
11 #include <asm/lv1call.h>
12 
13 #include "platform.h"
14 
15 enum ps3_vendor_id {
16 	PS3_VENDOR_ID_NONE = 0,
17 	PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
18 };
19 
20 enum ps3_lpar_id {
21 	PS3_LPAR_ID_CURRENT = 0,
22 	PS3_LPAR_ID_PME = 1,
23 };
24 
25 #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
_dump_field(const char * hdr,u64 n,const char * func,int line)26 static void _dump_field(const char *hdr, u64 n, const char *func, int line)
27 {
28 #if defined(DEBUG)
29 	char s[16];
30 	const char *const in = (const char *)&n;
31 	unsigned int i;
32 
33 	for (i = 0; i < 8; i++)
34 		s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
35 	s[i] = 0;
36 
37 	pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s);
38 #endif
39 }
40 
41 #define dump_node_name(_a, _b, _c, _d, _e) \
42 	_dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
_dump_node_name(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,const char * func,int line)43 static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
44 	u64 n4, const char *func, int line)
45 {
46 	pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
47 	_dump_field("n1: ", n1, func, line);
48 	_dump_field("n2: ", n2, func, line);
49 	_dump_field("n3: ", n3, func, line);
50 	_dump_field("n4: ", n4, func, line);
51 }
52 
53 #define dump_node(_a, _b, _c, _d, _e, _f, _g) \
54 	_dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
_dump_node(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2,const char * func,int line)55 static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
56 	u64 v1, u64 v2, const char *func, int line)
57 {
58 	pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
59 	_dump_field("n1: ", n1, func, line);
60 	_dump_field("n2: ", n2, func, line);
61 	_dump_field("n3: ", n3, func, line);
62 	_dump_field("n4: ", n4, func, line);
63 	pr_devel("%s:%d: v1: %016llx\n", func, line, v1);
64 	pr_devel("%s:%d: v2: %016llx\n", func, line, v2);
65 }
66 
67 /**
68  * make_first_field - Make the first field of a repository node name.
69  * @text: Text portion of the field.
70  * @index: Numeric index portion of the field.  Use zero for 'don't care'.
71  *
72  * This routine sets the vendor id to zero (non-vendor specific).
73  * Returns field value.
74  */
75 
make_first_field(const char * text,u64 index)76 static u64 make_first_field(const char *text, u64 index)
77 {
78 	u64 n = 0;
79 	size_t len = min(strlen(text), sizeof(n));
80 
81 	memcpy(&n, text, len);
82 	return PS3_VENDOR_ID_NONE + (n >> 32) + index;
83 }
84 
85 /**
86  * make_field - Make subsequent fields of a repository node name.
87  * @text: Text portion of the field.  Use "" for 'don't care'.
88  * @index: Numeric index portion of the field.  Use zero for 'don't care'.
89  *
90  * Returns field value.
91  */
92 
make_field(const char * text,u64 index)93 static u64 make_field(const char *text, u64 index)
94 {
95 	u64 n = 0;
96 
97 	memcpy((char *)&n, text, strnlen(text, sizeof(n)));
98 	return n + index;
99 }
100 
101 /**
102  * read_node - Read a repository node from raw fields.
103  * @n1: First field of node name.
104  * @n2: Second field of node name.  Use zero for 'don't care'.
105  * @n3: Third field of node name.  Use zero for 'don't care'.
106  * @n4: Fourth field of node name.  Use zero for 'don't care'.
107  * @v1: First repository value (high word).
108  * @v2: Second repository value (low word).  Optional parameter, use zero
109  *      for 'don't care'.
110  */
111 
read_node(unsigned int lpar_id,u64 n1,u64 n2,u64 n3,u64 n4,u64 * _v1,u64 * _v2)112 static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
113 	u64 *_v1, u64 *_v2)
114 {
115 	int result;
116 	u64 v1;
117 	u64 v2;
118 
119 	if (lpar_id == PS3_LPAR_ID_CURRENT) {
120 		u64 id;
121 		lv1_get_logical_partition_id(&id);
122 		lpar_id = id;
123 	}
124 
125 	result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1,
126 		&v2);
127 
128 	if (result) {
129 		pr_warn("%s:%d: lv1_read_repository_node failed: %s\n",
130 			__func__, __LINE__, ps3_result(result));
131 		dump_node_name(lpar_id, n1, n2, n3, n4);
132 		return -ENOENT;
133 	}
134 
135 	dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
136 
137 	if (_v1)
138 		*_v1 = v1;
139 	if (_v2)
140 		*_v2 = v2;
141 
142 	if (v1 && !_v1)
143 		pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n",
144 			__func__, __LINE__, v1);
145 	if (v2 && !_v2)
146 		pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n",
147 			__func__, __LINE__, v2);
148 
149 	return 0;
150 }
151 
ps3_repository_read_bus_str(unsigned int bus_index,const char * bus_str,u64 * value)152 int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
153 	u64 *value)
154 {
155 	return read_node(PS3_LPAR_ID_PME,
156 		make_first_field("bus", bus_index),
157 		make_field(bus_str, 0),
158 		0, 0,
159 		value, NULL);
160 }
161 
ps3_repository_read_bus_id(unsigned int bus_index,u64 * bus_id)162 int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
163 {
164 	return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
165 			 make_field("id", 0), 0, 0, bus_id, NULL);
166 }
167 
ps3_repository_read_bus_type(unsigned int bus_index,enum ps3_bus_type * bus_type)168 int ps3_repository_read_bus_type(unsigned int bus_index,
169 	enum ps3_bus_type *bus_type)
170 {
171 	int result;
172 	u64 v1 = 0;
173 
174 	result = read_node(PS3_LPAR_ID_PME,
175 		make_first_field("bus", bus_index),
176 		make_field("type", 0),
177 		0, 0,
178 		&v1, NULL);
179 	*bus_type = v1;
180 	return result;
181 }
182 
ps3_repository_read_bus_num_dev(unsigned int bus_index,unsigned int * num_dev)183 int ps3_repository_read_bus_num_dev(unsigned int bus_index,
184 	unsigned int *num_dev)
185 {
186 	int result;
187 	u64 v1 = 0;
188 
189 	result = read_node(PS3_LPAR_ID_PME,
190 		make_first_field("bus", bus_index),
191 		make_field("num_dev", 0),
192 		0, 0,
193 		&v1, NULL);
194 	*num_dev = v1;
195 	return result;
196 }
197 
ps3_repository_read_dev_str(unsigned int bus_index,unsigned int dev_index,const char * dev_str,u64 * value)198 int ps3_repository_read_dev_str(unsigned int bus_index,
199 	unsigned int dev_index, const char *dev_str, u64 *value)
200 {
201 	return read_node(PS3_LPAR_ID_PME,
202 		make_first_field("bus", bus_index),
203 		make_field("dev", dev_index),
204 		make_field(dev_str, 0),
205 		0,
206 		value, NULL);
207 }
208 
ps3_repository_read_dev_id(unsigned int bus_index,unsigned int dev_index,u64 * dev_id)209 int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
210 	u64 *dev_id)
211 {
212 	return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index),
213 			 make_field("dev", dev_index), make_field("id", 0), 0,
214 			 dev_id, NULL);
215 }
216 
ps3_repository_read_dev_type(unsigned int bus_index,unsigned int dev_index,enum ps3_dev_type * dev_type)217 int ps3_repository_read_dev_type(unsigned int bus_index,
218 	unsigned int dev_index, enum ps3_dev_type *dev_type)
219 {
220 	int result;
221 	u64 v1 = 0;
222 
223 	result = read_node(PS3_LPAR_ID_PME,
224 		make_first_field("bus", bus_index),
225 		make_field("dev", dev_index),
226 		make_field("type", 0),
227 		0,
228 		&v1, NULL);
229 	*dev_type = v1;
230 	return result;
231 }
232 
ps3_repository_read_dev_intr(unsigned int bus_index,unsigned int dev_index,unsigned int intr_index,enum ps3_interrupt_type * intr_type,unsigned int * interrupt_id)233 int ps3_repository_read_dev_intr(unsigned int bus_index,
234 	unsigned int dev_index, unsigned int intr_index,
235 	enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id)
236 {
237 	int result;
238 	u64 v1 = 0;
239 	u64 v2 = 0;
240 
241 	result = read_node(PS3_LPAR_ID_PME,
242 		make_first_field("bus", bus_index),
243 		make_field("dev", dev_index),
244 		make_field("intr", intr_index),
245 		0,
246 		&v1, &v2);
247 	*intr_type = v1;
248 	*interrupt_id = v2;
249 	return result;
250 }
251 
ps3_repository_read_dev_reg_type(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,enum ps3_reg_type * reg_type)252 int ps3_repository_read_dev_reg_type(unsigned int bus_index,
253 	unsigned int dev_index, unsigned int reg_index,
254 	enum ps3_reg_type *reg_type)
255 {
256 	int result;
257 	u64 v1 = 0;
258 
259 	result = read_node(PS3_LPAR_ID_PME,
260 		make_first_field("bus", bus_index),
261 		make_field("dev", dev_index),
262 		make_field("reg", reg_index),
263 		make_field("type", 0),
264 		&v1, NULL);
265 	*reg_type = v1;
266 	return result;
267 }
268 
ps3_repository_read_dev_reg_addr(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,u64 * bus_addr,u64 * len)269 int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
270 	unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
271 {
272 	return read_node(PS3_LPAR_ID_PME,
273 		make_first_field("bus", bus_index),
274 		make_field("dev", dev_index),
275 		make_field("reg", reg_index),
276 		make_field("data", 0),
277 		bus_addr, len);
278 }
279 
ps3_repository_read_dev_reg(unsigned int bus_index,unsigned int dev_index,unsigned int reg_index,enum ps3_reg_type * reg_type,u64 * bus_addr,u64 * len)280 int ps3_repository_read_dev_reg(unsigned int bus_index,
281 	unsigned int dev_index, unsigned int reg_index,
282 	enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
283 {
284 	int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
285 		reg_index, reg_type);
286 	return result ? result
287 		: ps3_repository_read_dev_reg_addr(bus_index, dev_index,
288 		reg_index, bus_addr, len);
289 }
290 
291 
292 
ps3_repository_find_device(struct ps3_repository_device * repo)293 int ps3_repository_find_device(struct ps3_repository_device *repo)
294 {
295 	int result;
296 	struct ps3_repository_device tmp = *repo;
297 	unsigned int num_dev;
298 
299 	BUG_ON(repo->bus_index > 10);
300 	BUG_ON(repo->dev_index > 10);
301 
302 	result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
303 
304 	if (result) {
305 		pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
306 		return result;
307 	}
308 
309 	pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n",
310 		__func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
311 		num_dev);
312 
313 	if (tmp.dev_index >= num_dev) {
314 		pr_devel("%s:%d: no device found\n", __func__, __LINE__);
315 		return -ENODEV;
316 	}
317 
318 	result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
319 		&tmp.dev_type);
320 
321 	if (result) {
322 		pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__);
323 		return result;
324 	}
325 
326 	result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
327 		&tmp.dev_id);
328 
329 	if (result) {
330 		pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__,
331 		__LINE__);
332 		return result;
333 	}
334 
335 	pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n",
336 		__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
337 
338 	*repo = tmp;
339 	return 0;
340 }
341 
ps3_repository_find_device_by_id(struct ps3_repository_device * repo,u64 bus_id,u64 dev_id)342 int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
343 				     u64 bus_id, u64 dev_id)
344 {
345 	int result = -ENODEV;
346 	struct ps3_repository_device tmp;
347 	unsigned int num_dev;
348 
349 	pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__,
350 		 bus_id, dev_id);
351 
352 	for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
353 		result = ps3_repository_read_bus_id(tmp.bus_index,
354 						    &tmp.bus_id);
355 		if (result) {
356 			pr_devel("%s:%u read_bus_id(%u) failed\n", __func__,
357 				 __LINE__, tmp.bus_index);
358 			return result;
359 		}
360 
361 		if (tmp.bus_id == bus_id)
362 			goto found_bus;
363 
364 		pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__,
365 			 tmp.bus_id);
366 	}
367 	pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
368 	return result;
369 
370 found_bus:
371 	result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
372 	if (result) {
373 		pr_devel("%s:%u read_bus_type(%u) failed\n", __func__,
374 			 __LINE__, tmp.bus_index);
375 		return result;
376 	}
377 
378 	result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
379 	if (result) {
380 		pr_devel("%s:%u read_bus_num_dev failed\n", __func__,
381 			 __LINE__);
382 		return result;
383 	}
384 
385 	for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
386 		result = ps3_repository_read_dev_id(tmp.bus_index,
387 						    tmp.dev_index,
388 						    &tmp.dev_id);
389 		if (result) {
390 			pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__,
391 				 __LINE__, tmp.bus_index, tmp.dev_index);
392 			return result;
393 		}
394 
395 		if (tmp.dev_id == dev_id)
396 			goto found_dev;
397 
398 		pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__,
399 			 tmp.dev_id);
400 	}
401 	pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__);
402 	return result;
403 
404 found_dev:
405 	result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
406 					      &tmp.dev_type);
407 	if (result) {
408 		pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__);
409 		return result;
410 	}
411 
412 	pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n",
413 		 __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
414 		 tmp.dev_index, tmp.bus_id, tmp.dev_id);
415 	*repo = tmp;
416 	return 0;
417 }
418 
ps3_repository_find_devices(enum ps3_bus_type bus_type,int (* callback)(const struct ps3_repository_device * repo))419 int __init ps3_repository_find_devices(enum ps3_bus_type bus_type,
420 	int (*callback)(const struct ps3_repository_device *repo))
421 {
422 	int result = 0;
423 	struct ps3_repository_device repo;
424 
425 	pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
426 
427 	repo.bus_type = bus_type;
428 	result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
429 	if (result) {
430 		pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
431 		return result;
432 	}
433 
434 	result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
435 	if (result) {
436 		pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
437 			 repo.bus_index);
438 		return result;
439 	}
440 
441 	for (repo.dev_index = 0; ; repo.dev_index++) {
442 		result = ps3_repository_find_device(&repo);
443 		if (result == -ENODEV) {
444 			result = 0;
445 			break;
446 		} else if (result)
447 			break;
448 
449 		result = callback(&repo);
450 		if (result) {
451 			pr_devel("%s:%d: abort at callback\n", __func__,
452 				__LINE__);
453 			break;
454 		}
455 	}
456 
457 	pr_devel(" <- %s:%d\n", __func__, __LINE__);
458 	return result;
459 }
460 
ps3_repository_find_bus(enum ps3_bus_type bus_type,unsigned int from,unsigned int * bus_index)461 int __init ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
462 	unsigned int *bus_index)
463 {
464 	unsigned int i;
465 	enum ps3_bus_type type;
466 	int error;
467 
468 	for (i = from; i < 10; i++) {
469 		error = ps3_repository_read_bus_type(i, &type);
470 		if (error) {
471 			pr_devel("%s:%d read_bus_type failed\n",
472 				__func__, __LINE__);
473 			*bus_index = UINT_MAX;
474 			return error;
475 		}
476 		if (type == bus_type) {
477 			*bus_index = i;
478 			return 0;
479 		}
480 	}
481 	*bus_index = UINT_MAX;
482 	return -ENODEV;
483 }
484 
ps3_repository_find_interrupt(const struct ps3_repository_device * repo,enum ps3_interrupt_type intr_type,unsigned int * interrupt_id)485 int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
486 	enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
487 {
488 	int result = 0;
489 	unsigned int res_index;
490 
491 	pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
492 
493 	*interrupt_id = UINT_MAX;
494 
495 	for (res_index = 0; res_index < 10; res_index++) {
496 		enum ps3_interrupt_type t;
497 		unsigned int id;
498 
499 		result = ps3_repository_read_dev_intr(repo->bus_index,
500 			repo->dev_index, res_index, &t, &id);
501 
502 		if (result) {
503 			pr_devel("%s:%d read_dev_intr failed\n",
504 				__func__, __LINE__);
505 			return result;
506 		}
507 
508 		if (t == intr_type) {
509 			*interrupt_id = id;
510 			break;
511 		}
512 	}
513 
514 	if (res_index == 10)
515 		return -ENODEV;
516 
517 	pr_devel("%s:%d: found intr_type %u at res_index %u\n",
518 		__func__, __LINE__, intr_type, res_index);
519 
520 	return result;
521 }
522 
ps3_repository_find_reg(const struct ps3_repository_device * repo,enum ps3_reg_type reg_type,u64 * bus_addr,u64 * len)523 int ps3_repository_find_reg(const struct ps3_repository_device *repo,
524 	enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
525 {
526 	int result = 0;
527 	unsigned int res_index;
528 
529 	pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
530 
531 	*bus_addr = *len = 0;
532 
533 	for (res_index = 0; res_index < 10; res_index++) {
534 		enum ps3_reg_type t;
535 		u64 a;
536 		u64 l;
537 
538 		result = ps3_repository_read_dev_reg(repo->bus_index,
539 			repo->dev_index, res_index, &t, &a, &l);
540 
541 		if (result) {
542 			pr_devel("%s:%d read_dev_reg failed\n",
543 				__func__, __LINE__);
544 			return result;
545 		}
546 
547 		if (t == reg_type) {
548 			*bus_addr = a;
549 			*len = l;
550 			break;
551 		}
552 	}
553 
554 	if (res_index == 10)
555 		return -ENODEV;
556 
557 	pr_devel("%s:%d: found reg_type %u at res_index %u\n",
558 		__func__, __LINE__, reg_type, res_index);
559 
560 	return result;
561 }
562 
ps3_repository_read_stor_dev_port(unsigned int bus_index,unsigned int dev_index,u64 * port)563 int ps3_repository_read_stor_dev_port(unsigned int bus_index,
564 	unsigned int dev_index, u64 *port)
565 {
566 	return read_node(PS3_LPAR_ID_PME,
567 		make_first_field("bus", bus_index),
568 		make_field("dev", dev_index),
569 		make_field("port", 0),
570 		0, port, NULL);
571 }
572 
ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,unsigned int dev_index,u64 * blk_size)573 int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
574 	unsigned int dev_index, u64 *blk_size)
575 {
576 	return read_node(PS3_LPAR_ID_PME,
577 		make_first_field("bus", bus_index),
578 		make_field("dev", dev_index),
579 		make_field("blk_size", 0),
580 		0, blk_size, NULL);
581 }
582 
ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,unsigned int dev_index,u64 * num_blocks)583 int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
584 	unsigned int dev_index, u64 *num_blocks)
585 {
586 	return read_node(PS3_LPAR_ID_PME,
587 		make_first_field("bus", bus_index),
588 		make_field("dev", dev_index),
589 		make_field("n_blocks", 0),
590 		0, num_blocks, NULL);
591 }
592 
ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,unsigned int dev_index,unsigned int * num_regions)593 int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
594 	unsigned int dev_index, unsigned int *num_regions)
595 {
596 	int result;
597 	u64 v1 = 0;
598 
599 	result = read_node(PS3_LPAR_ID_PME,
600 		make_first_field("bus", bus_index),
601 		make_field("dev", dev_index),
602 		make_field("n_regs", 0),
603 		0, &v1, NULL);
604 	*num_regions = v1;
605 	return result;
606 }
607 
ps3_repository_read_stor_dev_region_id(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,unsigned int * region_id)608 int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
609 	unsigned int dev_index, unsigned int region_index,
610 	unsigned int *region_id)
611 {
612 	int result;
613 	u64 v1 = 0;
614 
615 	result = read_node(PS3_LPAR_ID_PME,
616 	    make_first_field("bus", bus_index),
617 	    make_field("dev", dev_index),
618 	    make_field("region", region_index),
619 	    make_field("id", 0),
620 	    &v1, NULL);
621 	*region_id = v1;
622 	return result;
623 }
624 
ps3_repository_read_stor_dev_region_size(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,u64 * region_size)625 int ps3_repository_read_stor_dev_region_size(unsigned int bus_index,
626 	unsigned int dev_index,	unsigned int region_index, u64 *region_size)
627 {
628 	return read_node(PS3_LPAR_ID_PME,
629 	    make_first_field("bus", bus_index),
630 	    make_field("dev", dev_index),
631 	    make_field("region", region_index),
632 	    make_field("size", 0),
633 	    region_size, NULL);
634 }
635 
ps3_repository_read_stor_dev_region_start(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,u64 * region_start)636 int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
637 	unsigned int dev_index, unsigned int region_index, u64 *region_start)
638 {
639 	return read_node(PS3_LPAR_ID_PME,
640 	    make_first_field("bus", bus_index),
641 	    make_field("dev", dev_index),
642 	    make_field("region", region_index),
643 	    make_field("start", 0),
644 	    region_start, NULL);
645 }
646 
ps3_repository_read_stor_dev_info(unsigned int bus_index,unsigned int dev_index,u64 * port,u64 * blk_size,u64 * num_blocks,unsigned int * num_regions)647 int ps3_repository_read_stor_dev_info(unsigned int bus_index,
648 	unsigned int dev_index, u64 *port, u64 *blk_size,
649 	u64 *num_blocks, unsigned int *num_regions)
650 {
651 	int result;
652 
653 	result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port);
654 	if (result)
655 	    return result;
656 
657 	result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index,
658 		blk_size);
659 	if (result)
660 	    return result;
661 
662 	result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index,
663 		num_blocks);
664 	if (result)
665 	    return result;
666 
667 	result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index,
668 		num_regions);
669 	return result;
670 }
671 
ps3_repository_read_stor_dev_region(unsigned int bus_index,unsigned int dev_index,unsigned int region_index,unsigned int * region_id,u64 * region_start,u64 * region_size)672 int ps3_repository_read_stor_dev_region(unsigned int bus_index,
673 	unsigned int dev_index, unsigned int region_index,
674 	unsigned int *region_id, u64 *region_start, u64 *region_size)
675 {
676 	int result;
677 
678 	result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index,
679 		region_index, region_id);
680 	if (result)
681 	    return result;
682 
683 	result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index,
684 		region_index, region_start);
685 	if (result)
686 	    return result;
687 
688 	result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index,
689 		region_index, region_size);
690 	return result;
691 }
692 
693 /**
694  * ps3_repository_read_num_pu - Number of logical PU processors for this lpar.
695  */
696 
ps3_repository_read_num_pu(u64 * num_pu)697 int ps3_repository_read_num_pu(u64 *num_pu)
698 {
699 	*num_pu = 0;
700 	return read_node(PS3_LPAR_ID_CURRENT,
701 			   make_first_field("bi", 0),
702 			   make_field("pun", 0),
703 			   0, 0,
704 			   num_pu, NULL);
705 }
706 
707 /**
708  * ps3_repository_read_pu_id - Read the logical PU id.
709  * @pu_index: Zero based index.
710  * @pu_id: The logical PU id.
711  */
712 
ps3_repository_read_pu_id(unsigned int pu_index,u64 * pu_id)713 int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id)
714 {
715 	return read_node(PS3_LPAR_ID_CURRENT,
716 		make_first_field("bi", 0),
717 		make_field("pu", pu_index),
718 		0, 0,
719 		pu_id, NULL);
720 }
721 
ps3_repository_read_rm_size(unsigned int ppe_id,u64 * rm_size)722 int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
723 {
724 	return read_node(PS3_LPAR_ID_CURRENT,
725 		make_first_field("bi", 0),
726 		make_field("pu", 0),
727 		ppe_id,
728 		make_field("rm_size", 0),
729 		rm_size, NULL);
730 }
731 
ps3_repository_read_region_total(u64 * region_total)732 int ps3_repository_read_region_total(u64 *region_total)
733 {
734 	return read_node(PS3_LPAR_ID_CURRENT,
735 		make_first_field("bi", 0),
736 		make_field("rgntotal", 0),
737 		0, 0,
738 		region_total, NULL);
739 }
740 
741 /**
742  * ps3_repository_read_mm_info - Read mm info for single pu system.
743  * @rm_base: Real mode memory base address.
744  * @rm_size: Real mode memory size.
745  * @region_total: Maximum memory region size.
746  */
747 
ps3_repository_read_mm_info(u64 * rm_base,u64 * rm_size,u64 * region_total)748 int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
749 {
750 	int result;
751 	u64 ppe_id;
752 
753 	lv1_get_logical_ppe_id(&ppe_id);
754 	*rm_base = 0;
755 	result = ps3_repository_read_rm_size(ppe_id, rm_size);
756 	return result ? result
757 		: ps3_repository_read_region_total(region_total);
758 }
759 
760 /**
761  * ps3_repository_read_highmem_region_count - Read the number of highmem regions
762  *
763  * Bootloaders must arrange the repository nodes such that regions are indexed
764  * with a region_index from 0 to region_count-1.
765  */
766 
ps3_repository_read_highmem_region_count(unsigned int * region_count)767 int ps3_repository_read_highmem_region_count(unsigned int *region_count)
768 {
769 	int result;
770 	u64 v1 = 0;
771 
772 	result = read_node(PS3_LPAR_ID_CURRENT,
773 		make_first_field("highmem", 0),
774 		make_field("region", 0),
775 		make_field("count", 0),
776 		0,
777 		&v1, NULL);
778 	*region_count = v1;
779 	return result;
780 }
781 
782 
ps3_repository_read_highmem_base(unsigned int region_index,u64 * highmem_base)783 int ps3_repository_read_highmem_base(unsigned int region_index,
784 	u64 *highmem_base)
785 {
786 	return read_node(PS3_LPAR_ID_CURRENT,
787 		make_first_field("highmem", 0),
788 		make_field("region", region_index),
789 		make_field("base", 0),
790 		0,
791 		highmem_base, NULL);
792 }
793 
ps3_repository_read_highmem_size(unsigned int region_index,u64 * highmem_size)794 int ps3_repository_read_highmem_size(unsigned int region_index,
795 	u64 *highmem_size)
796 {
797 	return read_node(PS3_LPAR_ID_CURRENT,
798 		make_first_field("highmem", 0),
799 		make_field("region", region_index),
800 		make_field("size", 0),
801 		0,
802 		highmem_size, NULL);
803 }
804 
805 /**
806  * ps3_repository_read_highmem_info - Read high memory region info
807  * @region_index: Region index, {0,..,region_count-1}.
808  * @highmem_base: High memory base address.
809  * @highmem_size: High memory size.
810  *
811  * Bootloaders that preallocate highmem regions must place the
812  * region info into the repository at these well known nodes.
813  */
814 
ps3_repository_read_highmem_info(unsigned int region_index,u64 * highmem_base,u64 * highmem_size)815 int ps3_repository_read_highmem_info(unsigned int region_index,
816 	u64 *highmem_base, u64 *highmem_size)
817 {
818 	int result;
819 
820 	*highmem_base = 0;
821 	result = ps3_repository_read_highmem_base(region_index, highmem_base);
822 	return result ? result
823 		: ps3_repository_read_highmem_size(region_index, highmem_size);
824 }
825 
826 /**
827  * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
828  * @num_spu: Number of physical spus.
829  */
830 
ps3_repository_read_num_spu_reserved(unsigned int * num_spu_reserved)831 int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
832 {
833 	int result;
834 	u64 v1 = 0;
835 
836 	result = read_node(PS3_LPAR_ID_CURRENT,
837 		make_first_field("bi", 0),
838 		make_field("spun", 0),
839 		0, 0,
840 		&v1, NULL);
841 	*num_spu_reserved = v1;
842 	return result;
843 }
844 
845 /**
846  * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
847  * @num_resource_id: Number of spu resource ids.
848  */
849 
ps3_repository_read_num_spu_resource_id(unsigned int * num_resource_id)850 int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
851 {
852 	int result;
853 	u64 v1 = 0;
854 
855 	result = read_node(PS3_LPAR_ID_CURRENT,
856 		make_first_field("bi", 0),
857 		make_field("spursvn", 0),
858 		0, 0,
859 		&v1, NULL);
860 	*num_resource_id = v1;
861 	return result;
862 }
863 
864 /**
865  * ps3_repository_read_spu_resource_id - spu resource reservation id value.
866  * @res_index: Resource reservation index.
867  * @resource_type: Resource reservation type.
868  * @resource_id: Resource reservation id.
869  */
870 
ps3_repository_read_spu_resource_id(unsigned int res_index,enum ps3_spu_resource_type * resource_type,unsigned int * resource_id)871 int ps3_repository_read_spu_resource_id(unsigned int res_index,
872 	enum ps3_spu_resource_type *resource_type, unsigned int *resource_id)
873 {
874 	int result;
875 	u64 v1 = 0;
876 	u64 v2 = 0;
877 
878 	result = read_node(PS3_LPAR_ID_CURRENT,
879 		make_first_field("bi", 0),
880 		make_field("spursv", 0),
881 		res_index,
882 		0,
883 		&v1, &v2);
884 	*resource_type = v1;
885 	*resource_id = v2;
886 	return result;
887 }
888 
ps3_repository_read_boot_dat_address(u64 * address)889 static int ps3_repository_read_boot_dat_address(u64 *address)
890 {
891 	return read_node(PS3_LPAR_ID_CURRENT,
892 		make_first_field("bi", 0),
893 		make_field("boot_dat", 0),
894 		make_field("address", 0),
895 		0,
896 		address, NULL);
897 }
898 
ps3_repository_read_boot_dat_size(unsigned int * size)899 int ps3_repository_read_boot_dat_size(unsigned int *size)
900 {
901 	int result;
902 	u64 v1 = 0;
903 
904 	result = read_node(PS3_LPAR_ID_CURRENT,
905 		make_first_field("bi", 0),
906 		make_field("boot_dat", 0),
907 		make_field("size", 0),
908 		0,
909 		&v1, NULL);
910 	*size = v1;
911 	return result;
912 }
913 
ps3_repository_read_vuart_av_port(unsigned int * port)914 int __init ps3_repository_read_vuart_av_port(unsigned int *port)
915 {
916 	int result;
917 	u64 v1 = 0;
918 
919 	result = read_node(PS3_LPAR_ID_CURRENT,
920 		make_first_field("bi", 0),
921 		make_field("vir_uart", 0),
922 		make_field("port", 0),
923 		make_field("avset", 0),
924 		&v1, NULL);
925 	*port = v1;
926 	return result;
927 }
928 
ps3_repository_read_vuart_sysmgr_port(unsigned int * port)929 int __init ps3_repository_read_vuart_sysmgr_port(unsigned int *port)
930 {
931 	int result;
932 	u64 v1 = 0;
933 
934 	result = read_node(PS3_LPAR_ID_CURRENT,
935 		make_first_field("bi", 0),
936 		make_field("vir_uart", 0),
937 		make_field("port", 0),
938 		make_field("sysmgr", 0),
939 		&v1, NULL);
940 	*port = v1;
941 	return result;
942 }
943 
944 /**
945   * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
946   * @lpar_addr: lpar address of cell_ext_os_area
947   * @size: size of cell_ext_os_area
948   */
949 
ps3_repository_read_boot_dat_info(u64 * lpar_addr,unsigned int * size)950 int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
951 {
952 	int result;
953 
954 	*size = 0;
955 	result = ps3_repository_read_boot_dat_address(lpar_addr);
956 	return result ? result
957 		: ps3_repository_read_boot_dat_size(size);
958 }
959 
960 /**
961  * ps3_repository_read_num_be - Number of physical BE processors in the system.
962  */
963 
ps3_repository_read_num_be(unsigned int * num_be)964 int ps3_repository_read_num_be(unsigned int *num_be)
965 {
966 	int result;
967 	u64 v1 = 0;
968 
969 	result = read_node(PS3_LPAR_ID_PME,
970 		make_first_field("ben", 0),
971 		0,
972 		0,
973 		0,
974 		&v1, NULL);
975 	*num_be = v1;
976 	return result;
977 }
978 
979 /**
980  * ps3_repository_read_be_node_id - Read the physical BE processor node id.
981  * @be_index: Zero based index.
982  * @node_id: The BE processor node id.
983  */
984 
ps3_repository_read_be_node_id(unsigned int be_index,u64 * node_id)985 int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
986 {
987 	return read_node(PS3_LPAR_ID_PME,
988 		make_first_field("be", be_index),
989 		0,
990 		0,
991 		0,
992 		node_id, NULL);
993 }
994 
995 /**
996  * ps3_repository_read_be_id - Read the physical BE processor id.
997  * @node_id: The BE processor node id.
998  * @be_id: The BE processor id.
999  */
1000 
ps3_repository_read_be_id(u64 node_id,u64 * be_id)1001 int ps3_repository_read_be_id(u64 node_id, u64 *be_id)
1002 {
1003 	return read_node(PS3_LPAR_ID_PME,
1004 		make_first_field("be", 0),
1005 		node_id,
1006 		0,
1007 		0,
1008 		be_id, NULL);
1009 }
1010 
ps3_repository_read_tb_freq(u64 node_id,u64 * tb_freq)1011 int __init ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
1012 {
1013 	return read_node(PS3_LPAR_ID_PME,
1014 		make_first_field("be", 0),
1015 		node_id,
1016 		make_field("clock", 0),
1017 		0,
1018 		tb_freq, NULL);
1019 }
1020 
ps3_repository_read_be_tb_freq(unsigned int be_index,u64 * tb_freq)1021 int __init ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
1022 {
1023 	int result;
1024 	u64 node_id;
1025 
1026 	*tb_freq = 0;
1027 	result = ps3_repository_read_be_node_id(be_index, &node_id);
1028 	return result ? result
1029 		: ps3_repository_read_tb_freq(node_id, tb_freq);
1030 }
1031 
ps3_repository_read_lpm_privileges(unsigned int be_index,u64 * lpar,u64 * rights)1032 int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
1033 	u64 *rights)
1034 {
1035 	int result;
1036 	u64 node_id;
1037 
1038 	*lpar = 0;
1039 	*rights = 0;
1040 	result = ps3_repository_read_be_node_id(be_index, &node_id);
1041 	return result ? result
1042 		: read_node(PS3_LPAR_ID_PME,
1043 			    make_first_field("be", 0),
1044 			    node_id,
1045 			    make_field("lpm", 0),
1046 			    make_field("priv", 0),
1047 			    lpar, rights);
1048 }
1049 
1050 #if defined(CONFIG_PS3_REPOSITORY_WRITE)
1051 
create_node(u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2)1052 static int create_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
1053 {
1054 	int result;
1055 
1056 	dump_node(0, n1, n2, n3, n4, v1, v2);
1057 
1058 	result = lv1_create_repository_node(n1, n2, n3, n4, v1, v2);
1059 
1060 	if (result) {
1061 		pr_devel("%s:%d: lv1_create_repository_node failed: %s\n",
1062 			__func__, __LINE__, ps3_result(result));
1063 		return -ENOENT;
1064 	}
1065 
1066 	return 0;
1067 }
1068 
delete_node(u64 n1,u64 n2,u64 n3,u64 n4)1069 static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4)
1070 {
1071 	int result;
1072 
1073 	dump_node(0, n1, n2, n3, n4, 0, 0);
1074 
1075 	result = lv1_delete_repository_node(n1, n2, n3, n4);
1076 
1077 	if (result) {
1078 		pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n",
1079 			__func__, __LINE__, ps3_result(result));
1080 		return -ENOENT;
1081 	}
1082 
1083 	return 0;
1084 }
1085 
write_node(u64 n1,u64 n2,u64 n3,u64 n4,u64 v1,u64 v2)1086 static int write_node(u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2)
1087 {
1088 	int result;
1089 
1090 	result = create_node(n1, n2, n3, n4, v1, v2);
1091 
1092 	if (!result)
1093 		return 0;
1094 
1095 	result = lv1_write_repository_node(n1, n2, n3, n4, v1, v2);
1096 
1097 	if (result) {
1098 		pr_devel("%s:%d: lv1_write_repository_node failed: %s\n",
1099 			__func__, __LINE__, ps3_result(result));
1100 		return -ENOENT;
1101 	}
1102 
1103 	return 0;
1104 }
1105 
ps3_repository_write_highmem_region_count(unsigned int region_count)1106 int ps3_repository_write_highmem_region_count(unsigned int region_count)
1107 {
1108 	int result;
1109 	u64 v1 = (u64)region_count;
1110 
1111 	result = write_node(
1112 		make_first_field("highmem", 0),
1113 		make_field("region", 0),
1114 		make_field("count", 0),
1115 		0,
1116 		v1, 0);
1117 	return result;
1118 }
1119 
ps3_repository_write_highmem_base(unsigned int region_index,u64 highmem_base)1120 int ps3_repository_write_highmem_base(unsigned int region_index,
1121 	u64 highmem_base)
1122 {
1123 	return write_node(
1124 		make_first_field("highmem", 0),
1125 		make_field("region", region_index),
1126 		make_field("base", 0),
1127 		0,
1128 		highmem_base, 0);
1129 }
1130 
ps3_repository_write_highmem_size(unsigned int region_index,u64 highmem_size)1131 int ps3_repository_write_highmem_size(unsigned int region_index,
1132 	u64 highmem_size)
1133 {
1134 	return write_node(
1135 		make_first_field("highmem", 0),
1136 		make_field("region", region_index),
1137 		make_field("size", 0),
1138 		0,
1139 		highmem_size, 0);
1140 }
1141 
ps3_repository_write_highmem_info(unsigned int region_index,u64 highmem_base,u64 highmem_size)1142 int ps3_repository_write_highmem_info(unsigned int region_index,
1143 	u64 highmem_base, u64 highmem_size)
1144 {
1145 	int result;
1146 
1147 	result = ps3_repository_write_highmem_base(region_index, highmem_base);
1148 	return result ? result
1149 		: ps3_repository_write_highmem_size(region_index, highmem_size);
1150 }
1151 
ps3_repository_delete_highmem_base(unsigned int region_index)1152 static int ps3_repository_delete_highmem_base(unsigned int region_index)
1153 {
1154 	return delete_node(
1155 		make_first_field("highmem", 0),
1156 		make_field("region", region_index),
1157 		make_field("base", 0),
1158 		0);
1159 }
1160 
ps3_repository_delete_highmem_size(unsigned int region_index)1161 static int ps3_repository_delete_highmem_size(unsigned int region_index)
1162 {
1163 	return delete_node(
1164 		make_first_field("highmem", 0),
1165 		make_field("region", region_index),
1166 		make_field("size", 0),
1167 		0);
1168 }
1169 
ps3_repository_delete_highmem_info(unsigned int region_index)1170 int ps3_repository_delete_highmem_info(unsigned int region_index)
1171 {
1172 	int result;
1173 
1174 	result = ps3_repository_delete_highmem_base(region_index);
1175 	result += ps3_repository_delete_highmem_size(region_index);
1176 
1177 	return result ? -1 : 0;
1178 }
1179 
1180 #endif /* defined(CONFIG_PS3_REPOSITORY_WRITE) */
1181 
1182 #if defined(DEBUG)
1183 
ps3_repository_dump_resource_info(const struct ps3_repository_device * repo)1184 int __init ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
1185 {
1186 	int result = 0;
1187 	unsigned int res_index;
1188 
1189 	pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
1190 		repo->bus_index, repo->dev_index);
1191 
1192 	for (res_index = 0; res_index < 10; res_index++) {
1193 		enum ps3_interrupt_type intr_type;
1194 		unsigned int interrupt_id;
1195 
1196 		result = ps3_repository_read_dev_intr(repo->bus_index,
1197 			repo->dev_index, res_index, &intr_type, &interrupt_id);
1198 
1199 		if (result) {
1200 			if (result !=  LV1_NO_ENTRY)
1201 				pr_devel("%s:%d ps3_repository_read_dev_intr"
1202 					" (%u:%u) failed\n", __func__, __LINE__,
1203 					repo->bus_index, repo->dev_index);
1204 			break;
1205 		}
1206 
1207 		pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
1208 			__func__, __LINE__, repo->bus_index, repo->dev_index,
1209 			intr_type, interrupt_id);
1210 	}
1211 
1212 	for (res_index = 0; res_index < 10; res_index++) {
1213 		enum ps3_reg_type reg_type;
1214 		u64 bus_addr;
1215 		u64 len;
1216 
1217 		result = ps3_repository_read_dev_reg(repo->bus_index,
1218 			repo->dev_index, res_index, &reg_type, &bus_addr, &len);
1219 
1220 		if (result) {
1221 			if (result !=  LV1_NO_ENTRY)
1222 				pr_devel("%s:%d ps3_repository_read_dev_reg"
1223 					" (%u:%u) failed\n", __func__, __LINE__,
1224 					repo->bus_index, repo->dev_index);
1225 			break;
1226 		}
1227 
1228 		pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n",
1229 			__func__, __LINE__, repo->bus_index, repo->dev_index,
1230 			reg_type, bus_addr, len);
1231 	}
1232 
1233 	pr_devel(" <- %s:%d\n", __func__, __LINE__);
1234 	return result;
1235 }
1236 
dump_stor_dev_info(struct ps3_repository_device * repo)1237 static int __init dump_stor_dev_info(struct ps3_repository_device *repo)
1238 {
1239 	int result = 0;
1240 	unsigned int num_regions, region_index;
1241 	u64 port, blk_size, num_blocks;
1242 
1243 	pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
1244 		repo->bus_index, repo->dev_index);
1245 
1246 	result = ps3_repository_read_stor_dev_info(repo->bus_index,
1247 		repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
1248 	if (result) {
1249 		pr_devel("%s:%d ps3_repository_read_stor_dev_info"
1250 			" (%u:%u) failed\n", __func__, __LINE__,
1251 			repo->bus_index, repo->dev_index);
1252 		goto out;
1253 	}
1254 
1255 	pr_devel("%s:%d  (%u:%u): port %llu, blk_size %llu, num_blocks "
1256 		 "%llu, num_regions %u\n",
1257 		 __func__, __LINE__, repo->bus_index, repo->dev_index,
1258 		port, blk_size, num_blocks, num_regions);
1259 
1260 	for (region_index = 0; region_index < num_regions; region_index++) {
1261 		unsigned int region_id;
1262 		u64 region_start, region_size;
1263 
1264 		result = ps3_repository_read_stor_dev_region(repo->bus_index,
1265 			repo->dev_index, region_index, &region_id,
1266 			&region_start, &region_size);
1267 		if (result) {
1268 			 pr_devel("%s:%d ps3_repository_read_stor_dev_region"
1269 				  " (%u:%u) failed\n", __func__, __LINE__,
1270 				  repo->bus_index, repo->dev_index);
1271 			break;
1272 		}
1273 
1274 		pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
1275 			__func__, __LINE__, repo->bus_index, repo->dev_index,
1276 			region_id, (unsigned long)region_start,
1277 			(unsigned long)region_size);
1278 	}
1279 
1280 out:
1281 	pr_devel(" <- %s:%d\n", __func__, __LINE__);
1282 	return result;
1283 }
1284 
dump_device_info(struct ps3_repository_device * repo,unsigned int num_dev)1285 static int __init dump_device_info(struct ps3_repository_device *repo,
1286 	unsigned int num_dev)
1287 {
1288 	int result = 0;
1289 
1290 	pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
1291 
1292 	for (repo->dev_index = 0; repo->dev_index < num_dev;
1293 		repo->dev_index++) {
1294 
1295 		result = ps3_repository_read_dev_type(repo->bus_index,
1296 			repo->dev_index, &repo->dev_type);
1297 
1298 		if (result) {
1299 			pr_devel("%s:%d ps3_repository_read_dev_type"
1300 				" (%u:%u) failed\n", __func__, __LINE__,
1301 				repo->bus_index, repo->dev_index);
1302 			break;
1303 		}
1304 
1305 		result = ps3_repository_read_dev_id(repo->bus_index,
1306 			repo->dev_index, &repo->dev_id);
1307 
1308 		if (result) {
1309 			pr_devel("%s:%d ps3_repository_read_dev_id"
1310 				" (%u:%u) failed\n", __func__, __LINE__,
1311 				repo->bus_index, repo->dev_index);
1312 			continue;
1313 		}
1314 
1315 		pr_devel("%s:%d  (%u:%u): dev_type %u, dev_id %lu\n", __func__,
1316 			__LINE__, repo->bus_index, repo->dev_index,
1317 			repo->dev_type, (unsigned long)repo->dev_id);
1318 
1319 		ps3_repository_dump_resource_info(repo);
1320 
1321 		if (repo->bus_type == PS3_BUS_TYPE_STORAGE)
1322 			dump_stor_dev_info(repo);
1323 	}
1324 
1325 	pr_devel(" <- %s:%d\n", __func__, __LINE__);
1326 	return result;
1327 }
1328 
ps3_repository_dump_bus_info(void)1329 int __init ps3_repository_dump_bus_info(void)
1330 {
1331 	int result = 0;
1332 	struct ps3_repository_device repo;
1333 
1334 	pr_devel(" -> %s:%d\n", __func__, __LINE__);
1335 
1336 	memset(&repo, 0, sizeof(repo));
1337 
1338 	for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) {
1339 		unsigned int num_dev;
1340 
1341 		result = ps3_repository_read_bus_type(repo.bus_index,
1342 			&repo.bus_type);
1343 
1344 		if (result) {
1345 			pr_devel("%s:%d read_bus_type(%u) failed\n",
1346 				__func__, __LINE__, repo.bus_index);
1347 			break;
1348 		}
1349 
1350 		result = ps3_repository_read_bus_id(repo.bus_index,
1351 			&repo.bus_id);
1352 
1353 		if (result) {
1354 			pr_devel("%s:%d read_bus_id(%u) failed\n",
1355 				__func__, __LINE__, repo.bus_index);
1356 			continue;
1357 		}
1358 
1359 		if (repo.bus_index != repo.bus_id)
1360 			pr_devel("%s:%d bus_index != bus_id\n",
1361 				__func__, __LINE__);
1362 
1363 		result = ps3_repository_read_bus_num_dev(repo.bus_index,
1364 			&num_dev);
1365 
1366 		if (result) {
1367 			pr_devel("%s:%d read_bus_num_dev(%u) failed\n",
1368 				__func__, __LINE__, repo.bus_index);
1369 			continue;
1370 		}
1371 
1372 		pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
1373 			__func__, __LINE__, repo.bus_index, repo.bus_type,
1374 			(unsigned long)repo.bus_id, num_dev);
1375 
1376 		dump_device_info(&repo, num_dev);
1377 	}
1378 
1379 	pr_devel(" <- %s:%d\n", __func__, __LINE__);
1380 	return result;
1381 }
1382 
1383 #endif /* defined(DEBUG) */
1384