Hello,
Tnxs for Alan's detailed answer; it really shed light on the problem.
After reading it , it came to my mind to perform another (last ?) test:
I had noticed that when using default alternate setting of the driver ,
when everything works OK and there is no usb error, the MXPs of the EndPoint is 292.
However, the actual_length of the urb->iso_frame_desc[i].actual_length is 291 !
(in the driver completion ,namely in pwc-if pwc_isoc_handler()).
And as you would expect, the urb->iso_frame_desc[i].actual_length is also 291 in usb-ohci.c.
It is one less the MxPs of the EndPoint. So I set the urb->iso_frame_desc[i].actual_length to 195 in the usb-ohci.c and used alternate setting 1 (where MxPs is 196) .
No I do not have the -75 error (-EOVERFLOW).
But now there is another probelm, so it seesm to me :
It seems to me that in the pwc driver (so I understand from the source and the documenatation inside) it recognizes EOF in a manner which is good for ther default setting (it seems to me that
in such a case a shorter packet arrives, and when identifying such shorter packet this is a sign of the
EOF).And when using alternate setting 1 , with constantly setting the size to 195 ,
we don;t receive a shorter packet.
Now I try to delve in 2 usb issues:
How can I recognize and EOF packet ? is it by testing it's first 8 bytes (should be equal to 0)
and some value for the 9th byte ? (I saw it in some usb webcam driver code).
The second is:
how, when using default setting, the urb->iso_frame_desc[i].actual_length is set to one less than
MxPs (namely , to 291 intead 292; 202 is the MxPs of the EndPoint).
Regards, John
From: Alan Stern <[EMAIL PROTECTED]>
To: John Que <[EMAIL PROTECTED]>
CC: [EMAIL PROTECTED]
Subject: Re: [linux-usb-devel] actual_length of iso_frame_desc is 0 in handler after usb_
Date: Thu, 15 Jul 2004 10:43:55 -0400 (EDT)
On Thu, 15 Jul 2004, John Que wrote:
> Hello,
> Alan said:
> >More likely is that the packet
> >is larger than urb->iso_frame_desc[td->index].length
>
> I had added a check in the completion callback
> (pwc_isoc_handler)
> in the beginning of loop that iterates on the urb packets:
> .....
> for (i = 0; i < urb->number_of_packets; i++)
> {
> if ( urb->iso_frame_desc[i].actual_length > urb->iso_frame_desc[i].length)
> Err(KERN_ERR "actual_length>length");
> else
> Err(KERN_ERR "actual_length<=length");
>
> By running the app , I see the actual lenght is NEVER bigger than length.
Yes, that is always true. What you don't realize is that the .actual_length field isn't equal to the true length of the packet _if_ the packet is larger than the .length field. When a packet is longer than .length, then .actual_length is set to the amount of data that was stored in the buffer and -EOVERFLOW is set. The hardware doesn't provide any way to determine how long the packet really was.
> I see that the length is 196. (It is the "expected length" as I understand).
That's right.
> in the first iterations , actual length is 0 ; > afterwards it is 196
That is the same as the maxpacket value, right? So if the packet is longer than 196 bytes then it is longer than maxpacket. That's not impossible but it indicates a bug in the camera.
> I did also delved into the ohci layer. I looked in usb-ohci.c ; > I added some printing messages there ; and I know (see detial a little > below) > where it > does change the urb->iso_frame_desc[i].status to -75 (EOVERFLOW) > The urb (with this iso_frame_desc array) > is sent to the completion handler. > > But I do not know why this happens.
It happens because the controller says that the packet's true length was bigger than the .length field.
> details : there is a method there called dl_transfer_length().
> This message calculates the transfer length and updates the urb.
> In this message there is a calcaulation of the status field
> (urb->iso_frame_desc[i].status).
> This is done in this way :
> cc in an integer :
> it's valus is cc = (tdPSW >> 12) & 0xF;
>
> This integer is an index to an array of statuses.
> In the first entrances to the dl_transfer_length() it's value is 9.
> when it's value is 0
> the urb->iso_frame_desc[].status is set to 0 in dl_transfer_length().
>
> Then it becomes 8; and when it is 8,
> the urb->iso_frame_desc[].status is set to -75 in dl_transfer_length().
> a further look in cc_to_error[16] in the header usb-ohci.h explains why :
> an index pf 8 is USB_ST_DATAOVERRUN ;
> and in usb.h , you will find #define USB_ST_DATAOVERRUN (-EOVERFLOW)
>
> (BTW, you might wonder why , when status is 9 , it retruns status 0 ;
> the reason is : in the dl_transfer_length() , you have , a little
> afterwards:
> .....
> if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN))
> cc = TD_CC_NOERROR;
> and TD_DATAUNDERRUN is 9 (you have #define TD_DATAUNDERRUN 0x09 is
> usb-ohci.h).
TD_DATA_UNDERRUN means than .actual_length < .length; this isn't an error unless URB_SHORT_NOT_OK is set. In Linux 2.4, USB_DISABLE_SPD is a synonym for URB_SHORT_NOT_OK; in 2.6 that identifier is gone completely. In other words, this piece of code says that if the packet was shorter than expected then it's not an error unless the caller asked for it to be an error.
> This urb (with iso_frame_desc array where > iso_frame_desc[i].status=-75 is sent back to the completion handler, > which is pwc_isoc_hadler. > It is done in sohci_return_urb, in the case PIPE_ISOCHRONOUS > of the switch sentence. There is a call to urb->complete (urb) there. > > so the problem seems to be related somehow to tdPSW. > the psw is the packet status word ; and in fact, it value is > tdPSW = le16_to_cpu (td->hwPSW[0]); > > I do not know why this problem is caused.
hwPSW is set by the hardware. In this case it's set to indicate that the packet's length was larger than .length, and that's an error. The error is caused by the camera sending a packet longer than it should be.
Alan Stern
_________________________________________________________________
STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail
------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
