Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 33721)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 33722)
@@ -1964,42 +1964,8 @@
     int32_t     iFunction;
 } PciSlotAssignments[] = {
-    /* Due to somewhat inflexible PCI bus configuration, ConsoleImpl hardcodes 0:5:0 as HDA address, so we shalln't put elsewhere */
-#if 0
-    {
-        "lan",      25, 0 /* LAN controller */
-    },
-    {
-        "hda",      27, 0 /* High Definition Audio */
-    },
-#endif
+    /* The only override that have to be here, as host controller is added in the way invisible to bus slot assignment management, 
+       maybe to be changed in the future. */
     {
         "i82801",   30, 0 /* Host Controller */
-    },
-    /**
-     *  Please note, that for devices being functions, like we do here, device 0
-     *  must be multifunction, i.e. have header type 0x80. Our LPC device is.
-     *  Alternative approach is to assign separate slot to each device.
-     */
-    {
-        "lpc",      31, 0 /* Low Pin Count bus */
-    },
-    {
-        "piix3ide", 31, 1 /* IDE controller */
-    },
-    /* Disable, if we may wish to have multiple AHCI controllers */
-    {
-        "ahci",     31, 2 /* SATA controller */
-    },
-    {
-        "smbus",    31, 3 /* System Management Bus */
-    },
-    {
-        "usb-ohci", 31, 4 /* OHCI USB controller */
-    },
-    {
-        "usb-ehci", 31, 5 /* EHCI USB controller */
-    },
-    {
-        "thermal",  31, 6 /* Thermal controller */
     },
 };
Index: /trunk/src/VBox/Main/BusAssignmentManager.cpp
===================================================================
--- /trunk/src/VBox/Main/BusAssignmentManager.cpp	(revision 33721)
+++ /trunk/src/VBox/Main/BusAssignmentManager.cpp	(revision 33722)
@@ -25,4 +25,118 @@
 #include <map>
 #include <vector>
