Edward Pilatowicz wrote: > On Wed, Jun 20, 2007 at 11:46:30AM +0700, Doug Scott wrote: > >> Hey, >> Just thought I would give you an update the progress I have made so >> far in building a Joystick driver for OpenSolaris. >> >> The goals of doing this was - >> 1) The least user intervention as possible. Asking a user to find >> their product and vendor ID and modify /etc/driver-aliases, or >> /kernel/drv/<driver>.conf is very undesirable. All that should be >> required is to plug in the joystick and run the game. >> >> 2) Try to be compatible (as possible) with existing >> drivers/libraries from BSD and/or Linux. >> >> 3) The driver should support all Joysticks which comply with the >> USB-HID joystick standard. Other devices are out of scope at the moment. >> >> 4) Try as much as possible to change existing drivers. (Maybe >> impossible) >> >> The Investigation >> ----------------- >> >> Currently when you plug in a USB joystick, it should automatically be >> attached to the Solaris hid driver. You can see that this has happened >> by simply looking through the /devices directory for a file with the >> minor name of 'hid_1_4' (The '1' is for a 'Generic Desktop Device' and >> the '4' is that is a joystick). >> >> doug at prae> find /devices -name \*hid_1_4 >> /devices/pci at 0,0/pci1043,815a at 2/input at 8:hid_1_4 >> /devices/pci at 0,0/pci1043,815a at 2/input at 7:hid_1_4 >> >> The problem here is that the hid driver has attached to the device, but >> has no idea what to do with them. The other issue is that there is no >> usable link added to /dev/usb which libusb.so can use. >> >> My first test was to attach the ugen driver to the device and build a >> user-land driver with libusb.so. This actually works quite well, as I >> was able to find all of the joystick buttons, axis etc, and read the raw >> data quite easily. Unfortunately this breaks goal 1, and requires to >> much user intervention. I knew that this would not be the ideal >> solution, but it was the easiest way to play around with the device and >> learn what it does :) >> >> The next test was to write a driver that attaches to the existing hid >> driver and correctly adds minor node for each joystick found. I started >> doing this by writing a Solaris layered driver. It correctly attached to >> all of the usb joysticks on my system and added a minor node for each >> physical joystick (some have 2 physical joysticks on the same usb hid >> device). By opening each minor node the raw values from each of the >> joysticks buttons, and axis could easily be read. Doing this I realised >> that by not only looking for just joysticks, but adding minor nodes for >> all hid devices which currently are not supported by the Solaris hid >> device driver, this would be a BSD uhid compatible device driver. So I >> change the name of the device to uhid, and ported the BSD libusbhid >> library to Solaris. This would allow the access to many other usb hid >> devices other than joysticks. At this point I thought I was on the home >> run. All I need to do was to implement the BSD uhid ioctl calls in my >> driver. >> >> Suddenly I hit a brick wall. Since the current hid driver within Solaris >> does not implement any ioctl calls (it's a stream driver so actually >> M_IOCTL), and you can not access the M_CTL calls though ioctl, going >> this direction is totally stuffed unless I change the uid driver to >> support the required M_IOCTL's. Therefore the layered driver 'uhid' >> would not be required, and I should just focus on modifying the current >> hid driver. >> >> > > out of curiousity, could the layered driver recieve ioctl messages > and then send them to the usb hid streams driver below via ldi_putmsg() > and ldi_getmsg()? (obviously with some translation between ioctl > and msg bufs going on.) >
I tested using ioctl(fd,I_STR,<cmd>) and putmsg from user-land before trying using the ldi_ interface. Once I realised that eithen if I could get a M_CTL call to work, the hid driver does not have a M_CTL call to return the raw hid report descriptor. Therefore I thought it would be simpler to change the hid device rather than writing a layered driver. >> The nice thing here is that the current code for M_IOCTL simply returns >> ENOTTY error. Therefore the changes are adding functionality rather than >> changing existing calls. At this point I am most of the way through >> adding the M_IOCTLS code to support a mofified BSD libusbhid library. >> Once I have finished the last bit of coding, I should be able to share >> the code changes for the hid driver, libusbhid, and libSDL. >> >> Any thoughts/questions/feedback >> >> Doug >> > > i'm far from a usb expert, but this seems like it might be the better way > to go. the ldi approach would probably have additional issues with device > discovery, configuration, and hotplug. ie. how would the layered driver > know when a joystick was plugged into the system? once it had a joystick > device opened, how would it know when that device was removed from the > system so that it could release/close that device? etc.] > I agree. When I first looked at the problem, the ideal way was to change the hid device driver. I was looking for a way that people could just add an independent driver first without going through the whole put-back/arc review process. My laziness :) I have yet to test whether the layered driver could handle removing the device while the device was open. My thoughts were, that this would be handled in the hid device, and the layered device would just simply block. It was on my list of things to test... > wrt modifying the hid driver, another option you might consider is > creating a streams module that could be pushed onto joystick hid > device stream automatically (by say dacf.conf(4)), and that module > could implement all the necessary ioctl support. > I was thinking of this before, but I would still need a way of getting the raw hid report descriptor back to userland. It is trivial to add this code within the hid device driver. Doug
