Le 11/5/2007, "Jan Kiszka" <[EMAIL PROTECTED]> a écrit:

>Jan Kiszka wrote:
>> CHABAL David wrote:
>>> Le 11/5/2007, "Jan Kiszka" <[EMAIL PROTECTED]> a écrit:
>>>
>>>> Maksym Veremeyenko wrote:
>>>>> CHABAL David пишет:
>>>>>
>>>>>> I met some trouble with the 16550A driver provided in Xenomai 2.3.1
>>>>>> and my Moxa cards (PCI / 8 * RS232 / 168U ).
>>>>>>
>>>>>> It was a problem of baudrate computation before setting the LCR_DLAB
>>>>>> register.
>>>>>>
>>>>>> The formula implemented by the Xenomai driver is different from the one
>>>>>> provided by Moxa. So I copy/paste the formula from the mxser.c file
>>>>>> (present in the
>>>>>> kernel distro), and it seems to work fine.
>>>>>>
>>>>>> I think it's Moxa card dependant, may be caused by the high default baud
>>>>>> rate of this card.
>>>>> I have two Moxa boards with no problem, possible you need to specify 
>>>>> 'baud_base' param.
>>>>>
>>>>> I my case :
>>>>>
>>>>> # 8 ports board:
>>>>> /sbin/modprobe xeno_16550A \
>>>>> ioaddr=0x1000,0x1008,0x1010,0x1018,0x1020,0x1028,0x1030,0x1038 \
>>>>> irq=9,9,9,9,9,9,9,9 \
>>>>> baud_base=921600,921600,921600,921600,921600,921600,921600,921600
>>>>>
>>>>> # 2 ports board + onboards:
>>>>> /sbin/modprobe xeno_16550A ioaddr=0x3f8,0x2f8,0xdf00,0xdf08 
>>>>> irq=4,3,11,11 baud_base=115200,115200,921600,921600
>>>>>
>>>> Interesting. That would leave us just with the generic fix to catch
>>>> baud_rate==0. Far more attractive. :)
>>>>
>>>> David, can you confirm this? Weren't you just aware of the baud_base
>>>> parameter?
>>> I'm not totally convinced because if I compute by hand the DLAB register
>>> with the 19200 value (my config):
>>>
>>> With the moxa driver:
>>>   baud_div = 912.600 / 19.200 = 47
>>>
>>> With the Xeno driver:
>>>   baud_div = (912.600 - 9600) / 19.200 = 47
>>>
>>> Grrr, it's ok here because the rounded values are the same because the
>>> baud base is biggest than the speed requested, but I think a problem can
>>> occur with 115200 or more, example:
>>>
>>> moxa: 912.600/115.200 = 8
>>> xeno: = 7
>> 
>> Yeah, hard arguments. This really cries for a moxa tweak. (The
>> alternative would be to pass an artificially increased baud_base - but
>> that would be _really_ ugly and we could also ask the user for the
>> divider directly...)
>
>Here we go. This patch should add the most essential changes of your
>patch to SVN trunk (backport not officially planned, but it should not
>be tricky). The idea is to pass "variant=1" to xeno_16550A on load.
>That will kick out rounding on divider calculation and even switches
>the default baud base.
>
>Comments/test reports welcome.
>
>Jan
>
>
>Index: ksrc/drivers/serial/16550A.c
>===================================================================
>--- ksrc/drivers/serial/16550A.c       (Revision 2433)
>+++ ksrc/drivers/serial/16550A.c       (Arbeitskopie)
>@@ -28,10 +28,14 @@
> 
> #define MAX_DEVICES           8
> 
>+#define VARIANT_STANDARD      0
>+#define VARIANT_MOXA          1
>+
> #define IN_BUFFER_SIZE                4096
> #define OUT_BUFFER_SIZE               4096
> 
> #define DEFAULT_BAUD_BASE     115200
>+#define DEFAULT_BAUD_BASE_MOXA        921600
> #define DEFAULT_TX_FIFO               16
> 
> #define PARITY_MASK           0x03
>@@ -121,11 +125,13 @@ static struct rtdm_device *device[MAX_DE
> static unsigned int irq[MAX_DEVICES];
> static unsigned int baud_base[MAX_DEVICES];
> static int tx_fifo[MAX_DEVICES];
>+static int variant[MAX_DEVICES];
> static unsigned int start_index;
> 
> compat_module_param_array(irq, uint, MAX_DEVICES, 0400);
> compat_module_param_array(baud_base, uint, MAX_DEVICES, 0400);
> compat_module_param_array(tx_fifo, int, MAX_DEVICES, 0400);
>+compat_module_param_array(variant, int, MAX_DEVICES, 0400);
> 
> MODULE_PARM_DESC(irq, "IRQ numbers of the serial devices");
> MODULE_PARM_DESC(baud_base, "Maximum baud rate of the serial device "
>@@ -302,20 +308,24 @@ static int rt_16550_set_config(struct rt
>       rtdm_lockctx_t lock_ctx;
>       unsigned long base = ctx->base_addr;
>       int mode = rt_16550_io_mode_from_ctx(ctx);
>-      int dev_id;
>       int err = 0;
>-      int baud_div = 0;
> 
>       /* make line configuration atomic and IRQ-safe */
>       rtdm_lock_get_irqsave(&ctx->lock, lock_ctx);
> 
>       if (testbits(config->config_mask, RTSER_SET_BAUD)) {
>-              dev_id = container_of(((void *)ctx), struct rtdm_dev_context,
>-                                    dev_private)->device->device_id;
>+              int dev_id = container_of(((void *)ctx),
>+                                        struct rtdm_dev_context,
>+                                        dev_private)->device->device_id;
>+              int rounding = ctx->config.baud_rate >> 1;
>+              int baud_div = 0;
>+
>+              if (variant[dev_id] == VARIANT_MOXA)
>+                      rounding = 0;
> 
>               ctx->config.baud_rate = config->baud_rate;
>-              baud_div = (baud_base[dev_id] + (ctx->config.baud_rate >> 1)) /
>-                  ctx->config.baud_rate;
>+              baud_div = (baud_base[dev_id] + rounding) /
>+                      ctx->config.baud_rate;
>               rt_16550_reg_out(mode, base, LCR, LCR_DLAB);
>               rt_16550_reg_out(mode, base, DLL, baud_div & 0xff);
>               rt_16550_reg_out(mode, base, DLM, baud_div >> 8);
>@@ -595,10 +605,10 @@ int rt_16550_ioctl(struct rtdm_dev_conte
> 
>               if (testbits(config->config_mask, RTSER_SET_BAUD) &&
>                   (config->baud_rate >
>-                   baud_base[context->device->device_id])) {
>-                      /* the baudrate is to high for this port */
>+                   baud_base[context->device->device_id] ||
>+                   config->baud_rate <= 0))
>+                      /* invalid baudrate for this port */
>                       return -EINVAL;
>-              }
> 
>               if (testbits(config->config_mask,
>                            RTSER_SET_TIMESTAMP_HISTORY)) {
>@@ -1164,7 +1174,8 @@ int __init rt_16550_init(void)
>                       goto kfree_out;
> 
>               if (baud_base[i] == 0)
>-                      baud_base[i] = DEFAULT_BAUD_BASE;
>+                      baud_base[i] = (variant[i] == VARIANT_MOXA) ?
>+                              DEFAULT_BAUD_BASE_MOXA : DEFAULT_BAUD_BASE;
> 
>               if (tx_fifo[i] == 0)
>                       tx_fifo[i] = DEFAULT_TX_FIFO;
>

I think the DEFAULT_BAUD_BASE_MOXA constant shouldn't be added. May be
other Moxa cards work slowly (or will be faster) and include this
computation, I would keep this parameter free and ever modifiable by the
boot line.

David

_______________________________________________
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core

Reply via email to