Page 1 of 2

USB Help

Posted: Fri Oct 10, 2014 4:36 am
by bigbob
I have managed to communicate with USB devices thanks to the book "Benjamin David Lunt - USB: The Universal Serial Bus" and the code of PrettyOS (e.g. I use the code of PrettyOS to disable Legacy Support(BIOS), because Lunt's code didn't work on an old computer).
It seems that just an EHCI driver is enough for those who only need (high-speed) mass-storage-devices for their OSs. Even after succesfully disabling the Legacy Support for the EHCI controller, my USB-keyboard remains functioning(without a USB-keyboard driver) probably because UHCI or OHCI controller handles low- and full speed devices. This means that the legacy keyboard driver (I use the one from Brokenthorn) works and there is no need to write UHCI or OHCI USB-keyboard driver. My OS uses no mouse, but I suspect that the situation is the same in case of a mouse too.
For me, it took some time to realize which direction the PID of the Status-TD should have (it is not that clear in Lunt's book):
PID is IN(01b), if there are no data-TDs (as in SetAddress-request) or if there are data-OUT TDs. Otherwise PID is OUT(00b).

Here (at the end of the webpage) there is the USBTest.zip that retrieves the Device Descriptors of devices on EHCI, UHCI or OHCI.
It is written in assembly and in case of an error, the queue and the TDs(Transfer Descriptors) along with the request- and return buffers get printed on the screen. I tested it on two computers with EHCI and UHCI controllers. It's not a big deal but it can help, if you are an assembly programmer.
https://sites.google.com/site/forthoperatingsystem/

Of course, if you have a computer with xHCI (super-speed; that handles all-speed devices), then this post is not for you.

EDIT:
The USB-keyboard remains functioning on a desktop computer, but on a Netbook only the built-in keyboard works and the external USB-keyboard doesn't work.

Re: USB Help

Posted: Fri Oct 10, 2014 9:39 am
by Muazzam
bigbob wrote:I have managed to communicate with USB devices thanks to the book "Benjamin David Lunt - USB: The Universal Serial Bus" and the code of PrettyOS (e.g. I use the code of PrettyOS to disable Legacy Support(BIOS), because Lunt's code didn't work on an old computer).
It seems that just an EHCI driver is enough for those who only need (high-speed) mass-storage-devices for their OSs. Even after succesfully disabling the Legacy Support for the EHCI controller, my USB-keyboard remains functioning(without a USB-keyboard driver) probably because UHCI or OHCI controller handles low- and full speed devices. This means that the legacy keyboard driver (I use the one from Brokenthorn) works and there is no need to write UHCI or OHCI USB-keyboard driver. My OS uses no mouse, but I suspect that the situation is the same in case of a mouse too.
For me, it took some time to realize which direction the PID of the Status-TD should have (it is not that clear in Lunt's book):
PID is IN(01b), if there are no data-TDs (as in SetAddress-request) or if there are data-OUT TDs. Otherwise PID is OUT(00b).

Here (at the end of the webpage) there is the USBTest.zip that retrieves the Device Descriptors of devices on EHCI, UHCI or OHCI.
It is written in assembly and in case of an error, the queue and the TDs(Transfer Descriptors) along with the request- and return buffers get printed on the screen. I tested it on two computers with EHCI and UHCI controllers. It's not a big deal but it can help, if you are an assembly programmer.
https://sites.google.com/site/forthoperatingsystem/

Of course, if you have a computer with xHCI (super-speed; that handles all-speed devices), then this post is not for you.

EDIT:
The USB-keyboard remains functioning on a desktop computer, but on a Netbook only the built-in keyboard works and the external USB-keyboard doesn't work.
Thanks a lot for help!. I want to write USB mass storage drivers, I read echi specification but it can only describe register 0, 1, 2.. not actual registers ports. How can I get start with programming USB mass storage?. (and also I am assembly language programmer.).

Re: USB Help

Posted: Fri Oct 10, 2014 10:03 am
by bigbob
muazzam wrote: Thanks a lot for help!. I want to write USB mass storage drivers, I read echi specification but it can only describe register 0, 1, 2.. not actual registers ports. How can I get start with programming USB mass storage?. (and also I am assembly language programmer.).
If you want to understand what you are doing, then that book is a must.
On the other hand USBTest.zip is a good start, it prints the device descriptors (or it should :-) ).
There are still many things to do: to get the string descriptors (e.g. "Kingston - Mass Storage"), Configuration-, Interface- and Endpoint-descriptors. Then you can communicate with the Mass-storage-device with SCSI commands. It's all in the book.
I already added reading the String-Descriptors of devices to my OS (USBMTGFOS.zip on the same webpage).
Of course, it can be done from the USB-specs too, but it would take a much longer time.
usb1.1 spec
usb-2.0 spec
ehci spec (uhci, ohci specs)
usb-msc specs (mass storage)
SBC3 (SCSI Block Commands 3)

If you would like to understand how USB works, then you would need to read about 700 pages of specs.
The book explains it in less than 200 pages. It guides you, to be exact.
I am a little absent-minded lately: the string descriptors (manuafcturer and product) get printed in usbtest.zip too :-)

