Duncan Haldane wrote:
On 18-Nov-2002 Mark McClelland wrote:
Duncan Haldane wrote:
>If two cameras are registered, one on /dev/video0 and one on /dev/video1,
>and I use e.g. xawtv or gqcam to monitor them, I cannot open /dev/video1
>when /dev/video0 is open and vice-versa. This happens for two cpia
>devices and one cpia + one ov511 device.
That's because both cameras are trying to use nearly all of the USB's
bandwidth. Or, more precisely, each is trying to schedule an ISO packet
Yes, this seems correct: I have now traced the problem to disruption of
communication of commands to/from the cpia cam (ReadPacket() in cpia_usb.c/
cpia_usb_transferCmd()). This eventually causes de/re-registration of
the camera, leaving a frozen viewer window that needs a reboot to clear
it.... (incomplete cleanup ?) -- nasty.
OK, that makes sense. I've seen that with ov511 too occasionally, but I
have yet to find the exact cause.
Is there any kind of locking that cpia_usb_transferCmd could use to
temporarily grab the full usb bandwidth for camera control (so this takes
precedence over data transfer by other devices?)
Not that I know of. This issue was discussed briefly on linux-usb-devel
recently, but nothing came of it. (I'm CCing that list)
CONFIG_USB_BANDWIDTH might help if it can prevent the second camera from
submitting the ISO URB, but in my experience it causes more problems
than it solves.
At the very least I would hope to prevent hanging that requires a reboot!.
Agreed. I'm not sure why that happens, but I suspect the cpia driver is
at fault since lots of drivers have no problem with random disconnects.
It's possibly something to do with the synchronous calls (eg.
usb_control_msg()) being active when disconnect() gets called. There's
no solution to that currently, other than to use the async calls (ie.
usb_submit_urb()) and implement the necessary locking yourself. I'd also
check all of the codepaths that handle signals (eg. interrupted
syscalls), and check for function returns that don't drop all held
locks. I looked it over briefly, and nothing jumps out at me.
If you can't find anything, put a ton of printks in disconnect() and
close() and see where it hangs :)
<snip>
Check the descriptors. As long as there's an alternate setting where
MxPS <= 1023 / 2 then you should be in business. You can either have the
packet size or alternate number be a module param, or you can do a
"cams" thing like ov511. Or, you can allow the frame rate to be set
somewhere, and have the driver automatically choose the minimum possible
packet size that can still sustain that frame rate.
Mark, I attach a bzipped copy of cpia_usb.c, could you cast your experienced
eye over it to see where a setting like this could be controlled, and point
me at it? I gather that your ov511 code originally derived somewhat from
cpia driver code, maybe you can recognize something?
My idea about auto-adjusting the alternate setting based on the
framerate is probably too difficult for a driver this complex, since
features like compression make it difficult to know the minimum
necessary bandwidth. I recommend doing what ov511 does instead (allow
user to input the number of cameras in /proc or as a module param,
determine a packet size based on that, and set the corresponding
alternate setting in cpia_usb_open()).
--
Mark McClelland
mark@xxxxxxxxxxxxxxxx