Open Host Controller Interface

From OSDev Wiki
(Redirected from OHCI)
Jump to navigation Jump to search

The Open Host Controller Interface (OHCI) is an open standard that defines the interfaces between certain USB and Firewire drivers, hardware controllers, and devices. It was originally published by Compaq, Microsoft and National Semiconductor in 1999. Along with the Universal Host Controller Interface (UHCI), the OHCI makes up the USB 1.0 hardware controller interface standard.

Technical Details

According to the OHCI standard, the OHCI driver communicates with the OHCI controller using two primary methods: Memory Mapped Registers, and Shared Memory Linked Lists.

The OHCI defines 21 memory mapped registers, exposed through BAR0:

Offset (Hex) Name
00 HcRevision
04 HcControl
08 HcCommandStatus
0c HcInterruptStatus
10 HcInterruptEnable
14 HcInterruptDisable
18 HcHCCA
1c HcPeriodCurrentED
20 HcControlHeadED
24 HcControlCurrentED
28 HcBulkHeadED
2c HcBulkCurrentED
30 HcDoneHead
34 HcFmInterval
38 HcFmRemaining
3c HcFmNumber
40 HcPeriodicStart
44 HcLSThreshold
48 HcRhDescriptorA
4c HcRhDescriptorB
50 HcRhStatus

In addition to these registers, starting at offset 54h, each USB port on the root hub is assigned an HcRhPortStatus register that denotes the current status of the port.

PCI Configuration

The memory mapped registers listed above are not fixed in memory, and may be located at any 32-bit address regardless of how much memory is installed on the machine. To find the base register address, the PCI bus can be searched for a specific vendor/device id, or a specific Class ID to find any OHCI controllers. All OHCI controllers will have a Class ID of 0x0Ch, a subclass of 0x03h, and a program interface value of 0x10h. The PCI device configuration area contains a single Base Address that points to the memory mapped register block.

Shared Memory Linked Lists

All commands and data packets are supplied to the controller via a shared memory area containing tables and linked lists. The USB protocol defines 4 different message types: Interrupt, Isochronous, Control and Bulk. Each message type is given its own linked list of outgoing messages. As the controller processes these messages, they are moved to a corresponding "done" list, along with information concerning any errors encountered by the controller while delivering the message.

Control Messages

Control messages are used to initialize and configure a device that has been detected by a hub. Devices that have not been initialized will not respond to any control messages. To initialize a device, the hub port that the device is connected to must be reset. Upon reset, the device will default to address 0, and will begin responding to any control messages sent to that address. You should ensure that only one device is initialized at a time, and once the device's port has been reset, you should immediately send a SetAddress command to assign an unused address between 1 and 127 to the device. Once this command has been sent, the device will begin responding to its new address, and will no longer respond to address 0.

The HcControlHead register points to the first control Endpoint Descriptor (ED) in a linked list of Endpoint Descriptors. Each Endpoint Descriptor describes one endpoint on the USB bus that can be communicated with by the operating system. To send or receive data from an endpoint, a Transfer Descriptor is added to an Endpoint Descriptor by the operating system. Once the data has been transferred, the controller will move the Transfer Descriptor from the Endpoint Descriptor to the Done Queue.

Each Endpoint Descriptor has a "head" Transfer Descriptor field and a "tail" Transfer Descriptor field, as well as a "next" Endpoint Descriptor field. The final Endpoint Descriptor in the Endpoint Descriptor chain will have a "next" Endpoint Descriptor value of zero. When the "head" Transfer Descriptor matches the "tail" Transfer Descriptor, the Endpoint Descriptor is empty, and no more data will be sent.

The Endpoint Descriptors in the HcControlHead list can only be used to communicate with Control endpoints. All devices have a control endpoint 0 that is used to configure the device.

Bulk Messages

The HcBulkHeadED register points to the first bulk Endpoint Descriptor in the bulk endpoint descriptor list, and is used to send and receive bulk data packets. Otherwise, it is functionally identical to the HcControlHead register.

Endpoint Descriptors

An Endpoint Descriptor is a memory structure that contains information used to communicate with a specific endpoint on a specific device address. The structure must be aligned on a 16-byte boundary.

Offset (Hex) Name Description
00 Control Bits 0:6 - Function address

Bits 7:10 - Endpoint address

Bits 11:12 - Direction of dataflow (IN/OUT)

Bit 13 - If set, this is a low speed endpoint, if zero, this is full speed endpoint

Bit 14 - You set this if you want the host controller to skip processing this ED

Bit 15 - If set, TDs linked to this ED contain isochronous transfers

Bits 16:26 - Maximum packet size

Bits 27:31 - not used by the host controller

04 TD Queue Tail Pointer Physical address of TD queue tail. If this dword and the next dword are equal, it means the TD list is empty and there are not TDs to process
08 TD Queue Head Pointer Physical address of TD queue head. As TDs are 16-byte aligned, the lower 4 bits are not used, so the host controller uses some of them as follows:

Bit 0 - host controller sets this to tell you that processing of TD queue on this endpoint is halted (usually due to an error)

Bit 1 - toggle carry bit from the last retired TD

0c Next ED Physical address of the next ED. If NULL, this is the last ED in the list

Transfer Descriptors

Transfer Descriptors (TD) describe a memory buffer to be sent to, or read from, a USB endpoint.

There are 2 types:

  • General TD: used for interrupt, control and bulk transfers. Must be aligned on a 16-byte boundary.
  • Isochronous TD: used for isochronous transfers. Must be aligned on a 32-byte boundary and they use a different descriptor structure.


General Transfer Descriptor Structure

Offset (Hex) Name Description
00 Control Bits 0:17 - not used by the host controller

Bit 18 - if set, the last packet may be smaller than the buffer size without causing an error

Bits 19:20 - direction of transfer (00b SETUP; 01b OUT; 10b IN; 11b reserved)

Bits 21:23 - number of frames to wait after processing this TD and before sending an interrupt (a value of 111b means there is no interrupt for this TD)

Bits 24:25 - data toggle (DATA0/DATA1)

Bits 25:27 - error count

Bits 28:31 - status of last transaction

04 Current Buffer Pointer (CBP) Physical address of the first byte in the transfer buffer. Buffers can be upto 8,192 bytes in size, and can span upto 2 physically disjoint pages
08 Next TD (NextTD) Physical address of the next TD in the list for this endpoint
0c Buffer End (BE) Physical address of the last byte in the buffer (that is, bufsize - 1)

See also