Reworked part of the PCI driver to better allow PCI bridges
authorJohn Hodge <[email protected]>
Sat, 19 Jun 2010 02:23:50 +0000 (10:23 +0800)
committerJohn Hodge <[email protected]>
Sat, 19 Jun 2010 02:23:50 +0000 (10:23 +0800)
Kernel/drv/pci.c

index 20eb932..b6421e0 100644 (file)
@@ -34,6 +34,8 @@ typedef struct sPCIDevice
 \r
 // === PROTOTYPES ===\r
  int   PCI_Install(char **Arguments);\r
+ int   PCI_ScanBus(int ID);\r
\r
 char   *PCI_ReadDirRoot(tVFS_Node *node, int pos);\r
 tVFS_Node      *PCI_FindDirRoot(tVFS_Node *node, char *filename);\r
 Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer);\r
@@ -72,7 +74,8 @@ tDevFS_Driver gPCI_DriverStruct = {
        .FindDir = PCI_FindDirRoot\r
        }\r
 };\r
- Uint32        *gaPCI_PortBitmap = NULL;\r
+Uint32 *gaPCI_PortBitmap = NULL;\r
+Uint32 gaPCI_BusBitmap[256/32];\r
  \r
 // === CODE ===\r
 /**\r
@@ -81,10 +84,8 @@ tDevFS_Driver        gPCI_DriverStruct = {
  */\r
 int PCI_Install(char **Arguments)\r
 {\r
-        int    bus, dev, fcn, i;\r
-        int    space = 0;\r
-       tPCIDevice      devInfo;\r
-       void    *tmpPtr = NULL;\r
+        int    i;\r
+       void    *tmpPtr;\r
        \r
        // Build Portmap\r
        gaPCI_PortBitmap = malloc( 1 << 13 );\r
@@ -98,61 +99,16 @@ int PCI_Install(char **Arguments)
        for( i = 0; i < MAX_RESERVED_PORT % 32; i ++ )\r
                gaPCI_PortBitmap[MAX_RESERVED_PORT / 32] = 1 << i;\r
        \r
-       // Scan Busses\r
-       for( bus = 0; bus < giPCI_BusCount; bus++ )\r
-       {\r
-               for( dev = 0; dev < 32; dev++ ) // 32 Devices per bus\r
-               {\r
-                       for( fcn = 0; fcn < 8; fcn++ )  // Max 8 functions per device\r
-                       {\r
-                               // Check if the device/function exists\r
-                               if(!PCI_EnumDevice(bus, dev, fcn, &devInfo))\r
-                                       continue;\r
-                               \r
-                               if(giPCI_DeviceCount == space)\r
-                               {\r
-                                       space += SPACE_STEP;\r
-                                       tmpPtr = realloc(gPCI_Devices, space*sizeof(tPCIDevice));\r
-                                       if(tmpPtr == NULL)\r
-                                               return MODULE_ERR_MALLOC;\r
-                                       gPCI_Devices = tmpPtr;\r
-                               }\r
-                               if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
-                               {\r
-                                       #if LIST_DEVICES\r
-                                       Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
-                                               bus, dev, fcn, devInfo.vendor, devInfo.device);\r
-                                       #endif\r
-                                       giPCI_BusCount++;\r
-                               }\r
-                               else\r
-                               {\r
-                                       #if LIST_DEVICES\r
-                                       Log_Log("PCI", "Device %i,%i:%i %04x => 0x%04x:0x%04x",\r
-                                               bus, dev, fcn, devInfo.oc, devInfo.vendor, devInfo.device);\r
-                                       #endif\r
-                               }\r
-                               \r
-                               devInfo.Node.Inode = giPCI_DeviceCount;\r
-                               memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice));\r
-                               giPCI_DeviceCount ++;\r
-                               \r
-                               // WTF is this for?\r
-                               // Maybe bit 23 must be set for the device to be valid?\r
-                               // - Actually, maybe 23 means that there are sub-functions\r
-                               if(fcn == 0) {\r
-                                       if( !(devInfo.ConfigCache[3] & 0x800000) )\r
-                                               break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
+       // Scan Bus\r
+       i = PCI_ScanBus(0);\r
+       if(i != MODULE_ERR_OK)  return i;\r
+               \r
        if(giPCI_DeviceCount == 0) {\r
                Log_Notice("PCI", "No devices were found");\r
                return MODULE_ERR_NOTNEEDED;\r
        }\r
        \r
+       // Ensure the buffer is nice and tight\r
        tmpPtr = realloc(gPCI_Devices, giPCI_DeviceCount*sizeof(tPCIDevice));\r
        if(tmpPtr == NULL)\r
                return MODULE_ERR_MALLOC;\r
@@ -167,6 +123,69 @@ int PCI_Install(char **Arguments)
        return MODULE_ERR_OK;\r
 }\r
 \r
+/**\r
+ * \brief Scans a specific PCI Bus\r
+ */\r
+int PCI_ScanBus(int BusID)\r
+{\r
+        int    dev, fcn;\r
+       tPCIDevice      devInfo;\r
+       void    *tmpPtr = NULL;\r
+       \r
+       if( gaPCI_BusBitmap[BusID/32] & (1 << (BusID%32)) )\r
+               return MODULE_ERR_OK;\r
+       \r
+       gaPCI_BusBitmap[BusID/32] |= (1 << (BusID%32));\r
+       \r
+       for( dev = 0; dev < 32; dev++ ) // 32 Devices per bus\r
+       {\r
+               for( fcn = 0; fcn < 8; fcn++ )  // Max 8 functions per device\r
+               {\r
+                       // Check if the device/function exists\r
+                       if(!PCI_EnumDevice(BusID, dev, fcn, &devInfo))\r
+                               continue;\r
+                       \r
+                       // Allocate\r
+                       tmpPtr = realloc(gPCI_Devices, (giPCI_DeviceCount+1)*sizeof(tPCIDevice));\r
+                       if(tmpPtr == NULL)\r
+                               return MODULE_ERR_MALLOC;\r
+                       gPCI_Devices = tmpPtr;\r
+                       \r
+                       if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
+                       {\r
+                               #if LIST_DEVICES\r
+                               Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
+                                       BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
+                               #endif\r
+                               //TODO: Handle PCI-PCI Bridges\r
+                               //PCI_ScanBus( );\r
+                               giPCI_BusCount++;\r
+                       }\r
+                       else\r
+                       {\r
+                               #if LIST_DEVICES\r
+                               Log_Log("PCI", "Device %i,%i:%i %04x => 0x%04x:0x%04x",\r
+                                       BusID, dev, fcn, devInfo.oc, devInfo.vendor, devInfo.device);\r
+                               #endif\r
+                       }\r
+                       \r
+                       devInfo.Node.Inode = giPCI_DeviceCount;\r
+                       memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice));\r
+                       giPCI_DeviceCount ++;\r
+                       \r
+                       // WTF is this for?\r
+                       // Maybe bit 23 must be set for the device to be valid?\r
+                       // - Actually, maybe 23 means that there are sub-functions\r
+                       if(fcn == 0) {\r
+                               if( !(devInfo.ConfigCache[3] & 0x800000) )\r
+                                       break;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       return MODULE_ERR_OK;\r
+}\r
+\r
 /**\r
  * \fn char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos)\r
  * \brief Read from Root of PCI Driver\r
@@ -507,10 +526,11 @@ Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset)
        offset &= 0xFF; // 8 Bits\r
        \r
        address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC);\r
+       Debug("PCI_CfgReadDWord: address = %x", address);\r
        outd(0xCF8, address);\r
        \r
        data = ind(0xCFC);\r
-       return (Uint32)data;\r
+       return data;\r
 }\r
 void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data)\r
 {\r

UCC git Repository :: git.ucc.asn.au