I started implementing Garmin USB support via libusb in GPSBabel a while ago. There's some kind of a problem with the bulk read that I never got past. Any Garmin USB-using libusb jocks are encouraged to contact me so we can get it over the finish line.
As the author of GPSBabel (and more to the point, the author of the Garmin USB module) I'd like to pop that bubble.
Garmin has gone out of their way to not document the WIRE PROTOCOL of the USB units (60C, 76C, 96C, VistaC, Quest, 26xx, etc.) but to instead document the API into their underachieving Windows driver.
An earlier version of the spec pretended to be a protocol spec. I contacted them with a number of discrepancies betweeen my observations on a protocol analyzer and that specification. Within a few weeks, a new version of the spec appeared that removed the pretense of being a protocol spec.
> It must be possible to write drivers and other kernel modules that can be compiled separately from the kernel and work across many versions.
I agree. A formal interface between the modules is a good thing and solves a lot of these problems.
> it should be possible to package bits and pieces of the kernel separately.
I agree. This is why a suitable formal interface would include packaging information.
> It must be possible to write kernel modules with more safety in mind. There should also be some way to apply some memory protection to kernel modules when desired.
I agree. A design that allowed driver modules to potentially run in different address spaces would be a good step toward this. If it enforced symbol and address visibility between those modues, that would also help.
> Maybe it's time to get rid of "make" altogether
I agree. A driver interface that specified a build system, eliminating the morass of make would be a Good Thing.
These are all good points. Fortunately, these problems have been solved.
UDI is a driver model that addresses these. It's been proven to allow real device drivers to be independent of these kinds of implementation details. How independent? Independent enough that the drivers run unchanged on not only 2.2 vs. 2.4 or BIGMEM vs. BIGMEM-not but on completely different OSes. See www.projectudi.org for more info on the spec and projectudi.sourceforge.net for a reference implementation. (The ref implementation doesn't include things like the protected address space mentioned above.)
[UDI] would make Linux more stable, not less! (It would also allow blame for buggy drivers to be placed appropriately.) Also, you would still have the ability to implement an Open Source driver, which would hopefully be of higher quality than the closed source driver, giving the best of both worlds.
The decision of UDI vs something else is a different decision than Open Source vs. closed source. UDI also allows for source-level distributions. (It is a common -and incorrect- myth that it is a binary-only interface.) You can distribute your UDI driver as source and it will Just Work on any system that provides a UDI environment.
The Powers That Be in the Linux Kernel world are committed to not worrying about binary compatibility across releases for a variety of reasons. Some of these reasons are good, some smack of stubborness, but that's OK.
This is actually a reason to welcome UDI. UDI offers insulation from that. Kernel developers are then free to change things in ways they deem necessary. Perhaps the UDI environment has to adapt. (Better one module than hundreds of drivers.) Since the interface between the driver and the OS is well-defined and versioned in UDI, the drivers - source or binary - see no change. So changes like the recent ones where the locking primitives all got shuffled no longer sink all the drivers.
Just like the system call definition allows the underlying kernel to change without breaking the applications, a well-defined interface between the kernel and the driver allows either to change without impacting the other.
Solaris has a fairly nice abstract ddi/ddk layer, letting you abstract things like endianess out of your code. And my 2.5 drivers work without a hitch under 2.7.
Well-defined interfaces are convenient. Having your driver work on both a 1995 OS and a 1999 OS is nice. (My recollection of Sun version history might be off.) Would you expect your 1995 Linux driver (source or binary) to work on a 1999 Linux kernel?
With that as backround, I have to say that the 1 source compiling to many driver binaries will only work at all well for simple stuff. Things like inked-list DMA, card-to-card DMA, etc, are tricky beasts and are very OS sensitive.
And endianness persisit as an issue; Solaris lets you specify any arbitrary memory range to be an arbitrary endianess.
I'll agree those can be tricky beasts, but they aren't necessarily OS specific. If you're using a driver interface that addresses these issues for you (sometimes with your help; they aren't magic) that's less tricky code that you, as a driver writer, have to fret about. UDI addresses them.
[ UDI, ] like any such effort, it relies on an abstraction layer that interfaces the "real" OS-level driver layer with the driver components themselves.
Although that is one way to implement it, it isn't the only way. Programming is full of abstractions. Consider timer services, for example; at some level, there is a (probably horrible) chip that generates an interrupt once in a while. Well, we certainly don't want hoards of drivers talking to this chip directly so OSes provide services like schedule_timeout() to abstract it. Almost every OS provides similar services and they're all maddeningly different. So it is entirely possible to implement, say, udi_timer_start beside schedule_timeout instead of in terms of it. Viola, no interface to the "real" OS driver layer and no layering costs.
I'm not saying that this specific example makes sense to do, but the point is that common interfaces can be implemented without layering costs.
The problem with this product, as with UDI, is that performance suffers. The linux people refuse to take part in UDI for a number of various good reasons, which can most simply be expressed as "the performance sucks rocks."
That's merely speculation. I have seen the UDI code and understand how it performs. Apparently, "the linux people" in your statement have not.
The benefits of improved scalability and detaching policy from implementation mean that UDI drivers can often perform better than with many existing driver models.
Since I've read most of the the UDI specification (look for me in the Credits of the 1.0 spec.) let me try to clarify some of the recurring misinformation in these threads.
UDI allows either source or binary distribution of modules. How someone chooses to release a driver is entirely their decision. Certainly the most benefit of UDI is seen by those that release product as source.
Although Microsoft isn't a participant in Project UDI, there's certainly nothing UNIX-centric about the spec. An environment could be written - even by a third party - for those OSes.
The Linux driver interface, like every other driver interface that I know of, doesn't solve a lot of the problems that UDI addresses. We didn't exclude it out of snobbery; we are raising the bar. For example, UDI allows efficient scheduling of drivers while allowing the details to be handled by the OS and not the driver - no IPL changes, no sleeps, no locks. It also has strongly typed interfaces with well defined address and namespaces. Imagine a driver running in user space or even on the other side of a TCP socket...Besides, nothing precludes any existing driver interfaces from remaining.
UDI is certainly not only for IA32. Most CPUs that you would expect (Sparc, PA, Power, Alpha, IA64, etc.) are represented and will have ABI bindings published.
Drivers in UDI are implictly threaded. They don't know (and don't have to care) how the OS schedules the code and how many processors are available to do it.
There was concern about the spec changing over time. All the interfaces (source and binary) are version controlled so a conforming environment can run drivers as far back (or forward) as it can.
The spec publishes C bindings becuase those are the only ones defined for most architectures. C++ ABI's are laughable at this point. The suggesting of coding in assembly (have you tried to get a non-trivial chunk of assembler through two different assemblers for the SAME processor? How about different ones?:-) misses the point of a portable driver interface.
Please look at the white papers (if not the specs) at www.projectudi.org before drawing conclusions. I read a lot of stuff that was just plain fiction in these threads...
I started implementing Garmin USB support via libusb in GPSBabel a while ago. There's some kind of a problem with the bulk read that I never got past. Any Garmin USB-using libusb jocks are encouraged to contact me so we can get it over the finish line.
You can find the current status on our mailing list archive.
Garmin has gone out of their way to not document the WIRE PROTOCOL of the USB units (60C, 76C, 96C, VistaC, Quest, 26xx, etc.) but to instead document the API into their underachieving Windows driver.
An earlier version of the spec pretended to be a protocol spec. I contacted them with a number of discrepancies betweeen my observations on a protocol analyzer and that specification. Within a few weeks, a new version of the spec appeared that removed the pretense of being a protocol spec.
> It must be possible to write drivers and other kernel modules that can be compiled separately from the kernel and work across many versions.
I agree. A formal interface between the modules is a good thing and solves a lot of these problems.
> it should be possible to package bits and pieces of the kernel separately.
I agree. This is why a suitable formal interface would include packaging information.
> It must be possible to write kernel modules with more safety in mind. There should also be some way to apply some memory protection to kernel modules when desired.
I agree. A design that allowed driver modules to potentially run in different address spaces would be a good step toward this. If it enforced symbol and address visibility between those modues, that would also help.
> Maybe it's time to get rid of "make" altogether
I agree. A driver interface that specified a build system, eliminating the morass of make would be a Good Thing.
These are all good points. Fortunately, these problems have been solved.
UDI is a driver model that addresses these. It's been proven to allow real device drivers to be independent of these kinds of implementation details. How independent? Independent enough that the drivers run unchanged on not only 2.2 vs. 2.4 or BIGMEM vs. BIGMEM-not but on completely different OSes. See www.projectudi.org for more info on the spec and projectudi.sourceforge.net for a reference implementation. (The ref implementation doesn't include things like the protected address space mentioned above.)
[UDI] would make Linux more stable, not less! (It would also allow blame for buggy drivers to be placed appropriately.) Also, you would still have the ability to implement an Open Source driver, which would hopefully be of higher quality than the closed source driver, giving the best of both worlds.
The decision of UDI vs something else is a different decision than Open Source vs. closed source. UDI also allows for source-level distributions. (It is a common -and incorrect- myth that it is a binary-only interface.) You can distribute your UDI driver as source and it will Just Work on any system that provides a UDI environment.
The Powers That Be in the Linux Kernel world are committed to not worrying about binary compatibility across releases for a variety of reasons. Some of these reasons are good, some smack of stubborness, but that's OK.
This is actually a reason to welcome UDI. UDI offers insulation from that. Kernel developers are then free to change things in ways they deem necessary. Perhaps the UDI environment has to adapt. (Better one module than hundreds of drivers.) Since the interface between the driver and the OS is well-defined and versioned in UDI, the drivers - source or binary - see no change. So changes like the recent ones where the locking primitives all got shuffled no longer sink all the drivers.
Just like the system call definition allows the underlying kernel to change without breaking the applications, a well-defined interface between the kernel and the driver allows either to change without impacting the other.
Solaris has a fairly nice abstract ddi/ddk layer, letting you abstract things like endianess out of your code. And my 2.5 drivers work without a hitch under 2.7.
Well-defined interfaces are convenient. Having your driver work on both a 1995 OS and a 1999 OS is nice. (My recollection of Sun version history might be off.) Would you expect your 1995 Linux driver (source or binary) to work on a 1999 Linux kernel?
With that as backround, I have to say that the 1 source compiling to many driver binaries will only work at all well for simple stuff. Things like inked-list DMA, card-to-card DMA, etc, are tricky beasts and are very OS sensitive.
And endianness persisit as an issue; Solaris lets you specify any arbitrary memory range to be an arbitrary endianess.
I'll agree those can be tricky beasts, but they aren't necessarily OS specific. If you're using a driver interface that addresses these issues for you (sometimes with your help; they aren't magic) that's less tricky code that you, as a driver writer, have to fret about. UDI addresses them.
[ UDI, ] like any such effort, it relies on an abstraction layer that interfaces the "real" OS-level driver layer with the driver components themselves.
Although that is one way to implement it, it isn't the only way. Programming is full of abstractions. Consider timer services, for example; at some level, there is a (probably horrible) chip that generates an interrupt once in a while. Well, we certainly don't want hoards of drivers talking to this chip directly so OSes provide services like schedule_timeout() to abstract it. Almost every OS provides similar services and they're all maddeningly different. So it is entirely possible to implement, say, udi_timer_start beside schedule_timeout instead of in terms of it. Viola, no interface to the "real" OS driver layer and no layering costs.
I'm not saying that this specific example makes sense to do, but the point is that common interfaces can be implemented without layering costs.
The problem with this product, as with UDI, is that performance suffers. The linux people refuse to take part in UDI for a number of various good reasons, which can most simply be expressed as "the performance sucks rocks."
That's merely speculation. I have seen the UDI code and understand how it performs. Apparently, "the linux people" in your statement have not.
The benefits of improved scalability and detaching policy from implementation mean that UDI drivers can often perform better than with many existing driver models.
Since I've read most of the the UDI specification (look for me in the
:-) misses the point of a portable
Credits of the 1.0 spec.) let me try to clarify some of the recurring
misinformation in these threads.
UDI allows either source or binary distribution of modules. How someone
chooses to release a driver is entirely their decision. Certainly the
most benefit of UDI is seen by those that release product as source.
Although Microsoft isn't a participant in Project UDI, there's certainly
nothing UNIX-centric about the spec. An environment could be written -
even by a third party - for those OSes.
The Linux driver interface, like every other driver interface that I
know of, doesn't solve a lot of the problems that UDI addresses. We
didn't exclude it out of snobbery; we are raising the bar. For example,
UDI allows efficient scheduling of drivers while allowing the details to
be handled by the OS and not the driver - no IPL changes, no sleeps, no
locks. It also has strongly typed interfaces with well defined address
and namespaces. Imagine a driver running in user space or even on the
other side of a TCP socket...Besides, nothing precludes any existing
driver interfaces from remaining.
UDI is certainly not only for IA32. Most CPUs that you would expect
(Sparc, PA, Power, Alpha, IA64, etc.) are represented and will have ABI
bindings published.
Drivers in UDI are implictly threaded. They don't know (and don't have
to care) how the OS schedules the code and how many processors are
available to do it.
There was concern about the spec changing over time. All the interfaces
(source and binary) are version controlled so a conforming environment
can run drivers as far back (or forward) as it can.
The spec publishes C bindings becuase those are the only ones defined
for most architectures. C++ ABI's are laughable at this point. The
suggesting of coding in assembly (have you tried to get a non-trivial
chunk of assembler through two different assemblers for the SAME
processor? How about different ones?
driver interface.
Please look at the white papers (if not the specs) at www.projectudi.org
before drawing conclusions. I read a lot of stuff that was just plain
fiction in these threads...