+#include <algorithm>
+
+struct DeviceAssignmentRule
+{
+    const char* pszName;
+    int         iBus;
+    int         iDevice;
+    int         iFn;
+    int         iPriority;
+};
+
+struct DeviceAliasRule
+{
+    const char* pszDevName;
+    const char* pszDevAlias;
+};
+
+/* Those rules define PCI slots assignment */
+
+/* Generic rules */
+static const DeviceAssignmentRule aGenericRules[] =
+{
+    /* VGA controller */
+    {"vga",           0,  2, 0,  0},
+
+    /* VMM device */
+    {"VMMDev",        0,  4, 0,  0},
+
+    /* Audio controllers */
+    {"ichac97",       0,  5, 0,  0},
+    {"hda",           0,  5, 0,  0},
+
+    /* Storage controllers */
+    {"ahci",          0, 13, 0,  0},
+    {"lsilogic",      0, 20, 0,  0},
+    {"buslogic",      0, 21, 0,  0},
+    {"lsilogicsas",   0, 22, 0,  0},
+
+    /* USB controllers */
+    {"usb-ohci",      0,  6,  0, 0},
+    {"usb-ehci",      0, 11,  0, 0},
+
+    /* ACPI controller */
+    {"acpi",          0,  7,  0, 0},
+
+
+    /* Network controllers */
+    /* the first network card gets the PCI ID 3, the next 3 gets 8..10,
+     * next 4 get 16..19. */
+    {"nic",           0,  3,  0, 0},
+    {"nic",           0,  8,  0, 0},
+    {"nic",           0,  9,  0, 0},
+    {"nic",           0, 10,  0, 0},
+    {"nic",           0, 16,  0, 0},
+    {"nic",           0, 17,  0, 0},
+    {"nic",           0, 18,  0, 0},
+    {"nic",           0, 19,  0, 0},
+    /* VMWare assigns first NIC to slot 11 */
+    {"nic-vmware",    0, 11,  0, 0},
+
+    /* ISA/LPC controller */
+    {"lpc",           0, 31,  0, 0},
+
+    { NULL,          -1, -1, -1,  0}
+};
+
+/* PIIX3 chipset rules */
+static const DeviceAssignmentRule aPiix3Rules[] =
+{
+    {"piix3ide",      0,  1,  1, 0},
+    {"pcibridge",     0, 24,  0, 0},
+    {"pcibridge",     0, 25,  0, 0},
+    { NULL,          -1, -1, -1, 0}
+};
+
+
+/* ICH9 chipset rules */
+static const DeviceAssignmentRule aIch9Rules[] =
+{
+    /* Host Controller */
+    {"i82801",        0, 30, 0,  0},
+
+    /* Those are functions of LPC at 00:1e:00 */
+    /**
+     *  Please note, that for devices being functions, like we do here, device 0
+     *  must be multifunction, i.e. have header type 0x80. Our LPC device is.
+     *  Alternative approach is to assign separate slot to each device.
+     */
+    {"piix3ide",      0, 31, 1,  1},
+    {"ahci",          0, 31, 2,  1},
+    {"smbus",         0, 31, 3,  1},
+    {"usb-ohci",      0, 31, 4,  1},
+    {"usb-ehci",      0, 31, 5,  1},
+    {"thermal",       0, 31, 6,  1},
+
+    /* ths rule has lower priority than generic one */
+    {"lsilogic",      1, 20, 0,  -1},
+    {"lsilogic",      1, 20, 0,  -1},
+
+    /* to make sure rule never used before rules assigning devices on it */
+    {"ich9pcibridge", 0, 24, 0,  10},
+    {"ich9pcibridge", 0, 25, 0,  10},
+    {"ich9pcibridge", 1, 24, 0,   5},
+    {"ich9pcibridge", 1, 25, 0,   5},
+    { NULL,          -1, -1, -1,  0}
+};
+
+/* Aliasing rules */
+static const DeviceAliasRule aDeviceAliases[] =
+{
+    {"e1000",      "nic"},
+    {"pcnet",      "nic"},
+    {"virtio-net", "nic"}
+};
 
 struct BusAssignmentManager::State
@@ -50,4 +164,6 @@
     typedef std::map <PciBusAddress,PciDeviceRecord > PciMap;
     typedef std::vector<PciBusAddress>                PciAddrList;
+    typedef std::vector<const DeviceAssignmentRule*>  PciRulesList;
+
     typedef std::map <PciDeviceRecord,PciAddrList >   ReversePciMap;
 
@@ -69,4 +185,7 @@
     bool    checkAvailable(PciBusAddress& Address);
     bool    findPciAddress(const char* pszDevName, int iInstance, PciBusAddress& Address);
+
+    const char* findAlias(const char* pszName);
+    void addMatchingRules(const char* pszName, PciRulesList& aList);
 };
 
@@ -76,5 +195,4 @@
     return S_OK;
 }
-
 
 HRESULT BusAssignmentManager::State::record(const char* pszName, PciBusAddress& Address)
@@ -113,9 +231,77 @@
 }
 
