Discussion:
USB Mouse simulation using GadgetFS API, continued
Colleen Przybyla
2004-02-27 13:59:48 UTC
Permalink
Hello again,

I had written previously in regards to getting an embedded PXA255 chip
to work as a simulated USB mouse using the GadgetFS API. I have been
able to properly alter the example usb.c code example from GadgetFS to
initialize properly as a USB mouse. It uses only the control ep0
thread. Using the USB Snooper, the mouse sends all of the required
descriptors (including the HID report descriptor) to the host when
required. However, in trying to implement what I thought would be the
'easiest' part of the code, writing the simulated mouse bytes to the
endpoint, I am encountering some major problems.

After the device sends the HID report descriptor to the host, the device
is unable to perform any additional writes to fd. I have printed out
the contents of the buffer after filling them in with the desired 'mouse
movement byte', and this works perfectly. It is only when I attempt to
write this buffer to fd that I receive the (-1) message. I have tried
writing this buffer in numerous places of the code following the report
descriptor, and the write fails every time. The errno on the failure is
ESRCH = No such process. I thought perhaps there was a problem writing
the 'mouse bytes', and have simplified the code to simply try writing a
small buffer. This write also fails each time, in each spot of the
code. I believe that in using the control endpoint, the host will poll
the endpoint for the information (from the usb spec, it seems that the
host polling does not have a specific bRequestType, it simply uses the
bRequest = 9 (class) and looks for a report of the correct format). I
have followed the USBSnoop traces for both a working mouse, as well as
this attempt at an embedded simulation mouse, and the snoops for both
mice are exactly the same. (Which is disheartening as the working mouse
moves, while this simulation fails each time it is attempted!)

I would appreciate any help on this last piece of the puzzle! I asked a
few of my coworkers about this problem yesterday, and after trying the
write in numerous places over quite a few hours, this problem has each
of us completely stumped. (Also, thank you Dave for clarifying the
Control out/in transfers. I initially thought maybe this problem was
occurring due to my thinking of these incorrectly! I almost wish it had
been that 'quick' of a solution.)

I have attached the modified usb.c code which now initializes as a
Logitech USB mouse. Right now, the code uses the s_iCounter to tell
which USB request is being sent, and after the report descriptor is
sent, it attempts to write a simple buffer to fd. I'd greatly
appreciate any help, we are all scratching our heads on this end. I've
looked through the USB spec and Google, and this does not seem to be a
well documented problem.

Thank you,
Colleen
David Brownell
2004-02-28 02:40:03 UTC
Permalink
Post by Colleen Przybyla
Hello again,
I had written previously in regards to getting an embedded PXA255 chip
to work as a simulated USB mouse using the GadgetFS API. I have been
able to properly alter the example usb.c code example from GadgetFS to
initialize properly as a USB mouse. ...
Good start. I suspect user mode is exactly the right place to start
building some HID infrastructure, too!
Post by Colleen Przybyla
After the device sends the HID report descriptor to the host, the device
is unable to perform any additional writes to fd.
The fragment of code you sent was trying to send two separate data
stages for one control request. That's not going to work; write
the control-IN response all at once. You already have a loop that's
filling out the response data ... it can add more data.

Remember that all control responses are just going to be one read()
or write() system call.
Post by Colleen Przybyla
I have tried
writing this buffer in numerous places of the code following the report
descriptor, and the write fails every time. The errno on the failure is
ESRCH = No such process.
If you look at the source to gadgetfs, you'll notice that's a
response code used in a very few places. Two spots were
initialization; you're well past those. The ep0_read() and
ep0_write() paths were two others.

Given what you said, I'll guess this is in ep0_write(). I saw
this value getting returned on two paths, each with a different
debug message:

} else {
DBG(dev, "bogus ep0out stall!\n");
}
} else
DBG (dev, "fail %s, state %d\n", __FUNCTION__, dev->state);

