OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 4:06 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 71 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject: Re: USB OHCI specification.
PostPosted: Wed Apr 19, 2017 2:44 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1074
For some reason, I have three TDs instead of two. I think that my thought process was that SET_ADDRESS returned a result, and therefore needed a TD to return the result, and another TD to be the terminator.

I'm guessing that I can get rid of my second TD for the result, but just to be sure, does the device return anything after a SET_ADDRESS command, and is the controller supposed to handle it, or should the driver be reading the result?

_________________
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


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Wed Apr 19, 2017 8:35 pm 
Offline
Member
Member

Joined: Thu Jan 13, 2011 3:33 pm
Posts: 42
BenLunt wrote:
mindentropy wrote:
I tried sending the SET_ADDRESS request. I still get the "device not responding" error (0101) in the CC field of the TD.

I have the following register dump:

Before sending the packet:
Port status after reset (HcRhPortStatus register):
Port1 : 0x00100103
Port2 : 0x00000100

Did you clear bit 20? The hardware may or may not end the reset state until you acknowledge the finish of the reset by writing a '1' to bit 20.

mindentropy wrote:

<snip ED and TD dumps>

Is my port status fine? If I try to clear the PRSC bit by writing a 1 to it I get the status changes back to 0x00000100. Is this normal?

Yep, I guess you did clear the bit. You should do this before sending any TD's.


I was not very clear there. PORT1 is the active port that has a USB stick attached. PORT2 is not used and also I don't have a connector to it.

I have not cleared BIT20 the PRSC bit by writing a 1. In the code pasted I have commented it out. If I don't set the PRSC bit the values will be
Code:
PORT1:  0x00100103

I am assuming that the BIT2 the PES (Port Enable Status) bit should be set before I continue any further operations.
If I acknowledge the reset by writing a 1 to BIT20 then the status becomes:
Code:
PORT1:  0x00000101

BIT2 (PES) gets cleared for some reason and I am assuming it is wrong. Am I right in my understanding?

My sequence of resets is as follows:
Code:
reset_ohci_controller();
reset_usb_port(PORT1);

Is the above sequence correct?


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 11:52 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
SpyderTL wrote:
For some reason, I have three TDs instead of two. I think that my thought process was that SET_ADDRESS returned a result, and therefore needed a TD to return the result, and another TD to be the terminator.

I'm guessing that I can get rid of my second TD for the result, but just to be sure, does the device return anything after a SET_ADDRESS command, and is the controller supposed to handle it, or should the driver be reading the result?


Nope. Just the status TD. You send the Set Address TD, wait for the response, then send the Status TD.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 12:11 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
mindentropy wrote:
BenLunt wrote:
Did you clear bit 20? The hardware may or may not end the reset state until you acknowledge the finish of the reset by writing a '1' to bit 20.

I was not very clear there. PORT1 is the active port that has a USB stick attached. PORT2 is not used and also I don't have a connector to it.

I have not cleared BIT20 the PRSC bit by writing a 1. In the code pasted I have commented it out. If I don't set the PRSC bit the values will be
Code:
PORT1:  0x00100103

Correct.
Bit 20 = 1 = Port reset is complete
Bit 8 = 1 = Port has power
Bit 1 = 1 = Port is enabled
Bit 0 = 1 = Device attached

You need to clear bit 20 by writing a 1 to it. However, if you write 0x00100103 to the port, you are now writing a one to bit 0, disabling the port. You must first read the port, mask off the R/O bits and other bits you wish to preserve, then write your value back.

mindentropy wrote:
I am assuming that the BIT2 the PES (Port Enable Status) bit should be set before I continue any further operations.
If I acknowledge the reset by writing a 1 to BIT20 then the status becomes:
Code:
PORT1:  0x00000101

BIT2 (PES) gets cleared for some reason and I am assuming it is wrong. Am I right in my understanding?

Again, what do you write to the port. If you write a 1 to bit 0, you disable the port.

Read of Port 0: 0x00100103
Write to Port 0: 0x00100102
Read of Port 0: 0x00000103

If you write a 1 to bit 0, this tells the controller to disable the port, clearing the enable bit.

You need to read the specifications (or get a good book, hint, hint) that tells you what each bit in the port register is intended for. A read of a bit does one thing while a write to that bit can have a complete different meaning.

For example, reading bit 9 tells you if you have a Low Speed device attached. However, if you write to this bit (bit 9), you disable power to this port (power switching aside).

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 12:24 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 641
Location: Ukraine, Bachmut
Ben, I really need your book on USB, but I can't get - is it sold in the .pdf form? ("kindle" is not clear what the format is for me).

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 12:25 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1074
BenLunt wrote:
You send the Set Address TD, wait for the response, then send the Status TD.

Can you elaborate a bit, for clarity?

What "response" are you waiting for? Do you mean just wait for the TD ConditionCode to be something other than 0x0e (pending)?

