diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2018-01-13 17:37:13 -0500 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2018-01-16 10:47:29 -0500 |
commit | 883b8cb31a8546b9921c98b255d5f7779d1bc9f6 (patch) | |
tree | d9e1ae77b9ffece894ff6f1734093aa18e001e6f | |
parent | 4bccc4b629de3af24308a24c41aff6270a6404aa (diff) |
nubus: Generalize block resource handling
Scrap the specialized code to unpack video mode name resources and
driver resources. It isn't useful.
Instead, add a re-usable function to handle lists of block resources of
any kind, and descend into the video mode table resource directory.
Rename callers as nubus_get_foo(), consistent with their purpose and
with related functions in the same file.
Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | drivers/nubus/nubus.c | 123 |
1 files changed, 65 insertions, 58 deletions
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c index 4ae5c420f13f..c56ac36d91f2 100644 --- a/drivers/nubus/nubus.c +++ b/drivers/nubus/nubus.c | |||
@@ -331,16 +331,63 @@ EXPORT_SYMBOL(nubus_find_rsrc); | |||
331 | among other things. The rest of it should go in the /proc code. | 331 | among other things. The rest of it should go in the /proc code. |
332 | For now, we just use it to give verbose boot logs. */ | 332 | For now, we just use it to give verbose boot logs. */ |
333 | 333 | ||
334 | static int __init nubus_show_display_resource(struct nubus_dev *dev, | 334 | static int __init nubus_get_block_rsrc_dir(struct nubus_board *board, |
335 | const struct nubus_dirent *ent) | 335 | const struct nubus_dirent *parent) |
336 | { | ||
337 | struct nubus_dir dir; | ||
338 | struct nubus_dirent ent; | ||
339 | |||
340 | nubus_get_subdir(parent, &dir); | ||
341 | |||
342 | while (nubus_readdir(&dir, &ent) != -1) { | ||
343 | u32 size; | ||
344 | |||
345 | nubus_get_rsrc_mem(&size, &ent, 4); | ||
346 | pr_debug(" block (0x%x), size %d\n", ent.type, size); | ||
347 | } | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int __init nubus_get_display_vidmode(struct nubus_board *board, | ||
352 | const struct nubus_dirent *parent) | ||
353 | { | ||
354 | struct nubus_dir dir; | ||
355 | struct nubus_dirent ent; | ||
356 | |||
357 | nubus_get_subdir(parent, &dir); | ||
358 | |||
359 | while (nubus_readdir(&dir, &ent) != -1) { | ||
360 | switch (ent.type) { | ||
361 | case 1: /* mVidParams */ | ||
362 | case 2: /* mTable */ | ||
363 | { | ||
364 | u32 size; | ||
365 | |||
366 | nubus_get_rsrc_mem(&size, &ent, 4); | ||
367 | pr_debug(" block (0x%x), size %d\n", ent.type, | ||
368 | size); | ||
369 | break; | ||
370 | } | ||
371 | default: | ||
372 | pr_debug(" unknown resource 0x%02x, data 0x%06x\n", | ||
373 | ent.type, ent.data); | ||
374 | } | ||
375 | } | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int __init nubus_get_display_resource(struct nubus_dev *dev, | ||
380 | const struct nubus_dirent *ent) | ||
336 | { | 381 | { |
337 | switch (ent->type) { | 382 | switch (ent->type) { |
338 | case NUBUS_RESID_GAMMADIR: | 383 | case NUBUS_RESID_GAMMADIR: |
339 | pr_debug(" gamma directory offset: 0x%06x\n", ent->data); | 384 | pr_debug(" gamma directory offset: 0x%06x\n", ent->data); |
385 | nubus_get_block_rsrc_dir(dev->board, ent); | ||
340 | break; | 386 | break; |
341 | case 0x0080 ... 0x0085: | 387 | case 0x0080 ... 0x0085: |
342 | pr_debug(" mode 0x%02x info offset: 0x%06x\n", | 388 | pr_debug(" mode 0x%02x info offset: 0x%06x\n", |
343 | ent->type, ent->data); | 389 | ent->type, ent->data); |
390 | nubus_get_display_vidmode(dev->board, ent); | ||
344 | break; | 391 | break; |
345 | default: | 392 | default: |
346 | pr_debug(" unknown resource 0x%02x, data 0x%06x\n", | 393 | pr_debug(" unknown resource 0x%02x, data 0x%06x\n", |
@@ -349,8 +396,8 @@ static int __init nubus_show_display_resource(struct nubus_dev *dev, | |||
349 | return 0; | 396 | return 0; |
350 | } | 397 | } |
351 | 398 | ||
352 | static int __init nubus_show_network_resource(struct nubus_dev *dev, | 399 | static int __init nubus_get_network_resource(struct nubus_dev *dev, |
353 | const struct nubus_dirent *ent) | 400 | const struct nubus_dirent *ent) |
354 | { | 401 | { |
355 | switch (ent->type) { | 402 | switch (ent->type) { |
356 | case NUBUS_RESID_MAC_ADDRESS: | 403 | case NUBUS_RESID_MAC_ADDRESS: |
@@ -368,8 +415,8 @@ static int __init nubus_show_network_resource(struct nubus_dev *dev, | |||
368 | return 0; | 415 | return 0; |
369 | } | 416 | } |
370 | 417 | ||
371 | static int __init nubus_show_cpu_resource(struct nubus_dev *dev, | 418 | static int __init nubus_get_cpu_resource(struct nubus_dev *dev, |
372 | const struct nubus_dirent *ent) | 419 | const struct nubus_dirent *ent) |
373 | { | 420 | { |
374 | switch (ent->type) { | 421 | switch (ent->type) { |
375 | case NUBUS_RESID_MEMINFO: | 422 | case NUBUS_RESID_MEMINFO: |
@@ -397,18 +444,18 @@ static int __init nubus_show_cpu_resource(struct nubus_dev *dev, | |||
397 | return 0; | 444 | return 0; |
398 | } | 445 | } |
399 | 446 | ||
400 | static int __init nubus_show_private_resource(struct nubus_dev *dev, | 447 | static int __init nubus_get_private_resource(struct nubus_dev *dev, |
401 | const struct nubus_dirent *ent) | 448 | const struct nubus_dirent *ent) |
402 | { | 449 | { |
403 | switch (dev->category) { | 450 | switch (dev->category) { |
404 | case NUBUS_CAT_DISPLAY: | 451 | case NUBUS_CAT_DISPLAY: |
405 | nubus_show_display_resource(dev, ent); | 452 | nubus_get_display_resource(dev, ent); |
406 | break; | 453 | break; |
407 | case NUBUS_CAT_NETWORK: | 454 | case NUBUS_CAT_NETWORK: |
408 | nubus_show_network_resource(dev, ent); | 455 | nubus_get_network_resource(dev, ent); |
409 | break; | 456 | break; |
410 | case NUBUS_CAT_CPU: | 457 | case NUBUS_CAT_CPU: |
411 | nubus_show_cpu_resource(dev, ent); | 458 | nubus_get_cpu_resource(dev, ent); |
412 | break; | 459 | break; |
413 | default: | 460 | default: |
414 | pr_debug(" unknown resource 0x%02x, data 0x%06x\n", | 461 | pr_debug(" unknown resource 0x%02x, data 0x%06x\n", |
@@ -462,14 +509,9 @@ nubus_get_functional_resource(struct nubus_board *board, int slot, | |||
462 | { | 509 | { |
463 | /* MacOS driver. If we were NetBSD we might | 510 | /* MacOS driver. If we were NetBSD we might |
464 | use this :-) */ | 511 | use this :-) */ |
465 | struct nubus_dir drvr_dir; | 512 | pr_debug(" driver directory offset: 0x%06x\n", |
466 | struct nubus_dirent drvr_ent; | 513 | ent.data); |
467 | unsigned char *driver; | 514 | nubus_get_block_rsrc_dir(board, &ent); |
468 | |||
469 | nubus_get_subdir(&ent, &drvr_dir); | ||
470 | nubus_readdir(&drvr_dir, &drvr_ent); | ||
471 | driver = nubus_dirptr(&drvr_ent); | ||
472 | pr_debug(" driver at: 0x%p\n", driver); | ||
473 | break; | 515 | break; |
474 | } | 516 | } |
475 | case NUBUS_RESID_MINOR_BASEOS: | 517 | case NUBUS_RESID_MINOR_BASEOS: |
@@ -501,50 +543,13 @@ nubus_get_functional_resource(struct nubus_board *board, int slot, | |||
501 | default: | 543 | default: |
502 | /* Local/Private resources have their own | 544 | /* Local/Private resources have their own |
503 | function */ | 545 | function */ |
504 | nubus_show_private_resource(dev, &ent); | 546 | nubus_get_private_resource(dev, &ent); |
505 | } | 547 | } |
506 | } | 548 | } |
507 | 549 | ||
508 | return dev; | 550 | return dev; |
509 | } | 551 | } |
510 | 552 | ||
511 | /* This is cool. */ | ||
512 | static int __init nubus_get_vidnames(struct nubus_board *board, | ||
513 | const struct nubus_dirent *parent) | ||
514 | { | ||
515 | struct nubus_dir dir; | ||
516 | struct nubus_dirent ent; | ||
517 | |||
518 | /* FIXME: obviously we want to put this in a header file soon */ | ||
519 | struct vidmode { | ||
520 | u32 size; | ||
521 | /* Don't know what this is yet */ | ||
522 | u16 id; | ||
523 | /* Longest one I've seen so far is 26 characters */ | ||
524 | char name[36]; | ||
525 | }; | ||
526 | |||
527 | pr_debug(" video modes supported:\n"); | ||
528 | nubus_get_subdir(parent, &dir); | ||
529 | |||
530 | while (nubus_readdir(&dir, &ent) != -1) { | ||
531 | struct vidmode mode; | ||
532 | u32 size; | ||
533 | |||
534 | /* First get the length */ | ||
535 | nubus_get_rsrc_mem(&size, &ent, 4); | ||
536 | |||
537 | /* Now clobber the whole thing */ | ||
538 | if (size > sizeof(mode) - 1) | ||
539 | size = sizeof(mode) - 1; | ||
540 | memset(&mode, 0, sizeof(mode)); | ||
541 | nubus_get_rsrc_mem(&mode, &ent, size); | ||
542 | pr_debug(" 0x%02x: 0x%04x %s\n", ent.type, | ||
543 | mode.id, mode.name); | ||
544 | } | ||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | /* This is *really* cool. */ | 553 | /* This is *really* cool. */ |
549 | static int __init nubus_get_icon(struct nubus_board *board, | 554 | static int __init nubus_get_icon(struct nubus_board *board, |
550 | const struct nubus_dirent *ent) | 555 | const struct nubus_dirent *ent) |
@@ -641,7 +646,9 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot, | |||
641 | break; | 646 | break; |
642 | /* WTF isn't this in the functional resources? */ | 647 | /* WTF isn't this in the functional resources? */ |
643 | case NUBUS_RESID_VIDNAMES: | 648 | case NUBUS_RESID_VIDNAMES: |
644 | nubus_get_vidnames(board, &ent); | 649 | pr_debug(" vidnames directory offset: 0x%06x\n", |
650 | ent.data); | ||
651 | nubus_get_block_rsrc_dir(board, &ent); | ||
645 | break; | 652 | break; |
646 | /* Same goes for this */ | 653 | /* Same goes for this */ |
647 | case NUBUS_RESID_VIDMODES: | 654 | case NUBUS_RESID_VIDMODES: |