#include <linux/serialP.h>
#include <linux/console.h>
#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/semaphore.h>
+#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
local_irq_restore(flags);
}
-static int mcfrs_write(struct tty_struct * tty,
+static int mcfrs_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
volatile unsigned char *uartp;
int c, total = 0;
#if 0
- printk("%s(%d): mcfrs_write(tty=%x,buf=%x,count=%d)\n",
- __FILE__, __LINE__, (int)tty, (int)buf, count);
+ printk("%s(%d): mcfrs_write(tty=%x,from_user=%d,buf=%x,count=%d)\n",
+ __FILE__, __LINE__, (int)tty, from_user, (int)buf, count);
#endif
if (serial_paranoia_check(info, tty->name, "mcfrs_write"))
if (c <= 0)
break;
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ if (from_user) {
+ down(&mcfrs_tmp_buf_sem);
+ if (copy_from_user(mcfrs_tmp_buf, buf, c))
+ return -EFAULT;
+
+ local_irq_disable();
+ c = min(c, (int) min(((int)SERIAL_XMIT_SIZE) - info->xmit_cnt - 1,
+ ((int)SERIAL_XMIT_SIZE) - info->xmit_head));
+ local_irq_restore(flags);
+ memcpy(info->xmit_buf + info->xmit_head, mcfrs_tmp_buf, c);
+ up(&mcfrs_tmp_buf_sem);
+ } else
+ memcpy(info->xmit_buf + info->xmit_head, buf, c);
local_irq_disable();
info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
if (!info->addr)
return;
- set_current_state(TASK_INTERRUPTIBLE);
+ current->state = TASK_INTERRUPTIBLE;
uartp = info->addr;
local_irq_save(flags);
#endif
if (info->blocked_open) {
if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(info->close_delay);
}
wake_up_interruptible(&info->open_wait);
}
fifo_cnt++;
if (fifo_cnt == 0)
break;
- msleep_interruptible(jiffies_to_msecs(char_time));
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(char_time);
if (signal_pending(current))
break;
if (timeout && time_after(jiffies, orig_jiffies + timeout))