Re: USB Help

Posted: Fri Oct 10, 2014 10:43 am
by DavidCooper
I've been reading through the same book over the last few months to try to get the full picture of how USB works. I originally read the USB2 specification and was left thinking it was a horrific task that would take years just to understand (all that stuff about ruddy pipes drove me right up the wall), but now I've gone back to it and searched for simple things like "queue head" and "transcriptor", and it turns out that the USB2 specification simply doesn't mention them at all - the very things the OS developer most needs to know simply aren't in it! The trick is to look to the UHCI, OHCI, EHCI and XHCI specifications instead, as well as using Lunt's book to slash the time it takes to understand how to get going.

I've only started writing USB code in the last week, and I too am thinking of initially having only an EHCI driver to begin with because I discovered that the companion UHCI controllers on my netbook are not used at all by the BIOS, so the EHCI controller must be handling the keyboard and touchpad, unless they're wired in through a real PS/2 port. I haven't tested yet to see if I lose the keyboard by taking control of the EHCI controller, but I still expect the keyboard to stop working. If that happens, it'll make debugging my USB code magnitudes harder as I try to develop it. I'll try booting with an external keyboard plugged into a root port and see if that gets disabled too - it's just possible that the BIOS will set up a UHCI controller for it and that it'll keep running after I take over the EHCI controller. If that doesn't work, another option would be to try to find a machine like yours to work on (you lucky bastard), but it's hard to test machines before you buy them as people don't generally like it when you ask if you can boot them up with an operating system they've never heard of, and I don't have a lot of money to throw at it.

In anticipation of this loss-of-keyboard-input problem when developing USB drivers, I've put a lot of time into working on speech recognition so that I can use simulated keyboard input instead. I've managed to produce good sonographs (without using FFT), and I can distinguish different speech sounds visually on the screen, but it's still hard to get from there to reliable phoneme recognition. I might just take a shortcut for now and use simple musical notes to control the simulated keyboard input instead of speech sounds, whistling two or three notes for each keypress.