You probably hit the second case: no control request was
pending, since the previous write() completed the response.
("No process was expecting that response!")


Try leaving debug messages on in gadgetfs for a while. Normally,
only "interesting" paths like faults (and some initialization
or shutdown actions) cause messages. Or there's "VERBOSE"...

- Dave





-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Colleen Przybyla
2004-03-04 19:39:38 UTC
Permalink
Post by David Brownell
You probably hit the second case: no control request was
pending, since the previous write() completed the response.
("No process was expecting that response!")
Try leaving debug messages on in gadgetfs for a while. Normally,
only "interesting" paths like faults (and some initialization
or shutdown actions) cause messages. Or there's "VERBOSE"...
- Dave
Thanks for the suggestion. I did try incorporating the data into the
existing loop, and it was able to write to the buffer. However, the
host didn't recognize that as 'mouse movement'. I referred to other
sources regarding this problem, it seems that the data I am trying to
send is not in response to a control request, so incorporating the data
into that main loop will not work (the host polls by sending an IN
packet alone - no control request.)

I decided to write the mouse movements by creating a separate thread,
and an additional interrupt-IN endpoint in gadgetfs that the host can
poll, which will create a separate fd to write the mouse movement bytes
to. However, it seems that I am still having problems with "write" -
this time in ep_config.

