OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Oct 17, 2017 7:44 am

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: Fri Apr 21, 2017 6:47 am 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 181
Location: Ukraine, Bachmut
BenLunt wrote:
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

Yeah, I realized I asked an extremely stupid question, but only after I posted it. :)

_________________
future big goal: ANT - NT-like OS for mips, arm and x86 (and, possibly, ppc and itanium, hehehe).
current smaller goal: efify - UEFI for a couple of boards (mips and arm).


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 9:31 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 259
Location: USA
mindentropy wrote:
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)

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?

I had to look at my notes to remember. It is USB 2.0 that wants a port to be enabled after reset (with a connection). OHCI was created before USB 2.0. Therefore, the OHCI specs say to set the bit to enable the port. The USB 2.0 specs say that the port will become set after a successful reset after connection.

Anyway, all OHCI controllers I have used always enables the port after a successful reset, per the USB 2.0 specs.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 9:38 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 259
Location: USA
mindentropy wrote:
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?

Yes, but please refer to my previous note. Not all manufacturers are 100% compliant with the specifications. Since a well known OS would only request an 8-byte packet as the first packet sent to a newly reset device, some devices expect only an 8-byte request, even if the device is a full speed device with a max packet size greater than 8.

So, on the first packet, the Get Device Descriptor request, always only request the first 8 bytes with an 8-byte max packet setting. Once you have done this, found that there is no stall, do the reset, then you may request the 18 bytes using a 64-byte max packet setting. And yes, use the R bit.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 9:58 am 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1010
BenLunt wrote:
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?)

Yes. And this explains why I'm queueing up 3 TDs instead of 2. I'm assuming that the first TD will always work properly. I admit that this is naïve to ignore errors, but it fits the "theme" of the rest of my OS :)

So, for the SET_ADDRESS command, you send 1 "OUT" TD, and wait for its ConditionCode to be something other than Pending. Then if it is Successful, then you send an "IN" TD, with no data (zero length), and just wait for its ConditionCode to be something other than Pending. Then, if it is Successful, then you can start using the new Address for that device. Correct?

So, just for more clarity, what about terminator TDs. How important is it that each of these two TDs above be followed by another "dummy" TD that is only there so that you can put its address into the Tail field on the ED? Do these TDs actually have to exist in memory, or can you just set the tail to zero, and set the Next field of the last TD to zero?

Thanks. Sorry for the barrage of questions, and for somewhat hijacking the thread. :)

_________________
Project: OZone
Source: GitHub
Current Task: C64 Porting OS

"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: Fri Apr 21, 2017 10:21 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 259
Location: USA
SpyderTL wrote:
BenLunt wrote:
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?)

Yes. And this explains why I'm queueing up 3 TDs instead of 2. I'm assuming that the first TD will always work properly. I admit that this is naïve to ignore errors, but it fits the "theme" of the rest of my OS :)

So, for the SET_ADDRESS command, you send 1 "OUT" TD, and wait for its ConditionCode to be something other than Pending. Then if it is Successful, then you send an "IN" TD, with no data (zero length), and just wait for its ConditionCode to be something other than Pending. Then, if it is Successful, then you can start using the new Address for that device. Correct?

That is correct, assuming by "OUT" you mean a "SETUP" TD and by "IN" you mean a "Status IN" TD. The status is always an IN or an OUT depending on the direction of the other data. However, the first TD is always a SETUP TD, not an OUT TD.

SpyderTL wrote:
So, just for more clarity, what about terminator TDs. How important is it that each of these two TDs above be followed by another "dummy" TD that is only there so that you can put its address into the Tail field on the ED? Do these TDs actually have to exist in memory, or can you just set the tail to zero, and set the Next field of the last TD to zero?

You have lost me here. Why would you send any "dummy" TD's. The Head and Tail pointers are used to stop execution. The Status TD (the IN TD you mention above), should be the last TD of that packet. A device might get confused when it sees an out of sequence TD and may stall on the next Setup Packet.

Anyway, glad that you have it going as expected.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 12:01 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1010
BenLunt wrote:
The Head and Tail pointers are used to stop execution.