+void BusAssignmentManager::State::addMatchingRules(const char* pszName, PciRulesList& aList)
+{
+    size_t iRuleset, iRule;
+    const DeviceAssignmentRule* aArrays[2] = {aGenericRules, NULL};
+
+    switch (mChipsetType)
+    {
+        case ChipsetType_PIIX3:
+            aArrays[1] = aPiix3Rules;
+            break;
+        case ChipsetType_ICH9:
+            aArrays[1] = aIch9Rules;
+            break;
+        default:
+            Assert(false);
+            break;
+    }
+
+    for (iRuleset = 0; iRuleset < RT_ELEMENTS(aArrays); iRuleset++)
+    {
+        if (aArrays[iRuleset] == NULL)
+            continue;
+
+        for (iRule = 0; aArrays[iRuleset][iRule].pszName != NULL; iRule++)
+        {
+            if (strcmp(pszName, aArrays[iRuleset][iRule].pszName) == 0)
+                aList.push_back(&aArrays[iRuleset][iRule]);
+        }
+    }
+}
+
+const char* BusAssignmentManager::State::findAlias(const char* pszDev)
+{
+    for (size_t iAlias = 0; iAlias < RT_ELEMENTS(aDeviceAliases); iAlias++)
+    {
+        if (strcmp(pszDev, aDeviceAliases[iAlias].pszDevName) == 0)
+            return aDeviceAliases[iAlias].pszDevAlias;
+    }
+    return NULL;
+}
+
+static bool  RuleComparator(const DeviceAssignmentRule* r1, const DeviceAssignmentRule* r2)
+{
+    return (r1->iPriority > r2->iPriority);
+}
+
 HRESULT BusAssignmentManager::State::autoAssign(const char* pszName, PciBusAddress& Address)
 {
-    // unimplemented yet
-    Assert(false);
-    return S_OK;
+    PciRulesList matchingRules;
+
+    addMatchingRules(pszName,  matchingRules);
+    const char* pszAlias = findAlias(pszName);
+    if (pszAlias)
+        addMatchingRules(pszAlias, matchingRules);
+
+    AssertMsg(matchingRules.size() > 0, ("No rule for %s(%s)\n", pszName, pszAlias));
+
+    sort(matchingRules.begin(), matchingRules.end(), RuleComparator);
+
+    for (size_t iRule = 0; iRule < matchingRules.size(); iRule++)
+    {
+        const DeviceAssignmentRule* rule = matchingRules[iRule];
+
+        Address.iBus = rule->iBus;
+        Address.iDevice = rule->iDevice;
+        Address.iFn = rule->iFn;
+
+        if (checkAvailable(Address))
+            return S_OK;
+    }
+    AssertMsg(false, ("All possible candidate positions for %s exhausted\n", pszName));
+
+    return E_INVALIDARG;
 }
 
@@ -202,5 +388,5 @@
         return rc;
 
-    Assert(Address.valid());
+    Assert(Address.valid() && pState->checkAvailable(Address));
 
     rc = pState->record(pszDevName, Address);
Index: /trunk/src/VBox/Main/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 33721)
+++ /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 33722)
@@ -882,11 +882,9 @@
             InsertConfigNode(pDev,     "0", &pInst);
             InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-            PciAddr = PciBusAddress(0, 24, 0);
-            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst, PciAddr);                               H();
+            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);                               H();
 
             InsertConfigNode(pDev,     "1", &pInst);
             InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-            PciAddr = PciBusAddress(0, 25, 0);
-            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst, PciAddr);                               H();
+            hrc = BusMgr->assignPciDevice("ich9pcibridge", pInst);                               H();
         }
 
@@ -966,8 +964,5 @@
             InsertConfigNode(pDevices, "lpc", &pDev);
             InsertConfigNode(pDev,     "0", &pInst);
-#if 0
-            PciAddr = PciBusAddress(0, 31, 0);
             hrc = BusMgr->assignPciDevice("lpc", pInst);                               H();
-#endif
             InsertConfigInteger(pInst, "Trusted",   1); /* boolean */
         }
@@ -1061,6 +1056,5 @@
         InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
 
-        PciAddr = PciBusAddress(0, 2, 0);
-        hrc = BusMgr->assignPciDevice("vga", pInst, PciAddr);                               H();
+        hrc = BusMgr->assignPciDevice("vga", pInst);                               H();
         InsertConfigNode(pInst,    "Config", &pCfg);
         ULONG cVRamMBs;
