-static inline int __hvc_write_user(struct hvc_struct *hp,
- const unsigned char *buf, int count)
-{
- char *tbuf, *p;
- int tbsize, rsize, written = 0;
- unsigned long flags;
-
- tbsize = min(count, (int)PAGE_SIZE);
- if (!(tbuf = kmalloc(tbsize, GFP_KERNEL)))
- return -ENOMEM;
-
- while ((rsize = count - written) > 0) {
- int wsize;
- if (rsize > tbsize)
- rsize = tbsize;
-
- p = tbuf;
- rsize -= copy_from_user(p, buf, rsize);
- if (!rsize) {
- if (written == 0)
- written = -EFAULT;
- break;
- }
- buf += rsize;
-
- spin_lock_irqsave(&hp->lock, flags);
-
- /* Push pending writes: make some room in buffer */
- if (hp->n_outbuf > 0)
- hvc_push(hp);
-
- for (wsize = N_OUTBUF - hp->n_outbuf; rsize && wsize;
- wsize = N_OUTBUF - hp->n_outbuf) {
- if (wsize > rsize)
- wsize = rsize;
- memcpy(hp->outbuf + hp->n_outbuf, p, wsize);
- hp->n_outbuf += wsize;
- hvc_push(hp);
- rsize -= wsize;
- p += wsize;
- written += wsize;
- }
- spin_unlock_irqrestore(&hp->lock, flags);
-
- if (rsize)
- break;
-
- if (count < tbsize)
- tbsize = count;
- }
-
- kfree(tbuf);
-
- return written;
-}
-