diff options
-rw-r--r-- | drivers/char/hvc_console.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index f0a1456a597e..4b776f4eb467 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -102,10 +102,11 @@ static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs); | |||
102 | static DEFINE_SPINLOCK(hvc_structs_lock); | 102 | static DEFINE_SPINLOCK(hvc_structs_lock); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * This value is used to associate a tty->index value to a hvc_struct based | 105 | * This value is used to assign a tty->index value to a hvc_struct based |
106 | * upon order of exposure via hvc_probe(). | 106 | * upon order of exposure via hvc_probe(), when we can not match it to |
107 | * a console canidate registered with hvc_instantiate(). | ||
107 | */ | 108 | */ |
108 | static int hvc_count = -1; | 109 | static int last_hvc = -1; |
109 | 110 | ||
110 | /* | 111 | /* |
111 | * Do not call this function with either the hvc_strucst_lock or the hvc_struct | 112 | * Do not call this function with either the hvc_strucst_lock or the hvc_struct |
@@ -224,9 +225,10 @@ static int __init hvc_console_init(void) | |||
224 | console_initcall(hvc_console_init); | 225 | console_initcall(hvc_console_init); |
225 | 226 | ||
226 | /* | 227 | /* |
227 | * hvc_instantiate() is an early console discovery method which locates consoles | 228 | * hvc_instantiate() is an early console discovery method which locates |
228 | * prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT | 229 | * consoles * prior to the vio subsystem discovering them. Hotplugged |
229 | * get an hvc_instantiate() callback since the appear after early console init. | 230 | * vty adapters do NOT get an hvc_instantiate() callback since they |
231 | * appear after early console init. | ||
230 | */ | 232 | */ |
231 | int hvc_instantiate(uint32_t vtermno, int index) | 233 | int hvc_instantiate(uint32_t vtermno, int index) |
232 | { | 234 | { |
@@ -237,6 +239,11 @@ int hvc_instantiate(uint32_t vtermno, int index) | |||
237 | return -1; | 239 | return -1; |
238 | 240 | ||
239 | vtermnos[index] = vtermno; | 241 | vtermnos[index] = vtermno; |
242 | |||
243 | /* reserve all indices upto and including this index */ | ||
244 | if (last_hvc < index) | ||
245 | last_hvc = index; | ||
246 | |||
240 | return 0; | 247 | return 0; |
241 | } | 248 | } |
242 | 249 | ||
@@ -697,6 +704,7 @@ static int __devinit hvc_probe( | |||
697 | const struct vio_device_id *id) | 704 | const struct vio_device_id *id) |
698 | { | 705 | { |
699 | struct hvc_struct *hp; | 706 | struct hvc_struct *hp; |
707 | int i; | ||
700 | 708 | ||
701 | /* probed with invalid parameters. */ | 709 | /* probed with invalid parameters. */ |
702 | if (!dev || !id) | 710 | if (!dev || !id) |
@@ -717,7 +725,21 @@ static int __devinit hvc_probe( | |||
717 | 725 | ||
718 | spin_lock_init(&hp->lock); | 726 | spin_lock_init(&hp->lock); |
719 | spin_lock(&hvc_structs_lock); | 727 | spin_lock(&hvc_structs_lock); |
720 | hp->index = ++hvc_count; | 728 | |
729 | /* | ||
730 | * find index to use: | ||
731 | * see if this vterm id matches one registered for console. | ||
732 | */ | ||
733 | for (i=0; i < MAX_NR_HVC_CONSOLES; i++) | ||
734 | if (vtermnos[i] == hp->vtermno) | ||
735 | break; | ||
736 | |||
737 | /* no matching slot, just use a counter */ | ||
738 | if (i >= MAX_NR_HVC_CONSOLES) | ||
739 | i = ++last_hvc; | ||
740 | |||
741 | hp->index = i; | ||
742 | |||
721 | list_add_tail(&(hp->next), &hvc_structs); | 743 | list_add_tail(&(hp->next), &hvc_structs); |
722 | spin_unlock(&hvc_structs_lock); | 744 | spin_unlock(&hvc_structs_lock); |
723 | 745 | ||