diff --git a/Modules/USB/Core/Makefile b/Modules/USB/Core/Makefile
index af927313e7439f8dab60d2c71cb45b48f5c2d53c..b4cd32371ded5288d37b2f38cec4822936845eab 100644
--- a/Modules/USB/Core/Makefile
+++ b/Modules/USB/Core/Makefile
@@ -1,7 +1,7 @@
 #
 #
 
-OBJ = main.o uhci.o
+OBJ = main.o usb.o uhci.o
 NAME = Core
 
 -include ../Makefile.tpl
diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c
index 712f6028f2b3fbdd6503dcfda4061c63828e4f35..9a6458ef3cadf34193dc3b18189a117f58255b3c 100644
--- a/Modules/USB/Core/main.c
+++ b/Modules/USB/Core/main.c
@@ -32,12 +32,11 @@ tDevFS_Driver	gUSB_DrvInfo = {
 		.IOCtl = USB_IOCtl
 	}
 };
-tUSBDevice	*gUSB_Devices = NULL;
+tUSBDevice	*gUSB_RootHubs = NULL;
 tUSBHost	*gUSB_Hosts = NULL;
 
 // === CODE ===
 /**
- * \fn int ModuleLoad()
  * \brief Called once module is loaded
  */
 int USB_Install(char **Arguments)
@@ -48,7 +47,25 @@ int USB_Install(char **Arguments)
 }
 
 /**
- * \fn void USB_Cleanup()
+ * \brief USB polling thread
+ */
+int USB_PollThread(void *unused)
+{
+	for(;;)
+	{
+		for( tUSBHost *host = gUSB_Hosts; host; host = host->Next )
+		{
+			// host->CheckPorts(host);
+		}
+
+		for( tUSBDevice *dev = gUSB_RootHubs; dev; dev = dev->Next )
+		{
+			
+		}
+	}
+}
+
+/**
  * \brief Called just before module is unloaded
  */
 void USB_Cleanup()
diff --git a/Modules/USB/Core/uhci.c b/Modules/USB/Core/uhci.c
index 5a71d65623e1cdd33432777955bdaba0e923337e..f50324fa8a0ac0958b3d7d93cf394f8b348820da 100644
--- a/Modules/USB/Core/uhci.c
+++ b/Modules/USB/Core/uhci.c
@@ -6,6 +6,7 @@
 #include <acess.h>
 #include <vfs.h>
 #include <drv_pci.h>
+#include <modules.h>
 #include "usb.h"
 #include "uhci.h"
 
@@ -18,10 +19,10 @@
 void	UHCI_Cleanup();
 tUHCI_TD	*UHCI_int_AllocateTD(tUHCI_Controller *Cont);
 void	UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD);
- int	UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Fcn, int Endpt, int DataTgl, Uint8 Type, void *Data, size_t Length);
- int	UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
- int	UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
- int	UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
+void	*UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, int bIOC, void *Data, size_t Length);
+void	*UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
+void	*UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
+void	*UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
  int	UHCI_Int_InitHost(tUHCI_Controller *Host);
 void	UHCI_InterruptHandler(int IRQ, void *Ptr);
 
@@ -81,8 +82,8 @@ int UHCI_Initialise(const char **Arguments)
 	if(i == MAX_CONTROLLERS) {
 		Log_Warning("UHCI", "Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest");
 	}
-	LEAVE('i', i);
-	return i;
+	LEAVE('i', MODULE_ERR_OK);
+	return MODULE_ERR_OK;
 }
 
 /**
@@ -108,62 +109,63 @@ tUHCI_TD *UHCI_int_AllocateTD(tUHCI_Controller *Cont)
 
 void UHCI_int_AppendTD(tUHCI_Controller *Cont, tUHCI_TD *TD)
 {
-	
+	Log_Warning("UHCI", "TODO: Implement AppendTD");
 }
 
 /**
  * \brief Send a transaction to the USB bus
- * \param ControllerID Controller
- * \param Fcn	Function Address
- * \param Endpt	Endpoint
+ * \param Cont	Controller pointer
+ * \param Addr	Function Address * 16 + Endpoint
+ * \param bTgl	Data toggle value
  */
