Listing usb devices

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Macarse
Posts: 5
Joined: Tue Nov 04, 2008 4:35 am

Listing usb devices

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Listing usb devices

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
DragonHilord
Posts: 2
Joined: Mon Nov 03, 2008 11:19 am

Re: Listing usb devices

Post by DragonHilord »

Try 'lsusb -v' (you might need to install it depending on your distro).
Macarse
Posts: 5
Joined: Tue Nov 04, 2008 4:35 am

Re: Listing usb devices

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Listing usb devices

Post 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);
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
DragonHilord
Posts: 2
Joined: Mon Nov 03, 2008 11:19 am

Re: Listing usb devices

Post 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.
Macarse
Posts: 5
Joined: Tue Nov 04, 2008 4:35 am

Re: Listing usb devices

Post 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:

Code: Select all

(gdb) p inportl(port+8)
$10 = 0
Actually the only port tested that gave me something different to FFFF.


Thanks for reading!
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Listing usb devices

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Macarse
Posts: 5
Joined: Tue Nov 04, 2008 4:35 am

Re: Listing usb devices

Post 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.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Listing usb devices

Post 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.
Post Reply