From dfe55553735a8cfa2b7207e5096caddded32c992 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 25 Nov 2011 09:53:00 +0800 Subject: [PATCH] Modules/USB - Working on a structure for the USB subsystem --- Makefile.cfg | 5 ++- Modules/USB/Core/Makefile | 3 +- Modules/USB/Core/include/usb_core.h | 43 ++++++++++++++++++++++ Modules/USB/Core/include/usb_host.h | 31 ++++++++++++++++ Modules/USB/Core/include/usb_hub.h | 28 +++++++++++++++ Modules/USB/Core/main.c | 18 ++++------ Modules/USB/Core/usb.c | 51 +++++++++++++++++++++----- Modules/USB/Core/usb.h | 55 +++++++++++++---------------- Modules/USB/Core/usb_proto.h | 38 ++++++++++++++++++++ Modules/USB/HID/hid.h | 47 ++++++++++++++++++++++++ Modules/USB/UHCI/Makefile | 8 +++++ Modules/USB/{Core => UHCI}/uhci.c | 23 +++++++++--- Modules/USB/{Core => UHCI}/uhci.h | 2 ++ 13 files changed, 293 insertions(+), 59 deletions(-) create mode 100644 Modules/USB/Core/include/usb_core.h create mode 100644 Modules/USB/Core/include/usb_host.h create mode 100644 Modules/USB/Core/include/usb_hub.h create mode 100644 Modules/USB/Core/usb_proto.h create mode 100644 Modules/USB/HID/hid.h create mode 100644 Modules/USB/UHCI/Makefile rename Modules/USB/{Core => UHCI}/uhci.c (90%) rename Modules/USB/{Core => UHCI}/uhci.h (99%) diff --git a/Makefile.cfg b/Makefile.cfg index 3b1bfd5e..d36dca54 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -54,10 +54,10 @@ MODULES += Storage/FDDv2 MODULES += Network/NE2000 Network/RTL8139 MODULES += Display/VESA MODULES += Display/BochsGA -#MODULES += Interfaces/UDI MODULES += Input/PS2KbMouse MODULES += x86/ISADMA x86/VGAText -MODULES += USB/Core +MODULES += USB/Core USB/UHCI +#MODULES += Interfaces/UDI endif ifeq ($(ARCHDIR),x86_64) @@ -68,7 +68,6 @@ MODULES += Display/BochsGA MODULES += Interfaces/UDI MODULES += Input/PS2KbMouse MODULES += x86/ISADMA x86/VGAText -MODULES += USB/Core endif ifeq ($(ARCHDIR),armv7) diff --git a/Modules/USB/Core/Makefile b/Modules/USB/Core/Makefile index b4cd3237..7e8c30d9 100644 --- a/Modules/USB/Core/Makefile +++ b/Modules/USB/Core/Makefile @@ -1,7 +1,8 @@ # # -OBJ = main.o usb.o uhci.o +OBJ = main.o usb.o +CPPFLAGS = -Iinclude NAME = Core -include ../Makefile.tpl diff --git a/Modules/USB/Core/include/usb_core.h b/Modules/USB/Core/include/usb_core.h new file mode 100644 index 00000000..9169b0fa --- /dev/null +++ b/Modules/USB/Core/include/usb_core.h @@ -0,0 +1,43 @@ +/* + * Acess2 USB Stack + * - By John Hodge (thePowersGang) + * + * usb_core.h + * - Core USB IO Header + */ +#ifndef _USB_CORE_H_ +#define _USB_CORE_H_ + +typedef struct sUSBDevice tUSBDevice; +typedef struct sUSBDriver tUSBDriver; + +/** + */ +struct sUSBDriver +{ + tUSBDriver *Next; + + const char *Name; + + // TODO: Check class codes and provide other identifcation options + Uint32 ClassCode; + + void (*Connected)(tUSBDevice *Dev); + void (*Disconnected)(tUSBDevice *Dev); + + int MaxEndpoints; + struct { + // 0: Bulk, 1: Control, 2: Interrupt + int Type; + // Data availiable Callback + void (*Interrupt)(tUSBDevice *Dev, int Length, void *Data); + } Endpoints[]; +}; + +extern void *USB_GetDeviceDataPtr(tUSBDevice *Dev); +extern void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr); + +extern void USB_SendData(tUSBDevice *Dev, int Endpoint, int Length, void *Data); + +#endif + diff --git a/Modules/USB/Core/include/usb_host.h b/Modules/USB/Core/include/usb_host.h new file mode 100644 index 00000000..7dc79243 --- /dev/null +++ b/Modules/USB/Core/include/usb_host.h @@ -0,0 +1,31 @@ +/* + * Acess2 USB Stack + * - By John Hodge (thePowersGang) + * + * usb_host.h + * - USB Host Controller Interface + */ +#ifndef _USB_HOST_H_ +#define _USB_HOST_H_ + +#include "usb_core.h" +#include "usb_hub.h" + +typedef struct sUSBHostDef tUSBHostDef; + +/** + * \brief Defines a USB Host Controller type + */ +struct sUSBHostDef +{ + 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); + + void (*CheckPorts)(void *Ptr); +}; + +extern tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts); + +#endif + diff --git a/Modules/USB/Core/include/usb_hub.h b/Modules/USB/Core/include/usb_hub.h new file mode 100644 index 00000000..f48936bc --- /dev/null +++ b/Modules/USB/Core/include/usb_hub.h @@ -0,0 +1,28 @@ +/* + * Acess2 USB Stack + * - By John Hodge (thePowersGang) + * + * usb_hub.h + * - Core Hub Definitions + */ +#ifndef _USB_HUB_H_ +#define _USB_HUB_H_ + +#include "usb_core.h" + +typedef struct sUSBHub tUSBHub; + +typedef void (*tUSB_HubPoll)(tUSBHub *Hub, tUSBDevice *HubDev); + +/** + * \brief Register a device as a hub + * + * Used by the hub class initialisation routine. + */ +extern tUSBHub USB_RegisterHub(tUSBDevice *Device, int nPorts, tUSB_HubPoll PollCallback); + +extern void USB_DeviceConnected(tUSBHub *Hub, int Port); +extern void USB_DeviceDisconnected(tUSBHub *Hub, int Port); + +#endif + diff --git a/Modules/USB/Core/main.c b/Modules/USB/Core/main.c index 9a6458ef..baf13320 100644 --- a/Modules/USB/Core/main.c +++ b/Modules/USB/Core/main.c @@ -10,9 +10,6 @@ #include #include "usb.h" -// === IMPORTS === -extern int UHCI_Initialise(void); - // === PROTOTYPES === int USB_Install(char **Arguments); void USB_Cleanup(void); @@ -32,8 +29,9 @@ tDevFS_Driver gUSB_DrvInfo = { .IOCtl = USB_IOCtl } }; -tUSBDevice *gUSB_RootHubs = NULL; tUSBHost *gUSB_Hosts = NULL; +tUSBHub *gUSB_Hubs = NULL; +tUSBHub *gUSB_HubsEnd = NULL; // === CODE === /** @@ -41,7 +39,6 @@ tUSBHost *gUSB_Hosts = NULL; */ int USB_Install(char **Arguments) { - UHCI_Initialise(); Log_Warning("USB", "Not Complete - Devel Only"); return MODULE_ERR_OK; } @@ -53,15 +50,12 @@ 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 ) + for( tUSBHub *hub = gUSB_Hubs; hub; hub = hub->Next ) { - + hub->CheckPorts(hub, hub->Device); } + // TODO: Fine tune + Time_Delay(250); } } diff --git a/Modules/USB/Core/usb.c b/Modules/USB/Core/usb.c index ab9a4894..de884e48 100644 --- a/Modules/USB/Core/usb.c +++ b/Modules/USB/Core/usb.c @@ -7,24 +7,57 @@ #include #include #include "usb.h" +#include "usb_proto.h" +// === STRUCTURES === // === CODE === -void USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr) +tUSBHub *USB_RegisterHost(tUSBHostDef *HostDef, void *ControllerPtr, int nPorts) { // TODO: + return NULL; +} + +void USB_DeviceConnected(tUSBHub *Hub, int Port) +{ + if( Port >= Hub->nPorts ) return ; + if( Hub->Devices[Port] ) return ; + + // 0. Perform port init? (done in hub?) + // 1. Assign an address + + // 2. Get device information +} + +void USB_DeviceDisconnected(tUSBHub *Hub, int Port) +{ + +} + +void *USB_GetDeviceDataPtr(tUSBDevice *Dev) { return Dev->Data; } +void USB_SetDeviceDataPtr(tUSBDevice *Dev, void *Ptr) { Dev->Data = Ptr; } + +int USB_int_AllocateAddress(tUSBHost *Host) +{ + int i; + for( i = 1; i < 128; i ++ ) + { + if(Host->AddressBitmap[i/8] & (1 << i)) + continue ; + return i; + } + return 0; } int USB_int_SendSetupSetAddress(tUSBHost *Host, void *Ptr, int Address) { - Uint8 data[8]; - data[0] = 0; // bmRequestType - data[1] = 5; // SET_ADDRESS - data[2] = Address & 0x7F; // wValue (low) - data[3] = 0; // wValue (high) - data[4] = 0; // wLength - data[6] = 0; // wLength + struct sDeviceRequest req; + req.ReqType = 0; // bmRequestType + req.Request = 5; // SET_ADDRESS + req.Value = Address & 0x7F; // wValue + req.Index = 0; // wIndex + req.Length = 0; // wLength // Addr 0:0, Data Toggle = 0, no interrupt - return Host->SendSETUP(Ptr, 0, 0, 0, FALSE, data, 8) == NULL; + return Host->HostDef->SendSETUP(Ptr, 0, 0, 0, FALSE, &req, sizeof(req)) == NULL; } diff --git a/Modules/USB/Core/usb.h b/Modules/USB/Core/usb.h index 9bc45c8e..65bba9d0 100644 --- a/Modules/USB/Core/usb.h +++ b/Modules/USB/Core/usb.h @@ -5,37 +5,23 @@ #ifndef _USB_H_ #define _USB_H_ -// === TYPES === +#include +#include +#include + typedef struct sUSBHost tUSBHost; -typedef struct sUSBHub tUSBHub; -typedef struct sUSBDevice tUSBDevice; // === STRUCTURES === -/** - * \brief Defines a USB Host Controller type - */ -struct sUSBHost -{ - 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 USB Hub data */ struct sUSBHub { - /** - * \brief Host controller used - */ - tUSBHost *HostDef; - void *Controller; - + tUSBHub *Next; + tUSBDevice *Device; + + tUSB_HubPoll CheckPorts; + int nPorts; tUSBDevice *Devices[]; }; @@ -46,19 +32,28 @@ struct sUSBHub struct sUSBDevice { tUSBDevice *Next; - tUSBDevice *Hub; + tUSBDevice *ParentHub; + /** + * \brief Host controller used + */ + tUSBHost *Host; int Address; - int Type; + tUSBDriver *Driver; + void *Data; +}; + +struct sUSBHost +{ + struct sUSBHost *Next; + + tUSBHostDef *HostDef; + void *Ptr; - union { - tUSBHub Hub; - char Impl[0]; - } Data; + Uint8 AddressBitmap[128/8]; }; -extern void USB_RegisterHost(tUSBHost *HostDef, void *ControllerPtr); extern void USB_NewDevice(tUSBHub *Hub); #endif diff --git a/Modules/USB/Core/usb_proto.h b/Modules/USB/Core/usb_proto.h new file mode 100644 index 00000000..3a98e479 --- /dev/null +++ b/Modules/USB/Core/usb_proto.h @@ -0,0 +1,38 @@ +/** + */ +#ifndef _USB_PROTO_H_ +#define _USB_PROTO_H_ + +struct sDeviceRequest +{ + Uint8 ReqType; + Uint8 Request; + Uint16 Value; + Uint16 Index; + Uint16 Length; +}; + +/* + */ +struct sDescriptor_Device +{ + Uint8 Length; + Uint8 Type; // = + Uint16 USBVersion; // BCD, 0x210 = 2.10 + Uint8 DeviceClass; + Uint8 DeviceSubClass; + Uint8 DeviceProtocol; + Uint8 MaxPacketSize; + + Uint16 VendorID; + Uint16 ProductID; + + Uint8 ManufacturerStr; + Uint8 ProductStr; + Uint8 SerialNumberStr; + + Uint8 NumConfigurations; +}; + +#endif + diff --git a/Modules/USB/HID/hid.h b/Modules/USB/HID/hid.h new file mode 100644 index 00000000..373496e8 --- /dev/null +++ b/Modules/USB/HID/hid.h @@ -0,0 +1,47 @@ +/* + * Acess2 USB Stack HID Driver + * - By John Hodge (thePowersGang) + * + * hid.h + * - Core header + */ +#ifndef _HID_H_ +#define _HID_H_ + +// Report Descriptor Types +// - 0: Main +// > 8: Input - Axis/Button etc +// > 9: Output - LED/Position +// > B: Feature - +// > A: Collection - Group of Input/Output/Feature +// > C: End collection +// - 1: Global (Not restored on main) +// - 2: Local +// > +// - 3: Reserved/Unused + +// I/O/F Data Values +#define HID_IOF_CONSTANT 0x001 //!< Host Read-only +#define HID_IOF_VARIABLE 0x002 //!< + +struct sLongItem +{ + Uint8 Header; // 0xFE (Tag 15, Type 3, Size 2) + Uint8 DataSize; + Uint8 Tag; +}; + +struct sDescriptor_HID +{ + Uint8 Length; + Uint8 Type; // + Uint16 Version; // 0x0111 = 1.11 + Uint8 CountryCode; + Uint8 NumDescriptors; // >= 1 + struct { + Uint8 DescType; + Uint16 DescLen; + } Descriptors[]; +} + +#endif diff --git a/Modules/USB/UHCI/Makefile b/Modules/USB/UHCI/Makefile new file mode 100644 index 00000000..798159af --- /dev/null +++ b/Modules/USB/UHCI/Makefile @@ -0,0 +1,8 @@ +# +# + +OBJ = uhci.o +CPPFLAGS = -I../Core/include +NAME = UHCI + +-include ../Makefile.tpl diff --git a/Modules/USB/Core/uhci.c b/Modules/USB/UHCI/uhci.c similarity index 90% rename from Modules/USB/Core/uhci.c rename to Modules/USB/UHCI/uhci.c index f50324fa..8e41e27a 100644 --- a/Modules/USB/Core/uhci.c +++ b/Modules/USB/UHCI/uhci.c @@ -3,11 +3,12 @@ * Universal Host Controller Interface */ #define DEBUG 1 +#define VERSION VER2(0,5) #include #include #include #include -#include "usb.h" +#include #include "uhci.h" // === CONSTANTS === @@ -23,16 +24,20 @@ void *UHCI_int_SendTransaction(tUHCI_Controller *Cont, int Addr, Uint8 Type, int 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); +void UHCI_Hub_Poll(tUSBHub *Hub, tUSBDevice *Dev); int UHCI_Int_InitHost(tUHCI_Controller *Host); +void UHCI_CheckPortUpdate(tUHCI_Controller *Host); void UHCI_InterruptHandler(int IRQ, void *Ptr); // === GLOBALS === +MODULE_DEFINE(0, VERSION, USB_UHCI, UHCI_Initialise, NULL, "USB_Core", NULL); tUHCI_TD gaUHCI_TDPool[NUM_TDs]; tUHCI_Controller gUHCI_Controllers[MAX_CONTROLLERS]; -tUSBHost gUHCI_HostDef = { +tUSBHostDef gUHCI_HostDef = { .SendIN = UHCI_DataIN, .SendOUT = UHCI_DataOUT, .SendSETUP = UHCI_SendSetup, + .CheckPorts = (void*)UHCI_CheckPortUpdate }; // === CODE === @@ -75,7 +80,7 @@ int UHCI_Initialise(const char **Arguments) return ret; } - USB_RegisterHost(&gUHCI_HostDef, cinfo); + cinfo->RootHub = USB_RegisterHost(&gUHCI_HostDef, cinfo, 2); i ++; } @@ -168,6 +173,13 @@ void *UHCI_SendSetup(void *Ptr, int Fcn, int Endpt, int DataTgl, int bIOC, void return UHCI_int_SendTransaction(Ptr, Fcn*16+Endpt, 0x2D, DataTgl, bIOC, Data, Length); } +void UHCI_Hub_Poll(tUSBHub *Hub, tUSBDevice *Dev) +{ + tUHCI_Controller *cont = USB_GetDeviceDataPtr(Dev); + + UHCI_CheckPortUpdate(cont); +} + // === INTERNAL FUNCTIONS === /** * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host) @@ -227,7 +239,8 @@ void UHCI_CheckPortUpdate(tUHCI_Controller *Host) // Check if the port is connected if( !(inw(port) & 1) ) { - // TODO: Tell the USB code it's gone? + // Tell the USB code it's gone. + USB_DeviceDisconnected(Host->RootHub, i); continue; } else @@ -240,6 +253,8 @@ void UHCI_CheckPortUpdate(tUHCI_Controller *Host) // Enable port Time_Delay(50); // 50ms delay outw( port, inw(port) & 0x0004 ); + // Tell USB there's a new device + USB_DeviceConnected(Host->RootHub, i); } } } diff --git a/Modules/USB/Core/uhci.h b/Modules/USB/UHCI/uhci.h similarity index 99% rename from Modules/USB/Core/uhci.h rename to Modules/USB/UHCI/uhci.h index 968ce431..7d88d354 100644 --- a/Modules/USB/Core/uhci.h +++ b/Modules/USB/UHCI/uhci.h @@ -43,6 +43,8 @@ struct sUHCI_Controller * \brief Physical Address of the Frame List */ tPAddr PhysFrameList; + + tUSBHub *RootHub; }; struct sUHCI_TD -- 2.20.1