-int UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Fcn, int Endpt, int DataTgl, Uint8 Type, void *Data, size_t Length)
+void *UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int bTgl, int bIOC, void *Data, size_t Length)
 {
 	tUHCI_TD	*td;
 
-	if( Length > 0x400 )	return -1;	// Controller allows up to 0x500, but USB doesn't
+	if( Length > 0x400 )	return NULL;	// Controller allows up to 0x500, but USB doesn't
 
 	td = UHCI_int_AllocateTD(Cont);
 
 	td->Link = 1;
 	td->Control = (Length - 1) & 0x7FF;
 	td->Token  = ((Length - 1) & 0x7FF) << 21;
-	td->Token |= (DataTgl & 1) << 19;
-	td->Token |= (Endpt & 0xF) << 15;
-	td->Token |= (Fcn & 0xFF) << 8;
+	td->Token |= (bTgl & 1) << 19;
+	td->Token |= (Addr & 0xF) << 15;
+	td->Token |= ((Addr/16) & 0xFF) << 8;
 	td->Token |= Type;
 
 	// TODO: Ensure 32-bit paddr
 	if( ((tVAddr)Data & PAGE_SIZE) + Length > PAGE_SIZE ) {
 		Log_Warning("UHCI", "TODO: Support non single page transfers");
 //		td->BufferPointer = 
-		return 1;
+		return NULL;
 	}
 	else {
 		td->BufferPointer = MM_GetPhysAddr( (tVAddr)Data );
 	}
 
+	if( bIOC ) {
+//		td->Control
+	}
+
 	UHCI_int_AppendTD(Cont, td);
 
-	// Wait until done, then return
-	while(td->Link != 0)
-		Threads_Yield();
-	return 0;
+	return td;
 }
 
-int UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length)
+void *UHCI_DataIN(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
 {
-	return UHCI_int_SendTransaction(Ptr, Fcn, Endpt, DataTgl, 0x69, Data, Length);
+	return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0x69, DataTgl, bIOC, Data, Length);
 }
 
-int UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length)
+void *UHCI_DataOUT(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
 {
-	return UHCI_int_SendTransaction(Ptr, Fcn, Endpt, DataTgl, 0xE1, Data, Length);
+	return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0xE1, DataTgl, bIOC, Data, Length);
 }
 
-int UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length)
+void *UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length)
 {
-	return UHCI_int_SendTransaction(Ptr, Fcn, Endpt, DataTgl, 0x2D, Data, Length);
+	return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0x2D, DataTgl, bIOC, Data, Length);
 }
 
 // === INTERNAL FUNCTIONS ===
@@ -177,6 +179,7 @@ int UHCI_Int_InitHost(tUHCI_Controller *Host)
 	ENTER("pHost", Host);
 
 	outw( Host->IOBase + USBCMD, 4 );	// GRESET
+	Time_Delay(10);
 	// TODO: Wait for at least 10ms
 	outw( Host->IOBase + USBCMD, 0 );	// GRESET
 	
@@ -197,20 +200,51 @@ int UHCI_Int_InitHost(tUHCI_Controller *Host)
 	// Set frame length to 1 ms
 	outb( Host->IOBase + SOFMOD, 64 );
 	
-	// Set Frame List Address
+	// Set Frame List
 	outd( Host->IOBase + FLBASEADD, Host->PhysFrameList );
-	
-	// Set Frame Number
 	outw( Host->IOBase + FRNUM, 0 );
 	
 	// Enable Interrupts
-//	PCI_WriteWord( Host->PciId, 0xC0, 0x2000 );
-	
+	outw( Host->IOBase + USBINTR, 0x000F );
+	PCI_ConfigWrite( Host->PciId, 0xC0, 2, 0x2000 );
+
+	outw( Host->IOBase + USBCMD, 0x0001 );
+
 	LEAVE('i', 0);
 	return 0;
 }
 