Right. My understanding is that the host controller will keep processing TDs until the Head TD address equals the Tail TD address, and then it will stop. Which means that you can't have "just" one TD, because if your head TD and your tail TD both have the same address, it won't even attempt to process that TD.

So either you have to have a "real" TD in memory that you can use just as a "stop processing when you get here" place holder, OR you can just use, let's say, zero as the tail address, and use zero as the Next address on the last (or only) TD you want to send. I was using a "real" TD as a place holder, but my question was whether I could just use zero as my place holder instead of a real TD in memory.

_________________
Project: OZone
Source: GitHub
Current Task: C64 Porting OS

"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: Fri Apr 21, 2017 5:32 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 259
Location: USA
SpyderTL wrote:
BenLunt wrote:
The Head and Tail pointers are used to stop execution.

Right. My understanding is that the host controller will keep processing TDs until the Head TD address equals the Tail TD address, and then it will stop. Which means that you can't have "just" one TD, because if your head TD and your tail TD both have the same address, it won't even attempt to process that TD.

So either you have to have a "real" TD in memory that you can use just as a "stop processing when you get here" place holder, OR you can just use, let's say, zero as the tail address, and use zero as the Next address on the last (or only) TD you want to send. I was using a "real" TD as a place holder, but my question was whether I could just use zero as my place holder instead of a real TD in memory.

Oh, I see what you are getting at.

No, you don't have to have another ("dummy") TD to end the transfer, you just need to have the last TD's NextTD and the ED's TailP fields match.

When the controller retires a TD (after successfully processing it), it will copy the next TD's address to the ED's HeadP field. Then it will check to see if this new HeadP field and the current ED:TailP fields match. If so, no more to process.

So in a way, your last TD does point to another TD, but that TD is non-existent. All you need is the pointer.

You can do it other ways too. For example, place a value of zero in the ED:TailP field. Then place a value of zero in the last TD's NextTD field. It doesn't matter really. The only thing is, once the TD is retired, the controller copies that retired TD's NextTD field to ED:HeadP, then it compares this value with the ED:TailP field. If equal, stop executing.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Fri Apr 21, 2017 6:45 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 958
Location: Athens, GA, 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).


