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
[email protected]
https://mail.gna.org/listinfo/xenomai-core