X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fwan%2Fpc300_tty.c;h=931cbdf6d79165648e0a383235af4221c71581c6;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=d8e3f537c3ca0d9ac59956a02c2491c067b5d575;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index d8e3f537c..931cbdf6d 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -112,16 +112,15 @@ 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); @@ -133,9 +132,9 @@ 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; @@ -264,7 +264,7 @@ void cpc_tty_init(pc300dev_t *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); - 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; } @@ -688,28 +661,35 @@ static void cpc_tty_hangup(struct tty_struct *tty) */ static void cpc_tty_rx_work(void * data) { - int port, i, j; + unsigned long port; + int i, j; st_cpc_tty_area *cpc_tty; - volatile st_cpc_rx_buf * buf; + 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; + port = (unsigned long)data; 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 +708,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 +725,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 +753,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 +769,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 +782,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 = (st_cpc_rx_buf *)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 +815,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 +825,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 +843,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 +861,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; @@ -910,13 +893,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 +911,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 +928,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);