Hi, this patch improves the behaviour of xeno_16550A on RTSER_RTIOC_EVENT_WAIT. In case it is invoked from non-RT, the driver tries to trigger an automatic switch-back to RT via returning ENOSYS. The patch also fixes another remaining issue about the right context when calling RTSER_RTIOC_SET_CONFIG (forgot the corner case of releasing the RX history buffer in RT).
Note that I intentionally did not apply the EPERM->ENOSYS scheme on RTSER_RTIOC_SET_CONFIG. Here a switch to non-RT might be required if the device was opened in non-RT and a reconfigure request regarding the RX history buffer is now issued in RT. I think it's better to let the user decide via a preceding explicit switch to non-RT if leaving RT is really correct. The patch furthermore contains a README describing the device setup. I hope I addressed potential questions and problems sufficiently, feedback is welcome. Jan
Index: drivers/16550A/Kconfig
===================================================================
--- drivers/16550A/Kconfig (revision 73)
+++ drivers/16550A/Kconfig (working copy)
@@ -3,4 +3,5 @@
bool "16550A UART driver"
default n
help
- Real-time UART driver for 16550A compatible controllers.
+ Real-time UART driver for 16550A compatible controllers. See
+ drivers/16550A/README for more details.
Index: drivers/16550A/16550A.c
===================================================================
--- drivers/16550A/16550A.c (revision 73)
+++ drivers/16550A/16550A.c (working copy)
@@ -556,18 +556,24 @@
config = &config_buf;
}
- if (testbits(config->config_mask, RTSER_SET_TIMESTAMP_HISTORY) &&
- testbits(config->timestamp_history,
- RTSER_RX_TIMESTAMP_HISTORY)) {
- if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) {
- if (rtdm_in_rt_context())
- return -EPERM;
+ if (testbits(config->config_mask, RTSER_SET_TIMESTAMP_HISTORY)) {
+ if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags) &&
+ rtdm_in_rt_context()) {
+ /* already fail if we MAY allocate or release a non-RT
+ * buffer in RT context */
+ return -EPERM;
+ }
- hist_buf = kmalloc(IN_BUFFER_SIZE * sizeof(__u64),
- GFP_KERNEL);
- } else
- hist_buf =
- rtdm_malloc(IN_BUFFER_SIZE * sizeof(__u64));
+ if (testbits(config->timestamp_history,
+ RTSER_RX_TIMESTAMP_HISTORY)) {
+ if (test_bit(RTDM_CREATED_IN_NRT,
+ &context->context_flags))
+ hist_buf = kmalloc(IN_BUFFER_SIZE * sizeof(__u64),
+ GFP_KERNEL);
+ else
+ hist_buf =
+ rtdm_malloc(IN_BUFFER_SIZE * sizeof(__u64));
+ }
if (!hist_buf)
return -ENOMEM;
@@ -643,7 +649,7 @@
rtdm_toseq_t timeout_seq;
if (!rtdm_in_rt_context())
- return -EPERM;
+ return -ENOSYS;
/* only one waiter allowed, stop any further attempts here */
if (test_and_set_bit(0, &ctx->ioc_event_lock))
@@ -1005,7 +1011,7 @@
device_class: RTDM_CLASS_SERIAL,
device_sub_class: RTDM_SUBCLASS_16550A,
driver_name: "rt_16550A",
- driver_version: RTDM_DRIVER_VER(1, 1, 1),
+ driver_version: RTDM_DRIVER_VER(1, 1, 2),
peripheral_name: "UART 16550A",
provider_name: "Jan Kiszka",
};
Index: drivers/16550A/README
===================================================================
--- drivers/16550A/README (revision 0)
+++ drivers/16550A/README (revision 0)
@@ -0,0 +1,34 @@
+Real-Time Serial Driver for 16550A-Compatible Devices
+=====================================================
+
+Preparation
+-----------
+ - decide which serial ports are to be managed by the real-time driver
+
+ - identify their I/O addresses and IRQ numbers:
+
+ setserial /dev/ttyS<N>
+
+ - disable the Linux driver for all these devices:
+
+ setserial /dev/ttyS<N> uart none
+
+
+Invocation
+----------
+
+modprobe xeno_16550A ioaddr=<io1>[,<io2>...] irq=<irq1>[,<irq2>...]
+ [tx_fifo=<len1>[,<len2>...]] [start_index=<index>]
+
+Arguments:
+ ioaddr<N> - I/O address of device <N> (e.g. 0x3f8 for ttyS0)
+ irq<N> - interrupt number of device <N> (e.g. 4 for ttyS0)
+ tx_fifo<N> - Transmitter FIFO size in bytes of device <N>, default is 16
+ start_index - First device instance number to be used, default is 0
+
+
+Usage
+-----
+
+The API is described in the API documentation under Modules -> Real-Time
+Driver Model -> Device Profiles -> Serial Devices.
signature.asc
Description: OpenPGP digital signature