@@ -1329,6 +1323,5 @@
                 case StorageControllerType_LsiLogic:
                 {
-                    PciAddr = PciBusAddress(1, 20, 0);
-                    hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("lsilogic", pCtlInst);                               H();
 
 
@@ -1347,6 +1340,5 @@
                 case StorageControllerType_BusLogic:
                 {
-                    PciAddr = PciBusAddress(0, 21, 0);
-                    hrc = BusMgr->assignPciDevice("buslogic", pCtlInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("buslogic", pCtlInst);                               H();
 
                     /* Attach the status driver */
@@ -1364,6 +1356,5 @@
                 case StorageControllerType_IntelAhci:
                 {
-                    PciAddr = PciBusAddress(0, 13, 0);
-                    hrc = BusMgr->assignPciDevice("ahci", pCtlInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("ahci", pCtlInst);                               H();
 
                     ULONG cPorts = 0;
@@ -1410,6 +1401,5 @@
                      * IDE (update this when the main interface changes)
                      */
-                    PciAddr = PciBusAddress(0, 1, 1);
-                    hrc = BusMgr->assignPciDevice("ide", pCtlInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("piix3ide", pCtlInst);                               H();
                     InsertConfigString(pCfg,   "Type", controllerString(enmCtrlType));
 
@@ -1456,6 +1446,5 @@
                 case StorageControllerType_LsiLogicSas:
                 {
-                    PciAddr = PciBusAddress(0, 22, 0);
-                    hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("lsilogicsas", pCtlInst);                               H();
 
                     InsertConfigString(pCfg,  "ControllerType", "SAS1068");
@@ -1818,6 +1807,5 @@
         InsertConfigNode(pInst,    "Config", &pCfg);
         InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-        PciAddr = PciBusAddress(0, 4, 0);
-        hrc = BusMgr->assignPciDevice("VMMDev", pInst, PciAddr);                               H();
+        hrc = BusMgr->assignPciDevice("VMMDev", pInst);                               H();
 
         Bstr hwVersion;
@@ -1881,6 +1869,5 @@
                     InsertConfigNode(pDev,     "0", &pInst);
                     InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
-                    PciAddr = PciBusAddress(0, 5, 0);
-                    hrc = BusMgr->assignPciDevice("ichac97", pInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("ichac97", pInst);                               H();
                     InsertConfigNode(pInst,    "Config", &pCfg);
                     break;
@@ -1906,6 +1893,5 @@
                     InsertConfigNode(pDev,     "0", &pInst);
                     InsertConfigInteger(pInst, "Trusted",          1); /* boolean */
-                    PciAddr = PciBusAddress(0, 5, 0);
-                    hrc = BusMgr->assignPciDevice("hda", pInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("hda", pInst);                               H();
                     InsertConfigNode(pInst,    "Config", &pCfg);
                 }
@@ -2006,6 +1992,5 @@
                 InsertConfigNode(pInst,    "Config", &pCfg);
                 InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-                PciAddr = PciBusAddress(0, 6, 0);
-                hrc = BusMgr->assignPciDevice("usb-ohci", pInst, PciAddr);                               H();
+                hrc = BusMgr->assignPciDevice("usb-ohci", pInst);                           H();
                 InsertConfigNode(pInst,    "LUN#0", &pLunL0);
                 InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
@@ -2031,6 +2016,5 @@
                     InsertConfigNode(pInst,    "Config", &pCfg);
                     InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-                    PciAddr = PciBusAddress(0, 11, 0);
-                    hrc = BusMgr->assignPciDevice("usb-ohci", pInst, PciAddr);                               H();
+                    hrc = BusMgr->assignPciDevice("usb-ehci", pInst);                               H();
 
                     InsertConfigNode(pInst,    "LUN#0", &pLunL0);
@@ -2291,6 +2275,5 @@
             InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
             InsertConfigNode(pInst,    "Config", &pCfg);
-            PciAddr = PciBusAddress(0, 7, 0);
-            hrc = BusMgr->assignPciDevice("acpi", pInst, PciAddr);                               H();
+            hrc = BusMgr->assignPciDevice("acpi", pInst);                               H();
 
             InsertConfigInteger(pCfg,  "RamSize",          cbRam);
