diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2007-06-15 17:55:58 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-06-28 05:16:39 -0400 |
commit | a3323d1a52ec5b70821590e4beaaf13c466fd396 (patch) | |
tree | 0e2c39f3fb667bfbdd9d4279dcf82ef7d8fc6565 | |
parent | 6758555da6a171d3f21ce36c0e12a2b8cff7ca9d (diff) |
[POWERPC] PS3: Repository probe cleanups
Repository updates:
- Extract ps3_repository_find_bus() from ps3_repository_find_device(), as the
storage driver needs it.
- Make ps3_repository_find_device() return -ENODEV if a device is not found,
just like if a bus is not found.
- Add ps3_repository_read_vuart_sysmgr_port() and
ps3_repository_read_vuart_av_port() to get vuart port info.
- Add device enumeration routines ps3_repository_find_device() and
ps3_repository_find_devices().
- Cleanup debug routines.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/ps3/platform.h | 31 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/repository.c | 586 |
2 files changed, 337 insertions, 280 deletions
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 75cb8d9e90cb..87d52060fec0 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h | |||
@@ -131,24 +131,28 @@ int ps3_repository_read_dev_reg(unsigned int bus_index, | |||
131 | /* repository bus enumerators */ | 131 | /* repository bus enumerators */ |
132 | 132 | ||
133 | struct ps3_repository_device { | 133 | struct ps3_repository_device { |
134 | enum ps3_bus_type bus_type; | ||
134 | unsigned int bus_index; | 135 | unsigned int bus_index; |
136 | unsigned int bus_id; | ||
137 | enum ps3_dev_type dev_type; | ||
135 | unsigned int dev_index; | 138 | unsigned int dev_index; |
136 | struct ps3_device_id did; | 139 | unsigned int dev_id; |
137 | }; | 140 | }; |
138 | 141 | ||
139 | int ps3_repository_find_device(enum ps3_bus_type bus_type, | 142 | static inline struct ps3_repository_device *ps3_repository_bump_device( |
140 | enum ps3_dev_type dev_type, | 143 | struct ps3_repository_device *repo) |
141 | const struct ps3_repository_device *start_dev, | ||
142 | struct ps3_repository_device *dev); | ||
143 | static inline int ps3_repository_find_first_device( | ||
144 | enum ps3_bus_type bus_type, enum ps3_dev_type dev_type, | ||
145 | struct ps3_repository_device *dev) | ||
146 | { | 144 | { |
147 | return ps3_repository_find_device(bus_type, dev_type, NULL, dev); | 145 | repo->dev_index++; |
146 | return repo; | ||
148 | } | 147 | } |
149 | int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | 148 | int ps3_repository_find_device(struct ps3_repository_device *repo); |
149 | int ps3_repository_find_devices(enum ps3_bus_type bus_type, | ||
150 | int (*callback)(const struct ps3_repository_device *repo)); | ||
151 | int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, | ||
152 | unsigned int *bus_index); | ||
153 | int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | ||
150 | enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); | 154 | enum ps3_interrupt_type intr_type, unsigned int *interrupt_id); |
151 | int ps3_repository_find_reg(const struct ps3_repository_device *dev, | 155 | int ps3_repository_find_reg(const struct ps3_repository_device *repo, |
152 | enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); | 156 | enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len); |
153 | 157 | ||
154 | /* repository block device info */ | 158 | /* repository block device info */ |
@@ -218,6 +222,11 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id); | |||
218 | int ps3_repository_read_spu_resource_id(unsigned int res_index, | 222 | int ps3_repository_read_spu_resource_id(unsigned int res_index, |
219 | enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); | 223 | enum ps3_spu_resource_type* resource_type, unsigned int *resource_id); |
220 | 224 | ||
225 | /* repository vuart info */ | ||
226 | |||
227 | int ps3_repository_read_vuart_av_port(unsigned int *port); | ||
228 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port); | ||
229 | |||
221 | /* Page table entries */ | 230 | /* Page table entries */ |
222 | #define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ | 231 | #define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ |
223 | #define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ | 232 | #define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ |
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index ae586a0e5d3f..8cc37cfea0f2 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
@@ -138,7 +138,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
138 | pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", | 138 | pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", |
139 | __func__, __LINE__, ps3_result(result)); | 139 | __func__, __LINE__, ps3_result(result)); |
140 | dump_node_name(lpar_id, n1, n2, n3, n4); | 140 | dump_node_name(lpar_id, n1, n2, n3, n4); |
141 | return result; | 141 | return -ENOENT; |
142 | } | 142 | } |
143 | 143 | ||
144 | dump_node(lpar_id, n1, n2, n3, n4, v1, v2); | 144 | dump_node(lpar_id, n1, n2, n3, n4, v1, v2); |
@@ -155,7 +155,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
155 | pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", | 155 | pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", |
156 | __func__, __LINE__, v2); | 156 | __func__, __LINE__, v2); |
157 | 157 | ||
158 | return result; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
161 | int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, | 161 | int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, |
@@ -314,324 +314,140 @@ int ps3_repository_read_dev_reg(unsigned int bus_index, | |||
314 | reg_index, bus_addr, len); | 314 | reg_index, bus_addr, len); |
315 | } | 315 | } |
316 | 316 | ||
317 | #if defined(DEBUG) | ||
318 | int ps3_repository_dump_resource_info(unsigned int bus_index, | ||
319 | unsigned int dev_index) | ||
320 | { | ||
321 | int result = 0; | ||
322 | unsigned int res_index; | ||
323 | 317 | ||
324 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | ||
325 | bus_index, dev_index); | ||
326 | 318 | ||
327 | for (res_index = 0; res_index < 10; res_index++) { | 319 | int ps3_repository_find_device(struct ps3_repository_device *repo) |
328 | enum ps3_interrupt_type intr_type; | 320 | { |
329 | unsigned int interrupt_id; | 321 | int result; |
322 | struct ps3_repository_device tmp = *repo; | ||
323 | unsigned int num_dev; | ||
330 | 324 | ||
331 | result = ps3_repository_read_dev_intr(bus_index, dev_index, | 325 | BUG_ON(repo->bus_index > 10); |
332 | res_index, &intr_type, &interrupt_id); | 326 | BUG_ON(repo->dev_index > 10); |
333 | 327 | ||
334 | if (result) { | 328 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); |
335 | if (result != LV1_NO_ENTRY) | ||
336 | pr_debug("%s:%d ps3_repository_read_dev_intr" | ||
337 | " (%u:%u) failed\n", __func__, __LINE__, | ||
338 | bus_index, dev_index); | ||
339 | break; | ||
340 | } | ||
341 | 329 | ||
342 | pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", | 330 | if (result) { |
343 | __func__, __LINE__, bus_index, dev_index, intr_type, | 331 | pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); |
344 | interrupt_id); | 332 | return result; |
345 | } | 333 | } |
346 | 334 | ||
347 | for (res_index = 0; res_index < 10; res_index++) { | 335 | pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n", |
348 | enum ps3_reg_type reg_type; | 336 | __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, |
349 | u64 bus_addr; | 337 | num_dev); |
350 | u64 len; | ||
351 | |||
352 | result = ps3_repository_read_dev_reg(bus_index, dev_index, | ||
353 | res_index, ®_type, &bus_addr, &len); | ||
354 | 338 | ||
355 | if (result) { | 339 | if (tmp.dev_index >= num_dev) { |
356 | if (result != LV1_NO_ENTRY) | 340 | pr_debug("%s:%d: no device found\n", __func__, __LINE__); |
357 | pr_debug("%s:%d ps3_repository_read_dev_reg" | 341 | return -ENODEV; |
358 | " (%u:%u) failed\n", __func__, __LINE__, | ||
359 | bus_index, dev_index); | ||
360 | break; | ||
361 | } | ||
362 | |||
363 | pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", | ||
364 | __func__, __LINE__, bus_index, dev_index, reg_type, | ||
365 | bus_addr, len); | ||
366 | } | 342 | } |
367 | 343 | ||
368 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 344 | result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, |
369 | return result; | 345 | &tmp.dev_type); |
370 | } | ||
371 | |||
372 | static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index) | ||
373 | { | ||
374 | int result = 0; | ||
375 | unsigned int num_regions, region_index; | ||
376 | u64 port, blk_size, num_blocks; | ||
377 | |||
378 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | ||
379 | bus_index, dev_index); | ||
380 | 346 | ||
381 | result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port, | ||
382 | &blk_size, &num_blocks, &num_regions); | ||
383 | if (result) { | 347 | if (result) { |
384 | pr_debug("%s:%d ps3_repository_read_stor_dev_info" | 348 | pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__); |
385 | " (%u:%u) failed\n", __func__, __LINE__, | 349 | return result; |
386 | bus_index, dev_index); | ||
387 | goto out; | ||
388 | } | 350 | } |
389 | 351 | ||
390 | pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " | 352 | result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, |
391 | "%lu, num_regions %u\n", | 353 | &tmp.dev_id); |
392 | __func__, __LINE__, bus_index, dev_index, port, | ||
393 | blk_size, num_blocks, num_regions); | ||
394 | |||
395 | for (region_index = 0; region_index < num_regions; region_index++) { | ||
396 | unsigned int region_id; | ||
397 | u64 region_start, region_size; | ||
398 | |||
399 | result = ps3_repository_read_stor_dev_region(bus_index, | ||
400 | dev_index, region_index, ®ion_id, ®ion_start, | ||
401 | ®ion_size); | ||
402 | if (result) { | ||
403 | pr_debug("%s:%d ps3_repository_read_stor_dev_region" | ||
404 | " (%u:%u) failed\n", __func__, __LINE__, | ||
405 | bus_index, dev_index); | ||
406 | break; | ||
407 | } | ||
408 | 354 | ||
409 | pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", | 355 | if (result) { |
410 | __func__, __LINE__, bus_index, dev_index, region_id, | 356 | pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, |
411 | region_start, region_size); | 357 | __LINE__); |
358 | return result; | ||
412 | } | 359 | } |
413 | 360 | ||
414 | out: | 361 | pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n", |
415 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 362 | __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); |
416 | return result; | ||
417 | } | ||
418 | |||
419 | static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type, | ||
420 | unsigned int num_dev) | ||
421 | { | ||
422 | int result = 0; | ||
423 | unsigned int dev_index; | ||
424 | |||
425 | pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index); | ||
426 | |||
427 | for (dev_index = 0; dev_index < num_dev; dev_index++) { | ||
428 | enum ps3_dev_type dev_type; | ||
429 | unsigned int dev_id; | ||
430 | |||
431 | result = ps3_repository_read_dev_type(bus_index, dev_index, | ||
432 | &dev_type); | ||
433 | |||
434 | if (result) { | ||
435 | pr_debug("%s:%d ps3_repository_read_dev_type" | ||
436 | " (%u:%u) failed\n", __func__, __LINE__, | ||
437 | bus_index, dev_index); | ||
438 | break; | ||
439 | } | ||
440 | |||
441 | result = ps3_repository_read_dev_id(bus_index, dev_index, | ||
442 | &dev_id); | ||
443 | |||
444 | if (result) { | ||
445 | pr_debug("%s:%d ps3_repository_read_dev_id" | ||
446 | " (%u:%u) failed\n", __func__, __LINE__, | ||
447 | bus_index, dev_index); | ||
448 | continue; | ||
449 | } | ||
450 | 363 | ||
451 | pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, | 364 | *repo = tmp; |
452 | __LINE__, bus_index, dev_index, dev_type, dev_id); | 365 | return 0; |
453 | |||
454 | ps3_repository_dump_resource_info(bus_index, dev_index); | ||
455 | |||
456 | if (bus_type == PS3_BUS_TYPE_STORAGE) | ||
457 | dump_stor_dev_info(bus_index, dev_index); | ||
458 | } | ||
459 | |||
460 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
461 | return result; | ||
462 | } | 366 | } |
463 | 367 | ||
464 | int ps3_repository_dump_bus_info(void) | 368 | int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, |
369 | int (*callback)(const struct ps3_repository_device *repo)) | ||
465 | { | 370 | { |
466 | int result = 0; | 371 | int result = 0; |
467 | unsigned int bus_index; | 372 | struct ps3_repository_device repo; |
468 | 373 | ||
469 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | 374 | pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); |
470 | 375 | ||
471 | for (bus_index = 0; bus_index < 10; bus_index++) { | 376 | for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { |
472 | enum ps3_bus_type bus_type; | ||
473 | unsigned int bus_id; | ||
474 | unsigned int num_dev; | ||
475 | 377 | ||
476 | result = ps3_repository_read_bus_type(bus_index, &bus_type); | 378 | result = ps3_repository_read_bus_type(repo.bus_index, |
379 | &repo.bus_type); | ||
477 | 380 | ||
478 | if (result) { | 381 | if (result) { |
479 | pr_debug("%s:%d read_bus_type(%u) failed\n", | 382 | pr_debug("%s:%d read_bus_type(%u) failed\n", |
480 | __func__, __LINE__, bus_index); | 383 | __func__, __LINE__, repo.bus_index); |
481 | break; | 384 | break; |
482 | } | 385 | } |
483 | 386 | ||
484 | result = ps3_repository_read_bus_id(bus_index, &bus_id); | 387 | if (repo.bus_type != bus_type) { |
485 | 388 | pr_debug("%s:%d: skip, bus_type %u\n", __func__, | |
486 | if (result) { | 389 | __LINE__, repo.bus_type); |
487 | pr_debug("%s:%d read_bus_id(%u) failed\n", | ||
488 | __func__, __LINE__, bus_index); | ||
489 | continue; | 390 | continue; |
490 | } | 391 | } |
491 | 392 | ||
492 | if (bus_index != bus_id) | 393 | result = ps3_repository_read_bus_id(repo.bus_index, |
493 | pr_debug("%s:%d bus_index != bus_id\n", | 394 | &repo.bus_id); |
494 | __func__, __LINE__); | ||
495 | |||
496 | result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); | ||
497 | 395 | ||
498 | if (result) { | 396 | if (result) { |
499 | pr_debug("%s:%d read_bus_num_dev(%u) failed\n", | 397 | pr_debug("%s:%d read_bus_id(%u) failed\n", |
500 | __func__, __LINE__, bus_index); | 398 | __func__, __LINE__, repo.bus_index); |
501 | continue; | 399 | continue; |
502 | } | 400 | } |
503 | 401 | ||
504 | pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", | 402 | for (repo.dev_index = 0; ; repo.dev_index++) { |
505 | __func__, __LINE__, bus_index, bus_type, bus_id, | 403 | result = ps3_repository_find_device(&repo); |
506 | num_dev); | ||
507 | 404 | ||
508 | dump_device_info(bus_index, bus_type, num_dev); | 405 | if (result == -ENODEV) { |
509 | } | 406 | result = 0; |
407 | break; | ||
408 | } else if (result) | ||
409 | break; | ||
510 | 410 | ||
511 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 411 | result = callback(&repo); |
512 | return result; | ||
513 | } | ||
514 | #endif /* defined(DEBUG) */ | ||
515 | |||
516 | static int find_device(unsigned int bus_index, unsigned int num_dev, | ||
517 | unsigned int start_dev_index, enum ps3_dev_type dev_type, | ||
518 | struct ps3_repository_device *dev) | ||
519 | { | ||
520 | int result = 0; | ||
521 | unsigned int dev_index; | ||
522 | 412 | ||
523 | pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); | 413 | if (result) { |
524 | 414 | pr_debug("%s:%d: abort at callback\n", __func__, | |
525 | dev->dev_index = UINT_MAX; | 415 | __LINE__); |
526 | 416 | break; | |
527 | for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { | 417 | } |
528 | enum ps3_dev_type x; | ||
529 | |||
530 | result = ps3_repository_read_dev_type(bus_index, dev_index, | ||
531 | &x); | ||
532 | |||
533 | if (result) { | ||
534 | pr_debug("%s:%d read_dev_type failed\n", | ||
535 | __func__, __LINE__); | ||
536 | return result; | ||
537 | } | 418 | } |
538 | 419 | break; | |
539 | if (x == dev_type) | ||
540 | break; | ||
541 | } | ||
542 | |||
543 | if (dev_index == num_dev) | ||
544 | return -1; | ||
545 | |||
546 | pr_debug("%s:%d: found dev_type %u at dev_index %u\n", | ||
547 | __func__, __LINE__, dev_type, dev_index); | ||
548 | |||
549 | result = ps3_repository_read_dev_id(bus_index, dev_index, | ||
550 | &dev->did.dev_id); | ||
551 | |||
552 | if (result) { | ||
553 | pr_debug("%s:%d read_dev_id failed\n", | ||
554 | __func__, __LINE__); | ||
555 | return result; | ||
556 | } | 420 | } |
557 | 421 | ||
558 | dev->dev_index = dev_index; | 422 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
559 | |||
560 | pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__, | ||
561 | dev->did.dev_id); | ||
562 | |||
563 | return result; | 423 | return result; |
564 | } | 424 | } |
565 | 425 | ||
566 | int ps3_repository_find_device (enum ps3_bus_type bus_type, | 426 | int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, |
567 | enum ps3_dev_type dev_type, | 427 | unsigned int *bus_index) |
568 | const struct ps3_repository_device *start_dev, | ||
569 | struct ps3_repository_device *dev) | ||
570 | { | 428 | { |
571 | int result = 0; | 429 | unsigned int i; |
572 | unsigned int bus_index; | 430 | enum ps3_bus_type type; |
573 | unsigned int num_dev; | 431 | int error; |
574 | |||
575 | pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, | ||
576 | bus_type, dev_type); | ||
577 | |||
578 | BUG_ON(start_dev && start_dev->bus_index > 10); | ||
579 | |||
580 | for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; | ||
581 | bus_index++) { | ||
582 | enum ps3_bus_type x; | ||
583 | |||
584 | result = ps3_repository_read_bus_type(bus_index, &x); | ||
585 | 432 | ||
586 | if (result) { | 433 | for (i = from; i < 10; i++) { |
434 | error = ps3_repository_read_bus_type(i, &type); | ||
435 | if (error) { | ||
587 | pr_debug("%s:%d read_bus_type failed\n", | 436 | pr_debug("%s:%d read_bus_type failed\n", |
588 | __func__, __LINE__); | 437 | __func__, __LINE__); |
589 | dev->bus_index = UINT_MAX; | 438 | *bus_index = UINT_MAX; |
590 | return result; | 439 | return error; |
440 | } | ||
441 | if (type == bus_type) { | ||
442 | *bus_index = i; | ||
443 | return 0; | ||
591 | } | 444 | } |
592 | if (x == bus_type) | ||
593 | break; | ||
594 | } | ||
595 | |||
596 | if (bus_index >= 10) | ||
597 | return -ENODEV; | ||
598 | |||
599 | pr_debug("%s:%d: found bus_type %u at bus_index %u\n", | ||
600 | __func__, __LINE__, bus_type, bus_index); | ||
601 | |||
602 | result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); | ||
603 | |||
604 | if (result) { | ||
605 | pr_debug("%s:%d read_bus_num_dev failed\n", | ||
606 | __func__, __LINE__); | ||
607 | return result; | ||
608 | } | ||
609 | |||
610 | result = find_device(bus_index, num_dev, start_dev | ||
611 | ? start_dev->dev_index + 1 : 0, dev_type, dev); | ||
612 | |||
613 | if (result) { | ||
614 | pr_debug("%s:%d get_did failed\n", __func__, __LINE__); | ||
615 | return result; | ||
616 | } | ||
617 | |||
618 | result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id); | ||
619 | |||
620 | if (result) { | ||
621 | pr_debug("%s:%d read_bus_id failed\n", | ||
622 | __func__, __LINE__); | ||
623 | return result; | ||
624 | } | 445 | } |
625 | 446 | *bus_index = UINT_MAX; | |
626 | dev->bus_index = bus_index; | 447 | return -ENODEV; |
627 | |||
628 | pr_debug("%s:%d found: bus_id %u, dev_id %u\n", | ||
629 | __func__, __LINE__, dev->did.bus_id, dev->did.dev_id); | ||
630 | |||
631 | return result; | ||
632 | } | 448 | } |
633 | 449 | ||
634 | int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | 450 | int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, |
635 | enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) | 451 | enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) |
636 | { | 452 | { |
637 | int result = 0; | 453 | int result = 0; |
@@ -645,8 +461,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | |||
645 | enum ps3_interrupt_type t; | 461 | enum ps3_interrupt_type t; |
646 | unsigned int id; | 462 | unsigned int id; |
647 | 463 | ||
648 | result = ps3_repository_read_dev_intr(dev->bus_index, | 464 | result = ps3_repository_read_dev_intr(repo->bus_index, |
649 | dev->dev_index, res_index, &t, &id); | 465 | repo->dev_index, res_index, &t, &id); |
650 | 466 | ||
651 | if (result) { | 467 | if (result) { |
652 | pr_debug("%s:%d read_dev_intr failed\n", | 468 | pr_debug("%s:%d read_dev_intr failed\n", |
@@ -669,7 +485,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, | |||
669 | return result; | 485 | return result; |
670 | } | 486 | } |
671 | 487 | ||
672 | int ps3_repository_find_reg(const struct ps3_repository_device *dev, | 488 | int ps3_repository_find_reg(const struct ps3_repository_device *repo, |
673 | enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) | 489 | enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len) |
674 | { | 490 | { |
675 | int result = 0; | 491 | int result = 0; |
@@ -684,8 +500,8 @@ int ps3_repository_find_reg(const struct ps3_repository_device *dev, | |||
684 | u64 a; | 500 | u64 a; |
685 | u64 l; | 501 | u64 l; |
686 | 502 | ||
687 | result = ps3_repository_read_dev_reg(dev->bus_index, | 503 | result = ps3_repository_read_dev_reg(repo->bus_index, |
688 | dev->dev_index, res_index, &t, &a, &l); | 504 | repo->dev_index, res_index, &t, &a, &l); |
689 | 505 | ||
690 | if (result) { | 506 | if (result) { |
691 | pr_debug("%s:%d read_dev_reg failed\n", | 507 | pr_debug("%s:%d read_dev_reg failed\n", |
@@ -965,6 +781,36 @@ int ps3_repository_read_boot_dat_size(unsigned int *size) | |||
965 | return result; | 781 | return result; |
966 | } | 782 | } |
967 | 783 | ||
784 | int ps3_repository_read_vuart_av_port(unsigned int *port) | ||
785 | { | ||
786 | int result; | ||
787 | u64 v1; | ||
788 | |||
789 | result = read_node(PS3_LPAR_ID_CURRENT, | ||
790 | make_first_field("bi", 0), | ||
791 | make_field("vir_uart", 0), | ||
792 | make_field("port", 0), | ||
793 | make_field("avset", 0), | ||
794 | &v1, 0); | ||
795 | *port = v1; | ||
796 | return result; | ||
797 | } | ||
798 | |||
799 | int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) | ||
800 | { | ||
801 | int result; | ||
802 | u64 v1; | ||
803 | |||
804 | result = read_node(PS3_LPAR_ID_CURRENT, | ||
805 | make_first_field("bi", 0), | ||
806 | make_field("vir_uart", 0), | ||
807 | make_field("port", 0), | ||
808 | make_field("sysmgr", 0), | ||
809 | &v1, 0); | ||
810 | *port = v1; | ||
811 | return result; | ||
812 | } | ||
813 | |||
968 | /** | 814 | /** |
969 | * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. | 815 | * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. |
970 | * address: lpar address of cell_ext_os_area | 816 | * address: lpar address of cell_ext_os_area |
@@ -1026,3 +872,205 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) | |||
1026 | return result ? result | 872 | return result ? result |
1027 | : ps3_repository_read_tb_freq(node_id, tb_freq); | 873 | : ps3_repository_read_tb_freq(node_id, tb_freq); |
1028 | } | 874 | } |
875 | |||
876 | #if defined(DEBUG) | ||
877 | |||
878 | int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | ||
879 | { | ||
880 | int result = 0; | ||
881 | unsigned int res_index; | ||
882 | |||
883 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | ||
884 | repo->bus_index, repo->dev_index); | ||
885 | |||
886 | for (res_index = 0; res_index < 10; res_index++) { | ||
887 | enum ps3_interrupt_type intr_type; | ||
888 | unsigned int interrupt_id; | ||
889 | |||
890 | result = ps3_repository_read_dev_intr(repo->bus_index, | ||
891 | repo->dev_index, res_index, &intr_type, &interrupt_id); | ||
892 | |||
893 | if (result) { | ||
894 | if (result != LV1_NO_ENTRY) | ||
895 | pr_debug("%s:%d ps3_repository_read_dev_intr" | ||
896 | " (%u:%u) failed\n", __func__, __LINE__, | ||
897 | repo->bus_index, repo->dev_index); | ||
898 | break; | ||
899 | } | ||
900 | |||
901 | pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", | ||
902 | __func__, __LINE__, repo->bus_index, repo->dev_index, | ||
903 | intr_type, interrupt_id); | ||
904 | } | ||
905 | |||
906 | for (res_index = 0; res_index < 10; res_index++) { | ||
907 | enum ps3_reg_type reg_type; | ||
908 | u64 bus_addr; | ||
909 | u64 len; | ||
910 | |||
911 | result = ps3_repository_read_dev_reg(repo->bus_index, | ||
912 | repo->dev_index, res_index, ®_type, &bus_addr, &len); | ||
913 | |||
914 | if (result) { | ||
915 | if (result != LV1_NO_ENTRY) | ||
916 | pr_debug("%s:%d ps3_repository_read_dev_reg" | ||
917 | " (%u:%u) failed\n", __func__, __LINE__, | ||
918 | repo->bus_index, repo->dev_index); | ||
919 | break; | ||
920 | } | ||
921 | |||
922 | pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", | ||
923 | __func__, __LINE__, repo->bus_index, repo->dev_index, | ||
924 | reg_type, bus_addr, len); | ||
925 | } | ||
926 | |||
927 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
928 | return result; | ||
929 | } | ||
930 | |||
931 | static int dump_stor_dev_info(struct ps3_repository_device *repo) | ||
932 | { | ||
933 | int result = 0; | ||
934 | unsigned int num_regions, region_index; | ||
935 | u64 port, blk_size, num_blocks; | ||
936 | |||
937 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | ||
938 | repo->bus_index, repo->dev_index); | ||
939 | |||
940 | result = ps3_repository_read_stor_dev_info(repo->bus_index, | ||
941 | repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); | ||
942 | if (result) { | ||
943 | pr_debug("%s:%d ps3_repository_read_stor_dev_info" | ||
944 | " (%u:%u) failed\n", __func__, __LINE__, | ||
945 | repo->bus_index, repo->dev_index); | ||
946 | goto out; | ||
947 | } | ||
948 | |||
949 | pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " | ||
950 | "%lu, num_regions %u\n", | ||
951 | __func__, __LINE__, repo->bus_index, repo->dev_index, port, | ||
952 | blk_size, num_blocks, num_regions); | ||
953 | |||
954 | for (region_index = 0; region_index < num_regions; region_index++) { | ||
955 | unsigned int region_id; | ||
956 | u64 region_start, region_size; | ||
957 | |||
958 | result = ps3_repository_read_stor_dev_region(repo->bus_index, | ||
959 | repo->dev_index, region_index, ®ion_id, | ||
960 | ®ion_start, ®ion_size); | ||
961 | if (result) { | ||
962 | pr_debug("%s:%d ps3_repository_read_stor_dev_region" | ||
963 | " (%u:%u) failed\n", __func__, __LINE__, | ||
964 | repo->bus_index, repo->dev_index); | ||
965 | break; | ||
966 | } | ||
967 | |||
968 | pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", | ||
969 | __func__, __LINE__, repo->bus_index, repo->dev_index, | ||
970 | region_id, region_start, region_size); | ||
971 | } | ||
972 | |||
973 | out: | ||
974 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
975 | return result; | ||
976 | } | ||
977 | |||
978 | static int dump_device_info(struct ps3_repository_device *repo, | ||
979 | unsigned int num_dev) | ||
980 | { | ||
981 | int result = 0; | ||
982 | |||
983 | pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); | ||
984 | |||
985 | for (repo->dev_index = 0; repo->dev_index < num_dev; | ||
986 | repo->dev_index++) { | ||
987 | |||
988 | result = ps3_repository_read_dev_type(repo->bus_index, | ||
989 | repo->dev_index, &repo->dev_type); | ||
990 | |||
991 | if (result) { | ||
992 | pr_debug("%s:%d ps3_repository_read_dev_type" | ||
993 | " (%u:%u) failed\n", __func__, __LINE__, | ||
994 | repo->bus_index, repo->dev_index); | ||
995 | break; | ||
996 | } | ||
997 | |||
998 | result = ps3_repository_read_dev_id(repo->bus_index, | ||
999 | repo->dev_index, &repo->dev_id); | ||
1000 | |||
1001 | if (result) { | ||
1002 | pr_debug("%s:%d ps3_repository_read_dev_id" | ||
1003 | " (%u:%u) failed\n", __func__, __LINE__, | ||
1004 | repo->bus_index, repo->dev_index); | ||
1005 | continue; | ||
1006 | } | ||
1007 | |||
1008 | pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, | ||
1009 | __LINE__, repo->bus_index, repo->dev_index, | ||
1010 | repo->dev_type, repo->dev_id); | ||
1011 | |||
1012 | ps3_repository_dump_resource_info(repo); | ||
1013 | |||
1014 | if (repo->bus_type == PS3_BUS_TYPE_STORAGE) | ||
1015 | dump_stor_dev_info(repo); | ||
1016 | } | ||
1017 | |||
1018 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
1019 | return result; | ||
1020 | } | ||
1021 | |||
1022 | int ps3_repository_dump_bus_info(void) | ||
1023 | { | ||
1024 | int result = 0; | ||
1025 | struct ps3_repository_device repo; | ||
1026 | |||
1027 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | ||
1028 | |||
1029 | memset(&repo, 0, sizeof(repo)); | ||
1030 | |||
1031 | for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { | ||
1032 | unsigned int num_dev; | ||
1033 | |||
1034 | result = ps3_repository_read_bus_type(repo.bus_index, | ||
1035 | &repo.bus_type); | ||
1036 | |||
1037 | if (result) { | ||
1038 | pr_debug("%s:%d read_bus_type(%u) failed\n", | ||
1039 | __func__, __LINE__, repo.bus_index); | ||
1040 | break; | ||
1041 | } | ||
1042 | |||
1043 | result = ps3_repository_read_bus_id(repo.bus_index, | ||
1044 | &repo.bus_id); | ||
1045 | |||
1046 | if (result) { | ||
1047 | pr_debug("%s:%d read_bus_id(%u) failed\n", | ||
1048 | __func__, __LINE__, repo.bus_index); | ||
1049 | continue; | ||
1050 | } | ||
1051 | |||
1052 | if (repo.bus_index != repo.bus_id) | ||
1053 | pr_debug("%s:%d bus_index != bus_id\n", | ||
1054 | __func__, __LINE__); | ||
1055 | |||
1056 | result = ps3_repository_read_bus_num_dev(repo.bus_index, | ||
1057 | &num_dev); | ||
1058 | |||
1059 | if (result) { | ||
1060 | pr_debug("%s:%d read_bus_num_dev(%u) failed\n", | ||
1061 | __func__, __LINE__, repo.bus_index); | ||
1062 | continue; | ||
1063 | } | ||
1064 | |||
1065 | pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", | ||
1066 | __func__, __LINE__, repo.bus_index, repo.bus_type, | ||
1067 | repo.bus_id, num_dev); | ||
1068 | |||
1069 | dump_device_info(&repo, num_dev); | ||
1070 | } | ||
1071 | |||
1072 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | ||
1073 | return result; | ||
1074 | } | ||
1075 | |||
1076 | #endif /* defined(DEBUG) */ | ||