diff options
| -rw-r--r-- | drivers/char/hvc_console.c | 21 | ||||
| -rw-r--r-- | drivers/char/hvc_vio.c | 9 | ||||
| -rw-r--r-- | include/asm-ppc64/hvconsole.h | 9 |
3 files changed, 27 insertions, 12 deletions
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index df282cc9a7ab..cddb789902db 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
| @@ -85,6 +85,7 @@ struct hvc_struct { | |||
| 85 | char outbuf[N_OUTBUF] __ALIGNED__; | 85 | char outbuf[N_OUTBUF] __ALIGNED__; |
| 86 | int n_outbuf; | 86 | int n_outbuf; |
| 87 | uint32_t vtermno; | 87 | uint32_t vtermno; |
| 88 | struct hv_ops *ops; | ||
| 88 | int irq_requested; | 89 | int irq_requested; |
| 89 | int irq; | 90 | int irq; |
| 90 | struct list_head next; | 91 | struct list_head next; |
| @@ -142,6 +143,7 @@ struct hvc_struct *hvc_get_by_index(int index) | |||
| 142 | * console interfaces but can still be used as a tty device. This has to be | 143 | * console interfaces but can still be used as a tty device. This has to be |
| 143 | * static because kmalloc will not work during early console init. | 144 | * static because kmalloc will not work during early console init. |
| 144 | */ | 145 | */ |
| 146 | static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES]; | ||
| 145 | static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = | 147 | static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = |
| 146 | {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1}; | 148 | {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1}; |
| 147 | 149 | ||
| @@ -154,14 +156,14 @@ void hvc_console_print(struct console *co, const char *b, unsigned count) | |||
| 154 | { | 156 | { |
| 155 | char c[16] __ALIGNED__; | 157 | char c[16] __ALIGNED__; |
| 156 | unsigned i = 0, n = 0; | 158 | unsigned i = 0, n = 0; |
| 157 | int r, donecr = 0; | 159 | int r, donecr = 0, index = co->index; |
| 158 | 160 | ||
| 159 | /* Console access attempt outside of acceptable console range. */ | 161 | /* Console access attempt outside of acceptable console range. */ |
| 160 | if (co->index >= MAX_NR_HVC_CONSOLES) | 162 | if (index >= MAX_NR_HVC_CONSOLES) |
| 161 | return; | 163 | return; |
| 162 | 164 | ||
| 163 | /* This console adapter was removed so it is not useable. */ | 165 | /* This console adapter was removed so it is not useable. */ |
| 164 | if (vtermnos[co->index] < 0) | 166 | if (vtermnos[index] < 0) |
| 165 | return; | 167 | return; |
| 166 | 168 | ||
| 167 | while (count > 0 || i > 0) { | 169 | while (count > 0 || i > 0) { |
| @@ -175,7 +177,7 @@ void hvc_console_print(struct console *co, const char *b, unsigned count) | |||
| 175 | --count; | 177 | --count; |
| 176 | } | 178 | } |
| 177 | } else { | 179 | } else { |
| 178 | r = hvc_put_chars(vtermnos[co->index], c, i); | 180 | r = cons_ops[index]->put_chars(vtermnos[index], c, i); |
| 179 | if (r < 0) { | 181 | if (r < 0) { |
| 180 | /* throw away chars on error */ | 182 | /* throw away chars on error */ |
| 181 | i = 0; | 183 | i = 0; |
| @@ -245,7 +247,7 @@ console_initcall(hvc_console_init); | |||
| 245 | * vty adapters do NOT get an hvc_instantiate() callback since they | 247 | * vty adapters do NOT get an hvc_instantiate() callback since they |
| 246 | * appear after early console init. | 248 | * appear after early console init. |
| 247 | */ | 249 | */ |
| 248 | int hvc_instantiate(uint32_t vtermno, int index) | 250 | int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) |
| 249 | { | 251 | { |
| 250 | struct hvc_struct *hp; | 252 | struct hvc_struct *hp; |
| 251 | 253 | ||
| @@ -263,6 +265,7 @@ int hvc_instantiate(uint32_t vtermno, int index) | |||
| 263 | } | 265 | } |
| 264 | 266 | ||
| 265 | vtermnos[index] = vtermno; | 267 | vtermnos[index] = vtermno; |
| 268 | cons_ops[index] = ops; | ||
| 266 | 269 | ||
| 267 | /* reserve all indices upto and including this index */ | 270 | /* reserve all indices upto and including this index */ |
| 268 | if (last_hvc < index) | 271 | if (last_hvc < index) |
| @@ -466,7 +469,7 @@ static void hvc_push(struct hvc_struct *hp) | |||
| 466 | { | 469 | { |
| 467 | int n; | 470 | int n; |
| 468 | 471 | ||
| 469 | n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); | 472 | n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); |
| 470 | if (n <= 0) { | 473 | if (n <= 0) { |
| 471 | if (n == 0) | 474 | if (n == 0) |
| 472 | return; | 475 | return; |
| @@ -604,7 +607,7 @@ static int hvc_poll(struct hvc_struct *hp) | |||
| 604 | break; | 607 | break; |
| 605 | } | 608 | } |
| 606 | 609 | ||
| 607 | n = hvc_get_chars(hp->vtermno, buf, count); | 610 | n = hp->ops->get_chars(hp->vtermno, buf, count); |
| 608 | if (n <= 0) { | 611 | if (n <= 0) { |
| 609 | /* Hangup the tty when disconnected from host */ | 612 | /* Hangup the tty when disconnected from host */ |
| 610 | if (n == -EPIPE) { | 613 | if (n == -EPIPE) { |
| @@ -737,7 +740,8 @@ static struct kobj_type hvc_kobj_type = { | |||
| 737 | .release = destroy_hvc_struct, | 740 | .release = destroy_hvc_struct, |
| 738 | }; | 741 | }; |
| 739 | 742 | ||
| 740 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq) | 743 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, |
| 744 | struct hv_ops *ops) | ||
| 741 | { | 745 | { |
| 742 | struct hvc_struct *hp; | 746 | struct hvc_struct *hp; |
| 743 | int i; | 747 | int i; |
| @@ -750,6 +754,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq) | |||
| 750 | 754 | ||
| 751 | hp->vtermno = vtermno; | 755 | hp->vtermno = vtermno; |
| 752 | hp->irq = irq; | 756 | hp->irq = irq; |
| 757 | hp->ops = ops; | ||
| 753 | 758 | ||
| 754 | kobject_init(&hp->kobj); | 759 | kobject_init(&hp->kobj); |
| 755 | hp->kobj.ktype = &hvc_kobj_type; | 760 | hp->kobj.ktype = &hvc_kobj_type; |
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index d2928f90ab51..430a2c284ad2 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c | |||
| @@ -43,6 +43,11 @@ static struct vio_device_id hvc_driver_table[] __devinitdata = { | |||
| 43 | }; | 43 | }; |
| 44 | MODULE_DEVICE_TABLE(vio, hvc_driver_table); | 44 | MODULE_DEVICE_TABLE(vio, hvc_driver_table); |
| 45 | 45 | ||
| 46 | static struct hv_ops hvc_get_put_ops = { | ||
| 47 | .get_chars = hvc_get_chars, | ||
| 48 | .put_chars = hvc_put_chars, | ||
| 49 | }; | ||
| 50 | |||
| 46 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 51 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, |
| 47 | const struct vio_device_id *id) | 52 | const struct vio_device_id *id) |
| 48 | { | 53 | { |
| @@ -52,7 +57,7 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, | |||
| 52 | if (!vdev || !id) | 57 | if (!vdev || !id) |
| 53 | return -EPERM; | 58 | return -EPERM; |
| 54 | 59 | ||
| 55 | hp = hvc_alloc(vdev->unit_address, vdev->irq); | 60 | hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops); |
| 56 | if (IS_ERR(hp)) | 61 | if (IS_ERR(hp)) |
| 57 | return PTR_ERR(hp); | 62 | return PTR_ERR(hp); |
| 58 | dev_set_drvdata(&vdev->dev, hp); | 63 | dev_set_drvdata(&vdev->dev, hp); |
| @@ -115,7 +120,7 @@ static int hvc_find_vtys(void) | |||
| 115 | continue; | 120 | continue; |
| 116 | 121 | ||
| 117 | if (device_is_compatible(vty, "hvterm1")) { | 122 | if (device_is_compatible(vty, "hvterm1")) { |
| 118 | hvc_instantiate(*vtermno, num_found); | 123 | hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops); |
| 119 | ++num_found; | 124 | ++num_found; |
| 120 | } | 125 | } |
| 121 | } | 126 | } |
diff --git a/include/asm-ppc64/hvconsole.h b/include/asm-ppc64/hvconsole.h index 14667a78716d..6da93ce74dc0 100644 --- a/include/asm-ppc64/hvconsole.h +++ b/include/asm-ppc64/hvconsole.h | |||
| @@ -30,15 +30,20 @@ | |||
| 30 | #define MAX_NR_HVC_CONSOLES 16 | 30 | #define MAX_NR_HVC_CONSOLES 16 |
| 31 | 31 | ||
| 32 | /* implemented by a low level driver */ | 32 | /* implemented by a low level driver */ |
| 33 | struct hv_ops { | ||
| 34 | int (*get_chars)(uint32_t vtermno, char *buf, int count); | ||
| 35 | int (*put_chars)(uint32_t vtermno, const char *buf, int count); | ||
| 36 | }; | ||
| 33 | extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); | 37 | extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); |
| 34 | extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); | 38 | extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); |
| 35 | 39 | ||
| 36 | struct hvc_struct; | 40 | struct hvc_struct; |
| 37 | 41 | ||
| 38 | /* Register a vterm and a slot index for use as a console (console_init) */ | 42 | /* Register a vterm and a slot index for use as a console (console_init) */ |
| 39 | extern int hvc_instantiate(uint32_t vtermno, int index); | 43 | extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); |
| 40 | /* register a vterm for hvc tty operation (module_init or hotplug add) */ | 44 | /* register a vterm for hvc tty operation (module_init or hotplug add) */ |
| 41 | extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq); | 45 | extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, |
| 46 | struct hv_ops *ops); | ||
| 42 | /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ | 47 | /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ |
| 43 | extern int __devexit hvc_remove(struct hvc_struct *hp); | 48 | extern int __devexit hvc_remove(struct hvc_struct *hp); |
| 44 | #endif /* _PPC64_HVCONSOLE_H */ | 49 | #endif /* _PPC64_HVCONSOLE_H */ |
