This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / net / wan / pc300_tty.c
index 29f84ad..9e50d5d 100644 (file)
@@ -120,7 +120,8 @@ int cpc_tty_unreg_flag = 0;
 /* TTY functions prototype */
 static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
 static void cpc_tty_close(struct tty_struct *tty, struct file *flip);
-static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
+static int cpc_tty_write(struct tty_struct *tty, int from_user,
+                               const unsigned char *buf, int count);
 static int cpc_tty_write_room(struct tty_struct *tty);
 static int cpc_tty_chars_in_buffer(struct tty_struct *tty);
 static void cpc_tty_flush_buffer(struct tty_struct *tty);
@@ -426,7 +427,8 @@ static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
  * o verify the DCD signal
  * o send characters to board and start the transmission
  */
-static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static int cpc_tty_write(struct tty_struct *tty, int from_user,
+                       const unsigned char *buf, int count)
 {
        st_cpc_tty_area    *cpc_tty; 
        pc300ch_t *pc300chan; 
@@ -452,7 +454,8 @@ static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
                return -EINVAL;        /* frame too big */ 
        }
 
-       CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
+       CPC_TTY_DBG("%s: cpc_tty_write %s data len=%i\n",cpc_tty->name,
+               (from_user)?"from user" : "from kernel",count);
        
        pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
        stats = hdlc_stats(((pc300dev_t*)cpc_tty->pc300dev)->dev);
@@ -479,10 +482,27 @@ static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
                return -EINVAL; 
        }
 
-       if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
-          /* failed to send */
-          CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
-          return 0;
+       if (from_user) { 
+               unsigned char *buf_tmp; 
+
+               buf_tmp = cpc_tty->buf_tx;
+               if (copy_from_user(buf_tmp, buf, count)) { 
+                       /* failed to copy from user */
+                       CPC_TTY_DBG("%s: error in copy from user\n",cpc_tty->name);
+                       return -EINVAL; 
+               }
+
+               if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*) buf_tmp,count)) { 
+                       /* failed to send */ 
+                       CPC_TTY_DBG("%s: transmission error\n",cpc_tty->name);
+                       return 0; 
+               }
+       } else {
+               if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
+                  /* failed to send */
+                  CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
+                  return 0;
+               }
        }
        return count; 
 } 
@@ -710,13 +730,13 @@ static void cpc_tty_rx_work(void * data)
  */
 static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
 {
-       volatile pcsca_bd_t __iomem * ptdescr; 
+       volatile pcsca_bd_t * ptdescr; 
        volatile unsigned char status; 
        pc300_t *card = (pc300_t *)pc300chan->card; 
        int ch = pc300chan->channel; 
 
        /* dma buf read */ 
-       ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
+       ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
                                RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
        while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { 
                status = cpc_readb(&ptdescr->status); 
@@ -727,7 +747,7 @@ static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
                if (status & DST_EOM) { 
                        break; /* end of message */
                }
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
+               ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
        }
 }
 
@@ -737,7 +757,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
        pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
        pc300_t *card = (pc300_t *)pc300chan->card; 
        int ch = pc300chan->channel; 
-       volatile pcsca_bd_t  __iomem * ptdescr; 
+       volatile pcsca_bd_t * ptdescr; 
        struct net_device_stats *stats = hdlc_stats(pc300dev->dev);
        int rx_len, rx_aux; 
        volatile unsigned char status; 
@@ -755,14 +775,14 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
 
        while (1) { 
                rx_len = 0;
-               ptdescr = (pcsca_bd_t  __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
+               ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
                while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
                        rx_len += cpc_readw(&ptdescr->len);
                        first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
                        if (status & DST_EOM) {
                                break;
                        }
-                       ptdescr=(pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
+                       ptdescr=(pcsca_bd_t*)(card->hw.rambase+cpc_readl(&ptdescr->next));
                }
                        
                if (!rx_len) { 
@@ -794,7 +814,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                }
                
                /* dma buf read */ 
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
+               ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
                                RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
 
                rx_len = 0;     /* counter frame size */
@@ -838,7 +858,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        /* read the segment of the frame */
                        if (rx_aux != 0) {
                                memcpy_fromio((new->data + rx_len), 
-                                       (void __iomem *)(card->hw.rambase + 
+                                       (void *)(card->hw.rambase + 
                                         cpc_readl(&ptdescr->ptbuf)), rx_aux);
                                rx_len += rx_aux; 
                        }
@@ -848,7 +868,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                        (N_DMA_RX_BUF -1); 
                        if (status & DST_EOM)break;
                        
-                       ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + 
+                       ptdescr = (pcsca_bd_t *) (card->hw.rambase + 
                                        cpc_readl(&ptdescr->next)); 
                }
                /* update pointer */ 
@@ -916,7 +936,7 @@ static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
        int ch = chan->channel; 
        struct net_device_stats *stats = hdlc_stats(dev->dev);
        unsigned long flags; 
-       volatile pcsca_bd_t __iomem *ptdescr; 
+       volatile pcsca_bd_t ptdescr; 
        int i, nchar;
        int tosend = len;
        int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
@@ -933,11 +953,11 @@ static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
        CPC_TTY_DBG("%s: call dma_buf_write\n",
                        (st_cpc_tty_area *)dev->cpc_tty->name); 
        for (i = 0 ; i < nbuf ; i++) {
-               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
+               ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
                        TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
                nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN;
                if (cpc_readb(&ptdescr->status) & DST_OSB) {
-                       memcpy_toio((void __iomem *)(card->hw.rambase + 
+                       memcpy_toio((void *)(card->hw.rambase + 
                                cpc_readl(&ptdescr->ptbuf)), 
                                &pdata[len - tosend], 
                                nchar);