And what "Status TD" are you sending? Do you mean send a GET_STATUS message, and read the result? Is this strictly necessary?

Thanks.

_________________
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


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 12:51 pm 
Offline
Member
Member

Joined: Thu Jan 13, 2011 3:33 pm
Posts: 42
BenLunt wrote:
Again, what do you write to the port. If you write a 1 to bit 0, you disable the port.

Read of Port 0: 0x00100103
Write to Port 0: 0x00100102
Read of Port 0: 0x00000103

If you write a 1 to bit 0, this tells the controller to disable the port, clearing the enable bit.

Ugh! That was the mistake. I was using my helper functions setbits(..) and clearbits(..) which used to read the value out set the specified bit preserving the other bit values. This causes the exact same problem that you mentioned i.e. I am writing a '1' to a bit which I am not supposed thereby clearing some other setting.

BenLunt wrote:
You must first read the port, mask off the R/O bits and other bits you wish to preserve, then write your value back.

I don't need to preserve the bits for the HcRhPortStatus, correct? I just have to write a '1' to set the bit. As per the spec writing a '0' to the other bits even if it is set does not have any effect.

BenLunt wrote:
You need to read the specifications (or get a good book, hint, hint) that tells you what each bit in the port register is intended for. A read of a bit does one thing while a write to that bit can have a complete different meaning.

For example, reading bit 9 tells you if you have a Low Speed device attached. However, if you write to this bit (bit 9), you disable power to this port (power switching aside).
Ben

I am reading the specifications except that I made a really silly mistake above! It was just that I did not think twice when using my helper macros. I knew very well that setting a bit on one parameter clears the value in another parameter.

I still have the device not responding problem. Let me try out the things that you said and will update you on it.


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 3:32 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
zaval wrote:
Ben, I really need your book on USB, but I can't get - is it sold in the .pdf form? ("kindle" is not clear what the format is for me).

I'm sorry. It is not in .PDF form. Not that you would do it by any means, but a .PDF form of the book would be way to easy to leak to the web.

Sorry,
Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 3:50 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
SpyderTL wrote:
BenLunt wrote:
You send the Set Address TD, wait for the response, then send the Status TD.

Can you elaborate a bit, for clarity?

What "response" are you waiting for? Do you mean just wait for the TD ConditionCode to be something other than 0x0e (pending)?

And what "Status TD" are you sending? Do you mean send a GET_STATUS message, and read the result? Is this strictly necessary?

Thanks.

A device can stall after the start of a setup packet. The only way to clear the stall is to start a new setup packet.

If you send a setup packet, the first TD is a SETUP TD. This is when the device may stall. If your ED contains a list of TD's, two in this case, and the second TD is the Status TD, you haven't cleared a stall and the Status TD won't ever get processed. Your code could be waiting for the Status TD to complete for a long time.

Therefore, send the first TD, the SETUP TD. If and when it comes back successful, then send the Status TD. If it comes back stalled. You need to clear the stall by sending another Setup TD.

The reason for the Status TD is to indicate to the device that you have successfully sent/received a transfer. If you instantly send the Status TD before waiting for the device to process the request, it defeats the purpose of the Status TD. :-)

However, please note that if you have a Status TD right after a Setup TD in the same ED, the device won't process the Status TD until after it has processed the Setup TD. But if the device stalls, it will never get to the Status TD.

Therefore, send the Request TD, wait for a good transfer, then send the Status TD.

I gave an example to the OP of this thread of an ED with two TD's, assuming it would not stall. To create a good USB driver, you should not do this, but send a Setup TD, wait for the response, then send the Status TD, using two separate ED's, or the same ED, twice.

Does this help?

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 4:01 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
mindentropy wrote:
I don't need to preserve the bits for the HcRhPortStatus, correct? I just have to write a '1' to set the bit. As per the spec writing a '0' to the other bits even if it is set does not have any effect.

This is correct. The HCRhPortStatus register (the Port register) is setup so that writing a zero to any bit has no effect.

A note: If I remember correctly, the OHCI has to enable the port. Writing a 1 to bit 1 does not enable the port. (if memory serves me)

mindentropy wrote:
I still have the device not responding problem. Let me try out the things that you said and will update you on it.

This is what I like to hear. "Let me try out...and then get back with you" :-)

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 4:29 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1074
BenLunt wrote:
However, please note that if you have a Status TD right after a Setup TD in the same ED, the device won't process the Status TD until after it has processed the Setup TD. But if the device stalls, it will never get to the Status TD.

If the SETUP command is a SET_ADDRESS command, then the next command can't be on the same ED, because the address will change after the first TD, correct?

So should it be send a SET_ADDRESS on one TD on one ED (for address zero), wait for that TD to change from Pending to Successful, then send a GET_STATUS message on a separate TD on a separate ED, for whatever the new address for that device is?

