I've been toying with a Cypress EZ-USB FX chip for a few weeks nows. I
can quite easily tranfer things using Bulk or Interrupt transfers. Heck,
even control transfers are fine. But I cannot use isochornous transfers.
All of the packets arrive error free with status=0 but there is
absolutely no information in them - it's like I'm transferring
transfering garbage. For example I can get a packet
that's
0, 0, 0, 0, 0, 0, 0, 0, 20, 30
where in fact I attempt to transfer
1, 1, 1, 1, 1, 1, 1, 1, 1, 1
The number of bytes always seems correct but the transfered stuff
doesn't make sense.
If you would make a guess, is my firmware hossed [I even used the sample
firmware from windows dev. kit on Cypress webpage] or my driver or the
kernel? [2.4.18]
I'm not sure if this is related to the following thing (I'm kind
of a newbie in kernel programming :). When I try to store
a packet in the ISO callback routine in a buffer that >4k
and then I try to move it to user space with copy_to_user
I get
<10 bytes of stuff here> <zeros to end of the 4k page>
<10 same bytes as above> <zeros to end of 5k>
ie. the buffer is set to 32k allocated with GFP_ATOM [I'm assuing it
might be needed in the iso callback, anyone?] I set it to all 0
after I allocate it in the probe. Then I move 10 bytes into it
with just
for(i=0;i<10;i++)
big_buffer[i] = urb->transfer_buffer[urb->isopacket->buffer_offset+i];
[some structure members were changed to protect the innocent]
Then I transfer it in a read routine to userspace like
copy_to_user(user_buffer, big_buffer, 5*1024); // buffer is 32k :)
Why do I see same thing at offset 0 and 4k?
Do you have set the start addresses for the tranfer buffers for _each_ frame?
Ie. allocating n frames with usb_alloc_urb(n), and then setting
urb->iso_frame_desc[i].offset and .length for i in 0 to n-1. The offset is meant
to be the offset relative to urb->transfer_buffer, usually it is i*length.
--
Georg Acher, ac...@in.tum.de
http://wwwbode.in.tum.de/~acher
"Oh no, not again !" The bowl of petunias
First, sorry it took so long to reply. :) I looked for about a day for a
reply and then I didn't check the newsgroup until now..
Anyway, yes, I allocated N frames and set the thing up. In probe(...) I do:
static void * box_probe(struct usb_device *udev, unsigned int ifnum,
const struct usb_device_id *id)
{
......
/* Ok, this is the ISOCHRONEOUS EP that we need */
dbg("Iso IN Ep: %d", (int)(endpoint->bEndpointAddress &
USB_ENDPOINT_NUMBER_MASK));
dev->iso_in_packet_size = endpoint->wMaxPacketSize;
dev->iso_in_endpointAddr = endpoint->bEndpointAddress;
/* Now, let's allocate the URBs we'll use with this endpoint */
for(j=0;j<NUM_ISO_URBS;++j){
dev->in_iso_urb[j] = usb_alloc_urb(NUM_ISO_PACKETS_PER_URB);
if(!dev->in_iso_urb[j]){
err("No more free URBs!!");
goto error;
}
}
for(j=0;j<NUM_ISO_URBS;++j){ /* NOTE: First URBs have to be
allocated since we have to fill in $
parameter.
*/
if(dev->iso_in_buffer[j])
dbg("This EP was already allocated??? WEAIRD!!! FIX ASAP");
dev->iso_in_buffer[j] = kmalloc (dev->iso_in_packet_size *
NUM_ISO_PACKETS_PER_URB, GFP_KERNE$ if(!dev->iso_in_buffer[j]){
err("Couldn't allocate iso_in_buffer");
goto error;
}
/* Now we need to create the URB making sure we daisy chains
them */
spin_lock_init(&(dev->in_iso_urb[j])->lock);
dev->in_iso_urb[j]->dev = udev;
dev->in_iso_urb[j]->pipe = usb_rcvisocpipe(udev,
endpoint->bEndpointAddress & USB_ENDPOINT_NU$
dev->in_iso_urb[j]->transfer_buffer = dev->iso_in_buffer[j];
dev->in_iso_urb[j]->complete = box_iso_read_callback;
dev->in_iso_urb[j]->transfer_flags = USB_ISO_ASAP;
if(j==(NUM_ISO_URBS-1)) /* last URB goes to first one */
dev->in_iso_urb[j]->next = dev->in_iso_urb[0];
else
dev->in_iso_urb[j]->next = dev->in_iso_urb[j+1];
dev->in_iso_urb[j]->number_of_packets = NUM_ISO_PACKETS_PER_URB;
dev->in_iso_urb[j]->timeout = 250; /* Ah well, timeout of 250
jiffies */
dev->in_iso_urb[j]->context = dev; /* pass our usb_box
structure to callback */
for(k=0;k<NUM_ISO_PACKETS_PER_URB;++k){ /* we have to fill in
each packet in urb */
dev->in_iso_urb[j]->iso_frame_desc[k].offset = k *
dev->iso_in_packet_size;
dev->in_iso_urb[j]->iso_frame_desc[k].length =
dev->iso_in_packet_size;
}
}
/* start the ISO transfer */
usb_submit_urb(dev->in_iso_urb[0]);
and in the callback I just copy the stuff to userspace....
Do you see anything screwed up here? I get the right amount of packets
and traffic just junk instead of information. And no CRC errors or
otherwise....
Thanks,
- Adam