fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / wan / pc300_tty.c
index d8e3f53..5873c34 100644 (file)
@@ -112,30 +112,29 @@ typedef   struct _st_cpc_tty_area {
 static struct tty_driver serial_drv;
 
 /* local variables */
-st_cpc_tty_area        cpc_tty_area[CPC_TTY_NPORTS];
+static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
 
-int cpc_tty_cnt=0;     /* number of intrfaces configured with MLPPP */
-int cpc_tty_unreg_flag = 0;
+static int cpc_tty_cnt = 0;    /* number of intrfaces configured with MLPPP */
+static 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, int from_user,
-                               const unsigned char *buf, int count);
+static int cpc_tty_write(struct tty_struct *tty, 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);
 static void cpc_tty_hangup(struct tty_struct *tty);
-static void cpc_tty_rx_work(void *data);
-static void cpc_tty_tx_work(void *data);
+static void cpc_tty_rx_work(struct work_struct *work);
+static void cpc_tty_tx_work(struct work_struct *work);
 static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
 static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
 static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
 static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
 
-int pc300_tiocmset(struct tty_struct *, struct file *,
-                       unsigned int, unsigned int);
-int pc300_tiocmget(struct tty_struct *, struct file *);
+static int pc300_tiocmset(struct tty_struct *, struct file *,
+                         unsigned int, unsigned int);
+static int pc300_tiocmget(struct tty_struct *, struct file *);
 
 /* functions called by PC300 driver */
 void cpc_tty_init(pc300dev_t *dev);
@@ -192,13 +191,14 @@ static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal)
  */
 void cpc_tty_init(pc300dev_t *pc300dev)
 {
-       int port, aux;
+       unsigned long port;
+       int aux;
        st_cpc_tty_area * cpc_tty;
 
        /* hdlcX - X=interface number */
        port = pc300dev->dev->name[4] - '0';
        if (port >= CPC_TTY_NPORTS) {
-               printk("%s-tty: invalid interface selected (0-%i): %i", 
+               printk("%s-tty: invalid interface selected (0-%i): %li",
                        pc300dev->dev->name,
                        CPC_TTY_NPORTS-1,port);
                return;
@@ -261,10 +261,10 @@ void cpc_tty_init(pc300dev_t *pc300dev)
        cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
        cpc_tty->pc300dev = pc300dev; 
 
-       INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work, (void *)cpc_tty);
-       INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work, (void *)port);
+       INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work);
+       INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work);
        
-       cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = 0;
+       cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL;
 
        pc300dev->cpc_tty = (void *)cpc_tty; 
        
@@ -400,10 +400,8 @@ static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
                cpc_tty->buf_rx.last = NULL;
        }
        
-       if (cpc_tty->buf_tx) {
-               kfree(cpc_tty->buf_tx);
-               cpc_tty->buf_tx = NULL;
-       }
+       kfree(cpc_tty->buf_tx);
+       cpc_tty->buf_tx = NULL;
 
        CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
        
@@ -426,8 +424,7 @@ 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, int from_user,
-                       const unsigned char *buf, int count)
+static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
        st_cpc_tty_area    *cpc_tty; 
        pc300ch_t *pc300chan; 
@@ -453,8 +450,7 @@ static int cpc_tty_write(struct tty_struct *tty, int from_user,
                return -EINVAL;        /* frame too big */ 
        }
 
-       CPC_TTY_DBG("%s: cpc_tty_write %s data len=%i\n",cpc_tty->name,
-               (from_user)?"from user" : "from kernel",count);
+       CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
        
        pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
        stats = hdlc_stats(((pc300dev_t*)cpc_tty->pc300dev)->dev);
@@ -481,27 +477,10 @@ static int cpc_tty_write(struct tty_struct *tty, int from_user,
                return -EINVAL; 
        }
 
-       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;
-               }
+       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; 
 } 
@@ -559,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
        return(0); 
 } 
 
-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
-                       unsigned int set, unsigned int clear)
+static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+                         unsigned int set, unsigned int clear)
 {
        st_cpc_tty_area    *cpc_tty; 
 
@@ -586,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
 {
        unsigned int result;
        unsigned char status;
@@ -634,14 +613,8 @@ static void cpc_tty_flush_buffer(struct tty_struct *tty)
        }
 
        CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);
-       
-       wake_up_interruptible(&tty->write_wait); 
-
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
-               CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name);
-               tty->ldisc.write_wakeup(tty); 
-       } 
 
+       tty_wakeup(tty);        
        return; 
 } 
 
@@ -686,30 +659,39 @@ static void cpc_tty_hangup(struct tty_struct *tty)
  * o call the line disc. read
  * o free memory
  */
