Keep browsing

Blog post by emitrax on Wed, 2007-04-18 17:33

I’ve been reading some more code and I’m getting more confident with it.

Basically data transfer is done with memcpy.

In the ehci controller, registers are mapped every time a controller is found. This is done in the controller constructor.

As the ehci specs says: Register Space. Implementation-specific parameters and capabilities, plus operational control and status registers. This space, normally referred to as I/O space, must be implemented as memory-mapped I/O space.

So…

EHCI::EHCI(pci_info *info, Stack *stack)
...
 // map the registers
 fRegisterArea = map_physical_memory("EHCI memory mapped registers",
                (void *)physicalAddress, mapSize, B_ANY_KERNEL_BLOCK_ADDRESS,
                B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA,
                (void **)&fCapabilityRegisters);
...
 fCapabilityRegisters += offset;
 fOperationalRegisters = fCapabilityRegisters + ReadCapReg8(EHCI_CAPLENGTH);
...

fCapabilityRegisters and fOperationRegisters will be used to access the registers. Capability and Operation register functions are available to make things easier. Good.

In the UHCI controllor, things are a little bit different.

The specs says: USB Host Controller I/O Registers. This block of Control and Status registers is I/O mapped into PCI I/O space and controls the various operations of the USB (Table 2). The Base portion of the address location is set via a PCI configuration register.

UHCI::UHCI(pci_info *info, Stack *stack)
...
     fRegisterBase = sPCIModule->read_pci_config(fPCIInfo->bus,
                fPCIInfo->device, fPCIInfo->function, PCI_memory_base, 4);
        fRegisterBase &= PCI_address_io_mask;
....

A pci_module_info struct is used to access the registers by using fRegisterBase. Like with the ehci controller class, functions to access registers are also provided.

I guess I’ll go with the uhci controller first, even though I’m still far from start coding.

Both class controllers (ehci and uhci) have a static method AddTo which is called to look for controllers. They both have very similar code

EHCI::AddTo
...
 for (int32 i = 0; sPCIModule->get_nth_pci_info(i, item) >= B_OK; i++) {
                if (item->class_base == PCI_serial_bus && item->class_sub == PCI_usb
                        && item->class_api == PCI_usb_ehci) {
...
}
...
                        EHCI *bus = new(std::nothrow) EHCI(item, stack);
...

What I haven’t figure out yet is who and when is calling this methods.

host_controller_info ehci_module = {
        {
                "busses/usb/ehci",
                0,
                ehci_std_ops
        },
        NULL,
        EHCI::AddTo
};

I guess I’ll find my answer in the BeBook, or perhaps some of you can save me some time?! :)