OHCI Done Queue and Finding Endpoint
Posted: Tue Jan 12, 2016 1:00 pm
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
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