-static void cpc_tty_rx_work(void * data)
+static void cpc_tty_rx_work(struct work_struct *work)
 {
-       int port, i, j;
-       st_cpc_tty_area *cpc_tty; 
-       volatile st_cpc_rx_buf * buf;
+       st_cpc_tty_area *cpc_tty;
+       unsigned long port;
+       int i, j;
+       volatile st_cpc_rx_buf *buf;
        char flags=0,flg_rx=1; 
+       struct tty_ldisc *ld;
 
        if (cpc_tty_cnt == 0) return;
-
+       
        for (i=0; (i < 4) && flg_rx ; i++) {
                flg_rx = 0;
-               port = (int) data;
+
+               cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work);
+               port = cpc_tty - cpc_tty_area;
+
                for (j=0; j < CPC_TTY_NPORTS; j++) {
                        cpc_tty = &cpc_tty_area[port];
                
                        if ((buf=cpc_tty->buf_rx.first) != 0) {
-                                                                                                                       
-                               if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { 
-                                       CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
-                                       cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, (char *)(buf->data), 
-                                       &flags, buf->size);
+                               if (cpc_tty->tty) {
+                                       ld = tty_ldisc_ref(cpc_tty->tty);
+                                       if (ld) {
+                                               if (ld->receive_buf) {
+                                                       CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
+                                                       ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
+                                               }
+                                               tty_ldisc_deref(ld);
+                                       }
                                }       
                                cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
-                               kfree((unsigned char *)buf);
+                               kfree((void *)buf);
                                buf = cpc_tty->buf_rx.first;
                                flg_rx = 1;
                        }
@@ -728,13 +710,13 @@ static void cpc_tty_rx_work(void * data)
  */
 static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
 {
-       volatile pcsca_bd_t * ptdescr; 
+       volatile pcsca_bd_t __iomem * ptdescr; 
        volatile unsigned char status; 
        pc300_t *card = (pc300_t *)pc300chan->card; 
        int ch = pc300chan->channel; 
 
        /* dma buf read */ 
-       ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+       ptdescr = (pcsca_bd_t __iomem *)(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); 
@@ -745,22 +727,22 @@ static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
                if (status & DST_EOM) { 
                        break; /* end of message */
                }
-               ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
+               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
        }
 }
 
 void cpc_tty_receive(pc300dev_t *pc300dev)
 {
-       st_cpc_tty_area    *cpc_tty; 
+       st_cpc_tty_area *cpc_tty; 
        pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
        pc300_t *card = (pc300_t *)pc300chan->card; 
        int ch = pc300chan->channel; 
-       volatile pcsca_bd_t * ptdescr; 
+       volatile pcsca_bd_t  __iomem * ptdescr; 
        struct net_device_stats *stats = hdlc_stats(pc300dev->dev);
        int rx_len, rx_aux; 
        volatile unsigned char status; 
        unsigned short first_bd = pc300chan->rx_first_bd;
-       st_cpc_rx_buf   *new;
+       st_cpc_rx_buf *new = NULL;
        unsigned char dsr_rx;
 
        if (pc300dev->cpc_tty == NULL) { 
@@ -773,14 +755,14 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
 
        while (1) { 
                rx_len = 0;
-               ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
+               ptdescr = (pcsca_bd_t  __iomem *)(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*)(card->hw.rambase+cpc_readl(&ptdescr->next));
+                       ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next));
                }
                        
                if (!rx_len) { 
@@ -789,6 +771,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
                                                RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
                        }
+                       kfree(new);
                        return; 
                }
                
@@ -801,14 +784,14 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        continue;
                } 
                
-               new = (st_cpc_rx_buf *) kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+               new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
                if (new == 0) {
                        cpc_tty_rx_disc_frame(pc300chan);
                        continue;
                }
                
                /* dma buf read */ 
-               ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+               ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + 
                                RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
 
                rx_len = 0;     /* counter frame size */
@@ -834,7 +817,8 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                                cpc_tty->name);
                                cpc_tty_rx_disc_frame(pc300chan);
                                rx_len = 0;
-                               kfree((unsigned char *)new);
+                               kfree(new);
+                               new = NULL;
                                break; /* read next frame - while(1) */
                        }
 
@@ -843,14 +827,15 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                cpc_tty_rx_disc_frame(pc300chan);
                                stats->rx_dropped++; 
                                rx_len = 0; 
-                               kfree((unsigned char *)new);
+                               kfree(new);
+                               new = NULL;
                                break; /* read next frame - while(1) */
                        }
 
                        /* read the segment of the frame */
                        if (rx_aux != 0) {
                                memcpy_fromio((new->data + rx_len), 
-                                       (void *)(card->hw.rambase + 
+                                       (void __iomem *)(card->hw.rambase + 
                                         cpc_readl(&ptdescr->ptbuf)), rx_aux);
                                rx_len += rx_aux; 
                        }
@@ -860,7 +845,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                        (N_DMA_RX_BUF -1); 
                        if (status & DST_EOM)break;
                        
-                       ptdescr = (pcsca_bd_t *) (card->hw.rambase + 
+                       ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + 
                                        cpc_readl(&ptdescr->next)); 
                }
                /* update pointer */ 
@@ -878,7 +863,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                                cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); 
                        } 
                        new->size = rx_len;
-                       new->next = 0;
+                       new->next = NULL;
                        if (cpc_tty->buf_rx.first == 0) {
                                cpc_tty->buf_rx.first = new;
                                cpc_tty->buf_rx.last = new;
@@ -899,9 +884,10 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
  * o if need call line discipline wakeup
  * o call wake_up_interruptible
  */
-static void cpc_tty_tx_work(void *data)
+static void cpc_tty_tx_work(struct work_struct *work)
 {
-       st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data; 
+       st_cpc_tty_area *cpc_tty =
+               container_of(work, st_cpc_tty_area, tty_tx_work);
        struct tty_struct *tty; 
 
        CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
@@ -910,13 +896,7 @@ static void cpc_tty_tx_work(void *data)
                CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
                return; 
        }
-
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
-               CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name);
-               tty->ldisc.write_wakeup (tty); 
-       }
-
-       wake_up_interruptible(&tty->write_wait); 
+       tty_wakeup(tty);
 }
 
 /*
@@ -934,7 +914,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 ptdescr; 
+       volatile pcsca_bd_t __iomem *ptdescr; 
        int i, nchar;
        int tosend = len;
        int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
@@ -951,11 +931,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 *)(card->hw.rambase + 
+               ptdescr = (pcsca_bd_t __iomem *)(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 *)(card->hw.rambase + 
+                       memcpy_toio((void __iomem *)(card->hw.rambase + 
                                cpc_readl(&ptdescr->ptbuf)), 
                                &pdata[len - tosend], 
                                nchar);