From 1474ce5c1ba164bbccfefa411883805d12a0dc62 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 4 Oct 2011 12:01:54 +0800 Subject: [PATCH] Modules/USB - Fiddling with USB --- Modules/USB/Core/Makefile | 2 +- Modules/USB/Core/main.c | 23 +++++++-- Modules/USB/Core/uhci.c | 98 ++++++++++++++++++++++++++------------- Modules/USB/Core/usb.c | 10 +++- Modules/USB/Core/usb.h | 46 +++++++++++++----- 5 files changed, 130 insertions(+), 49 deletions(-) diff --git a/Modules/USB/Core/Makefile b/Modules/USB/Core/Makefile index af927313..b4cd3237 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 712f6028..9a6458ef 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 5a71d656..f50324fa 100644 --- a/Modules/USB/Core/uhci.c +++ b/Modules/USB/Core/uhci.c @@ -6,6 +6,7 @@ #include #include #include +#include #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 60f2ab81..ab9a4894 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 c0cf7854..9bc45c8e 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 -- 2.20.1