aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorPaul Fulghum <paulkf@microgate.com>2006-10-01 02:27:45 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:22 -0400
commitcb10dc9ac7eea2c891df6b79b9ef1fbe59cb5429 (patch)
tree68afaa1be814d2845c1f516920a48cc59270fa0c /drivers/char
parent3c1fcfe229e99752c74efb945a4a3f560be04204 (diff)
[PATCH] synclink_gt: add bisync and monosync modes
Add bisync and monosync serial protocol support to the synclink_gt driver. Signed-off-by: Paul Fulghum <paulkf@microgate.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/synclink_gt.c88
1 files changed, 63 insertions, 25 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 2f07b085536b..bd3821679ac8 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -461,7 +461,7 @@ static int adapter_test(struct slgt_info *info);
461static void reset_adapter(struct slgt_info *info); 461static void reset_adapter(struct slgt_info *info);
462static void reset_port(struct slgt_info *info); 462static void reset_port(struct slgt_info *info);
463static void async_mode(struct slgt_info *info); 463static void async_mode(struct slgt_info *info);
464static void hdlc_mode(struct slgt_info *info); 464static void sync_mode(struct slgt_info *info);
465 465
466static void rx_stop(struct slgt_info *info); 466static void rx_stop(struct slgt_info *info);
467static void rx_start(struct slgt_info *info); 467static void rx_start(struct slgt_info *info);
@@ -881,7 +881,9 @@ static int write(struct tty_struct *tty,
881 if (!count) 881 if (!count)
882 goto cleanup; 882 goto cleanup;
883 883
884 if (info->params.mode == MGSL_MODE_RAW) { 884 if (info->params.mode == MGSL_MODE_RAW ||
885 info->params.mode == MGSL_MODE_MONOSYNC ||
886 info->params.mode == MGSL_MODE_BISYNC) {
885 unsigned int bufs_needed = (count/DMABUFSIZE); 887 unsigned int bufs_needed = (count/DMABUFSIZE);
886 unsigned int bufs_free = free_tbuf_count(info); 888 unsigned int bufs_free = free_tbuf_count(info);
887 if (count % DMABUFSIZE) 889 if (count % DMABUFSIZE)
@@ -1897,6 +1899,8 @@ static void bh_handler(void* context)
1897 while(rx_get_frame(info)); 1899 while(rx_get_frame(info));
1898 break; 1900 break;
1899 case MGSL_MODE_RAW: 1901 case MGSL_MODE_RAW:
1902 case MGSL_MODE_MONOSYNC:
1903 case MGSL_MODE_BISYNC:
1900 while(rx_get_buf(info)); 1904 while(rx_get_buf(info));
1901 break; 1905 break;
1902 } 1906 }
@@ -2362,10 +2366,9 @@ static void program_hw(struct slgt_info *info)
2362 rx_stop(info); 2366 rx_stop(info);
2363 tx_stop(info); 2367 tx_stop(info);
2364 2368
2365 if (info->params.mode == MGSL_MODE_HDLC || 2369 if (info->params.mode != MGSL_MODE_ASYNC ||
2366 info->params.mode == MGSL_MODE_RAW ||
2367 info->netcount) 2370 info->netcount)
2368 hdlc_mode(info); 2371 sync_mode(info);
2369 else 2372 else
2370 async_mode(info); 2373 async_mode(info);
2371 2374
@@ -2564,6 +2567,10 @@ static int rx_enable(struct slgt_info *info, int enable)
2564 if (enable) { 2567 if (enable) {
2565 if (!info->rx_enabled) 2568 if (!info->rx_enabled)
2566 rx_start(info); 2569 rx_start(info);
2570 else if (enable == 2) {
2571 /* force hunt mode (write 1 to RCR[3]) */
2572 wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3);
2573 }
2567 } else { 2574 } else {
2568 if (info->rx_enabled) 2575 if (info->rx_enabled)
2569 rx_stop(info); 2576 rx_stop(info);
@@ -3748,7 +3755,7 @@ static void tx_start(struct slgt_info *info)
3748{ 3755{
3749 if (!info->tx_enabled) { 3756 if (!info->tx_enabled) {
3750 wr_reg16(info, TCR, 3757 wr_reg16(info, TCR,
3751 (unsigned short)(rd_reg16(info, TCR) | BIT1)); 3758 (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2));
3752 info->tx_enabled = TRUE; 3759 info->tx_enabled = TRUE;
3753 } 3760 }
3754 3761
@@ -3775,13 +3782,18 @@ static void tx_start(struct slgt_info *info)
3775 tdma_reset(info); 3782 tdma_reset(info);
3776 /* set 1st descriptor address */ 3783 /* set 1st descriptor address */
3777 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); 3784 wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
3778 if (info->params.mode == MGSL_MODE_RAW) 3785 switch(info->params.mode) {
3786 case MGSL_MODE_RAW:
3787 case MGSL_MODE_MONOSYNC:
3788 case MGSL_MODE_BISYNC:
3779 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ 3789 wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
3780 else 3790 break;
3791 default:
3781 wr_reg32(info, TDCSR, BIT0); /* DMA enable */ 3792 wr_reg32(info, TDCSR, BIT0); /* DMA enable */
3793 }
3782 } 3794 }
3783 3795
3784 if (info->params.mode != MGSL_MODE_RAW) { 3796 if (info->params.mode == MGSL_MODE_HDLC) {
3785 info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); 3797 info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
3786 add_timer(&info->tx_timer); 3798 add_timer(&info->tx_timer);
3787 } 3799 }
@@ -3814,7 +3826,6 @@ static void tx_stop(struct slgt_info *info)
3814 /* reset and disable transmitter */ 3826 /* reset and disable transmitter */
3815 val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ 3827 val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */
3816 wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ 3828 wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
3817 wr_reg16(info, TCR, val); /* clear reset */
3818 3829
3819 slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); 3830 slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
3820 3831
@@ -3982,7 +3993,7 @@ static void async_mode(struct slgt_info *info)
3982 enable_loopback(info); 3993 enable_loopback(info);
3983} 3994}
3984 3995
3985static void hdlc_mode(struct slgt_info *info) 3996static void sync_mode(struct slgt_info *info)
3986{ 3997{
3987 unsigned short val; 3998 unsigned short val;
3988 3999
@@ -3992,7 +4003,7 @@ static void hdlc_mode(struct slgt_info *info)
3992 4003
3993 /* TCR (tx control) 4004 /* TCR (tx control)
3994 * 4005 *
3995 * 15..13 mode, 000=HDLC 001=raw sync 4006 * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
3996 * 12..10 encoding 4007 * 12..10 encoding
3997 * 09 CRC enable 4008 * 09 CRC enable
3998 * 08 CRC32 4009 * 08 CRC32
@@ -4006,8 +4017,11 @@ static void hdlc_mode(struct slgt_info *info)
4006 */ 4017 */
4007 val = 0; 4018 val = 0;
4008 4019
4009 if (info->params.mode == MGSL_MODE_RAW) 4020 switch(info->params.mode) {
4010 val |= BIT13; 4021 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
4022 case MGSL_MODE_BISYNC: val |= BIT15; break;
4023 case MGSL_MODE_RAW: val |= BIT13; break;
4024 }
4011 if (info->if_mode & MGSL_INTERFACE_RTS_EN) 4025 if (info->if_mode & MGSL_INTERFACE_RTS_EN)
4012 val |= BIT7; 4026 val |= BIT7;
4013 4027
@@ -4058,7 +4072,7 @@ static void hdlc_mode(struct slgt_info *info)
4058 4072
4059 /* RCR (rx control) 4073 /* RCR (rx control)
4060 * 4074 *
4061 * 15..13 mode, 000=HDLC 001=raw sync 4075 * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync
4062 * 12..10 encoding 4076 * 12..10 encoding
4063 * 09 CRC enable 4077 * 09 CRC enable
4064 * 08 CRC32 4078 * 08 CRC32
@@ -4069,8 +4083,11 @@ static void hdlc_mode(struct slgt_info *info)
4069 */ 4083 */
4070 val = 0; 4084 val = 0;
4071 4085
4072 if (info->params.mode == MGSL_MODE_RAW) 4086 switch(info->params.mode) {
4073 val |= BIT13; 4087 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
4088 case MGSL_MODE_BISYNC: val |= BIT15; break;
4089 case MGSL_MODE_RAW: val |= BIT13; break;
4090 }
4074 4091
4075 switch(info->params.encoding) 4092 switch(info->params.encoding)
4076 { 4093 {
@@ -4309,10 +4326,15 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
4309 while(!done) { 4326 while(!done) {
4310 /* reset current buffer for reuse */ 4327 /* reset current buffer for reuse */
4311 info->rbufs[i].status = 0; 4328 info->rbufs[i].status = 0;
4312 if (info->params.mode == MGSL_MODE_RAW) 4329 switch(info->params.mode) {
4330 case MGSL_MODE_RAW:
4331 case MGSL_MODE_MONOSYNC:
4332 case MGSL_MODE_BISYNC:
4313 set_desc_count(info->rbufs[i], info->raw_rx_size); 4333 set_desc_count(info->rbufs[i], info->raw_rx_size);
4314 else 4334 break;
4335 default:
4315 set_desc_count(info->rbufs[i], DMABUFSIZE); 4336 set_desc_count(info->rbufs[i], DMABUFSIZE);
4337 }
4316 4338
4317 if (i == last) 4339 if (i == last)
4318 done = 1; 4340 done = 1;
@@ -4477,13 +4499,24 @@ cleanup:
4477static int rx_get_buf(struct slgt_info *info) 4499static int rx_get_buf(struct slgt_info *info)
4478{ 4500{
4479 unsigned int i = info->rbuf_current; 4501 unsigned int i = info->rbuf_current;
4502 unsigned int count;
4480 4503
4481 if (!desc_complete(info->rbufs[i])) 4504 if (!desc_complete(info->rbufs[i]))
4482 return 0; 4505 return 0;
4483 DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx"); 4506 count = desc_count(info->rbufs[i]);
4484 DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i]))); 4507 switch(info->params.mode) {
4485 ldisc_receive_buf(info->tty, info->rbufs[i].buf, 4508 case MGSL_MODE_MONOSYNC:
4486 info->flag_buf, desc_count(info->rbufs[i])); 4509 case MGSL_MODE_BISYNC:
4510 /* ignore residue in byte synchronous modes */
4511 if (desc_residue(info->rbufs[i]))
4512 count--;
4513 break;
4514 }
4515 DBGDATA(info, info->rbufs[i].buf, count, "rx");
4516 DBGINFO(("rx_get_buf size=%d\n", count));
4517 if (count)
4518 ldisc_receive_buf(info->tty, info->rbufs[i].buf,
4519 info->flag_buf, count);
4487 free_rbufs(info, i, i); 4520 free_rbufs(info, i, i);
4488 return 1; 4521 return 1;
4489} 4522}
@@ -4549,8 +4582,13 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
4549 size -= count; 4582 size -= count;
4550 buf += count; 4583 buf += count;
4551 4584
4552 if (!size && info->params.mode != MGSL_MODE_RAW) 4585 /*
4553 set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */ 4586 * set EOF bit for last buffer of HDLC frame or
4587 * for every buffer in raw mode
4588 */
4589 if ((!size && info->params.mode == MGSL_MODE_HDLC) ||
4590 info->params.mode == MGSL_MODE_RAW)
4591 set_desc_eof(*d, 1);
4554 else 4592 else
4555 set_desc_eof(*d, 0); 4593 set_desc_eof(*d, 0);
4556 4594