+void UHCI_CheckPortUpdate(tUHCI_Controller *Host)
+{
+	// Enable ports
+	for( int i = 0; i < 2; i ++ )
+	{
+		 int	port = Host->IOBase + PORTSC1 + i*2;
+		// Check for port change
+		if( !(inw(port) & 0x0002) )	continue;
+		outw(port, 0x0002);
+		
+		// Check if the port is connected
+		if( !(inw(port) & 1) )
+		{
+			// TODO: Tell the USB code it's gone?
+			continue;
+		}
+		else
+		{
+			LOG("Port %i has something", i);
+			// Reset port (set bit 9)
+			outw( port, 0x0100 );
+			Time_Delay(50);	// 50ms delay
+			outw( port, inw(port) & ~0x0100 );
+			// Enable port
+			Time_Delay(50);	// 50ms delay
+			outw( port, inw(port) & 0x0004 );
+		}
+	}
+}
+
 void UHCI_InterruptHandler(int IRQ, void *Ptr)
 {
-	
+	Log_Debug("UHCI", "UHIC Interrupt");
 }
diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c
index 60f2ab81c7c59704a0e224884896d977fb3f330b..ab9a48940e8748ae31839a6ed34eb0b2bdb84396 100644
--- a/Modules/USB/Core/usb.c
+++ b/Modules/USB/Core/usb.c
@@ -10,7 +10,12 @@
 
 
 // === CODE ===
-int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address)
+void USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr)
+{
+	// TODO:
+}
+
+int USB_int_SendSetupSetAddress(tUSBHost *Host, void *Ptr, int Address)
 {
 	Uint8	data[8];
 	data[0] = 0;	// bmRequestType
@@ -20,5 +25,6 @@ int USB_int_SendSetupSetAddress(tUSBHost *Host, int Address)
 	data[4] = 0;	// wLength
 	data[6] = 0;	// wLength
 	
-	Host->SendSETUP(Host, 0, 0, 0, data, 8);
+	// Addr 0:0, Data Toggle = 0, no interrupt
+	return Host->SendSETUP(Ptr, 0, 0, 0, FALSE, data, 8) == NULL;
 }
diff --git a/Modules/USB/Core/usb.h b/Modules/USB/Core/usb.h
index c0cf7854a1425bfd59e083f8198b334a33840d87..9bc45c8e08df1149e3489dc1f3c60f4a9600387d 100644
--- a/Modules/USB/Core/usb.h
+++ b/Modules/USB/Core/usb.h
@@ -7,34 +7,58 @@
 
 // === TYPES ===
 typedef struct sUSBHost	tUSBHost;
+typedef struct sUSBHub	tUSBHub;
 typedef struct sUSBDevice	tUSBDevice;
 
 // === STRUCTURES ===
 /**
- * \brief Defines a USB Host Controller
+ * \brief Defines a USB Host Controller type
  */
 struct sUSBHost
 {
-	 int	(*SendIN)(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
-	 int	(*SendOUT)(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
-	 int	(*SendSETUP)(void *Ptr, int Fcn, int Endpt, int DataTgl, void *Data, size_t Length);
+	tUSBHost	*Next;
+
+	void	(*CheckPorts)(void *Ptr);
+
+	void	*(*SendIN)(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
+	void	*(*SendOUT)(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
+	void	*(*SendSETUP)(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void *Data, size_t Length);
 };
 
 /**
- * \brief Defines a single device on the USB Bus
+ * \brief USB Hub data
  */
-struct sUSBDevice
+struct sUSBHub
 {
+	/**
+	 * \brief Host controller used
+	 */
 	tUSBHost	*HostDef;
 	void	*Controller;
 
-	 int	Address;
+	 int	nPorts;
+	tUSBDevice	*Devices[];
+};
 
-	 int	MaxControl;
-	 int	MaxBulk;
-	 int	MaxISync;
+/**
+ * \brief Defines a single device on the USB Bus
+ */
+struct sUSBDevice
+{
+	tUSBDevice	*Next;
+	tUSBDevice	*Hub;
+
+	 int	Address;
+	
+	 int	Type;
+	
+	union {
+		tUSBHub	Hub;
+		char	Impl[0];
+	}	Data;
 };
 
-extern void USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr);
+extern void	USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr);
+extern void	USB_NewDevice(tUSBHub *Hub);
 
 #endif