X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Fhvc_console.c;h=a76d2c40dd5e7e5e375a9a39054333c3752fdafa;hb=0a4254058037eb172758961d0a5b94f4320a1425;hp=2b6a56b2bf35c78b53153d87b032c720b5b0b004;hpb=95d465fd750897ab32462a6702fbfe1b122cbbc0;p=linux-2.6 diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 2b6a56b2bf..a76d2c40dd 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -22,7 +22,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -81,7 +80,8 @@ struct hvc_struct { struct tty_struct *tty; unsigned int count; int do_wakeup; - char outbuf[N_OUTBUF] __ALIGNED__; + char *outbuf; + int outbuf_size; int n_outbuf; uint32_t vtermno; struct hv_ops *ops; @@ -320,10 +320,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) struct kobject *kobjp; /* Auto increments kobject reference if found. */ - if (!(hp = hvc_get_by_index(tty->index))) { - printk(KERN_WARNING "hvc_console: tty open failed, no vty associated with tty.\n"); + if (!(hp = hvc_get_by_index(tty->index))) return -ENODEV; - } spin_lock_irqsave(&hp->lock, flags); /* Check and then increment for fast path open. */ @@ -347,7 +345,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) spin_unlock_irqrestore(&hp->lock, flags); /* check error, fallback to non-irq */ if (irq != NO_IRQ) - rc = request_irq(irq, hvc_handle_interrupt, SA_INTERRUPT, "hvc_console", hp); + rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp); /* * If the request_irq() fails and we return an error. The tty layer @@ -506,7 +504,7 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count if (hp->n_outbuf > 0) hvc_push(hp); - while (count > 0 && (rsize = N_OUTBUF - hp->n_outbuf) > 0) { + while (count > 0 && (rsize = hp->outbuf_size - hp->n_outbuf) > 0) { if (rsize > count) rsize = count; memcpy(hp->outbuf + hp->n_outbuf, buf, rsize); @@ -539,7 +537,7 @@ static int hvc_write_room(struct tty_struct *tty) if (!hp) return -1; - return N_OUTBUF - hp->n_outbuf; + return hp->outbuf_size - hp->n_outbuf; } static int hvc_chars_in_buffer(struct tty_struct *tty) @@ -553,7 +551,6 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) #define HVC_POLL_READ 0x00000001 #define HVC_POLL_WRITE 0x00000002 -#define HVC_POLL_QUICK 0x00000004 static int hvc_poll(struct hvc_struct *hp) { @@ -568,6 +565,7 @@ static int hvc_poll(struct hvc_struct *hp) /* Push pending writes */ if (hp->n_outbuf > 0) hvc_push(hp); + /* Reschedule us if still some write pending */ if (hp->n_outbuf > 0) poll_mask |= HVC_POLL_WRITE; @@ -669,6 +667,7 @@ int khvcd(void *unused) do { poll_mask = 0; hvc_kicked = 0; + try_to_freeze(); wmb(); if (cpus_empty(cpus_in_xmon)) { spin_lock(&hvc_structs_lock); @@ -680,7 +679,7 @@ int khvcd(void *unused) poll_mask |= HVC_POLL_READ; if (hvc_kicked) continue; - if (poll_mask & HVC_POLL_QUICK) { + if (poll_mask & HVC_POLL_WRITE) { yield(); continue; } @@ -729,12 +728,13 @@ static struct kobj_type hvc_kobj_type = { }; struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, - struct hv_ops *ops) + struct hv_ops *ops, int outbuf_size) { struct hvc_struct *hp; int i; - hp = kmalloc(sizeof(*hp), GFP_KERNEL); + hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size, + GFP_KERNEL); if (!hp) return ERR_PTR(-ENOMEM); @@ -743,6 +743,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, hp->vtermno = vtermno; hp->irq = irq; hp->ops = ops; + hp->outbuf_size = outbuf_size; + hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; kobject_init(&hp->kobj); hp->kobj.ktype = &hvc_kobj_type; @@ -820,7 +822,6 @@ int __init hvc_init(void) return -ENOMEM; drv->owner = THIS_MODULE; - drv->devfs_name = "hvc/"; drv->driver_name = "hvc"; drv->name = "hvc"; drv->major = HVC_MAJOR;