iomux.c 3.1 KB

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