Kindle is in fact the name of a specific format, namely, the format developed for the original Amazon Kindle e-reader about ten years ago, and subsequently used in Amazon's cloud and webapp distribution methods as well. It is a proprietary format, and one designed with DRM from the outset, which is great for authors but also tends to leave your books at Amazon's ransom (as the webapp and e-reader only keep a handful of books in local cache at a given time, with anything you haven't read recently only stored on their cloud servers).

While Amazon have, for the most part, operated their Kindle services in good faith, there have been some problems (fewer than, say, iTunes, but they have occurred). In general, though, it is a good service, but if you have an ideological problem with DRM (as many do), it can be seen with distaste.

Personally, I have no issue with DRM in principle; assignment of authorship credit and support for micro-payments (ones which actually lived up to the name, that is, with lower boundaries in the range of a ten-thousandth of a cent) were two of the primary goals of Xanadu, and for good reason (they still are, though I don't know how far the released version that finally came out in 2014 goes in the planned support - yeah, it took them 53 years to get half the job done, I know, I know, but I still think the ideas are sounder than those at the heart of most current systems).

However, ideology aside, DRM got a bad name as much from the many terribly designed and heavy-handed most approaches to 'copy protection' over the years - and the fact that it is, in a real sense, counter to the general behavior of computers - as it did from worries about loss of freedom. and while I have some real problems with it in practice, the fact remains that the alternative is to abandon copyright and for-profit authorship entirely.

Kindle is, fortunately, a relatively light touch when it comes to its requirements and restrictions, and I have several books which I have purchased in this way. There is some trepidation over the fact that I don't really have control over them, but that holds true with anything 'on the cloud' (e.g., distributed and mirrored over remote servers through automatic means - I would complain about the term 'cloud' being cybercrud and doublespeak, but I've already beaten that horse to death long since).

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
μή εἶναι βασιλικήν ἀτραπόν ἐπί γεωμετρίαν
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Mon Apr 24, 2017 1:05 pm 
Offline
Member
Member

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

I tested by sending the SET_ADDRESS first and seeing if I get any response. I still get the TD error code CC = 0101 i.e. Device not responding.

(Please note that I have plugged in a USB 2.0 storage stick to the USB OHCI 1.1 port of my development board.)

Below are my improved logs:
Code:
Port status :
0x00000103
0x00000100

Before sending my ED and TD values:
Code:
ED:
Endpt ctrl: 0x00080000
TailP: 0x300077C0
HeadP: 0x300077B0
NextED: 0x00000000

TD0:
TD addr:0x300077B0
TDCTRL : 0xE2E00000
CBP : 0x300075A4
NXT_TD : 0x300077C0
buffer_end: 0x300075AC

CBP dump: 0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00

TD1:
TD addr:0x300077C0
TDCTRL : 0xE3100000
CBP : 0x00000000
NXT_TD : 0x00000000
buffer_end: 0x00000000

After transaction:
Code:
HccaDoneHead: 0x300077B1
TD addr:0x300077B0
TDCTRL : 0x5EE00000
CBP : 0x300075A4
NXT_TD : 0x00000000
buffer_end: 0x300075AC


Note the TDCTRL is 0x5EE0000 which is 0101 code for CC which is "Device not responding". Even if I send any other TD I should not get the USB not responding problem, correct? Why am I getting this problem?


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Mon Apr 24, 2017 4:58 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1010
Just a few points that I noticed:

1. Your buffer length field should be 7, not 9. (It's actual buffer length - 1)
2. I'm using TDCTRL of 0xE0E00000 for TD0, and 0xE0F00000 for TD1. I'm too lazy to look up the bits right now, but give it a shot.
3. ED.TailP should probably be 0x00000000. See Ben's response above to understand why.
4. Make sure you have reset the port before sending any commands to the device. Set bit 4 on the port status/control register and wait for it to flip back to zero before sending any data.
5. Just for sanity, make sure any other controllers are disabled, specifically any EHCI controllers.

All of this is just based on my code, which works in VirtualBox. (mostly)

_________________
Project: OZone
Source: GitHub
Current Task: C64 Porting OS

"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: Mon Apr 24, 2017 9:25 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 259
Location: USA
mindentropy wrote:
Ben,

I tested by sending the SET_ADDRESS first and seeing if I get any response. I still get the TD error code CC = 0101 i.e. Device not responding.

(Please note that I have plugged in a USB 2.0 storage stick to the USB OHCI 1.1 port of my development board.)

Does your machine have an EHCI and if so, is the OHCI one of the companion controllers of this EHCI? If so, you won't get the OHCI to do anything for the USB 2.0 storage stick (if it is a high-speed device). Only the EHCI will communicate with the stick. If this is the case, this is why you are having problems with it.

The OHCI, if a companion controller, will only see the low-speed and full-speed devices.

If you want to work with OHCI to make sure it works correctly, you can get a PCI OHCI card off the internet for less than what the shipping would be.

I got multiple cards for my testing of my book. This way, you can plug a high-speed device into it and make sure your low- and full-speed OHCI controller driver works with the high-speed device. Note that the high-speed device plugged into the OHCI will now show up as a full-speed device.

Ben


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Mon Apr 24, 2017 11:16 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1010
I definitely would listen to Ben instead of me. He literally wrote the book on USB drivers.

But... I just happen to be going through the EHCI specs as we speak, and I specifically remember reading earlier today that most EHCI controllers will default to pass through control to any USB 1.x controllers. It even justified this stating that it was done for backward compatibility for OSes that didn't have USB 2.0 support, but that did have USB 1.x support.

I definately got the impression that you had to specifically enable the global "default owner" register bit if you wanted the EHCI controller to own all ports by default.

Again, I could be wrong, or the manufacturer may not follow the specs, or whatever. But I thought I'd mention it just in case it turned out that I knew something that Ben didn't. :)

In any case, if nothing else, you could just put your OHCI driver on hold and start working on your EHCI driver. :) They're actually pretty similar from what I'm reading, so far.

Edit: It's in section 4.2 in the EHCI specs.. :)

_________________
Project: OZone
Source: GitHub
Current Task: C64 Porting OS

"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: Mon Apr 24, 2017 11:48 pm 
Offline
Member
Member

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

