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

Reply via email to