i'd like to thank everyone who respond to this cry for help (especially greg
and david). i've solved the problem and i wanted to give an update.

to recap, the problem was why my data buffer for BULK only transactions was
getting corrupted, but only sometimes.  i thought that the problems had to
deal w/ pointers or the way that i allocated memory for my data buffer.  BUT
no, the problem lies in the data toggle bit.  you see, my usb device is a
testcard.  i can program it do anything i want and i was not programming the
data toggle bit correctly.

more specifically, whenever i did a bulk read, my testcard would return data
(as i have observed on the bus), but it is not received by the host
controller since the toggle bit was incorrect.  thus my buffer never got
data.

you can easily check for this condition if device driver is programmed to
error out whenever the actual length for data transfer does not match the
expected transfer length... applies to BULK only.

alas, all this trouble from user-error,
-charyll

-----Original Message-----
From: David Brownell [mailto:[EMAIL PROTECTED]]
Sent: Saturday, December 29, 2001 2:30 PM
To: Angderson, Charyll
Subject: Re: [linux-usb-devel] bulk read xfers returns wrong data


> yes, i've had many comments about WORD (my 2 byte definition) and i will
> change that to standard _u16.  i mean to have asynchronous behavior... see
> below.

It's mostly because that's a really alien programming model,
imported from the MSFT 16bit world.  Most modern CPUs have
words that are 32 bits (4 bytes) wide ... though there's a lot of
SPARC v9 out there too, most of the code there uses 32bit mode! :)


> here is the big picture (run in a controlled environment w/ only USB card
> "test" cards)
> 1- disable run bit

That is, you're trying to test the host controller itself?  What run bit?

> 2- submit all sorts of transactions (bulk, isoc, and control)
> 3- enable run bit

I'm not sure that you should expect host controller drivers to work at
all if you're changing the controller registers underneath them.  The
model is that USB device drivers should never touch any hardware
registers at all, except maybe indirectly by making device requests
through USB.

> 4- verify transactions after some timeout 
> 
> for test purposes, i only submit one transaction at a time and wait for
the
> time out.  with the current implementation (of 1 bulk transfer at a time),
i
> am checking the status after each call back.

Check it _during_ each callback ... that's always safe, it's harder to
give a solid rule of thumb otherwise.


>     if there are no errors, i
> assume that i got my bulk data.  is this wrong?  i get 2/3 "wrong data"
and
> 1/3 "correct data".  data is 100% correct the FIRST time the transaction
> goes out on the wire. 
> 
> what i think is happening, is that in application space, i'm passing in a
> data buffer pointer of what i want the transaction to be. is there rules
on
> how these buffers are defined so that as the program moves from
application
> to driver space and from driver back to application space, i don't get my
> buffer pointer swapped out on me?

Absolutely.  USB requests must be given DMA-able memory, allocated
using kmalloc().  If you're using memory that can't be DMA'd, maybe the
address as provided in a system call, that's virtual memory and you
need to copy out of it (or back into it) from DMA-able memory.


> BTW:  my eventual goal is to verify all the submitted transactions after
> some timeout.  i plan to scan through the status bits of all submitted
> transactions, but i currently know how to do that only for one transaction
> at a time.  help?

There are no status bits, there's only a single urb->status value.  And
while
you can check that in a completion handler, or any time you "own" the URB,
you can't check it for periodic URBs except inside that handler.

- Dave


> please tolerate any "stupid" questions.  i'm new to linux/unix and usb all
> at once.  :)
> -charyll
> 
> -----Original Message-----
> From: David Brownell [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, December 27, 2001 4:15 PM
> To: Angderson, Charyll; [EMAIL PROTECTED]
> Subject: Re: [linux-usb-devel] bulk read xfers returns wrong data
> 
> 
> Well for starters, this is where you should use the
> usb_bulk_msg() call ... don't do async submits and
> then expect that anything except the competion
> callback will give you the data.  When your I/O model
> is synchronous, use the standard synchronous calls.
> 
> I'd be rather surprised if the problem is anywhere
> except in your driver, and that idiom (as well as
> any CPU-specific notion of "WORD" size :) looks
> rather suspicious.
> 
> - Dave
> 
> 
> ----- Original Message ----- 
> From: "Angderson, Charyll" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Cc: "Angderson, Charyll" <[EMAIL PROTECTED]>
> Sent: Friday, December 21, 2001 9:43 AM
> Subject: [linux-usb-devel] bulk read xfers returns wrong data
> 
> 
> > i expect that the bulk data read on the wire would be the same data in
> > "buf".  i see different data on the wire than that returned by "buf" 50%
> of
> > the time.  
> > 
> > isoc reads seem to be consistent.  and both isoc/bulk writes are
correct.
> i
> > only have one "buf".  i've tried making "buf" a static pointer:  static
> WORD
> > * buf;  and when ever user wants to do transfers i have to read the
"size"
> > they pass in and do a "kmalloc" for "buf".  after each transaction "buf"
> is
> > freed.  but definitely not until transaction is done.  
> > 
> > i even have a print statement right after transaction completes (see
> below)
> > and it proves that "buf" is bad.
> > 
> > anyone have any ideas?  snippet of my code is below.
> > 
> > did i put unlinking in the right place..it only unlinks if there was a
> > status error.  is there a problem with unlinking w/o a status error?  or
> is
> > this something i should always do?
> > 
> > in the future, i will not do this callback.  i will just keep doing
> > submit_trans, but i didn't know how to make sure everything was
completed?
> > can someone tell me?
> > 
> > thanks,
> > -charyll angderson
> > 
> > #define WORD      unsigned short int  //2 bytes
> > int usbx_submit_trans(struct usbxDevice *usbxPtr, struct usb_device
*dev, 
> > struct _Transaction *trans, WORD *buf)
> > {
> > int i,j,k;
> > usbx_show_trans(trans);
> > 
> > switch(trans->type) {
> > case USBX_R_BULK:
> > FILL_BULK_URB(usbxPtr->usbx_urb, dev, usb_rcvbulkpipe(dev,
> > trans->endpoint),
> > buf, trans->size, usbx_urb_complete, usbxPtr);
> > break;
> > default:
> > dbg("invaid trans type!");
> > break;
> > }
> > 
> > usbx_submit_urb(usbxPtr->usbx_urb);
> > interruptible_sleep_on_timeout(&(usbxPtr->wait), trans->timeout);
> > 
> > if (usbxPtr->usbx_urb->status!=0) {
> > err("TIMEOUT awoken %i (%s)
> > status=0x%x",current->pid,current->comm,usbxPtr->usbx_urb->status); //ca
> > debug
> > usbx_unlink_urb(usbxPtr->usbx_urb);  // remove urb safely
> > }
> > 
> > switch (trans->type) {
> > case USBX_R_BULK:
> > dbg("usbx_submit_trans:  print buffer read ..
> > address=0x%lx", (DWORD)&buf);
> > for (i=0; i<(trans->size/2); i++) {
> > dbg(" %x ",(WORD)buf[i]);
> > }
> > break;
> > default:
> > break;
> > }
> > 
> > return usbxPtr->usbx_urb->status;
> > }
> > 
> > 
> > _______________________________________________
> > [EMAIL PROTECTED]
> > To unsubscribe, use the last form field at:
> > https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to