I tested by sending the SET_ADDRESS first and seeing if I get any response. I still get the TD error code CC = 0101 i.e. Device not responding.

(Please note that I have plugged in a USB 2.0 storage stick to the USB OHCI 1.1 port of my development board.)

Does your machine have an EHCI and if so, is the OHCI one of the companion controllers of this EHCI? If so, you won't get the OHCI to do anything for the USB 2.0 storage stick (if it is a high-speed device). Only the EHCI will communicate with the stick. If this is the case, this is why you are having problems with it.

The OHCI, if a companion controller, will only see the low-speed and full-speed devices.

If you want to work with OHCI to make sure it works correctly, you can get a PCI OHCI card off the internet for less than what the shipping would be.

I got multiple cards for my testing of my book. This way, you can plug a high-speed device into it and make sure your low- and full-speed OHCI controller driver works with the high-speed device. Note that the high-speed device plugged into the OHCI will now show up as a full-speed device.

Ben


My ARM development board has only the OHCI (Rev 1.0 compatible) and USB (Rev 1.1 compatible). It has support for both low speed and high speed devices. The USB stick (Ver 2.0 compatible) shows as high speed device for me. I have attached the block diagram for reference.
Attachment:
File comment: USB ohci diagram.
usb_ohci.png
usb_ohci.png [ 125.75 KiB | Viewed 790 times ]
. I think I can eliminate compatibility problems here.


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Tue Apr 25, 2017 3:00 am 
Offline
Member
Member

Joined: Thu Jan 13, 2011 3:33 pm
Posts: 42
SpyderTL wrote:
Just a few points that I noticed:
1. Your buffer length field should be 7, not 9. (It's actual buffer length - 1)

Is it present in the spec? I did not find this in the MaximumPacketSize definition.
SpyderTL wrote:
2. I'm using TDCTRL of 0xE0E00000 for TD0, and 0xE0F00000 for TD1. I'm too lazy to look up the bits right now, but give it a shot.

You have ignored the T (DataToggle bits). The problem is in the spec it says:
For control endpoints, the convention is that the Setup packet will always use a data PID of DATA0, the first data packet will use a data PID of DATA1, and the Status packet will use a data PID of DATA1. Since this sequence does not rely on any previous data toggle history, the Setup, data, and status packets should be queued with the MSb of the dataToggle field = 1 and the LSb of each TD set appropriately (Setup = 0; Status = 1; and first data, if any, = 1.) Although the Host Controller updates the toggleCarry bit in the ED whenever a General TD is retired, the data toggle is determined solely by
the General TD.


I have set the SETUP TD DataToggle to 10b and Status TD DataToggle to 11b.

SpyderTL wrote:
3. ED.TailP should probably be 0x00000000. See Ben's response above to understand why.

I get the same no response. I have kept the ED.TailP == 0 and NextTD == 0 as per Ben and the spec.

SpyderTL wrote:
4. Make sure you have reset the port before sending any commands to the device. Set bit 4 on the port status/control register and wait for it to flip back to zero before sending any data.

I have done it. Hope it is correct.

SpyderTL wrote:
5. Just for sanity, make sure any other controllers are disabled, specifically any EHCI controllers.

No EHCI controllers in my SoC. Everything else is disabled.


Top
 Profile  
 
 Post subject: Re: USB OHCI specification.
PostPosted: Tue Apr 25, 2017 6:26 am 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1010
I meant your TD0 buffer end should be 0x300075AA, not 0x300075AC. The buffer end field is the address of the last byte to send.

Also, your ED has a max packet size of 8, which seems low. I'm not sure what this value should be, since you have to get data back from the device before you know what its maximum packet size is. I just looked mine up with USBView and hard coded mine, I think.

Try setting this to 32, if nothing else works.

Also, try setting the Speed on the ED to 1. That also shouldn't work, but I'm running out of ideas. :)

And I'm not setting the toggle bits in my TD at all. I'm just letting the controller keep up with them in the carry field on the ED, and it seems to work. It may be worth a shot.

_________________
Project: OZone
Source: GitHub
Current Task: C64 Porting OS

"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott


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: Bing [Bot], Google [Bot], Korona and 18 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