If it turns out that the keyboard and touchpad are connected through EHCI, it would suggest that they are either USB2 devices (which Lunt's book says is unlikely), or they are USB1 devices connected to an internal USB2 hub, which I think might allow them to be handled by the EHCI controller instead of being being passed to a companion controller. Does anyone know if that's how it works? I haven't managed to work that out yet, so it may not be the case, but if it is, it would allow you to postpone the development of your UHCI and OHCI drivers indefinitely and just tell users to plug any USB1 devices into a USB2 hub instead of to a root port, the only downside being that your OS wouldn't do very much on older machines which lack USB2.

Re: USB Help

Posted: Fri Oct 10, 2014 11:02 am
by bigbob
DavidCooper wrote:I've been reading through the same book over the last few months to try to get the full picture of how USB works. I originally read the USB2 specification and was left thinking it was a horrific task that would take years just to understand (all that stuff about ruddy pipes drove me right up the wall), but now I've gone back to it and searched for simple things like "queue head" and "transcriptor", and it turns out that the USB2 specification simply doesn't mention them at all - the very things the OS developer most needs to know simply aren't in it! The trick is to look to the UHCI, OHCI, EHCI and XHCI specifications instead, as well as using Lunt's book to slash the time it takes to understand how to get going.
...
If it turns out that the keyboard and touchpad are connected through EHCI, it would suggest that they are either USB2 devices (which Lunt's book says is unlikely), or they are USB1 devices connected to an internal USB2 hub, which I think might allow them to be handled by the EHCI controller instead of being being passed to a companion controller. Does anyone know if that's how it works? I haven't managed to work that out yet, so it may not be the case, but if it is, it would allow you to postpone the development of your UHCI and OHCI drivers indefinitely and just tell users to plug any USB1 devices into a USB2 hub instead of to a root port, the only downside being that your OS wouldn't do very much on older machines which lack USB2.
As I understand it, EHCI handles only high-speed devices, and keyboard is not that. The EHCI-part of the C-code that comes with the book prints a "Low- or full speed device found" if finds a non-high speed device and suggests using UHCI or OHCI driver for those devices to be enumerated instead. In my opinion the "contained" UHCI or OHCI controller handles it.
My original purpose was that writing every USB driver is at least not urgent, if you only need to read/write from/to pen-drives.
My experiments show that keyboards work (built-in on netbooks or laptops; USB-keyboard on an old desktop computer) without a usb-keyboard driver.
Before I read your comments about USB-specs, I edited my previous post and I'd like to add that I wouldn't have started writing USB-drives without that book.

Re: USB Help

Posted: Fri Oct 10, 2014 11:10 am
by Brynet-Inc
Many newer systems omit the UHCI/OHCI legacy controllers by using a "Rate Matching Hub" attached to the EHCI controllers root hub, unfortunately some very new systems also forgo on EHCI as well now, providing only an xHCI controller.

ACPI FACP/FADT call tell you if there is an i8042 controller, presumably even an emulated one. If not, you should only use the BIOS services until your USB drivers can properly initialize the USB keyboard itself.

Re: USB Help

Posted: Fri Oct 10, 2014 1:20 pm
by SpyderTL
DavidCooper wrote:The trick is to look to the UHCI, OHCI, EHCI and XHCI specifications instead, as well as using Lunt's book to slash the time it takes to understand how to get going.
Yep. OHCI, EHCI, UHCI and xHCI are standardized hardware interfaces, like IDE Controllers. USB is a protocol, like SCSI commands.
DavidCooper wrote:If it turns out that the keyboard and touchpad are connected through EHCI, it would suggest that they are either USB2 devices (which Lunt's book says is unlikely), or they are USB1 devices connected to an internal USB2 hub, which I think might allow them to be handled by the EHCI controller instead of being being passed to a companion controller. Does anyone know if that's how it works? I haven't managed to work that out yet, so it may not be the case, but if it is, it would allow you to postpone the development of your UHCI and OHCI drivers indefinitely and just tell users to plug any USB1 devices into a USB2 hub instead of to a root port, the only downside being that your OS wouldn't do very much on older machines which lack USB2.
USB -> PS/2 Keyboard and Mouse emulation is handled by the BIOS (specifically, the SMBIOS), until it is disabled by setting a flag on the OHCI/EHCI/UHCI/xHCI controller. The SMBIOS "owns" the USB controller until your operating system "takes" control away from the SMBIOS.

However, this emulation is probably only enabled by the BIOS at boot time if it does not find a PS/2 keyboard attached.

This is my understanding, anyway. Someone correct me if I am wrong...

Re: USB Help

Posted: Fri Oct 10, 2014 1:48 pm
by Owen
An alternative to a machine with PS/2 ports is a machine with a serial port (note: you can get PCI(-E) serial port cards and your BIOS should have no trouble detecting them and sticking their I/O ports in the BDA, but regardless if you're doing USB you have sufficient bus enumeration to find a crappy old serial port, so any desktop with a free expansion slot is viable)

Never underestimate the utility of a serial port

Re: USB Help

Posted: Sat Oct 11, 2014 12:45 am
by iocoder
muazzam wrote:
bigbob wrote:I have managed to communicate with USB devices thanks to the book "Benjamin David Lunt - USB: The Universal Serial Bus" and the code of PrettyOS (e.g. I use the code of PrettyOS to disable Legacy Support(BIOS), because Lunt's code didn't work on an old computer).
It seems that just an EHCI driver is enough for those who only need (high-speed) mass-storage-devices for their OSs. Even after succesfully disabling the Legacy Support for the EHCI controller, my USB-keyboard remains functioning(without a USB-keyboard driver) probably because UHCI or OHCI controller handles low- and full speed devices. This means that the legacy keyboard driver (I use the one from Brokenthorn) works and there is no need to write UHCI or OHCI USB-keyboard driver. My OS uses no mouse, but I suspect that the situation is the same in case of a mouse too.
For me, it took some time to realize which direction the PID of the Status-TD should have (it is not that clear in Lunt's book):
PID is IN(01b), if there are no data-TDs (as in SetAddress-request) or if there are data-OUT TDs. Otherwise PID is OUT(00b).

Here (at the end of the webpage) there is the USBTest.zip that retrieves the Device Descriptors of devices on EHCI, UHCI or OHCI.
It is written in assembly and in case of an error, the queue and the TDs(Transfer Descriptors) along with the request- and return buffers get printed on the screen. I tested it on two computers with EHCI and UHCI controllers. It's not a big deal but it can help, if you are an assembly programmer.
https://sites.google.com/site/forthoperatingsystem/

Of course, if you have a computer with xHCI (super-speed; that handles all-speed devices), then this post is not for you.

EDIT:
The USB-keyboard remains functioning on a desktop computer, but on a Netbook only the built-in keyboard works and the external USB-keyboard doesn't work.
Thanks a lot for help!. I want to write USB mass storage drivers, I read echi specification but it can only describe register 0, 1, 2.. not actual registers ports. How can I get start with programming USB mass storage?. (and also I am assembly language programmer.).
You need to get (or configure) the base address through PCI configuration space for the controller.

Re: USB Help

Posted: Sat Oct 11, 2014 2:29 am
by bigbob
I don't know how to put it: the desktop computer I was referring to, has PS/2 keyboard (David was right when he mentioned PS/2), so I simply remembered wrong because there are several USB-stuff attached to it, including an external hub.
But still, the built-in keyboard of the netbook remains functioning.

Re: USB Help

Posted: Sat Oct 11, 2014 2:40 am
by Muazzam
iocoder wrote: You need to get (or configure) the base address through PCI configuration space for the controller.
Can you explain what is PCI? (in simple words). Why do I need PCI?. How to configure PCI? etc.

Re: USB Help

Posted: Sat Oct 11, 2014 2:57 am
by bigbob
muazzam wrote:[
Can you explain what is PCI? (in simple words). Why do I need PCI?. How to configure PCI? etc.
PCI is a bus, controllers (e.g. IDE, USB, stb) are connected to it.
So, if you want to have USB, then you need to "talk" to the USB-controllers via the PCI-bus (get BASE address, etc)
In my opinion these links are good:
http://wiki.osdev.org/PCI
http://en.wikipedia.org/wiki/PCI_configuration_space

EDIT:
The output of the lspci command from linux explains a lot:
00:00.0 Host bridge: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
00:02.0 VGA compatible controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
00:02.1 Display controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
00:1b.0 Audio device: Intel Corporation NM10/ICH7 Family High Definition Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 2 (rev 02)
00:1c.3 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 4 (rev 02)
00:1d.0 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #1 (rev 02)
00:1d.1 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #2 (rev 02)
00:1d.2 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #3 (rev 02)
00:1d.3 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #4 (rev 02)
00:1d.7 USB controller: Intel Corporation NM10/ICH7 Family USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2)
00:1f.0 ISA bridge: Intel Corporation NM10 Family LPC Controller (rev 02)
00:1f.2 SATA controller: Intel Corporation NM10/ICH7 Family SATA Controller [AHCI mode] (rev 02)
00:1f.3 SMBus: Intel Corporation NM10/ICH7 Family SMBus Controller (rev 02)
01:00.0 Ethernet controller: Atheros Communications Inc. AR8132 Fast Ethernet (rev c0)
02:00.0 Network controller: Atheros Communications Inc. AR2427 802.11bg Wireless Network Adapter (PCI-Express) (rev 01)

e.g. the EHCI controller is on 00:1d.7 (BUS:DEVICE.FUNCTION). This is what your OS should also do: find the device you would like to communicate with on the PCI-bus, because if you know its address (bus:device.function), you can do that.

Re: USB Help

Posted: Sat Oct 11, 2014 6:34 am
by SpyderTL
From the operating systems point of view, you use PCI to "find" a USB controller. (It will be either an OHCI, a UHCI, a EHCI, or an xHCI controller.)

Then you use the controller to find and communicate with all of the USB devices connected to the system.

Re: USB Help

Posted: Sat Oct 11, 2014 7:12 am
by Muazzam
bigbob wrote:
muazzam wrote:[
Can you explain what is PCI? (in simple words). Why do I need PCI?. How to configure PCI? etc.
PCI is a bus, controllers (e.g. IDE, USB, stb) are connected to it.
So, if you want to have USB, then you need to "talk" to the USB-controllers via the PCI-bus (get BASE address, etc)
In my opinion these links are good:
http://wiki.osdev.org/PCI
http://en.wikipedia.org/wiki/PCI_configuration_space

EDIT:
The output of the lspci command from linux explains a lot:
00:00.0 Host bridge: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx DMI Bridge
00:02.0 VGA compatible controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
00:02.1 Display controller: Intel Corporation Atom Processor D4xx/D5xx/N4xx/N5xx Integrated Graphics Controller
00:1b.0 Audio device: Intel Corporation NM10/ICH7 Family High Definition Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 2 (rev 02)
00:1c.3 PCI bridge: Intel Corporation NM10/ICH7 Family PCI Express Port 4 (rev 02)
00:1d.0 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #1 (rev 02)
00:1d.1 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #2 (rev 02)
00:1d.2 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #3 (rev 02)
00:1d.3 USB controller: Intel Corporation NM10/ICH7 Family USB UHCI Controller #4 (rev 02)
00:1d.7 USB controller: Intel Corporation NM10/ICH7 Family USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2)
00:1f.0 ISA bridge: Intel Corporation NM10 Family LPC Controller (rev 02)
00:1f.2 SATA controller: Intel Corporation NM10/ICH7 Family SATA Controller [AHCI mode] (rev 02)
00:1f.3 SMBus: Intel Corporation NM10/ICH7 Family SMBus Controller (rev 02)
01:00.0 Ethernet controller: Atheros Communications Inc. AR8132 Fast Ethernet (rev c0)
02:00.0 Network controller: Atheros Communications Inc. AR2427 802.11bg Wireless Network Adapter (PCI-Express) (rev 01)

e.g. the EHCI controller is on 00:1d.7 (BUS:DEVICE.FUNCTION). This is what your OS should also do: find the device you would like to communicate with on the PCI-bus, because if you know its address (bus:device.function), you can do that.
So, Is PCI is used to detect hardware?

Re: USB Help

Posted: Sat Oct 11, 2014 7:50 am
by bigbob
muazzam wrote: So, Is PCI is used to detect hardware?
I think not.
Devices in a hardware are usually put on a bus.
The goal is to configure and communicate with the devices on a bus. In order to achieve that, first you need to know where they are on the bus (their address).

A pseudo-code to find USB-controllers on the bus:

Code: Select all

for(bus 0 to 255)
	for(device 0 to 32)	// device is also called slot
		for(function 0 to 8)
     {
			vID = readPCIWord(bus, device, function, VendorID)	// VendorID is an offset in the PCI-config space
			if (vID==0xFFFF) // no device
				continue
			else
			{
				cc == readPCIByte(bus, device, function, ClassCode)	// Classcode is an offset too
				sc == readPCIByte(bus, device, function, SubClass)	// SubClasscode is an offset too
				if (cc != 0x0C and sc != 0x03)	// USB-controllers have 0x0C as classcode and 0x03 as SubClasscode
					continue
				else
				{
					print("USB-controller found at", bus, device, function)
				}
			}
      }
You can read just a word instead of the two bytes (classcode and subclasscode) because they are on consecutive memory addresses.
You can find VendorID, ClassCode and Subclasscode on http://wiki.osdev.org/PCI in the config-space.
How to read and write a byte/word/dword from/to PCI is explained at many places on the Net and also on that webpage.
That webpage is good.