iomux.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2008
  4. * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
  5. */
  6. #include <common.h>
  7. #include <console.h>
  8. #include <serial.h>
  9. #include <malloc.h>
  10. #if CONFIG_IS_ENABLED(CONSOLE_MUX)
  11. void iomux_printdevs(const int console)
  12. {
  13. int i;
  14. struct stdio_dev *dev;
  15. for (i = 0; i < cd_count[console]; i++) {
  16. dev = console_devices[console][i];
  17. printf("%s ", dev->name);
  18. }
  19. printf("\n");
  20. }
  21. /* This tries to preserve the old list if an error occurs. */
  22. int iomux_doenv(const int console, const char *arg)
  23. {
  24. char *console_args, *temp, **start;
  25. int i, j, k, io_flag, cs_idx, repeat;
  26. struct stdio_dev *dev;
  27. struct stdio_dev **cons_set;
  28. console_args = strdup(arg);
  29. if (console_args == NULL)
  30. return 1;
  31. /*
  32. * Check whether a comma separated list of devices was
  33. * entered and count how many devices were entered.
  34. * The array start[] has pointers to the beginning of
  35. * each device name (up to MAX_CONSARGS devices).
  36. *
  37. * Have to do this twice - once to count the number of
  38. * commas and then again to populate start.
  39. */
  40. i = 0;
  41. temp = console_args;
  42. for (;;) {
  43. temp = strchr(temp, ',');
  44. if (temp != NULL) {
  45. i++;
  46. temp++;
  47. continue;
  48. }
  49. /* There's always one entry more than the number of commas. */
  50. i++;
  51. break;
  52. }
  53. start = (char **)malloc(i * sizeof(char *));
  54. if (start == NULL) {
  55. free(console_args);
  56. return 1;
  57. }
  58. i = 0;
  59. start[0] = console_args;
  60. for (;;) {
  61. temp = strchr(start[i++], ',');
  62. if (temp == NULL)
  63. break;
  64. *temp = '\0';
  65. start[i] = temp + 1;
  66. }
  67. cons_set = (struct stdio_dev **)calloc(i, sizeof(struct stdio_dev *));
  68. if (cons_set == NULL) {
  69. free(start);
  70. free(console_args);
  71. return 1;
  72. }
  73. switch (console) {
  74. case stdin:
  75. io_flag = DEV_FLAGS_INPUT;
  76. break;
  77. case stdout:
  78. case stderr:
  79. io_flag = DEV_FLAGS_OUTPUT;
  80. break;
  81. default:
  82. free(start);
  83. free(console_args);
  84. free(cons_set);
  85. return 1;
  86. }
  87. cs_idx = 0;
  88. for (j = 0; j < i; j++) {
  89. /*
  90. * Check whether the device exists and is valid.
  91. * console_assign() also calls search_device(),
  92. * but I need the pointer to the device.
  93. */
  94. dev = search_device(io_flag, start[j]);
  95. if (dev == NULL)
  96. continue;
  97. /*
  98. * Prevent multiple entries for a device.
  99. */
  100. repeat = 0;
  101. for (k = 0; k < cs_idx; k++) {
  102. if (dev == cons_set[k]) {
  103. repeat++;
  104. break;
  105. }
  106. }
  107. if (repeat)
  108. continue;
  109. /*
  110. * Try assigning the specified device.
  111. * This could screw up the console settings for apps.
  112. */
  113. if (console_assign(console, start[j]) < 0)
  114. continue;
  115. cons_set[cs_idx++] = dev;
  116. }
  117. free(console_args);
  118. free(start);
  119. /* failed to set any console */
  120. if (cs_idx == 0) {
  121. free(cons_set);
  122. return 1;
  123. } else {
  124. /* Works even if console_devices[console] is NULL. */
  125. console_devices[console] =
  126. (struct stdio_dev **)realloc(console_devices[console],
  127. cs_idx * sizeof(struct stdio_dev *));
  128. if (console_devices[console] == NULL) {
  129. free(cons_set);
  130. return 1;
  131. }
  132. memcpy(console_devices[console], cons_set, cs_idx *
  133. sizeof(struct stdio_dev *));
  134. cd_count[console] = cs_idx;
  135. }
  136. free(cons_set);
  137. return 0;
  138. }
  139. #endif /* CONSOLE_MUX */