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
