On 08/30/2017 08:48 PM, Jeff Webb wrote:
> On 08/29/2017 02:56 AM, Philippe Gerum wrote:
>> On 08/28/2017 08:45 PM, Jeff Webb wrote:
>>> On 08/07/2017 11:15 AM, Jeff Webb wrote:
>>>> On 08/07/2017 10:08 AM, Jeff Webb wrote:
>>>>> I am attempting to port legacy Xenomai 2.6.4 code to Xenomai 3.
>>>>> In our current code base, we implement userspace drivers using
>>>>> libpci, iopl, inb/outb, /dev/mem, and the pthread_intr_*_np
>>>>> family of functions.  Since the pthread_intr_*_np functions are
>>>>> no longer part of Xenomai, I have been researching and
>>>>> experimenting with the new UDD framework as a replacement.
>>>>> Although documentation and examples are a little scarce, I have
>>>>> found most of the information I need.  I also used some
>>>>> documentation on the Linux UIO framwork to fill in some gaps in
>>>>> my knowledge.  My preliminary conclusion is that using the UDD
>>>>> framework would allow us to port our existing code base without
>>>>> too much modification, but I still have a few remaining
>>>>> questions.
>>>>>
>>>>> I see the way that PCI device memory regions can be accessed
>>>>> using mmap with UDD_MEM_PHYS mem_regions, but on some PCI devices
>>>>> we also need to access I/O port regions, such as:
>>>>>
>>>>>    Region 0: Memory at f7102000 (32-bit, non-prefetchable) [size=128]
>>>>>    Region 1: I/O ports at b100 [size=128]
>>>>>    Region 2: I/O ports at b280 [size=4]
>>>>>
>>>>> The UIO documentation recommends using the struct uio_info's port
>>>>> field (an array of 'uio_port' structs) to pass information about
>>>>> the I/O port regions associated with the device to userspace.  I
>>>>> did not see the equivalent of this functionality in the UDD
>>>>> framework, and was wondering why it was omitted.  What is the
>>>>> recommended way of determining the ports associated with a device
>>>>> when using a UDD driver?  It seems like continuing to do this
>>>>> using libpci and then somehow matching this up with the
>>>>> corresponding UDD device would be messy and error-prone.
>>>>
>>>> If no other support exists, perhaps I could use kmalloc to allocate a
>>>> UDD_MEM_LOGICAL region corresponding to each PCI I/O port region on the
>>>> card.  The kernel UDD driver would then populate these regions with
>>>> the I/O addresses of the corresponding PCI I/O port regions.  The
>>>> UDD_MEM_LOGICAL regions could then be read by the userspace driver
>>>> to determine the I/O address to use with inb/outb (and iopl).
>>>
>>> Another way would be to pass the port I/O region addresses (and possibly
>>> sizes) to userspace via explicit IOCTLs.  If so, should the IOCTL
>>> numbers for such a use case be standardized?
>>>
>>> If there is no standard way to do this sort of thing, and if there are
>>> no recommendations about how to do proceed, I'll just do what feels
>>> right in my case, but I thought someone might have some experience or
>>> opinion on how this should be done in the Xenomai UDD context, since the
>>> Linux UIO method of passing port information is not available.
>>>
>>
>> I would implement this as the original UIO driver does, which is
>> basically about adding a sysfs hierarchy that represents each I/O port
>> range declared by the UIO device.
>>
>> For UDD, that would entail adding an array of "udd_ioport" structures to
>> struct udd_device to be filled in by the caller. Then,
>> udd_register_device() would iterate over this array, creating sysfs
>> entries on the fly, based on the information available into each ioport
>> definition, such as name, start and size.
>>
>> The sysfs mechanism has the advantage of only requiring to define a pack
>> of attributes and a couple of sysfs handlers for showing them. Besides,
>> requiring that the app retrieves those attributes from secondary mode at
>> init, using regular file I/O on sysfs entries seems acceptable, those
>> attributes are not supposed to vary anyway.
> 
> That sounds like good advice, Philippe. Thanks.
> 
> Your suggestion to follow the UIO approach for the I/O ports now
> has me wondering why the Linux UIO approach and structures
> weren't mirrored more closely in Xenomai UDD. I personally like
> the way some things are done better in UDD, but I would think
> that keeping things as similar as possible to how the standard
> kernel works would ease the learning curve and allow some of the
> init code to be reused, but I might be missing something. It
> would seem that the UDD and UIO kernel-space code one would need
> to write for a particular device would be almost identical, and
> having the APIs as similar as possible would be desirable.
> 
>

IIRC, having to pass the mapping number in the offset field of the
mmap() request with UIO (offset = N * getpagesize()) was the scary API
detail that froze my brain machinery. From that point, I did not care
that much for compatibility between UIO and UDD for the rest of the API,
a stance which was admittedly wrong.

There are things imposed on Cobalt drivers though, such as having the
device nodes managed by RTDM under the /dev/rtdm hierarchy, and not by
sysfs. The choice of using the ioctl() interface instead of
read()/write() for interrupt control has no particular justification.

So I agree with you. In retrospect, if I were to (re)write UDD, I would
indeed conform to the UIO interface for all technically compatible
aspects, except for the mmap() support where providing a distinct device
entry for each mapping is clearly better.

-- 
Philippe.

_______________________________________________
Xenomai mailing list
[email protected]
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to