I am attempting to use FILO and libpayload with an Intel Atom E6XX processor; specifically, the Intel Tunnel Creek development kit.
This is a SOC-type processor that has four integrated PCIe links, one of which goes to an Intel IOH (sort of a southbridge). The IOH in turn contains a USB host controller (EHCI/OHCI).
Another of the PCIe links goes through a PCIe <-> PCI bridge to a standard PCI slot. Finally, the other two PCIe links go to standard PCIe slots.
I want to boot Linux from a Sandisk USB stick, so I first tried inserting the stick into one of the IOH USB ports. When I do that, I get a message:
giving up port 1, it's USB1
and FILO appears to hang.
The next thing I tried was connecting a NEC USB host controller card to the PCI slot. That one works properly. The Sandisk stick is correctly recognized, and I get:
port 2 hosts a USB2 device highspeed device device 0x0781:0x5530 is USB 2.0 (MSC) it uses SCSI transparent command set it uses Bulk-Only Transport protocol using endpoint 81 as in, 2 as out has 1 luns Waiting for device to become ready... ok. spin up. OK. Reading capacity of mass storage device. has 15625216 blocks sized 512b
I've also tried connecting a Pericom USB host controller to one of the PCIe slots. It contains a Pericom PI7C9X440SL chip. It gives the same error behavior as does the IOH. So the FILO / libpayload tally at this point is: NEC host bridge works, IOH and Pericom don't.
I've also tried an experiment where I boot Linux using the NEC controller, then plug a second Sandisk stick into the IOH controller. Linux has no problem using the IOH USB ports. Linux also has no problem using the Pericom USB ports.
I'm trying to instrument the code in ehci_rh_scanport(). I added a number of printf messages. So far, I don't see the problem. Reading some of the port status bits gives me:
port power 1, port enable 0, port reset 0, line status 2
The line status of 2 means this is an EHCI device and that an EHCI reset should be done. The code does that, but port_enable apparently stays at 0, which causes a call to ehci_rh_hand_over_port(). That routine prints the "giving up" message, and then the world ends.
The one thing I noticed in the code that might be a problem is that bit-fields are used for things like port_enable and port_reset. So to reset the port, the code does:
p->port_enable = 0; p->port_reset = 1; mdelay(50); p->port_reset = 0;
That means that port_enable and port_reset won't change at the same moment, even though they are in the same register.
In contrast, the Linux driver uses temporary variables, such that both bits will change in the same register access. I don't know if that is the problem, but it is one difference I noticed. The Linux code looks like this:
} else { ehci_vdbg (ehci, "port %d reset\n", wIndex + 1); temp |= PORT_RESET; temp &= ~PORT_PE;
/* * caller must wait, then call GetPortStatus * usb 2.0 spec says 50 ms resets on root */ ehci->reset_done [wIndex] = jiffies + msecs_to_jiffies (50); } ehci_writel(ehci, temp, status_reg);
What have other folks experiences been with the EHCI driver in libpayload?
Steve