lkml.org 
[lkml]   [2008]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] hvc - register all available consoles (was: Re: [PATCH] powerpc/lpar - defer prefered console setup)
    On Wed, Jul 30, 2008 at 08:29:19AM +0200, Bastian Blank wrote:
    > Okay, so hvc_console is the culprit. It don't register a preferred
    > console if it knows it is not the first in the list.

    The patch registers all available hvc consoles. It adds one "struct
    console" for all possible hvc consoles.

    Signed-off-by: Bastian Blank <waldi@debian.org>

    diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
    index 44160d5..143a4b2 100644
    --- a/drivers/char/hvc_console.c
    +++ b/drivers/char/hvc_console.c
    @@ -137,15 +137,36 @@ static struct hvc_struct *hvc_get_by_index(int index)
    }


    +static void hvc_console_print(struct console *co, const char *b,
    + unsigned count);
    +static struct tty_driver *hvc_console_device(struct console *c, int *index);
    +static int __init hvc_console_setup(struct console *co, char *options);
    +
    /*
    * Initial console vtermnos for console API usage prior to full console
    * initialization. Any vty adapter outside this range will not have usable
    * console interfaces but can still be used as a tty device. This has to be
    * static because kmalloc will not work during early console init.
    */
    -static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
    -static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
    - {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
    +struct hvc_console
    +{
    + uint32_t vtermno;
    + struct hv_ops *ops;
    + struct console console;
    +};
    +static struct hvc_console consoles[MAX_NR_HVC_CONSOLES] = {
    + [0 ... MAX_NR_HVC_CONSOLES - 1] = {
    + .vtermno = -1,
    + .console = {
    + .name = "hvc",
    + .write = hvc_console_print,
    + .device = hvc_console_device,
    + .setup = hvc_console_setup,
    + .flags = CON_PRINTBUFFER,
    + .index = -1,
    + },
    + }
    +};

    /*
    * Console APIs, NOT TTY. These APIs are available immediately when
    @@ -164,7 +185,7 @@ static void hvc_console_print(struct console *co, const char *b,
    return;

    /* This console adapter was removed so it is not usable. */
    - if (vtermnos[index] < 0)
    + if (consoles[index].vtermno < 0)
    return;

    while (count > 0 || i > 0) {
    @@ -178,7 +199,7 @@ static void hvc_console_print(struct console *co, const char *b,
    --count;
    }
    } else {
    - r = cons_ops[index]->put_chars(vtermnos[index], c, i);
    + r = consoles[index].ops->put_chars(consoles[index].vtermno, c, i);
    if (r < 0) {
    /* throw away chars on error */
    i = 0;
    @@ -193,7 +214,7 @@ static void hvc_console_print(struct console *co, const char *b,

    static struct tty_driver *hvc_console_device(struct console *c, int *index)
    {
    - if (vtermnos[c->index] == -1)
    + if (consoles[c->index].vtermno == -1)
    return NULL;

    *index = c->index;
    @@ -205,43 +226,12 @@ static int __init hvc_console_setup(struct console *co, char *options)
    if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
    return -ENODEV;

    - if (vtermnos[co->index] == -1)
    + if (consoles[co->index].vtermno == -1)
    return -ENODEV;

    return 0;
    }

    -static struct console hvc_con_driver = {
    - .name = "hvc",
    - .write = hvc_console_print,
    - .device = hvc_console_device,
    - .setup = hvc_console_setup,
    - .flags = CON_PRINTBUFFER,
    - .index = -1,
    -};
    -
    -/*
    - * Early console initialization. Precedes driver initialization.
    - *
    - * (1) we are first, and the user specified another driver
    - * -- index will remain -1
    - * (2) we are first and the user specified no driver
    - * -- index will be set to 0, then we will fail setup.
    - * (3) we are first and the user specified our driver
    - * -- index will be set to user specified driver, and we will fail
    - * (4) we are after driver, and this initcall will register us
    - * -- if the user didn't specify a driver then the console will match
    - *
    - * Note that for cases 2 and 3, we will match later when the io driver
    - * calls hvc_instantiate() and call register again.
    - */
    -static int __init hvc_console_init(void)
    -{
    - register_console(&hvc_con_driver);
    - return 0;
    -}
    -console_initcall(hvc_console_init);
    -
    /* callback when the kboject ref count reaches zero. */
    static void destroy_hvc_struct(struct kref *kref)
    {
    @@ -267,12 +257,13 @@ static void destroy_hvc_struct(struct kref *kref)
    */
    int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
    {
    + struct hvc_console *hc;
    struct hvc_struct *hp;

    if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
    return -1;

    - if (vtermnos[index] != -1)
    + if (consoles[index].vtermno != -1)
    return -1;

    /* make sure no no tty has been registered in this index */
    @@ -282,19 +273,17 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
    return -1;
    }

    - vtermnos[index] = vtermno;
    - cons_ops[index] = ops;
    + hc = &consoles[index];
    +
    + hc->vtermno = vtermno;
    + hc->ops = ops;
    + hc->console.index = index;

    /* reserve all indices up to and including this index */
    if (last_hvc < index)
    last_hvc = index;

    - /* if this index is what the user requested, then register
    - * now (setup won't fail at this point). It's ok to just
    - * call register again if previously .setup failed.
    - */
    - if (index == hvc_con_driver.index)
    - register_console(&hvc_con_driver);
    + register_console(&hc->console);

    return 0;
    }
    @@ -637,7 +626,7 @@ static int hvc_poll(struct hvc_struct *hp)
    }
    for (i = 0; i < n; ++i) {
    #ifdef CONFIG_MAGIC_SYSRQ
    - if (hp->index == hvc_con_driver.index) {
    + if (consoles[hp->index].console.flags & CON_CONSDEV) {
    /* Handle the SysRq Hack */
    /* XXX should support a sequence */
    if (buf[i] == '\x0f') { /* ^O */
    @@ -775,8 +764,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
    * see if this vterm id matches one registered for console.
    */
    for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
    - if (vtermnos[i] == hp->vtermno &&
    - cons_ops[i] == hp->ops)
    + if (consoles[i].vtermno == hp->vtermno &&
    + consoles[i].ops == hp->ops)
    break;

    /* no matching slot, just use a counter */
    @@ -800,7 +789,7 @@ int __devexit hvc_remove(struct hvc_struct *hp)
    tty = hp->tty;

    if (hp->index < MAX_NR_HVC_CONSOLES)
    - vtermnos[hp->index] = -1;
    + consoles[hp->index].vtermno = -1;

    /* Don't whack hp->irq because tty_hangup() will need to free the irq. */

    @@ -881,13 +870,16 @@ out:
    */
    static void __exit hvc_exit(void)
    {
    + int i;
    +
    if (hvc_driver) {
    kthread_stop(hvc_task);

    tty_unregister_driver(hvc_driver);
    /* return tty_struct instances allocated in hvc_init(). */
    put_tty_driver(hvc_driver);
    - unregister_console(&hvc_con_driver);
    + for (i = 0; i < MAX_NR_HVC_CONSOLES; i++)
    + unregister_console(&consoles->console);
    }
    }
    module_exit(hvc_exit);
    --
    There is an order of things in this universe.
    -- Apollo, "Who Mourns for Adonais?" stardate 3468.1


    \
     
     \ /
      Last update: 2008-07-30 09:37    [W:0.030 / U:61.752 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site