When ep_config is called from the simple_source_thread function, it
correctly opens a new fd for this endpoint. Memcpy -ing the endpoint
descriptor data returns a pointer to memory, as it should. However,
when the function enters the
status = write(fd, buf, (4+USB_DT_ENDPOINT_SIZE);
portion of the code, I receive the EBUSY error. From consulting the
gadgetfs kernel code, it seems that ep_open is having a problem such
that the endpoint data->state is not entering STATE_EP_DISABLE loop as
it should be to write the data. It appears to me that the data
structure and inode values are filled in without my knowledge, and are
not attributes that I can set. Is there a way to set this in the user
level code initially so that the endpoint will configure properly?

Thanks,
Colleen



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
David Brownell
2004-03-06 03:10:47 UTC
Permalink
Post by Colleen Przybyla
When ep_config is called from the simple_source_thread function, it
correctly opens a new fd for this endpoint. Memcpy -ing the endpoint
descriptor data returns a pointer to memory, as it should. However,
when the function enters the
status = write(fd, buf, (4+USB_DT_ENDPOINT_SIZE);
portion of the code, I receive the EBUSY error. From consulting the
gadgetfs kernel code, it seems that ep_open is having a problem such
It happens on endpoint open(), and also when trying to write
a response on ep0 in certain cases. If you enabled DEBUG (as
I suggested) the "dmesg" output should help say which it was.

Maybe you forgot to use the "interrupt" endpoint file descriptor
when writing your response.
Post by Colleen Przybyla
that the endpoint data->state is not entering STATE_EP_DISABLE loop as
it should be to write the data. It appears to me that the data
structure and inode values are filled in without my knowledge, and are
not attributes that I can set. Is there a way to set this in the user
level code initially so that the endpoint will configure properly?
From user space, just stick to the file system API ... if for any
reason that's not working, it's just a bug. It should keep you from
being too wrong. In this case it sounds like you've strayed off the
path of righteousness by some indeterminate amount.

- Dave




-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Colleen Przybyla
2004-03-11 17:45:48 UTC
Permalink
Post by David Brownell
From user space, just stick to the file system API ... if for any
reason that's not working, it's just a bug. It should keep you from
being too wrong. In this case it sounds like you've strayed off the
path of righteousness by some indeterminate amount.
- Dave
I'm trying to work my way though the debug messages from the kernel, and
I had a couple of questions. I've inserted my own 'printk' commands
alongside of each DBG line of code as I've had some trouble turning on
verbosity and debug messages in make config. I've tried enabling a
variety of the different 'debug' options with no success on seeing the
printouts. Is there a simple way to do this which will eliminate the
need for all the 'printk' statements?

For the time being however, the printk statements are providing the same
functionality as the DBG messages would. I've been able to follow the
endpoint configuration through from the printk output statements.

The user level program is trying to set up and configure an IN "ep1"
which is described by an interrupt endpoint descriptor.

The kernel messages show that upon a SET_CONFIGURATION request, gadgetfs
properly attempts to set up the endpoint by running ep_open successfully
and entering into ep_config. However, in both of these functions, the
kernel is trying to set up ep->name "ep2out-bulk", not "ep1".
"ep2out-bulk" is not defined anywhere in the user level code, nor in the
inode.c file. I haven't been able to determine how the epfiles list of
endpoints is set up for the API, or how the entries to this was defined.
How would I set this list to configure the endpoint I'm calling from the
user level code? It seems that the user level code would be able to
complete the ep configuration correctly if the kernel were configuring
the correct endpoint....

Best,
Colleen



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
David Brownell
2004-03-12 18:26:44 UTC
Permalink
Post by Colleen Przybyla
Post by David Brownell
From user space, just stick to the file system API ... if for any
reason that's not working, it's just a bug. It should keep you from
being too wrong. In this case it sounds like you've strayed off the
path of righteousness by some indeterminate amount.
- Dave
I'm trying to work my way though the debug messages from the kernel, and
I had a couple of questions. I've inserted my own 'printk' commands
alongside of each DBG line of code as I've had some trouble turning on
verbosity and debug messages in make config. I've tried enabling a
It's not a "config" option. Just enable the lines at the top
of the "inode.c" source file.
Post by Colleen Przybyla
variety of the different 'debug' options with no success on seeing the
printouts. Is there a simple way to do this which will eliminate the
need for all the 'printk' statements?
For the time being however, the printk statements are providing the same
functionality as the DBG messages would. I've been able to follow the
endpoint configuration through from the printk output statements.
The user level program is trying to set up and configure an IN "ep1"
which is described by an interrupt endpoint descriptor.
I don't think any of the currently available controller drivers
have an endpoint with that name...
Post by Colleen Przybyla
The kernel messages show that upon a SET_CONFIGURATION request, gadgetfs
properly attempts to set up the endpoint by running ep_open successfully
and entering into ep_config. However, in both of these functions, the
kernel is trying to set up ep->name "ep2out-bulk", not "ep1".
You were using the 2.4 version of the driver, right? That's
probably where the issue came up. You had to "mknod" a bunch
of character special files, and didn't match their minor
numbers to match what the controller driver uses.

See the attached script.

This particular set of issues wouldn't come up if you did the
work on a 2.6 kernel. It's one of the reasons that the 2.4
version of "gadgetfs" is particularly "experimental". (And
in fact, on 2.4 it's not actually a filesystem ... although
the user mode API is the same as on 2.6, where it is.)
Post by Colleen Przybyla
"ep2out-bulk" is not defined anywhere in the user level code, nor in the
inode.c file. I haven't been able to determine how the epfiles list of
endpoints is set up for the API, or how the entries to this was defined.
Actually the names don't matter as much as how they correspond
to the names used by the gadget controller. "ep2out-bulk" makes
me think you've got a pxa2xx_udc driver.

In that case you'll want something "mknod ep1in-bulk c 240 1".
Post by Colleen Przybyla
How would I set this list to configure the endpoint I'm calling from the
user level code? It seems that the user level code would be able to
complete the ep configuration correctly if the kernel were configuring
the correct endpoint....
This is an advantage of using the 2.6 gadgetfs code, which can
throw the names from the gadget controller right into the file
system, and keep problems like that from happening.

Of course, someone could also do the same thing with the 2.4
code, but that person would need to be more fluent in how
the 2.4 filesystem code works than I am. And it's just a lot
easier to do this stuff on 2.6 in any case ... :-)

- Dave
Post by Colleen Przybyla
Best,
Colleen
Loading...