Page 1 of 1
Error in UHCI PORTSC Line Status
Posted: Fri Jun 04, 2010 3:11 pm
by iocoder
Hello All!
I have been trying to get access to a USB Mouse connected to UHCI in my real PC. the computer contains 4 UHCI controllers. each one has 2 ports. each port always gives a value of 0x80 when i try to read it, except the first port of the fourth controller. It is 0x83.
After resetting and enabling the port, it is finally 0x1A5, and when i try to send any command to the device at the default address, it doesn't respond, like there isn't a device.
Notice that it is a USB Mouse which works well on Microsoft Windows and on Linux. a value of 0x1A5 in the PORTSC should mean that there LINE STATUS = 2. this should mean a fault has been happened.
however, all of that works well on VMWare, QEMU, and BOCHS, the port gives 0x85.
anyone has any idea plz???
Regards,
Mostafa
Re: Error in UHCI PORTSC Line Status
Posted: Sat Jun 05, 2010 5:08 am
by smil3
did you wait 100ms after you detect the mouse?
Re: Error in UHCI PORTSC Line Status
Posted: Sat Jun 05, 2010 10:45 am
by iocoder
smil3 wrote:did you wait 100ms after you detect the mouse?
Sure, I first set reset bit, and then wait 100ms, then i clear it and set Enable bit, and wait also until the port is enabled, then i read the port to see 0x1A5.
Notice that i tried writing 0x020E (in order to reset and enable at the same time), then i waited 100ms. the port gives 0x0288, and when i enable it again by writing 0x000E to it, it become 0x1A5.
i tried making it delaying 1000ms instead of 100ms, but there is no difference in results.
Regards,
Mostafa.
Re: Error in UHCI PORTSC Line Status
Posted: Sat Jun 05, 2010 2:08 pm
by iocoder
I disabled Legacy Support from BIOS.
I do a HCReset. and I poll the register until HCReset Bit becomes Zero.
I read the port which gives 0x183
I do a reset, by writing 0x0200 to the port.
I wait 100ms, then i read the port, it gives 0x0282
then I write 0x0000 to the port, in order to stop resetting.
I read the port, it gives 0x01A3;
if I write 0x0002 to clear CSC, or i write 0x0004 to enable the port after resetting, it stills giving a LINE STATUS Error.
Re: Error in UHCI PORTSC Line Status
Posted: Sat Jun 05, 2010 3:58 pm
by ehenkes
look at tatOS, it has USB UHCI inside for the mouse.
Re: Error in UHCI PORTSC Line Status
Posted: Sun Jun 06, 2010 4:14 am
by iocoder
ehenkes wrote:look at tatOS, it has USB UHCI inside for the mouse.
thanks ehenkes, i downloaded your OS and had a look through your code. Good Work!
But the problem is not in the mouse, it is in
resetting any drive attached to UHCI, even the hub.
I looked at the way you reset the ports and the way you initialize the HC, i changed my code to do the same you do, but the problem is still.
here is my code:
Code: Select all
void uhci_init() {
asm("movw %%ds, %%ax":"=a"(ds));
unsigned int i;
unsigned char bus = usb_pack[0x12];
unsigned char dev = usb_pack[0x13];
unsigned char func = usb_pack[0x14];
unsigned char reset = 0;
printk(" Initializing UHCI USB Device Driver ...\n");
// I: Initialize Descriptors:
// ----------------------------
//printk(" Port 0: %x\n", usbio.readregw(UHCI_REG_PORTBASE + 0));
//printk(" Port 1: %x\n", usbio.readregw(UHCI_REG_PORTBASE + 2));
// 1- Pointers:
uhci_frlst = (unsigned int *)((unsigned int)(uhci_data + 0x0FFF) & 0xFFFFF000);
uhci_qhlst = (eightbytelen *)((unsigned int) uhci_frlst + 0x1000);
uhci_tdlst = (sixteenbytelen *)((unsigned int) uhci_qhlst + 0x0010);
// 2- TDs:
uhci_tdlst[0].lng[0] = 0x00000001;
uhci_tdlst[0].lng[1] = 0x00000000;
uhci_tdlst[0].lng[2] = 0x00000000;
uhci_tdlst[0].lng[3] = 0x00000000;
// 3- QHs:
uhci_qhlst[0].lng[0] = ((unsigned int) &uhci_qhlst[1] + krnl_get_selector_base(ds)) | 0x00000002;
uhci_qhlst[0].lng[1] = 0x00000001;
uhci_qhlst[1].lng[0] = 0x00000001;
uhci_qhlst[1].lng[1] = ((unsigned int) &uhci_tdlst[0] + krnl_get_selector_base(ds)) | 0x00000000;
// 4- Frame List:
for (i = 0; i < 0x400; i++)
uhci_frlst[i] = ((unsigned int) &uhci_qhlst[0] + krnl_get_selector_base(ds)) | 0x00000002;
// II: Initialize Structures:
// ----------------------------
unsigned char *struct_ptr = (unsigned char *) &uhci_devices;
for (i = 0; i < sizeof(uhci_devices); i++) struct_ptr[i] = 0;
// III: Initialize UHCI:
// ----------------------------
// 1- Set Bus Master and I/O Space Enable Bits.
unsigned int pci_command;
pci_command = pci_readw(bus, dev, func, 4);
pci_writew(pci_command | 5, bus, dev, func, 4);
// 2- Turn off PIRQ and disable SMI. this shall turn off BIOS's legacy support.
pci_writew(0x8f00, bus, dev, func, 0xC0);
// 3- Reset the host controller:
usbio.writeregw(2, UHCI_REG_USBCMD);
while(usbio.readregw(UHCI_REG_USBCMD) & 2);
sleep(1000); // Sleep for 1 second.
// 4- Setup Registers:
usbio.writeregb(64, UHCI_REG_SOFMOD); // 64+11936=12000. (1ms for each frame).
usbio.writeregl((unsigned int) uhci_frlst + krnl_get_selector_base(ds), UHCI_REG_FRBASEADD);
usbio.writeregw(0x00, UHCI_REG_FRNUM); // Frame Number
usbio.writeregw(0x01, UHCI_REG_USBCMD); // RUN
// IV: Search for Connected Devices:
// -----------------------------------
for (i = 0; i < 2; i++) {
unsigned int portsc = usbio.readregw(UHCI_REG_PORTBASE + (2*i));
while (portsc & 1) {
// Set Reset Bit:
usbio.writeregw(0x0200, UHCI_REG_PORTBASE + (2*i)); // Reset
sleep(500);
usbio.writeregw(0x0000, UHCI_REG_PORTBASE + (2*i)); // Stop Reset
sleep(100);
usbio.writeregw(0x000E, UHCI_REG_PORTBASE + (2*i)); // Enable
sleep(500);
if (!uhci_enumerate(i)) break;
}
}
}
anyone has an idea about the problem plz????
i'm sorry but really i disliked UHCI
. it is full of strange behaviors, i programmed FDC, ATA, ATAPI, RTC, KBC, etc ... and never seen this fatigue. and (in my point of view) the specs of UHCI doesn't have any use, it is only describe registers and concepts of USB..., it never talks about steps to initialize the UHCI or steps to reset a port, and so on... VMware controls UHCI in a way that is full of bugs, QEMU and BOCHS emulates UHCI in a way which always works well with my code, but don't know why my real UHCI doesn't work with the code like the emulators. i think it's mainly because legacy support
. i disabled it from BIOS and no difference. anyone plz has an idea????
Best Regards,
Mostafa
Re: Error in UHCI PORTSC Line Status
Posted: Mon Jun 07, 2010 3:39 am
by Nugget
Hi mostafazizo,
I sympathize with your problems. I remember having lots of trouble getting my OHCI driver working on real hardware. These devices seem very fussy. Probably not relevant to your problem, but I found that not responding to IRQs quickly and efficiently really seems to upset USB controllers. A few printf's in the interrupt handler can be enough to make things unstable. My OHCI device appears to be very timing sensitive.
I agree with the depth (or lack of it) of the UHCI spec. Just a description of the registers and some other stuff. Not a proper description of
how to use it. The OHCI spec went into much more detail, so having a look at that might shed some light on things. It's different, of course, but similar enough to be worth a read anyway.
I'm just starting my UHCI driver at the moment, and the first thing that's worrying me is that there are lots of UHCI controllers in every system. The driver will need coding carefully so it can handle multiple devices, which isn't something my OS is good at handling yet.
Have you taken this into account?
Re: Error in UHCI PORTSC Line Status
Posted: Mon Jun 07, 2010 4:03 am
by iocoder
Dear Nugget,
Really reading OHCI specs made me say what i said about UHCI. I found the first more detailed, and supplied with code examples, it also describes everything in the controller, like how to initialise it and how to schedule your frame list in details and so on... I'm waiting for the day when I finish this UHCI driver cause I have been so tired from programming something with no source except source codes of Linux and others.
Code: Select all
I'm just starting my UHCI driver at the moment, and the first thing that's worrying me is that there are lots of UHCI controllers in every system. The driver will need coding carefully so it can handle multiple devices
u can make an only one UHCI driver for one controller, and when your OS finds a controller on PCI or whatever, it can copy this driver to memory, and so on with other controllers, as each controller has no relationship to the others, and there are machines that have only one controller (VMware, QEMU and BOCHS).
Code: Select all
I'm just starting my UHCI driver at the moment,
Good Luck!
Regards,
Mostafa
Re: Error in UHCI PORTSC Line Status
Posted: Wed Jun 09, 2010 2:52 am
by Nugget
After a look at the Mindshare USB book, I think that a line status of 2 is ok. It just means D- is 1 and D+ is 0. That could mean that it's just idle.
After resetting and enabling the port, it is finally 0x1A5, and when i try to send any command to the device at the default address, it doesn't respond, like there isn't a device.
In what way doesn't it respond? Is it not processing the TD or setting an error flag or something else?
PS. I discovered something about UHCI interrupts last night... When the IOC interrupt gets raised you need to write a 1 to bit0 of the USBSTS register to acknowledge it. That isn't documented anywhere! The interrupt just keeps firing until you tell it to stop. I had to find that out from some googled code.
Re: Error in UHCI PORTSC Line Status
Posted: Wed Jun 09, 2010 12:20 pm
by iocoder
Nugget wrote:After a look at the Mindshare USB book, I think that a line status of 2 is ok. It just means D- is 1 and D+ is 0. That could mean that it's just idle.
After resetting and enabling the port, it is finally 0x1A5, and when i try to send any command to the device at the default address, it doesn't respond, like there isn't a device.
In what way doesn't it respond? Is it not processing the TD or setting an error flag or something else?
Dear Nugget,
Thanks for answer. you are right, LINE STATUS isn't the cause of what happens. i found that it is LEGACY SUPPORT. there was a tiny typo in pci_writew(); which stopped everything from working.
Now the UHCI works well but there is another problem i face, while i'm inserting this USB Mouse, PORT0 is 0x1A5 indicating that a Low Speed Device is attached. PORT1 is 0x80.
When i insert my flash memory [Hi-Speed], PORT1 is 0x95 indicating that there is a full speed device is attached. when i enumerate that. SET ADDRESS Succeeds, but GET_DESCRIPTOR Fails with bubble and stall in the second TD [First One in Data Stage].
Does anyone have an idea??
when i looked at Microsoft Windows Device Management, I found that the root hub of that UHCI contains of 2 ports, a HID device is attached in the first port of it. the strange is that it says that the second port is free. while in EHCI's root hub, there are 7 free ports and a Mass Storage Device is attached to the last port of it.
What does that mean? does that mean that i should programme an EHCI Device Driver in order not to see a Hi-Speed Device in UHCI????
Nugget wrote:
PS. I discovered something about UHCI interrupts last night... When the IOC interrupt gets raised you need to write a 1 to bit0 of the USBSTS register to acknowledge it. That isn't documented anywhere! The interrupt just keeps firing until you tell it to stop. I had to find that out from some googled code.
Good Work! but is using IOC necessary in Bulk & Interrupt Transfers??
Finally, Thanks and Great Regards,
Mostafa
Re: Error in UHCI PORTSC Line Status
Posted: Wed Jun 09, 2010 11:41 pm
by eddyb
mostafazizo wrote:
Nugget wrote:
PS. I discovered something about UHCI interrupts last night... When the IOC interrupt gets raised you need to write a 1 to bit0 of the USBSTS register to acknowledge it. That isn't documented anywhere! The interrupt just keeps firing until you tell it to stop. I had to find that out from some googled code.
Good Work! but is using IOC necessary in Bulk & Interrupt Transfers??
Oh, well, I think because IOC stands for
Interrupt
On
Completion it doesn't mean it has to be used for interrupt transfers
. You can't do interrupt transfers without a constantly active TD *with* IOC enabled, which makes the host controller send an interrupt(otherwise it wouldn't be a interrupt transfer, would it?), LOL
. As for the bulk transfers, does any of you have an os with semaphores or something that could be used to make an async request used as a sync one? I suppose not, so you could/have to wait for a bool to change its value(or for those who don't have an usb stack of some sort, even the active bit in the TD).
Re: Error in UHCI PORTSC Line Status
Posted: Thu Jun 10, 2010 9:50 am
by Nugget
Good Work! but is using IOC necessary in Bulk & Interrupt Transfers??
eddyb is right. I was referring to the Interrupt On Completion bit in the TD that causes an interrupt when the TD completes. I think you can use this for any TD. The transfer type doesn't matter.
I suspect that your mass storage issues are related to the EHCI getting in the way. From what I've read on other threads configuring it correctly can allow you to work in a UHCI only mode. As you can tell, I'm hand waving a bit.... I haven't looked at EHCI yet.
As for synchronisation, I'm planning on having the calling thread block on a "wait" object. Once the relevant TD completes, the interrupt will tidy up and flag the object to say it's done. I expect the wait object will just be a binary semaphore or something similar.
Re: Error in UHCI PORTSC Line Status
Posted: Thu Jun 10, 2010 11:42 am
by eddyb
Nugget wrote:Good Work! but is using IOC necessary in Bulk & Interrupt Transfers??
eddyb is right. I was referring to the Interrupt On Completion bit in the TD that causes an interrupt when the TD completes. I think you can use this for any TD. The transfer type doesn't matter.
I suspect that your mass storage issues are related to the EHCI getting in the way. From what I've read on other threads configuring it correctly can allow you to work in a UHCI only mode. As you can tell, I'm hand waving a bit.... I haven't looked at EHCI yet.
As for synchronisation, I'm planning on having the calling thread block on a "wait" object. Once the relevant TD completes, the interrupt will tidy up and flag the object to say it's done. I expect the wait object will just be a binary semaphore or something similar.
You're on the right track
. About EHCI, are you (or whoever is) running on realHW? If so, there's a way you can avoid EHCI being even enabled in the system and figure UHCI out. I've seen a "USB 2.0 support" in each BIOS setup I've seen, so you could use it
.
Re: Error in UHCI PORTSC Line Status
Posted: Mon Jun 14, 2010 3:57 am
by Nugget
Excellent tip! That's made things a bit easier.