* Cannot read using USB Skeleton Driver
@ 2011-09-15 13:32 Felix Varghese
2011-09-16 7:01 ` Greg KH
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-15 13:32 UTC (permalink / raw)
To: kernelnewbies
Hi,
I have been trying to communicate with a custom usb device from a
SAM9G20-EK board using the usb-skeleton.c driver example in the linux
source. I modified the driver to add my device's vendor and product
id. The USB device enumerates with two bulk endpoints - one IN and one
OUT. The (modified) skel driver successfully detects my device and I
get a minor number allocated. After creating a device file with that
minor number, I am able to write into the device by typing 'echo "HI"
> /dev/mydevice'. I verified that this data arrives at my device
intact. Next, I started sending data back from the device and tried to
read it back using 'cat /dev/mydevice'. The problem is that read not
only doesn't work, but also makes the app get totally stuck. Ctrl-C
doesn't work and I have to reboot the board.
Some debugging using printk's led me to the following snippet which
seems to be causing the hang. If I change the wait to a
wait_for_completion_interruptible, Ctrl-C starts working, but still no
data is received.
if (!dev->processed_urb) {
/*
* the URB hasn't been processed
* do it now
*/
wait_for_completion(&dev->bulk_in_completion);
dev->bulk_in_copied = 0;
dev->processed_urb = 1;
}
Oh, btw I am using linux kernel 2.6.39.4. Any Ideas anyone??
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread* Cannot read using USB Skeleton Driver
2011-09-15 13:32 Cannot read using USB Skeleton Driver Felix Varghese
@ 2011-09-16 7:01 ` Greg KH
2011-09-16 11:29 ` Felix Varghese
0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2011-09-16 7:01 UTC (permalink / raw)
To: kernelnewbies
On Thu, Sep 15, 2011 at 07:02:59PM +0530, Felix Varghese wrote:
> Hi,
>
> I have been trying to communicate with a custom usb device from a
> SAM9G20-EK board using the usb-skeleton.c driver example in the linux
> source. I modified the driver to add my device's vendor and product
> id. The USB device enumerates with two bulk endpoints - one IN and one
> OUT. The (modified) skel driver successfully detects my device and I
> get a minor number allocated. After creating a device file with that
> minor number, I am able to write into the device by typing 'echo "HI"
> > /dev/mydevice'. I verified that this data arrives at my device
> intact. Next, I started sending data back from the device and tried to
> read it back using 'cat /dev/mydevice'. The problem is that read not
> only doesn't work, but also makes the app get totally stuck. Ctrl-C
> doesn't work and I have to reboot the board.
>
> Some debugging using printk's led me to the following snippet which
> seems to be causing the hang. If I change the wait to a
> wait_for_completion_interruptible, Ctrl-C starts working, but still no
> data is received.
>
> if (!dev->processed_urb) {
> /*
> * the URB hasn't been processed
> * do it now
> */
> wait_for_completion(&dev->bulk_in_completion);
> dev->bulk_in_copied = 0;
> dev->processed_urb = 1;
> }
>
> Oh, btw I am using linux kernel 2.6.39.4. Any Ideas anyone??
Odds are you need to send the proper command to your device in order to
get it to send data to you. You are hanging, waiting for device to be
sent from the device to userspace, and if no data is sent, then it will
continue to wait.
So, please read the documentation on how to talk to your device and send
the proper USB commands to it and all should be fine.
But note, the usb-skeleton driver really isn't a good framework for a
"real" USB device in that it doesn't expose the proper userspace
interface for it.
What type of device is this you are wishing to write a driver for? That
will determine the type of interface you need to use, odds are it is not
going to be a simple char device.
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread* Cannot read using USB Skeleton Driver
2011-09-16 7:01 ` Greg KH
@ 2011-09-16 11:29 ` Felix Varghese
2011-09-16 14:31 ` Greg KH
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-16 11:29 UTC (permalink / raw)
To: kernelnewbies
> What type of device is this you are wishing to write a driver for? That
> will determine the type of interface you need to use, odds are it is not
> going to be a simple char device.
The device is a custom USB dongle whose firmware is also under
development. We are still in the process of deciding what it should
actually show up as on the linux side but right now, we decided to use
a character device for simplicity reasons until we have simple two-way
communication over USB up and running. Since I am writing the firmware
on the device side too, it had indeed been (and still is) my first
suspect :). But I checked the code multiple times and now I am
reasonably sure that I am in fact, doing all that is required to send
out data properly. Besides, data transfer in the other direction works
fine. I have registered only one IN and one OUT endpoint apart from
endpoint 0 and I try to send my data through the IN end-point.
I noticed that after making the wait interruptible, if I hit Ctrl-C
while we are hanging on a read, the device side shows transfer
complete. So the device, apparently, thinks the data has been sent
successfully when we have actually aborted the transfer at the other
end! Shouldn't this mean that something happens after coming out of
the wait_for_completion that really makes the transfer happen?
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-16 11:29 ` Felix Varghese
@ 2011-09-16 14:31 ` Greg KH
2011-09-19 5:43 ` Felix Varghese
0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2011-09-16 14:31 UTC (permalink / raw)
To: kernelnewbies
On Fri, Sep 16, 2011 at 04:59:08PM +0530, Felix Varghese wrote:
> > What type of device is this you are wishing to write a driver for? That
> > will determine the type of interface you need to use, odds are it is not
> > going to be a simple char device.
>
> The device is a custom USB dongle whose firmware is also under
> development. We are still in the process of deciding what it should
> actually show up as on the linux side but right now, we decided to use
> a character device for simplicity reasons until we have simple two-way
> communication over USB up and running. Since I am writing the firmware
> on the device side too, it had indeed been (and still is) my first
> suspect :). But I checked the code multiple times and now I am
> reasonably sure that I am in fact, doing all that is required to send
> out data properly. Besides, data transfer in the other direction works
> fine. I have registered only one IN and one OUT endpoint apart from
> endpoint 0 and I try to send my data through the IN end-point.
For real simplicity, just use the usb-serial generic interface and you
will get a tty device node created for you that you can read and write
data from.
Just do:
modprobe usb_serial vendor=0x0000 product=0x0000
with the proper vendor and product ids for your device, then plug it in.
No kernel changes needed at all, just have a pair of bulk in/out
endpoints and all will work automatically for you.
But that interface is slow as there is only one urb in flight at any
point in time, so don't rely on that for anything but basic development
and testing.
> I noticed that after making the wait interruptible, if I hit Ctrl-C
> while we are hanging on a read, the device side shows transfer
> complete. So the device, apparently, thinks the data has been sent
> successfully when we have actually aborted the transfer at the other
> end! Shouldn't this mean that something happens after coming out of
> the wait_for_completion that really makes the transfer happen?
Look at the USB data on the wire to make sure that you really are
sending data properly.
good luck,
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-16 14:31 ` Greg KH
@ 2011-09-19 5:43 ` Felix Varghese
2011-09-19 12:38 ` Greg KH
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-19 5:43 UTC (permalink / raw)
To: kernelnewbies
> Just do:
> ? ? ? ?modprobe usb_serial vendor=0x0000 product=0x0000
> with the proper vendor and product ids for your device, then plug it in.
>
> No kernel changes needed at all, just have a pair of bulk in/out
> endpoints and all will work automatically for you.
Thanks Greg, I had thought that the usbserial driver would only work
with proper CDC class virtual COM devices.
I compiled it and tried it on my device and it worked fine! I was able
to do bidirectional communication. So at least now I can be sure that
one end is working. But the same device with the same firmware still
doesn't work with the (customized) usb-skeleton. What could be wrong?
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-19 5:43 ` Felix Varghese
@ 2011-09-19 12:38 ` Greg KH
2011-09-19 13:21 ` Felix Varghese
0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2011-09-19 12:38 UTC (permalink / raw)
To: kernelnewbies
On Mon, Sep 19, 2011 at 11:13:33AM +0530, Felix Varghese wrote:
> > Just do:
> > ? ? ? ?modprobe usb_serial vendor=0x0000 product=0x0000
> > with the proper vendor and product ids for your device, then plug it in.
> >
> > No kernel changes needed at all, just have a pair of bulk in/out
> > endpoints and all will work automatically for you.
>
> Thanks Greg, I had thought that the usbserial driver would only work
> with proper CDC class virtual COM devices.
> I compiled it and tried it on my device and it worked fine! I was able
> to do bidirectional communication. So at least now I can be sure that
> one end is working. But the same device with the same firmware still
> doesn't work with the (customized) usb-skeleton. What could be wrong?
As I don't know what you customized exactly, nor how your hardware
exactly works, I could not say, sorry.
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-19 12:38 ` Greg KH
@ 2011-09-19 13:21 ` Felix Varghese
2011-09-19 13:46 ` Greg KH
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-19 13:21 UTC (permalink / raw)
To: kernelnewbies
Oh I don't think I have customized it to the point of breaking it. I
just modified the VID and PID to those of my device. And later, when I
noticed where it was getting stuck, I changed the wait_for_completion
to wait_for_completion_interruptible (in the code snippet quoted
previously) so that I could recover with Ctrl-C instead of a reboot.
And my hardware works fine with the usbserial driver you suggested (I
can read/write to it from a simple terminal program). But, to develop
a full-fledged driver, the skeleton driver seemed like a better
starting point, which is I am still trying to get it working.
The condition which causes the code to wait for eternity (from the
line I quoted in one of my previous mails) seems to be: if
(!dev->processed_urb)
But I notice that this variable is not true even for the first read.
So the code seems to wait for the completion of something that has not
yet started. Also, I do not see this variable being explicitly set to
false either, anywhere within the driver. I may be on the wrong track,
but isn't this variable one that is used only within our driver? If
so, what exactly is it used for, considering that it is only set to 1
(never to 0) and is 0 initially?
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-19 13:21 ` Felix Varghese
@ 2011-09-19 13:46 ` Greg KH
2011-09-20 3:49 ` Felix Varghese
0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2011-09-19 13:46 UTC (permalink / raw)
To: kernelnewbies
On Mon, Sep 19, 2011 at 06:51:18PM +0530, Felix Varghese wrote:
> Oh I don't think I have customized it to the point of breaking it. I
> just modified the VID and PID to those of my device. And later, when I
> noticed where it was getting stuck, I changed the wait_for_completion
> to wait_for_completion_interruptible (in the code snippet quoted
> previously) so that I could recover with Ctrl-C instead of a reboot.
> And my hardware works fine with the usbserial driver you suggested (I
> can read/write to it from a simple terminal program). But, to develop
> a full-fledged driver, the skeleton driver seemed like a better
> starting point, which is I am still trying to get it working.
>
> The condition which causes the code to wait for eternity (from the
> line I quoted in one of my previous mails) seems to be: if
> (!dev->processed_urb)
> But I notice that this variable is not true even for the first read.
> So the code seems to wait for the completion of something that has not
> yet started. Also, I do not see this variable being explicitly set to
> false either, anywhere within the driver. I may be on the wrong track,
> but isn't this variable one that is used only within our driver? If
> so, what exactly is it used for, considering that it is only set to 1
> (never to 0) and is 0 initially?
You might be right and the code might be wrong, care to send a patch for
it correcting the issue?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-19 13:46 ` Greg KH
@ 2011-09-20 3:49 ` Felix Varghese
2011-09-21 13:29 ` Felix Varghese
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-20 3:49 UTC (permalink / raw)
To: kernelnewbies
> You might be right and the code might be wrong, care to send a patch for
> it correcting the issue?
Would be glad to do that, if I am able to resolve the issue.
Meanwhile, any insights from anybody on this would be welcome!
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Cannot read using USB Skeleton Driver
2011-09-20 3:49 ` Felix Varghese
@ 2011-09-21 13:29 ` Felix Varghese
2011-09-21 16:00 ` Greg KH
0 siblings, 1 reply; 11+ messages in thread
From: Felix Varghese @ 2011-09-21 13:29 UTC (permalink / raw)
To: kernelnewbies
With some modification, I have finally made the skel driver work with
my device. I think I have some initial theories about the root cause
of the problems that I ran into with skel:
1) The condition if (!dev->processed_urb) is always false in the
beginning and this induces a wait without any scope for completion, so
it has to be removed.
2) A blocking read and blocking write cannot happen simultaneously.
This is because in read, we go to sleep after locking a mutex
'iomutex'. Before writing, we try to lock the same mutex, so if we try
to write() from one thread (or process) while waiting for read() to
complete in another, we will have both threads blocked, waiting
indefinitely for each other (the device won't respond until you send
data to it). This can be fixed by unlocking the mutex before entering
into the wait but then that mutex might be there for a reason and I
might be doing the wrong thing.
3) If the buffer associated with your read urb is not big enough to
accommodate the packet that arrives over USB, the transfer request
will fail with error -75 in the completion callback. We could handle
this by either propagating the error back to the user or by issuing
transfer requests with big enough buffers and keeping the data
buffered until the user asks for it. Then we could give as much data
as he asks for and keep the rest buffered. But in the latter case, the
user may issue a read() call expecting a transfer to happen, but he
might not necessarily see one (in case there is data already
buffered). Also the buffer size would be somewhat arbitrarily chosen
which is not nice.
Does anybody have anything to add or oppose on this or would you guys
rather have me send a patch along with my changes?
Regards,
Felix.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-09-21 16:00 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-15 13:32 Cannot read using USB Skeleton Driver Felix Varghese
2011-09-16 7:01 ` Greg KH
2011-09-16 11:29 ` Felix Varghese
2011-09-16 14:31 ` Greg KH
2011-09-19 5:43 ` Felix Varghese
2011-09-19 12:38 ` Greg KH
2011-09-19 13:21 ` Felix Varghese
2011-09-19 13:46 ` Greg KH
2011-09-20 3:49 ` Felix Varghese
2011-09-21 13:29 ` Felix Varghese
2011-09-21 16:00 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).