OHCI Done Queue and Finding Endpoint

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

OHCI Done Queue and Finding Endpoint

Post by SpyderTL »

I'm getting back to working on my OHCI USB Controller Drivers, and I've run into a snag. For receiving data from the device, I was planning on walking the Done Queue and looking for any Transfer Descriptors that matched a specific endpoint. For example, for mass storage devices, I was going to look for TDs that matched the IN bulk endpoint number.

But, it turns out that the TD doesn't have any reference to the endpoint number. The controller walks the Endpoint Descriptors and sends/receives all of the Transfer Descriptors attached to it, but then it "moves" the TD from the Endpoint Descriptor to the Done Queue.

I see no way to find the endpoint for a TD in the Done Queue (since there is only one Done Queue), and I see no way to find the "completed" TDs for a specific endpoint, since they are no longer pointed to by the Endpoint Descriptor after they are sent/filled. I'm not even sure how you are supposed to know which device (address) a TD in the done queue came from. Do I have to keep a mapping of TDs to EDs, myself?

I know that I've got to be missing something obvious, because no one else seems to be having a problem figuring this out. I'm reading through the Linux driver source, but so far I haven't figured out how they are matching up completed TDs to EDs, either.

Maybe someone here can answer this quicker than I can find it, myself.

Thanks, guys.

Edit: Okay, that didn't take long. Somehow posting a question on this forum makes the answer jump out at you within 5 minutes... Linux is storing a link to the Endpoint Descriptor immediately after the Transfer Descriptor. Since the OHCI controller only reads/writes to the TD/ED structures, and it never moves them, you can add any amount of information to the end of the descriptor that you want. This never even crossed my mind, because I was stacking my descriptors immediately one after the other, in memory...

Thanks for all the help :)
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: OHCI Done Queue and Finding Endpoint

Post by SpyderTL »

Alright, I've got a new problem. My bulk out transfers are not being processed by the OCHI controller at all.

Here is what I am doing on controller initialize:
  • Queue a "dummy" bulk Endpoint Descriptor, so that I am guaranteed to always have at least one. This makes adding additional endpoints simpler, later on. It has the Skip flag set, so it should be ignored.
  • Set the Bulk Head Endpoint Descriptor Address register on the OCHI controller BAR0 + 0x28 to the address of the descriptor above.
  • Set the Control register BAR0 + 0x04 to 0xb0 (Operational, Control List Enable, Bulk List Enable)
Here is what I am doing when the endpoints are discovered and initialized:
  • Create an Endpoint Descriptor with Flags set to 0x00404000 (plus the endpoint and function address...) (Skip, Max Packet Size 64, which matches the endpoint descriptor)
  • Queue the Endpoint Descriptor at the end of the list.
And here is what I am doing when sending a packet:
  • Create a Transfer Descriptor with Flags set to 0xe0e10000 (Pending, Endpoint Toggle Source, No Interrupt, Direction Out)

    UGH... Nevermind... I just figured it out..

    It should be 0xe0e80000...

    Thanks again guys!! It's working now :)
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Post Reply