diff options
author | Dave Jones <davej@redhat.com> | 2006-12-12 18:13:32 -0500 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2006-12-12 18:13:32 -0500 |
commit | f0eef25339f92f7cd4aeea23d9ae97987a5a1e82 (patch) | |
tree | 2472e94d39f43a9580a6d2d5d92de0b749023263 /drivers/char/synclink_gt.c | |
parent | 0cfea5dd98205f2fa318836da664a7d7df1afbc1 (diff) | |
parent | e1036502e5263851259d147771226161e5ccc85a (diff) |
Merge ../linus
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r-- | drivers/char/synclink_gt.c | 144 |
1 files changed, 93 insertions, 51 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 2f07b085536b..792c79c315e0 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: synclink_gt.c,v 4.25 2006/02/06 21:20:33 paulkf Exp $ | 2 | * $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $ |
3 | * | 3 | * |
4 | * Device driver for Microgate SyncLink GT serial adapters. | 4 | * Device driver for Microgate SyncLink GT serial adapters. |
5 | * | 5 | * |
@@ -83,20 +83,22 @@ | |||
83 | 83 | ||
84 | #include "linux/synclink.h" | 84 | #include "linux/synclink.h" |
85 | 85 | ||
86 | #ifdef CONFIG_HDLC_MODULE | 86 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) |
87 | #define CONFIG_HDLC 1 | 87 | #define SYNCLINK_GENERIC_HDLC 1 |
88 | #else | ||
89 | #define SYNCLINK_GENERIC_HDLC 0 | ||
88 | #endif | 90 | #endif |
89 | 91 | ||
90 | /* | 92 | /* |
91 | * module identification | 93 | * module identification |
92 | */ | 94 | */ |
93 | static char *driver_name = "SyncLink GT"; | 95 | static char *driver_name = "SyncLink GT"; |
94 | static char *driver_version = "$Revision: 4.25 $"; | 96 | static char *driver_version = "$Revision: 4.36 $"; |
95 | static char *tty_driver_name = "synclink_gt"; | 97 | static char *tty_driver_name = "synclink_gt"; |
96 | static char *tty_dev_prefix = "ttySLG"; | 98 | static char *tty_dev_prefix = "ttySLG"; |
97 | MODULE_LICENSE("GPL"); | 99 | MODULE_LICENSE("GPL"); |
98 | #define MGSL_MAGIC 0x5401 | 100 | #define MGSL_MAGIC 0x5401 |
99 | #define MAX_DEVICES 12 | 101 | #define MAX_DEVICES 32 |
100 | 102 | ||
101 | static struct pci_device_id pci_table[] = { | 103 | static struct pci_device_id pci_table[] = { |
102 | {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | 104 | {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
@@ -149,7 +151,7 @@ static struct tty_driver *serial_driver; | |||
149 | static int open(struct tty_struct *tty, struct file * filp); | 151 | static int open(struct tty_struct *tty, struct file * filp); |
150 | static void close(struct tty_struct *tty, struct file * filp); | 152 | static void close(struct tty_struct *tty, struct file * filp); |
151 | static void hangup(struct tty_struct *tty); | 153 | static void hangup(struct tty_struct *tty); |
152 | static void set_termios(struct tty_struct *tty, struct termios *old_termios); | 154 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); |
153 | 155 | ||
154 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); | 156 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); |
155 | static void put_char(struct tty_struct *tty, unsigned char ch); | 157 | static void put_char(struct tty_struct *tty, unsigned char ch); |
@@ -171,7 +173,7 @@ static void set_break(struct tty_struct *tty, int break_state); | |||
171 | /* | 173 | /* |
172 | * generic HDLC support and callbacks | 174 | * generic HDLC support and callbacks |
173 | */ | 175 | */ |
174 | #ifdef CONFIG_HDLC | 176 | #if SYNCLINK_GENERIC_HDLC |
175 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 177 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) |
176 | static void hdlcdev_tx_done(struct slgt_info *info); | 178 | static void hdlcdev_tx_done(struct slgt_info *info); |
177 | static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); | 179 | static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); |
@@ -359,7 +361,7 @@ struct slgt_info { | |||
359 | int netcount; | 361 | int netcount; |
360 | int dosyncppp; | 362 | int dosyncppp; |
361 | spinlock_t netlock; | 363 | spinlock_t netlock; |
362 | #ifdef CONFIG_HDLC | 364 | #if SYNCLINK_GENERIC_HDLC |
363 | struct net_device *netdev; | 365 | struct net_device *netdev; |
364 | #endif | 366 | #endif |
365 | 367 | ||
@@ -461,7 +463,7 @@ static int adapter_test(struct slgt_info *info); | |||
461 | static void reset_adapter(struct slgt_info *info); | 463 | static void reset_adapter(struct slgt_info *info); |
462 | static void reset_port(struct slgt_info *info); | 464 | static void reset_port(struct slgt_info *info); |
463 | static void async_mode(struct slgt_info *info); | 465 | static void async_mode(struct slgt_info *info); |
464 | static void hdlc_mode(struct slgt_info *info); | 466 | static void sync_mode(struct slgt_info *info); |
465 | 467 | ||
466 | static void rx_stop(struct slgt_info *info); | 468 | static void rx_stop(struct slgt_info *info); |
467 | static void rx_start(struct slgt_info *info); | 469 | static void rx_start(struct slgt_info *info); |
@@ -485,13 +487,13 @@ static void enable_loopback(struct slgt_info *info); | |||
485 | static void set_rate(struct slgt_info *info, u32 data_rate); | 487 | static void set_rate(struct slgt_info *info, u32 data_rate); |
486 | 488 | ||
487 | static int bh_action(struct slgt_info *info); | 489 | static int bh_action(struct slgt_info *info); |
488 | static void bh_handler(void* context); | 490 | static void bh_handler(struct work_struct *work); |
489 | static void bh_transmit(struct slgt_info *info); | 491 | static void bh_transmit(struct slgt_info *info); |
490 | static void isr_serial(struct slgt_info *info); | 492 | static void isr_serial(struct slgt_info *info); |
491 | static void isr_rdma(struct slgt_info *info); | 493 | static void isr_rdma(struct slgt_info *info); |
492 | static void isr_txeom(struct slgt_info *info, unsigned short status); | 494 | static void isr_txeom(struct slgt_info *info, unsigned short status); |
493 | static void isr_tdma(struct slgt_info *info); | 495 | static void isr_tdma(struct slgt_info *info); |
494 | static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs); | 496 | static irqreturn_t slgt_interrupt(int irq, void *dev_id); |
495 | 497 | ||
496 | static int alloc_dma_bufs(struct slgt_info *info); | 498 | static int alloc_dma_bufs(struct slgt_info *info); |
497 | static void free_dma_bufs(struct slgt_info *info); | 499 | static void free_dma_bufs(struct slgt_info *info); |
@@ -814,7 +816,7 @@ static void hangup(struct tty_struct *tty) | |||
814 | wake_up_interruptible(&info->open_wait); | 816 | wake_up_interruptible(&info->open_wait); |
815 | } | 817 | } |
816 | 818 | ||
817 | static void set_termios(struct tty_struct *tty, struct termios *old_termios) | 819 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
818 | { | 820 | { |
819 | struct slgt_info *info = tty->driver_data; | 821 | struct slgt_info *info = tty->driver_data; |
820 | unsigned long flags; | 822 | unsigned long flags; |
@@ -881,7 +883,9 @@ static int write(struct tty_struct *tty, | |||
881 | if (!count) | 883 | if (!count) |
882 | goto cleanup; | 884 | goto cleanup; |
883 | 885 | ||
884 | if (info->params.mode == MGSL_MODE_RAW) { | 886 | if (info->params.mode == MGSL_MODE_RAW || |
887 | info->params.mode == MGSL_MODE_MONOSYNC || | ||
888 | info->params.mode == MGSL_MODE_BISYNC) { | ||
885 | unsigned int bufs_needed = (count/DMABUFSIZE); | 889 | unsigned int bufs_needed = (count/DMABUFSIZE); |
886 | unsigned int bufs_free = free_tbuf_count(info); | 890 | unsigned int bufs_free = free_tbuf_count(info); |
887 | if (count % DMABUFSIZE) | 891 | if (count % DMABUFSIZE) |
@@ -1352,7 +1356,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1352 | spin_unlock_irqrestore(&info->lock,flags); | 1356 | spin_unlock_irqrestore(&info->lock,flags); |
1353 | } | 1357 | } |
1354 | 1358 | ||
1355 | #ifdef CONFIG_HDLC | 1359 | #if SYNCLINK_GENERIC_HDLC |
1356 | 1360 | ||
1357 | /** | 1361 | /** |
1358 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) | 1362 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) |
@@ -1876,9 +1880,9 @@ static int bh_action(struct slgt_info *info) | |||
1876 | /* | 1880 | /* |
1877 | * perform bottom half processing | 1881 | * perform bottom half processing |
1878 | */ | 1882 | */ |
1879 | static void bh_handler(void* context) | 1883 | static void bh_handler(struct work_struct *work) |
1880 | { | 1884 | { |
1881 | struct slgt_info *info = context; | 1885 | struct slgt_info *info = container_of(work, struct slgt_info, task); |
1882 | int action; | 1886 | int action; |
1883 | 1887 | ||
1884 | if (!info) | 1888 | if (!info) |
@@ -1897,6 +1901,8 @@ static void bh_handler(void* context) | |||
1897 | while(rx_get_frame(info)); | 1901 | while(rx_get_frame(info)); |
1898 | break; | 1902 | break; |
1899 | case MGSL_MODE_RAW: | 1903 | case MGSL_MODE_RAW: |
1904 | case MGSL_MODE_MONOSYNC: | ||
1905 | case MGSL_MODE_BISYNC: | ||
1900 | while(rx_get_buf(info)); | 1906 | while(rx_get_buf(info)); |
1901 | break; | 1907 | break; |
1902 | } | 1908 | } |
@@ -1998,7 +2004,7 @@ static void dcd_change(struct slgt_info *info) | |||
1998 | } else { | 2004 | } else { |
1999 | info->input_signal_events.dcd_down++; | 2005 | info->input_signal_events.dcd_down++; |
2000 | } | 2006 | } |
2001 | #ifdef CONFIG_HDLC | 2007 | #if SYNCLINK_GENERIC_HDLC |
2002 | if (info->netcount) { | 2008 | if (info->netcount) { |
2003 | if (info->signals & SerialSignal_DCD) | 2009 | if (info->signals & SerialSignal_DCD) |
2004 | netif_carrier_on(info->netdev); | 2010 | netif_carrier_on(info->netdev); |
@@ -2176,7 +2182,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status) | |||
2176 | set_signals(info); | 2182 | set_signals(info); |
2177 | } | 2183 | } |
2178 | 2184 | ||
2179 | #ifdef CONFIG_HDLC | 2185 | #if SYNCLINK_GENERIC_HDLC |
2180 | if (info->netcount) | 2186 | if (info->netcount) |
2181 | hdlcdev_tx_done(info); | 2187 | hdlcdev_tx_done(info); |
2182 | else | 2188 | else |
@@ -2213,9 +2219,8 @@ static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int | |||
2213 | * | 2219 | * |
2214 | * irq interrupt number | 2220 | * irq interrupt number |
2215 | * dev_id device ID supplied during interrupt registration | 2221 | * dev_id device ID supplied during interrupt registration |
2216 | * regs interrupted processor context | ||
2217 | */ | 2222 | */ |
2218 | static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs) | 2223 | static irqreturn_t slgt_interrupt(int irq, void *dev_id) |
2219 | { | 2224 | { |
2220 | struct slgt_info *info; | 2225 | struct slgt_info *info; |
2221 | unsigned int gsr; | 2226 | unsigned int gsr; |
@@ -2362,10 +2367,9 @@ static void program_hw(struct slgt_info *info) | |||
2362 | rx_stop(info); | 2367 | rx_stop(info); |
2363 | tx_stop(info); | 2368 | tx_stop(info); |
2364 | 2369 | ||
2365 | if (info->params.mode == MGSL_MODE_HDLC || | 2370 | if (info->params.mode != MGSL_MODE_ASYNC || |
2366 | info->params.mode == MGSL_MODE_RAW || | ||
2367 | info->netcount) | 2371 | info->netcount) |
2368 | hdlc_mode(info); | 2372 | sync_mode(info); |
2369 | else | 2373 | else |
2370 | async_mode(info); | 2374 | async_mode(info); |
2371 | 2375 | ||
@@ -2564,6 +2568,10 @@ static int rx_enable(struct slgt_info *info, int enable) | |||
2564 | if (enable) { | 2568 | if (enable) { |
2565 | if (!info->rx_enabled) | 2569 | if (!info->rx_enabled) |
2566 | rx_start(info); | 2570 | rx_start(info); |
2571 | else if (enable == 2) { | ||
2572 | /* force hunt mode (write 1 to RCR[3]) */ | ||
2573 | wr_reg16(info, RCR, rd_reg16(info, RCR) | BIT3); | ||
2574 | } | ||
2567 | } else { | 2575 | } else { |
2568 | if (info->rx_enabled) | 2576 | if (info->rx_enabled) |
2569 | rx_stop(info); | 2577 | rx_stop(info); |
@@ -3300,7 +3308,7 @@ static void add_device(struct slgt_info *info) | |||
3300 | devstr, info->device_name, info->phys_reg_addr, | 3308 | devstr, info->device_name, info->phys_reg_addr, |
3301 | info->irq_level, info->max_frame_size); | 3309 | info->irq_level, info->max_frame_size); |
3302 | 3310 | ||
3303 | #ifdef CONFIG_HDLC | 3311 | #if SYNCLINK_GENERIC_HDLC |
3304 | hdlcdev_init(info); | 3312 | hdlcdev_init(info); |
3305 | #endif | 3313 | #endif |
3306 | } | 3314 | } |
@@ -3320,7 +3328,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev | |||
3320 | } else { | 3328 | } else { |
3321 | memset(info, 0, sizeof(struct slgt_info)); | 3329 | memset(info, 0, sizeof(struct slgt_info)); |
3322 | info->magic = MGSL_MAGIC; | 3330 | info->magic = MGSL_MAGIC; |
3323 | INIT_WORK(&info->task, bh_handler, info); | 3331 | INIT_WORK(&info->task, bh_handler); |
3324 | info->max_frame_size = 4096; | 3332 | info->max_frame_size = 4096; |
3325 | info->raw_rx_size = DMABUFSIZE; | 3333 | info->raw_rx_size = DMABUFSIZE; |
3326 | info->close_delay = 5*HZ/10; | 3334 | info->close_delay = 5*HZ/10; |
@@ -3434,7 +3442,7 @@ static void __devexit remove_one(struct pci_dev *dev) | |||
3434 | { | 3442 | { |
3435 | } | 3443 | } |
3436 | 3444 | ||
3437 | static struct tty_operations ops = { | 3445 | static const struct tty_operations ops = { |
3438 | .open = open, | 3446 | .open = open, |
3439 | .close = close, | 3447 | .close = close, |
3440 | .write = write, | 3448 | .write = write, |
@@ -3482,7 +3490,7 @@ static void slgt_cleanup(void) | |||
3482 | /* release devices */ | 3490 | /* release devices */ |
3483 | info = slgt_device_list; | 3491 | info = slgt_device_list; |
3484 | while(info) { | 3492 | while(info) { |
3485 | #ifdef CONFIG_HDLC | 3493 | #if SYNCLINK_GENERIC_HDLC |
3486 | hdlcdev_exit(info); | 3494 | hdlcdev_exit(info); |
3487 | #endif | 3495 | #endif |
3488 | free_dma_bufs(info); | 3496 | free_dma_bufs(info); |
@@ -3516,6 +3524,7 @@ static int __init slgt_init(void) | |||
3516 | 3524 | ||
3517 | if (!slgt_device_list) { | 3525 | if (!slgt_device_list) { |
3518 | printk("%s no devices found\n",driver_name); | 3526 | printk("%s no devices found\n",driver_name); |
3527 | pci_unregister_driver(&pci_driver); | ||
3519 | return -ENODEV; | 3528 | return -ENODEV; |
3520 | } | 3529 | } |
3521 | 3530 | ||
@@ -3537,6 +3546,8 @@ static int __init slgt_init(void) | |||
3537 | serial_driver->init_termios = tty_std_termios; | 3546 | serial_driver->init_termios = tty_std_termios; |
3538 | serial_driver->init_termios.c_cflag = | 3547 | serial_driver->init_termios.c_cflag = |
3539 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 3548 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
3549 | serial_driver->init_termios.c_ispeed = 9600; | ||
3550 | serial_driver->init_termios.c_ospeed = 9600; | ||
3540 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 3551 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
3541 | tty_set_operations(serial_driver, &ops); | 3552 | tty_set_operations(serial_driver, &ops); |
3542 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 3553 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
@@ -3748,7 +3759,7 @@ static void tx_start(struct slgt_info *info) | |||
3748 | { | 3759 | { |
3749 | if (!info->tx_enabled) { | 3760 | if (!info->tx_enabled) { |
3750 | wr_reg16(info, TCR, | 3761 | wr_reg16(info, TCR, |
3751 | (unsigned short)(rd_reg16(info, TCR) | BIT1)); | 3762 | (unsigned short)((rd_reg16(info, TCR) | BIT1) & ~BIT2)); |
3752 | info->tx_enabled = TRUE; | 3763 | info->tx_enabled = TRUE; |
3753 | } | 3764 | } |
3754 | 3765 | ||
@@ -3775,13 +3786,18 @@ static void tx_start(struct slgt_info *info) | |||
3775 | tdma_reset(info); | 3786 | tdma_reset(info); |
3776 | /* set 1st descriptor address */ | 3787 | /* set 1st descriptor address */ |
3777 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); | 3788 | wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); |
3778 | if (info->params.mode == MGSL_MODE_RAW) | 3789 | switch(info->params.mode) { |
3790 | case MGSL_MODE_RAW: | ||
3791 | case MGSL_MODE_MONOSYNC: | ||
3792 | case MGSL_MODE_BISYNC: | ||
3779 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ | 3793 | wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ |
3780 | else | 3794 | break; |
3795 | default: | ||
3781 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ | 3796 | wr_reg32(info, TDCSR, BIT0); /* DMA enable */ |
3797 | } | ||
3782 | } | 3798 | } |
3783 | 3799 | ||
3784 | if (info->params.mode != MGSL_MODE_RAW) { | 3800 | if (info->params.mode == MGSL_MODE_HDLC) { |
3785 | info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); | 3801 | info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); |
3786 | add_timer(&info->tx_timer); | 3802 | add_timer(&info->tx_timer); |
3787 | } | 3803 | } |
@@ -3814,7 +3830,6 @@ static void tx_stop(struct slgt_info *info) | |||
3814 | /* reset and disable transmitter */ | 3830 | /* reset and disable transmitter */ |
3815 | val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ | 3831 | val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ |
3816 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ | 3832 | wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ |
3817 | wr_reg16(info, TCR, val); /* clear reset */ | ||
3818 | 3833 | ||
3819 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); | 3834 | slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); |
3820 | 3835 | ||
@@ -3982,7 +3997,7 @@ static void async_mode(struct slgt_info *info) | |||
3982 | enable_loopback(info); | 3997 | enable_loopback(info); |
3983 | } | 3998 | } |
3984 | 3999 | ||
3985 | static void hdlc_mode(struct slgt_info *info) | 4000 | static void sync_mode(struct slgt_info *info) |
3986 | { | 4001 | { |
3987 | unsigned short val; | 4002 | unsigned short val; |
3988 | 4003 | ||
@@ -3992,7 +4007,7 @@ static void hdlc_mode(struct slgt_info *info) | |||
3992 | 4007 | ||
3993 | /* TCR (tx control) | 4008 | /* TCR (tx control) |
3994 | * | 4009 | * |
3995 | * 15..13 mode, 000=HDLC 001=raw sync | 4010 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync |
3996 | * 12..10 encoding | 4011 | * 12..10 encoding |
3997 | * 09 CRC enable | 4012 | * 09 CRC enable |
3998 | * 08 CRC32 | 4013 | * 08 CRC32 |
@@ -4006,8 +4021,11 @@ static void hdlc_mode(struct slgt_info *info) | |||
4006 | */ | 4021 | */ |
4007 | val = 0; | 4022 | val = 0; |
4008 | 4023 | ||
4009 | if (info->params.mode == MGSL_MODE_RAW) | 4024 | switch(info->params.mode) { |
4010 | val |= BIT13; | 4025 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4026 | case MGSL_MODE_BISYNC: val |= BIT15; break; | ||
4027 | case MGSL_MODE_RAW: val |= BIT13; break; | ||
4028 | } | ||
4011 | if (info->if_mode & MGSL_INTERFACE_RTS_EN) | 4029 | if (info->if_mode & MGSL_INTERFACE_RTS_EN) |
4012 | val |= BIT7; | 4030 | val |= BIT7; |
4013 | 4031 | ||
@@ -4058,7 +4076,7 @@ static void hdlc_mode(struct slgt_info *info) | |||
4058 | 4076 | ||
4059 | /* RCR (rx control) | 4077 | /* RCR (rx control) |
4060 | * | 4078 | * |
4061 | * 15..13 mode, 000=HDLC 001=raw sync | 4079 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync |
4062 | * 12..10 encoding | 4080 | * 12..10 encoding |
4063 | * 09 CRC enable | 4081 | * 09 CRC enable |
4064 | * 08 CRC32 | 4082 | * 08 CRC32 |
@@ -4069,8 +4087,11 @@ static void hdlc_mode(struct slgt_info *info) | |||
4069 | */ | 4087 | */ |
4070 | val = 0; | 4088 | val = 0; |
4071 | 4089 | ||
4072 | if (info->params.mode == MGSL_MODE_RAW) | 4090 | switch(info->params.mode) { |
4073 | val |= BIT13; | 4091 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4092 | case MGSL_MODE_BISYNC: val |= BIT15; break; | ||
4093 | case MGSL_MODE_RAW: val |= BIT13; break; | ||
4094 | } | ||
4074 | 4095 | ||
4075 | switch(info->params.encoding) | 4096 | switch(info->params.encoding) |
4076 | { | 4097 | { |
@@ -4309,10 +4330,15 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last | |||
4309 | while(!done) { | 4330 | while(!done) { |
4310 | /* reset current buffer for reuse */ | 4331 | /* reset current buffer for reuse */ |
4311 | info->rbufs[i].status = 0; | 4332 | info->rbufs[i].status = 0; |
4312 | if (info->params.mode == MGSL_MODE_RAW) | 4333 | switch(info->params.mode) { |
4334 | case MGSL_MODE_RAW: | ||
4335 | case MGSL_MODE_MONOSYNC: | ||
4336 | case MGSL_MODE_BISYNC: | ||
4313 | set_desc_count(info->rbufs[i], info->raw_rx_size); | 4337 | set_desc_count(info->rbufs[i], info->raw_rx_size); |
4314 | else | 4338 | break; |
4339 | default: | ||
4315 | set_desc_count(info->rbufs[i], DMABUFSIZE); | 4340 | set_desc_count(info->rbufs[i], DMABUFSIZE); |
4341 | } | ||
4316 | 4342 | ||
4317 | if (i == last) | 4343 | if (i == last) |
4318 | done = 1; | 4344 | done = 1; |
@@ -4412,7 +4438,7 @@ check_again: | |||
4412 | framesize = 0; | 4438 | framesize = 0; |
4413 | } | 4439 | } |
4414 | 4440 | ||
4415 | #ifdef CONFIG_HDLC | 4441 | #if SYNCLINK_GENERIC_HDLC |
4416 | if (framesize == 0) { | 4442 | if (framesize == 0) { |
4417 | struct net_device_stats *stats = hdlc_stats(info->netdev); | 4443 | struct net_device_stats *stats = hdlc_stats(info->netdev); |
4418 | stats->rx_errors++; | 4444 | stats->rx_errors++; |
@@ -4455,7 +4481,7 @@ check_again: | |||
4455 | framesize++; | 4481 | framesize++; |
4456 | } | 4482 | } |
4457 | 4483 | ||
4458 | #ifdef CONFIG_HDLC | 4484 | #if SYNCLINK_GENERIC_HDLC |
4459 | if (info->netcount) | 4485 | if (info->netcount) |
4460 | hdlcdev_rx(info,info->tmp_rbuf, framesize); | 4486 | hdlcdev_rx(info,info->tmp_rbuf, framesize); |
4461 | else | 4487 | else |
@@ -4477,13 +4503,24 @@ cleanup: | |||
4477 | static int rx_get_buf(struct slgt_info *info) | 4503 | static int rx_get_buf(struct slgt_info *info) |
4478 | { | 4504 | { |
4479 | unsigned int i = info->rbuf_current; | 4505 | unsigned int i = info->rbuf_current; |
4506 | unsigned int count; | ||
4480 | 4507 | ||
4481 | if (!desc_complete(info->rbufs[i])) | 4508 | if (!desc_complete(info->rbufs[i])) |
4482 | return 0; | 4509 | return 0; |
4483 | DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx"); | 4510 | count = desc_count(info->rbufs[i]); |
4484 | DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i]))); | 4511 | switch(info->params.mode) { |
4485 | ldisc_receive_buf(info->tty, info->rbufs[i].buf, | 4512 | case MGSL_MODE_MONOSYNC: |
4486 | info->flag_buf, desc_count(info->rbufs[i])); | 4513 | case MGSL_MODE_BISYNC: |
4514 | /* ignore residue in byte synchronous modes */ | ||
4515 | if (desc_residue(info->rbufs[i])) | ||
4516 | count--; | ||
4517 | break; | ||
4518 | } | ||
4519 | DBGDATA(info, info->rbufs[i].buf, count, "rx"); | ||
4520 | DBGINFO(("rx_get_buf size=%d\n", count)); | ||
4521 | if (count) | ||
4522 | ldisc_receive_buf(info->tty, info->rbufs[i].buf, | ||
4523 | info->flag_buf, count); | ||
4487 | free_rbufs(info, i, i); | 4524 | free_rbufs(info, i, i); |
4488 | return 1; | 4525 | return 1; |
4489 | } | 4526 | } |
@@ -4549,8 +4586,13 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) | |||
4549 | size -= count; | 4586 | size -= count; |
4550 | buf += count; | 4587 | buf += count; |
4551 | 4588 | ||
4552 | if (!size && info->params.mode != MGSL_MODE_RAW) | 4589 | /* |
4553 | set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */ | 4590 | * set EOF bit for last buffer of HDLC frame or |
4591 | * for every buffer in raw mode | ||
4592 | */ | ||
4593 | if ((!size && info->params.mode == MGSL_MODE_HDLC) || | ||
4594 | info->params.mode == MGSL_MODE_RAW) | ||
4595 | set_desc_eof(*d, 1); | ||
4554 | else | 4596 | else |
4555 | set_desc_eof(*d, 0); | 4597 | set_desc_eof(*d, 0); |
4556 | 4598 | ||
@@ -4742,7 +4784,7 @@ static void tx_timeout(unsigned long context) | |||
4742 | info->tx_count = 0; | 4784 | info->tx_count = 0; |
4743 | spin_unlock_irqrestore(&info->lock,flags); | 4785 | spin_unlock_irqrestore(&info->lock,flags); |
4744 | 4786 | ||
4745 | #ifdef CONFIG_HDLC | 4787 | #if SYNCLINK_GENERIC_HDLC |
4746 | if (info->netcount) | 4788 | if (info->netcount) |
4747 | hdlcdev_tx_done(info); | 4789 | hdlcdev_tx_done(info); |
4748 | else | 4790 | else |
@@ -4762,6 +4804,6 @@ static void rx_timeout(unsigned long context) | |||
4762 | spin_lock_irqsave(&info->lock, flags); | 4804 | spin_lock_irqsave(&info->lock, flags); |
4763 | info->pending_bh |= BH_RECEIVE; | 4805 | info->pending_bh |= BH_RECEIVE; |
4764 | spin_unlock_irqrestore(&info->lock, flags); | 4806 | spin_unlock_irqrestore(&info->lock, flags); |
4765 | bh_handler(info); | 4807 | bh_handler(&info->task); |
4766 | } | 4808 | } |
4767 | 4809 | ||