But, my original question was, if you were just getting started with OHCI, sending the GET_STATUS message can be skipped and everything should still work. In other words, the USB specifications don't state that you must send a GET_STATUS message at all, correct? It's just the only way you can determine if the device is working properly.

_________________
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


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 5:38 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
SpyderTL wrote:
BenLunt wrote:
However, please note that if you have a Status TD right after a Setup TD in the same ED, the device won't process the Status TD until after it has processed the Setup TD. But if the device stalls, it will never get to the Status TD.

If the SETUP command is a SET_ADDRESS command, then the next command can't be on the same ED, because the address will change after the first TD, correct?

So should it be send a SET_ADDRESS on one TD on one ED (for address zero), wait for that TD to change from Pending to Successful, then send a GET_STATUS message on a separate TD on a separate ED, for whatever the new address for that device is?

But, my original question was, if you were just getting started with OHCI, sending the GET_STATUS message can be skipped and everything should still work. In other words, the USB specifications don't state that you must send a GET_STATUS message at all, correct? It's just the only way you can determine if the device is working properly.


First, I am not talking about the GET_STATUS message (request). Forget about it.

Every SETUP packet, a packet being all necessary TD's to complete the SETUP transfer, every (successful) SETUP packet contains a SETUP TD, zero or more DATA TD's, *and* one STATUS TD.

When sending the SET_ADDRESS request (SETUP packet), you send a SETUP TD, no DATA TD's, and one (1) STATUS TD. Two (2) TD's in total.

The Device *will not* change it's address until the STATUS TD is processed, successfully, meaning the whole packet (both TD's) where successfully processed.

The STATUS TD is there to tell the device as well as the controller/software that the whole packet was successful.

So, with this in mind, send the SETUP TD, wait for it to have been processed (check its status in the TD), then if successful, send the STATUS TD. If unsuccessful, you need to find out why and try again.

Does this make it clear? (clear as mud?)

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Thu Apr 20, 2017 5:54 pm 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1108
Re: clear as mud.
I just learned that clean dirt is a thing. English makes me wanna cry sometimes. :)


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 12:23 am 
Offline
Member
Member

Joined: Thu Jan 13, 2011 3:33 pm
Posts: 42
BenLunt wrote:
mindentropy wrote:
I don't need to preserve the bits for the HcRhPortStatus, correct? I just have to write a '1' to set the bit. As per the spec writing a '0' to the other bits even if it is set does not have any effect.

This is correct. The HCRhPortStatus register (the Port register) is setup so that writing a zero to any bit has no effect.

A note: If I remember correctly, the OHCI has to enable the port. Writing a 1 to bit 1 does not enable the port. (if memory serves me)


From the spec:
(read) PortEnableStatus
This bit indicates whether the port is enabled or disabled. The Root Hub may clear this bit when an overcurrent condition, disconnect event, switched-off power, or operational bus error such as babble is detected. This change also causes PortEnabledStatusChange to be set. HCD sets this bit by writing SetPortEnable and clears it by writing ClearPortEnable. This bit cannot be set when CurrentConnectStatus is cleared. This bit is also set, if not already, at the completion of a port reset when ResetStatusChange is set or port suspend when SuspendStatusChange is set.

0 = port is disabled
1 = port is enabled

(write) SetPortEnable
The HCD sets PortEnableStatus by writing a ‘1’. Writing a ‘0’ has no effect. If CurrentConnectStatus is cleared, this write does not set PortEnableStatus, but instead sets ConnectStatusChange. This informs the driver that it attempted to enable a disconnected port.


So I have understood that the HCD should set the PortEnableStatus to 1 by writing to this bit position. The write would be SetPortEnable. Correct?


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 1:04 am 
Offline
Member
Member

Joined: Thu Jan 13, 2011 3:33 pm
Posts: 42
BenLunt wrote:

Rather than interpret your ED and TD's, I am going to show you the example ED with two TD's that will set the address:
Code:
  // ED at physical address 0x01234000:
      0x00082000  // control
      0x01234030  // tail
      0x01234010  // head
      to next ED    // next ed
  // first TD at physical address 0x01234010:
      0xE2E00000  // control
      0x01234030  // Current Buffer Pointer
      0x01234020  // Next TD
      0x01234037  // Buffer End  (8 bytes)
  // second TD at physical address 0x01234020:
      0xE3100000  // control
      0x00000000  // Current Buffer Pointer (none)
      0x01234030  // Next TD (Doesn't matter, but our loop gave us a pointer to here plus 0x10)
      0x00000000  // Buffer End  (none)
  // Packet at physical address 0x01234030:
      0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00



In the TD Control you have 0xE2E00000 i.e from the spec the last data packet of the TD from an endpoint must exactly fill the defined data buffer. I have TD data packet buffer size of 64 bytes. Hence I set the R bit of the TD_CTRL as the SET_ADDRESS just takes 8 bytes and hence it does not have a rounded buffer. Correct?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 71 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Amazonbot [bot], Bing [Bot], cloudapio and 64 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group