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, ®_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, ®ion_id,
1266 ®ion_start, ®ion_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