#include <asm/io.h>
#include <asm/irq.h>
#include <asm/dma.h>
-#include <linux/bitops.h>
+#include <asm/bitops.h>
#include <asm/types.h>
#include <linux/termios.h>
#include <linux/workqueue.h>
* Arguments:
*
* tty pointer to tty information structure
+ * from_user flag: 1 = from user process
* buf pointer to buffer containing send data
* count size of send data in bytes
*
* Returns: number of characters written
*/
-static int mgslpc_write(struct tty_struct * tty,
+static int mgslpc_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
- int c, ret = 0;
+ int c, ret = 0, err;
MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
unsigned long flags;
if (c <= 0)
break;
- memcpy(info->tx_buf + info->tx_put, buf, c);
+ if (from_user) {
+ COPY_FROM_USER(err, info->tx_buf + info->tx_put, buf, c);
+ if (err) {
+ if (!ret)
+ ret = -EFAULT;
+ break;
+ }
+ } else
+ memcpy(info->tx_buf + info->tx_put, buf, c);
spin_lock_irqsave(&info->lock,flags);
info->tx_put = (info->tx_put + c) & (TXBUFSIZE-1);
if (info->blocked_open) {
if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(info->close_delay);
}
wake_up_interruptible(&info->open_wait);
}
if (info->params.mode == MGSL_MODE_HDLC) {
while (info->tx_active) {
- 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))
} else {
while ((info->tx_count || info->tx_active) &&
info->tx_enabled) {
- 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))
end_time=100;
while(end_time-- && !info->irq_occurred) {
- msleep_interruptible(10);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(10));
}
info->testing_irq = FALSE;
memcpy(skb_put(skb, size),buf,size);
- skb->protocol = hdlc_type_trans(skb, info->netdev);
+ skb->dev = info->netdev;
+ skb->mac.raw = skb->data;
+ skb->protocol = hdlc_type_trans(skb, skb->dev);
stats->rx_packets++;
stats->rx_bytes += size;