From: John Hodge Date: Wed, 6 Jul 2011 08:30:04 +0000 (+0800) Subject: Kernel - Reworked PCI API to be cleaner X-Git-Tag: rel0.10~46 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=4ac38b7ae3d361dc2456b866bdd1effb0dfa6ca0;p=tpg%2Facess2.git Kernel - Reworked PCI API to be cleaner - Part of some mods to get UDIref ported (not in git) --- diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index 8dc947cc..1a555d78 100644 --- a/Kernel/drv/pci.c +++ b/Kernel/drv/pci.c @@ -28,7 +28,7 @@ typedef struct sPCIDevice }; Uint16 oc; }; - Uint16 revision; + Uint8 revision, progif; Uint32 ConfigCache[256/4]; char Name[8]; tVFS_Node Node; @@ -42,25 +42,10 @@ typedef struct sPCIDevice int PCI_Install(char **Arguments); int PCI_ScanBus(int ID, int bFill); -char *PCI_ReadDirRoot(tVFS_Node *node, int pos); -tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename); -Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer); - -#if 0 - int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn); - int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx); - int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev); -Uint8 PCI_GetIRQ(int id); -Uint32 PCI_GetBAR0(int id); -Uint32 PCI_GetBAR1(int id); -Uint32 PCI_GetBAR2(int id); -Uint32 PCI_GetBAR3(int id); -Uint32 PCI_GetBAR4(int id); -Uint32 PCI_GetBAR5(int id); -Uint16 PCI_AssignPort(int id, int bar, int count); -#endif - - int PCI_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info); +char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos); +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename); +Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer); + int PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info); // === GLOBALS === MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL); @@ -75,8 +60,8 @@ tDevFS_Driver gPCI_DriverStruct = { .Size = -1, .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, - .ReadDir = PCI_ReadDirRoot, - .FindDir = PCI_FindDirRoot + .ReadDir = PCI_int_ReadDirRoot, + .FindDir = PCI_int_FindDirRoot } }; Uint32 *gaPCI_PortBitmap = NULL; @@ -159,7 +144,7 @@ int PCI_ScanBus(int BusID, int bFill) for( fcn = 0; fcn < 8; fcn++ ) // Max 8 functions per device { // Check if the device/function exists - if(!PCI_EnumDevice(BusID, dev, fcn, &devInfo)) + if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo)) continue; if(devInfo.oc == PCI_OC_PCIBRIDGE) @@ -196,10 +181,9 @@ int PCI_ScanBus(int BusID, int bFill) } /** - * \fn char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) * \brief Read from Root of PCI Driver */ -char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) +char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos) { ENTER("pNode iPos", Node, Pos); if(Pos < 0 || Pos >= giPCI_DeviceCount) { @@ -211,9 +195,8 @@ char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) return strdup( gPCI_Devices[Pos].Name ); } /** - * \fn tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename) */ -tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename) +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename) { int bus,slot,fcn; int i; @@ -251,9 +234,8 @@ tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename) } /** - * \fn Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) */ -Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) +Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) { if( pos + length > 256 ) return 0; @@ -267,41 +249,35 @@ Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) // --- Kernel Code Interface --- /** - \fn int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn) - \brief Counts the devices with the specified codes - \param vendor Vendor ID - \param device Device ID - \param fcn Function ID -*/ -int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn) + * \brief Counts the devices with the specified codes + * \param vendor Vendor ID + * \param device Device ID + */ +int PCI_CountDevices(Uint16 vendor, Uint16 device) { int i, ret=0; for(i=0;i= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[15]; - //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C); + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(Vendor) *Vendor = dev->vendor; + if(Device) *Device = dev->device; + if(Class) *Class = dev->oc; + return 0; } -/** - \fn Uint32 PCI_GetBAR0(int id) -*/ -Uint32 PCI_GetBAR0(int id) +int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision, Uint8 *ProgIF) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[4]; + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(Revision) *Revision = dev->revision; + if(ProgIF) *ProgIF = dev->progif; + return 0; } -/** - \fn Uint32 PCI_GetBAR1(int id) -*/ -Uint32 PCI_GetBAR1(int id) +int PCI_GetDeviceSubsys(tPCIDev ID, Uint16 *SubsystemVendor, Uint16 *SubsystemID) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[5]; + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(SubsystemVendor) *SubsystemVendor = dev->ConfigCache[0x2c/4] & 0xFFFF; + if(SubsystemID) *SubsystemID = dev->ConfigCache[0x2c/4] >> 16; + + return 0; } -/** - \fn Uint32 PCI_GetBAR2(int id) -*/ -Uint32 PCI_GetBAR2(int id) +Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size) { - if(id < 0 || id >= giPCI_DeviceCount) + tPCIDevice *dev; + Uint32 dword; + if( ID < 0 || ID >= giPCI_DeviceCount ) return 0; + if( Offset < 0 || Offset > 256 ) return 0; + + // TODO: Should I support non-aligned reads? + if( Offset & (Size - 1) ) return 0; + + dev = &gPCI_Devices[ID]; + + dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset / 4); + gPCI_Devices[ID].ConfigCache[Offset/4] = dword; + switch( Size ) + { + case 1: return (dword >> (8 * (Offset&3))) & 0xFF; + case 2: return (dword >> (8 * (Offset&2))) & 0xFFFF; + case 4: return dword; + default: return 0; - return gPCI_Devices[id].ConfigCache[6]; + } } -/** - \fn Uint32 PCI_GetBAR3(int id) -*/ -Uint32 PCI_GetBAR3(int id) +void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[7]; + tPCIDevice *dev; + Uint32 dword; + int shift; + if( ID < 0 || ID >= giPCI_DeviceCount ) return ; + if( Offset < 0 || Offset > 256 ) return ; + + dev = &gPCI_Devices[ID]; + + dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset/4); + switch(Size) + { + case 1: + shift = (Offset&3)*8; + dword &= ~(0xFF << shift); + dword |= Value << shift; + break; + case 2: + shift = (Offset&2)*8; + dword &= ~(0xFFFF << shift); + dword |= Value << shift; + break; + case 4: + dword = Value; + break; + default: + return; + } + PCI_CfgWriteDWord(dev->bus, dev->slot, dev->fcn, Offset/4, dword); } /** - \fn Uint32 PCI_GetBAR4(int id) -*/ -Uint32 PCI_GetBAR4(int id) + * \brief Get the IRQ assigned to a device + */ +Uint8 PCI_GetIRQ(tPCIDev id) { if(id < 0 || id >= giPCI_DeviceCount) return 0; - return gPCI_Devices[id].ConfigCache[8]; + return gPCI_Devices[id].ConfigCache[15] & 0xFF; + //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C); } /** - \fn Uint32 PCI_GetBAR5(int id) -*/ -Uint32 PCI_GetBAR5(int id) + * \brief Read the a BAR (base address register) from the PCI config space + */ +Uint32 PCI_GetBAR(tPCIDev id, int BARNum) { if(id < 0 || id >= giPCI_DeviceCount) return 0; - return gPCI_Devices[id].ConfigCache[9]; + if(BARNum < 0 || BARNum >= 6) + return 0; + return gPCI_Devices[id].ConfigCache[4+BARNum]; } -Uint16 PCI_AssignPort(int id, int bar, int count) +#if 0 +/** + * \brief Assign a port to a BAR + */ +Uint16 PCI_AssignPort(tPCIDev ID, int bar, int Count) { #if 1 Uint16 rv; tPCIDevice *dev; if(id < 0 || id >= giPCI_DeviceCount) return 0; - if(bar < 0 || bar > 5) return 0; + if(bar < 0 || bar >= 6) return 0; dev = &gPCI_Devices[id]; rv = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 ); @@ -480,12 +499,12 @@ Uint16 PCI_AssignPort(int id, int bar, int count) return portVals; #endif } +#endif /** - * \fn int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) * \brief Get device information for a slot/function */ -int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) +int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) { Uint16 vendor; int i; @@ -531,7 +550,7 @@ int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) info->Node.NumACLs = 1; info->Node.ACLs = &gVFS_ACL_EveryoneRO; - info->Node.Read = PCI_ReadDevice; + info->Node.Read = PCI_int_ReadDevice; return 1; } @@ -541,6 +560,10 @@ int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) EXPORT(PCI_CountDevices); EXPORT(PCI_GetDevice); EXPORT(PCI_GetDeviceByClass); -EXPORT(PCI_AssignPort); +EXPORT(PCI_GetDeviceInfo); +EXPORT(PCI_GetDeviceVersion); +EXPORT(PCI_GetDeviceSubsys); +//EXPORT(PCI_AssignPort); +EXPORT(PCI_GetBAR); EXPORT(PCI_GetIRQ); //*/ diff --git a/Kernel/include/acess.h b/Kernel/include/acess.h index d4feaf7b..31664769 100644 --- a/Kernel/include/acess.h +++ b/Kernel/include/acess.h @@ -100,6 +100,7 @@ typedef struct sKernelSymbol { // === FUNCTIONS === // --- IRQs --- extern int IRQ_AddHandler(int Num, void (*Callback)(int)); +extern void IRQ_RemHandler(int Handle); // --- Logging --- extern void Log_KernelPanic(const char *Ident, const char *Message, ...); diff --git a/Kernel/include/drv_pci.h b/Kernel/include/drv_pci.h index 128f1052..9697df0a 100644 --- a/Kernel/include/drv_pci.h +++ b/Kernel/include/drv_pci.h @@ -33,22 +33,26 @@ enum ePCIOverClasses PCI_OC_SCSI = 0x0100 }; +typedef int tPCIDev; + /** * \brief Count PCI Devices * * Counts the number of devices with specified Vendor and Device IDs */ -extern int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn); - -extern int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx); -extern int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev); -extern Uint8 PCI_GetIRQ(int id); -extern Uint32 PCI_GetBAR0(int id); -extern Uint32 PCI_GetBAR1(int id); -extern Uint32 PCI_GetBAR2(int id); -extern Uint32 PCI_GetBAR3(int id); -extern Uint32 PCI_GetBAR4(int id); -extern Uint32 PCI_GetBAR5(int id); -extern Uint16 PCI_AssignPort(int id, int bar, int count); +extern int PCI_CountDevices(Uint16 VendorID, Uint16 DeviceID); +extern tPCIDev PCI_GetDevice(Uint16 VendorID, Uint16 DeviceID, int index); +extern tPCIDev PCI_GetDeviceByClass(Uint16 ClassCode, Uint16 Mask, tPCIDev prev); + +extern int PCI_GetDeviceInfo(tPCIDev id, Uint16 *Vendor, Uint16 *Device, Uint16 *Class); +extern int PCI_GetDeviceVersion(tPCIDev id, Uint8 *Revision, Uint8 *ProgIF); +extern int PCI_GetDeviceSubsys(tPCIDev id, Uint16 *SubsystemVendor, Uint16 *SubsystemID); + +extern Uint32 PCI_ConfigRead(tPCIDev id, int Offset, int Size); +extern void PCI_ConfigWrite(tPCIDev id, int Offset, int Size, Uint32 Value); + +extern Uint8 PCI_GetIRQ(tPCIDev id); +extern Uint32 PCI_GetBAR(tPCIDev id, int BAR); +//extern Uint16 PCI_AssignPort(tPCIDev id, int bar, int count); #endif diff --git a/Modules/Network/NE2000/ne2000.c b/Modules/Network/NE2000/ne2000.c index 3fa85f47..cb760d66 100644 --- a/Modules/Network/NE2000/ne2000.c +++ b/Modules/Network/NE2000/ne2000.c @@ -118,14 +118,15 @@ tCard *gpNe2k_Cards = NULL; int Ne2k_Install(char **Options) { int i, j, k; - int count, id, base; + int count, base; + tPCIDev id; // --- Scan PCI Bus --- // Count Cards giNe2k_CardCount = 0; for( i = 0; i < NUM_COMPAT_DEVICES; i ++ ) { - giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 ); + giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device ); } if( giNe2k_CardCount == 0 ) { @@ -139,12 +140,12 @@ int Ne2k_Install(char **Options) for( i = 0; i < NUM_COMPAT_DEVICES; i ++ ) { - count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 ); + count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device ); for( j = 0; j < count; j ++,k ++ ) { - id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0, j ); + id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, j ); // Create Structure - base = PCI_AssignPort( id, 0, 0x20 ); + base = PCI_GetBAR( id, 0 ); gpNe2k_Cards[ k ].IOBase = base; gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id ); gpNe2k_Cards[ k ].NextMemPage = 64; diff --git a/Modules/Network/RTL8139/rtl8139.c b/Modules/Network/RTL8139/rtl8139.c index d77fe273..c2ec80a6 100644 --- a/Modules/Network/RTL8139/rtl8139.c +++ b/Modules/Network/RTL8139/rtl8139.c @@ -125,7 +125,7 @@ int RTL8139_Install(char **Options) Uint16 base; tCard *card; - giRTL8139_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID, 0); + giRTL8139_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID); Log_Debug("RTL8139", "%i cards", giRTL8139_CardCount); if( giRTL8139_CardCount == 0 ) return MODULE_ERR_NOTNEEDED; @@ -133,10 +133,10 @@ int RTL8139_Install(char **Options) gaRTL8139_Cards = calloc( giRTL8139_CardCount, sizeof(tCard) ); //while( (id = PCI_GetDevice(0x10EC, 0x8139, 0, id)) != -1 ) - while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, 0, i)) != -1 ) + while( (id = PCI_GetDevice(VENDOR_ID, DEVICE_ID, i)) != -1 ) { card = &gaRTL8139_Cards[i]; - base = PCI_AssignPort( id, 0, 0x100 ); + base = PCI_GetBAR( id, 0 ); card->IOBase = base; card->IRQ = PCI_GetIRQ( id ); diff --git a/Modules/Storage/ATA/io.c b/Modules/Storage/ATA/io.c index 73c33b28..368c310b 100644 --- a/Modules/Storage/ATA/io.c +++ b/Modules/Storage/ATA/io.c @@ -119,7 +119,7 @@ int ATA_SetupIO(void) // Get IDE Controller's PCI Entry ent = PCI_GetDeviceByClass(0x0101, 0xFFFF, -1); LOG("ent = %i", ent); - gATA_BusMasterBase = PCI_GetBAR4( ent ); + gATA_BusMasterBase = PCI_GetBAR(ent, 4); if( gATA_BusMasterBase == 0 ) { Log_Warning("ATA", "It seems that there is no Bus Master Controller on this machine. Get one"); // TODO: Use PIO mode instead @@ -127,8 +127,8 @@ int ATA_SetupIO(void) return MODULE_ERR_NOTNEEDED; } - LOG("BAR5 = 0x%x", PCI_GetBAR5( ent )); - LOG("IRQ = %i", PCI_GetIRQ( ent )); + LOG("BAR5 = 0x%x", PCI_GetBAR(ent, 5)); + LOG("IRQ = %i", PCI_GetIRQ(ent)); // Map memory if( !(gATA_BusMasterBase & 1) ) diff --git a/Modules/USB/Core/uhci.c b/Modules/USB/Core/uhci.c index fb92d545..948f6e64 100644 --- a/Modules/USB/Core/uhci.c +++ b/Modules/USB/Core/uhci.c @@ -1,127 +1,126 @@ -/* - * Acess 2 USB Stack - * Universal Host Controller Interface - */ -#define DEBUG 1 -#include -#include -#include -#include "usb.h" -#include "uhci.h" - -// === CONSTANTS === -#define MAX_CONTROLLERS 4 -#define NUM_TDs 1024 - -// === PROTOTYPES === - int UHCI_Initialise(); -void UHCI_Cleanup(); - int UHCI_IOCtl(tVFS_Node *node, int id, void *data); - int UHCI_Int_InitHost(tUHCI_Controller *Host); - +/* + * Acess 2 USB Stack + * Universal Host Controller Interface + */ +#define DEBUG 1 +#include +#include +#include +#include "usb.h" +#include "uhci.h" + +// === CONSTANTS === +#define MAX_CONTROLLERS 4 +#define NUM_TDs 1024 + +// === PROTOTYPES === + int UHCI_Initialise(); +void UHCI_Cleanup(); + int UHCI_IOCtl(tVFS_Node *node, int id, void *data); + int UHCI_Int_InitHost(tUHCI_Controller *Host); + // === GLOBALS === -//Uint gaFrameList[1024]; -tUHCI_TD gaUHCI_TDPool[NUM_TDs]; -tUHCI_Controller gUHCI_Controllers[MAX_CONTROLLERS]; - -// === CODE === -/** - * \fn int UHCI_Initialise() - * \brief Called to initialise the UHCI Driver - */ -int UHCI_Initialise() -{ - int i=0, id=-1; - int ret; - - ENTER(""); - - // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices - while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS ) - { - // NOTE: Check "protocol" from PCI? - - gUHCI_Controllers[i].PciId = id; - // Assign a port range (BAR4, Reserve 32 ports) - //base = PCI_AssignPort( id, 4, 0x20 ); - gUHCI_Controllers[i].IOBase = PCI_GetBAR4(id); - gUHCI_Controllers[i].IRQNum = PCI_GetIRQ(id); - - Log("[USB ] Controller PCI #%i: IO Base = 0x%x, IRQ %i", - id, gUHCI_Controllers[i].IOBase, gUHCI_Controllers[i].IRQNum); - - // Initialise Host - ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]); - // Detect an error - if(ret != 0) { - LEAVE('i', ret); - return ret; - } - - i ++; - } - if(i == MAX_CONTROLLERS) { - Warning("[UHCI ] Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest"); - } - LEAVE('i', i); - return i; -} - -/** - * \fn void UHCI_Cleanup() - * \brief Called just before module is unloaded - */ -void UHCI_Cleanup() -{ +//Uint gaFrameList[1024]; +tUHCI_TD gaUHCI_TDPool[NUM_TDs]; +tUHCI_Controller gUHCI_Controllers[MAX_CONTROLLERS]; + +// === CODE === +/** + * \fn int UHCI_Initialise() + * \brief Called to initialise the UHCI Driver + */ +int UHCI_Initialise() +{ + int i=0, id=-1; + int ret; + + ENTER(""); + + // Enumerate PCI Bus, getting a maximum of `MAX_CONTROLLERS` devices + while( (id = PCI_GetDeviceByClass(0x0C03, 0xFFFF, id)) >= 0 && i < MAX_CONTROLLERS ) + { + // NOTE: Check "protocol" from PCI? + + gUHCI_Controllers[i].PciId = id; + // Assign a port range (BAR4, Reserve 32 ports) + gUHCI_Controllers[i].IOBase = PCI_GetBAR(id, 4); + gUHCI_Controllers[i].IRQNum = PCI_GetIRQ(id); + + Log("[USB ] Controller PCI #%i: IO Base = 0x%x, IRQ %i", + id, gUHCI_Controllers[i].IOBase, gUHCI_Controllers[i].IRQNum); + + // Initialise Host + ret = UHCI_Int_InitHost(&gUHCI_Controllers[i]); + // Detect an error + if(ret != 0) { + LEAVE('i', ret); + return ret; + } + + i ++; + } + if(i == MAX_CONTROLLERS) { + Log_Warning("UHCI", "Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest"); + } + LEAVE('i', i); + return i; +} + +/** + * \fn void UHCI_Cleanup() + * \brief Called just before module is unloaded + */ +void UHCI_Cleanup() +{ +} + +/** + * \brief Sends a packet to a device endpoint + */ +int UHCI_SendPacket(int ControllerId, int Length) +{ + //tUHCI_TD *td = UHCI_AllocateTD(); + return 0; +} + +// === INTERNAL FUNCTIONS === +/** + * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host) + * \brief Initialises a UHCI host controller + * \param Host Pointer - Host to initialise + */ +int UHCI_Int_InitHost(tUHCI_Controller *Host) +{ + ENTER("pHost", Host); + + outw( Host->IOBase + USBCMD, 4 ); // GRESET + // TODO: Wait for at least 10ms + outw( Host->IOBase + USBCMD, 0 ); // GRESET + + // Allocate Frame List + Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList); // 1 Page, 32-bit + if( !Host->FrameList ) { + Log_Warning("UHCI", "Unable to allocate frame list, aborting"); + LEAVE('i', -1); + return -1; + } + LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList); + memsetd( Host->FrameList, 1, 1024 ); // Clear List (Disabling all entries) + + //! \todo Properly fill frame list + + // Set frame length to 1 ms + outb( Host->IOBase + SOFMOD, 64 ); + + // Set Frame List Address + outd( Host->IOBase + FLBASEADD, Host->PhysFrameList ); + + // Set Frame Number + outw( Host->IOBase + FRNUM, 0 ); + + // Enable Interrupts + //PCI_WriteWord( Host->PciId, 0xC0, 0x2000 ); + + LEAVE('i', 0); + return 0; } - -/** - * \brief Sends a packet to a device endpoint - */ -int UHCI_SendPacket(int ControllerId, int Length) -{ - //tUHCI_TD *td = UHCI_AllocateTD(); - return 0; -} - -// === INTERNAL FUNCTIONS === -/** - * \fn int UHCI_Int_InitHost(tUCHI_Controller *Host) - * \brief Initialises a UHCI host controller - * \param Host Pointer - Host to initialise - */ -int UHCI_Int_InitHost(tUHCI_Controller *Host) -{ - ENTER("pHost", Host); - - outw( Host->IOBase + USBCMD, 4 ); // GRESET - // TODO: Wait for at least 10ms - outw( Host->IOBase + USBCMD, 0 ); // GRESET - - // Allocate Frame List - Host->FrameList = (void *) MM_AllocDMA(1, 32, &Host->PhysFrameList); // 1 Page, 32-bit - if( !Host->FrameList ) { - Log_Warning("UHCI", "Unable to allocate frame list, aborting"); - LEAVE('i', -1); - return -1; - } - LOG("Allocated frame list 0x%x (0x%x)", Host->FrameList, Host->PhysFrameList); - memsetd( Host->FrameList, 1, 1024 ); // Clear List (Disabling all entries) - - //! \todo Properly fill frame list - - // Set frame length to 1 ms - outb( Host->IOBase + SOFMOD, 64 ); - - // Set Frame List Address - outd( Host->IOBase + FLBASEADD, Host->PhysFrameList ); - - // Set Frame Number - outw( Host->IOBase + FRNUM, 0 ); - - // Enable Interrupts - //PCI_WriteWord( Host->PciId, 0xC0, 0x2000 ); - - LEAVE('i', 0); - return 0; -}