Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux and Isochronous USB transfers

1 view
Skip to first unread message

Adam Majer

unread,
Sep 10, 2002, 12:09:48 PM9/10/02
to
Hi all,

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?

Georg Acher

unread,
Sep 12, 2002, 6:29:38 AM9/12/02
to
In article <3D7E194C...@galacticasoftware.com>,

Adam Majer <ad...@galacticasoftware.com> writes:
|> Hi all,
|>
|> 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.

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

Adam Majer

unread,
Oct 2, 2002, 7:33:06 PM10/2/02
to

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

0 new messages