Look, I'm not advocating running the fucking filesystem or a network driver in the userspace. I advocate running leaf drivers there -- such as application-specific USB drivers and the console. The console "driver" doesn't provide services used by any other applications. It receives stuff from the kernel and does something with it, and there it ends. It's just like the audit deamon!
When you have exclusive device ownership by an application, with app-specific USB devices, etc., there's absolutely no point in having a device-specific kernel driver. None. Those devices generally are data sinks or sources, and you don't need anything in the kernel besides the regular USB host stack. All of the requests can be handled by the userspace without loss of performance. I know, I've done that, and it works great. FTDI's unix drivers are completely broken on OS X since they use libusb, and libusb doesn't know how to deal with sub-second timeouts on OS X because it uses the wrong APIs that only time out with a second granularity. Thus I've written my own userspace driver from scratch, and it performs beautifully. I can have a bog-standard userspace process get worken up every two milliseconds to process incoming bulk transfer, and to respond to it. It allows regular userspace to provide soft-realtime kind of performance -- I can easily get 3ms device-to-device latency, with userspace application in the middle. It's very useful for prototyping, where occasional glitches can be worked around or even ignored.
Same goes for Windows, where FTDI's stupid driver doesn't feel it necessary to inform you that the device got disconnected. Basically FTDI's driver is written mostly for the braindead blocking kind of use, and they have half-heartedly added an event source that signals arrival of data and change in control line status. I mean give me a fucking break, how stupid that is -- obviously in their minds no one cares if the device has gone away, or when a data transfer had finished, etc. Anyway, that driver code works on OS X using their USB api, Linux using their api, and Windows using UMDF. The performance on all of the platforms is exactly the same. So I specifically don't buy any bullshit arguments about userspace being slow. Yeah, if you need to go back and forth between kernel, userspace driver, kernel, and other applications -- like for networking, filesystems, block devices etc, then sure it's slow. If your application is the sole user of a device, there are few if any benefits to having a kernel driver -- at least if a lower-level kernel driver already handles the bus transaction queuing, as is the case in any modern device bus you can think of (ata/sata, usb, modern pci, etc.). If you want to stream data at a low overhead between the USB device and the userspace, the userspace driver merely needs to keep the device's request queue filled in the host stack, and keep the finished requests drained. That's all there's to it, and it works well, and I can easily keep the device saturated -- running at a rate limited by the device itself and the host usb stack. I can transfer about 33 megabytes/s when talking to FT232H chip connected to a fast CPU -- and that's without trying particularly hard. So, again, I don't buy bullshit arguments that don't stand to a simple experimental confirmation. Remember: the ultimate test is the experiment. Nothing else matters.