Page 1 of 1
Listing usb devices
Posted: Wed Nov 05, 2008 3:19 pm
by Macarse
Hi.
I've been trying to list usb devices following this
thread
So far I have an lspci alike working using shiner's source code @
this thread
My lspci lists a USB Host Controller by Intel so I started reading Universal Host Controller Interface (UHCI) Design Guide.
I have issues trying to do next step:
2) Reset Host
2.1.1 USBCMD USB COMMAND REGISTER
I/O Address: Base+ (00−01h)
Default Value: 0000h
Attribute: Read/Write
Size: 16 bits
Bit = 1
Host Controller Reset (HCRESET). When this bit is set, the Host Controller module resets its internal
timers, counters, state machines, etc. to their initial value. Any transaction currently in progress on
USB is immediately terminated. This bit is reset by the Host Controller when the reset process is
complete.
I don't get what to send to the pci device to do that operation.
Thanks for your time.
Re: Listing usb devices
Posted: Wed Nov 05, 2008 6:39 pm
by Combuster
I expect the device to have a number of BARs set to I/O and MMIO ranges. You should get the I/O range's offset (i.e. the Base), add the register index (Base + 0), then use that as the address for a series of port OUTs and INs
The chipset will convert the IN/OUT operations you do to that address to the corresponding PCI cycles.
Re: Listing usb devices
Posted: Wed Nov 05, 2008 10:18 pm
by DragonHilord
Try 'lsusb -v' (you might need to install it depending on your distro).
Re: Listing usb devices
Posted: Wed Nov 05, 2008 10:35 pm
by Macarse
Thanks for the reply!
DragonHilord:
I've read the lsub source code. It parses /proc/bus/usb/devices so it isn't what I need.
Combuster:
This are the BARs I get from the pci device.
Code: Select all
(gdb) p usbDevice.BAR0
$1 = 0
(gdb) p usbDevice.BAR1
$2 = 0
(gdb) p usbDevice.BAR2
$3 = 0
(gdb) p usbDevice.BAR3
$4 = 0
(gdb) p usbDevice.BAR4
$5 = 49185
(gdb) p usbDevice.BAR5
$6 = 0
Here's the structure:
Code: Select all
typedef struct
{
unsigned short VendorID;
unsigned short DeviceID;
short CommandReg;
short StatusReg;
short RevisionID;
char SubClass;
char ClassCode;
char CachelineSize;
char Latency;
char HeaderType;
char BIST;
int BAR0;
int BAR1;
int BAR2;
int BAR3;
int BAR4;
int BAR5;
int CardbusCISPtr;
short SubVendorID;
short SubDeviceID;
int ExRomAddress;
int Reserved1;
int Reserved2;
char IRQ;
char PIN;
char MinGrant;
char MaxLatency;
}PCI_Device_t;
From the osdev wiki
BARs are used to hold memory addresses used by the device, for example the DMA address. It can also hold I/O ports. To distinguish between them, you can check if the lowest bit is 1. If it is, the lower word represents the I/O port. Also don't forget to zero the lowest bit.
49185 to hex is: 0xC021
lowest word = 21
zero the lowest bit = 20h
If 20h is the offset, which is the base adress? 0xCF8? (pci out port)
I am using qemu to test.
Thanks.
Re: Listing usb devices
Posted: Thu Nov 06, 2008 3:48 am
by Combuster
Macarse wrote:49185 to hex is: 0xC021
lowest word = 21
a word is 16 bits. The lowest word is therefore the last four digits of 0x(0000)C021
zero the lowest bit = 20h
If 20h is the offset, which is the base adress? 0xCF8? (pci out port)
0xC020 is the Base
therefore you out(0xC020+offset, data); and in(0xC020+offset);
Re: Listing usb devices
Posted: Thu Nov 06, 2008 7:44 am
by DragonHilord
Macarse wrote:DragonHilord:
I've read the lsub source code. It parses /proc/bus/usb/devices so it isn't what I need.
Sorry bud, I must've misunderstood the exact question.
Re: Listing usb devices
Posted: Sat Nov 08, 2008 10:45 am
by Macarse
DragonHilord: np
Combuster: my bad
I quite don't yet understand how my address should be.
The Universal Host Controller Interface (UHCI) Design Guide says:
2.1.1 USBCMD USB COMMAND REGISTER
I/O Address: Base+ (00−01h)
Default Value: 0000h
Attribute: Read/Write
Size: 16 bits
Bit Description
15:8 Reserved.
7 Max Packet (MAXP). 1=64 bytes. 0=32 bytes. This bit selects the maximum packet size that can be
used for full speed bandwidth reclamation at the end of a frame. This value is used by the Host
Controller to determine whether it should initiate another transaction based on the time remaining in
the SOF counter. Use of reclamation packets larger than the programmed size will cause a Babble
error if executed during the critical window at frame end. The Babble error results in the offending
endpoint being stalled. Software is responsible for ensuring that any packet which could be executed
under bandwidth reclamation be within this size limit.
.......
To test I was "creating" the address correctly I tried reading the Max Packet (MAXP)
But once again, I don't understand the specs.
I/O Address: Base+ (00−01h)
(00−01h) depending on what?
7 Max Packet (MAXP). 1=64 bytes. 0=32 bytes.
Bit 7 means I have to do base + 80h?
So I started testing, and printing what comes from in(port)
port == 0xC020
Code: Select all
(gdb) p inportl(port)
$2 = 4294967295
(gdb) p inportl(port+128)
$12 = 4294967295
After testing with different offsets I got this:
Actually the only port tested that gave me something different to FFFF.
Thanks for reading!
Re: Listing usb devices
Posted: Sun Nov 09, 2008 7:18 am
by Combuster
Look at the specifications - it says its a 16-bit port, you're doing a 32-bit read. That is bound to give problems.
Re: Listing usb devices
Posted: Tue Nov 11, 2008 8:02 pm
by Macarse
Combuster: thanks for your help.
This days I've been advancing quite a lot.
I've been reading the linux kernel and getting some ideas from there.
I'll post the code when finish.
Thanks for the help.
Re: Listing usb devices
Posted: Tue Nov 11, 2008 8:22 pm
by pcmattman
(00−01h) depending on what?
AFAIK 00-01h as in, two ports, which means either two 8-bit reads (shift the bits around) or one 16-bit read.