Bonfra wrote:BenLunt wrote:
however it doesn't mean the SMI has given up control of the EHCI and UHCI(s).
This should only apply to HDIs so it should not be a problem (since I'm working with an msd) but I've followed your suggestion so it should not interfere.
BenLunt wrote:A simple write to PCI configuration word 0xC0 of 0x8F00 does the trick.
I am guessing you meant HID instead of HDI. However, with newer firmware, it manages MSDs as well, to be able to boot from them. However, since you sent the "release", I don't think this is a problem.
Bonfra wrote:After the "Waiting for port to be ready" message 10 iterations are performed spinning on the PORTSC_ENABLE bit sleeping 10ms between each and logging the value each time. I'm not quite sure about that 0xE2 value repeated three times but idk I'm a bit confused
I don't know where you got the 0xE2 from either. I doubt the port had a value of 0xE2. Place a "printf()" at
line 152 and see what value it has. Something that will print the iteration number and the value. For example:
Code: Select all
printf(" %i: 0x%04X\n", iteration++, status); // of course defining 'iteration' as an integer with a value of zero at the top of your function.
Curious, is your UHCI an HP brand (vendor id = 0x103C)?
At
Line 143, you clear the reset bit, but also write a 1 to the CSC bit (the CSC bit is set after the reset, so writing the existing value writes a 1 to the CSC bit at line 143). I have found that this doesn't work on some controllers.
Throughout my research with the UHCI, the following code has worked the best:
(see the note at line 2. 'base' is the portIO base value, your 'controller->io' value)
(udelay() delays for a given microseconds while mdelay() for a given milliseconds)
Code: Select all
ret = -1;
const bit8u port = ??????; // Bonfra: 'port' = 0x10, 0x12, etc. Modify to match your code...
bit16u val = 0;
// reset the port, holding the bit set at least 50 ms for a root hub
val = inpw(base + port);
outpw(base + port, val | (1<<9));
mdelay(USB_TDRSTR);
// clear the reset bit, do not clear the CSC bit while
// we clear the reset. The controller needs to have
// it cleared (written to) while *not* in reset
// also, write a zero to the enable bit
val = inpw(base + port);
outpw(base + port, val & 0xFCB1);
udelay(300); // note that this is *not* the USB specification delay
// if we wait the recommended USB_TRSTRCY time after clearing the reset,
// the device will not enable when we set the enable bit below.
// the CSC bit must be clear *before* we set the Enable bit
// so clear the CSC bit (Write Clear), then set the Enable bit
val = inpw(base + port);
outpw(base + port, val | 0x0003);
outpw(base + port, val | 0x0005);
// wait for it to be enabled
udelay(50);
// now clear the PEDC bit, and CSC if it still
// happens to be set, while making sure to keep the
// Enable bit and CCS bits set
val = inpw(base + port);
outpw(base + port, val | 0xF);
// short delay before we start sending packets
mdelay(50);
// return successful if the Enabled bit was set
if (inpw(base + port) & (1<<2))
ret = SUCCESS_RESET;
return ret;
I have found this code to work on 99% of all low-, full-, high-, and super-speed devices I have plugged into an UHCI. (Granted, the high- and super-speed devices revert to full-speed).
Try this and see what happens.
Ben
-
https://www.fysnet.net/the_universal_serial_bus.htm