StorageControllerImpl.cpp revision 8b5c19912f3e141c16afb49b7aeb9df38a309588
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Implementation of IStorageController.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2008-2015 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync */
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "StorageControllerImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "MachineImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VirtualBoxImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "SystemPropertiesImpl.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/string.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <iprt/cpp/utils.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/err.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <VBox/settings.h>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include <algorithm>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "AutoStateDep.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "AutoCaller.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "Logging.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// defines
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync//
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncDEFINE_EMPTY_CTOR_DTOR(StorageController)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstruct BackupableStorageControllerData
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Constructor. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BackupableStorageControllerData()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : mStorageBus(StorageBus_IDE),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mStorageControllerType(StorageControllerType_PIIX4),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mInstance(0),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mPortCount(2),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fUseHostIOCache(true),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fBootable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mPortIde0Master(0),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mPortIde0Slave(1),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mPortIde1Master(2),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mPortIde1Slave(3)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync { }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Unique name of the storage controller. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Utf8Str strName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The connection type of the storage controller. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync StorageBus_T mStorageBus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Type of the Storage controller. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync StorageControllerType_T mStorageControllerType;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Instance number of the storage controller. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG mInstance;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Number of usable ports. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG mPortCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Whether to use the host IO caches. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOL fUseHostIOCache;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Whether it is possible to boot from disks attached to this controller. */
cfb3a8ae5e9668de4506cf5c053b8009bcc89dafvboxsync BOOL fBootable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The following is only for the SATA controller atm. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Port which acts as primary master for ide emulation. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG mPortIde0Master;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Port which acts as primary slave for ide emulation. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG mPortIde0Slave;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /** Port which acts as secondary master for ide emulation. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG mPortIde1Master;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Port which acts as secondary slave for ide emulation. */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync ULONG mPortIde1Slave;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncstruct StorageController::Data
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync Data(Machine * const aMachine)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync : pVirtualBox(NULL),
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pSystemProperties(NULL),
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync pParent(aMachine)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync unconst(pVirtualBox) = aMachine->i_getVirtualBox();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync unconst(pSystemProperties) = pVirtualBox->i_getSystemProperties();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VirtualBox * const pVirtualBox;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SystemProperties * const pSystemProperties;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Machine * const pParent;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync const ComObjPtr<StorageController> pPeer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Backupable<BackupableStorageControllerData> bd;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync};
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// constructor / destructor
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/////////////////////////////////////////////////////////////////////////////
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncHRESULT StorageController::FinalConstruct()
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return BaseFinalConstruct();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncvoid StorageController::FinalRelease()
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync uninit();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync BaseFinalRelease();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync// public initializer/uninitializer for internal purposes only
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync/////////////////////////////////////////////////////////////////////////////
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * Initializes the storage controller object.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * @returns COM result indicator.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aParent Pointer to our parent object.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aName Name of the storage controller.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aInstance Instance number of the storage controller.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::init(Machine *aParent,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync const Utf8Str &aName,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync StorageBus_T aStorageBus,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG aInstance, bool fBootable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aParent=%p aName=\"%s\" aInstance=%u\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aParent, aName.c_str(), aInstance));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComAssertRet(aParent && !aName.isEmpty(), E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( (aStorageBus <= StorageBus_Null)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || (aStorageBus > StorageBus_USB))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid storage connection type"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG maxInstances;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ChipsetType_T chipsetType;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = aParent->COMGETTER(ChipsetType)(&chipsetType);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = aParent->i_getVirtualBox()->i_getSystemProperties()->
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync GetMaxInstancesOfStorageBus(chipsetType, aStorageBus, &maxInstances);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aInstance >= maxInstances)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Too many storage controllers of this type"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoInitSpan autoInitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m = new Data(aParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* m->pPeer is left null */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.allocate();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->strName = aName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mInstance = aInstance;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync m->bd->fBootable = fBootable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageBus = aStorageBus;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if ( aStorageBus != StorageBus_IDE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && aStorageBus != StorageBus_Floppy)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->fUseHostIOCache = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->fUseHostIOCache = true;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync switch (aStorageBus)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_IDE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 2;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync m->bd->mStorageControllerType = StorageControllerType_PIIX4;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SATA:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 30;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = StorageControllerType_IntelAhci;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SCSI:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 16;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = StorageControllerType_LsiLogic;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_Floppy:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = StorageControllerType_I82078;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SAS:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 8;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = StorageControllerType_LsiLogicSas;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_USB:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = 8;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = StorageControllerType_USB;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Confirm a successful initialization */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync autoInitSpan.setSucceeded();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initializes the object given another object
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * (a kind of copy constructor). This object shares data with
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the object passed as an argument.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aReshare
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * When false, the original object will remain a data owner.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Otherwise, data ownership will be transferred from the original
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * object to this one.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note This object must be destroyed before the original object
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * it shares data with is destroyed.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note Locks @a aThat object for writing if @a aReshare is @c true, or for
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * reading if @a aReshare is false.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::init(Machine *aParent,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync StorageController *aThat,
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync bool aReshare /* = false */)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync LogFlowThisFunc(("aParent=%p, aThat=%p, aReshare=%RTbool\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aParent, aThat, aReshare));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComAssertRet(aParent && aThat, E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoInitSpan autoInitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m = new Data(aParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync /* sanity */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller thatCaller(aThat);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertComRCReturnRC(thatCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aReshare)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync unconst(aThat->m->pPeer) = this;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.attach (aThat->m->bd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
344f8996b5cf3f8bbc2c361f9d526eb5b1350916vboxsync unconst(m->pPeer) = aThat;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.share (aThat->m->bd);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d8df004f4caf4f71e78f0be1cc2e2a918358ae9fvboxsync /* Confirm successful initialization */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync autoInitSpan.setSucceeded();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
78a205e3fc6719d59e8c561b3d287d3a4f879852vboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
344f8996b5cf3f8bbc2c361f9d526eb5b1350916vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initializes the storage controller object given another guest object
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (a kind of copy constructor). This object makes a private copy of data
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync * of the original object passed as an argument.
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::initCopy(Machine *aParent, StorageController *aThat)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComAssertRet(aParent && aThat, E_INVALIDARG);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoInitSpan autoInitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m = new Data(aParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* m->pPeer is left null */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller thatCaller(aThat);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturnRC(thatCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync m->bd.attachCopy(aThat->m->bd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Confirm a successful initialization */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync autoInitSpan.setSucceeded();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Uninitializes the instance and sets the ready flag to FALSE.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid StorageController::uninit()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("\n"));
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync /* Enclose the state transition Ready->InUninit->NotReady */
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync AutoUninitSpan autoUninitSpan(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (autoUninitSpan.uninitDone())
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.free();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(m->pPeer) = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(m->pParent) = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync delete m;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m = NULL;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// IStorageController properties
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getName(com::Utf8Str &aName)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* mName is constant during life time, no need to lock */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync aName = m->bd.data()->strName;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getBus(StorageBus_T *aBus)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgOutPointerValid(aBus);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aBus = m->bd->mStorageBus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getControllerType(StorageControllerType_T *aControllerType)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgOutPointerValid(aControllerType);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *aControllerType = m->bd->mStorageControllerType;
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::setControllerType(StorageControllerType_T aControllerType)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (m->bd->mStorageBus)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_IDE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( (aControllerType != StorageControllerType_PIIX3)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && (aControllerType != StorageControllerType_PIIX4)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && (aControllerType != StorageControllerType_ICH6))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SATA:
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aControllerType != StorageControllerType_IntelAhci)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SCSI:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( (aControllerType != StorageControllerType_LsiLogic)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync && (aControllerType != StorageControllerType_BusLogic))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_Floppy:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aControllerType != StorageControllerType_I82078)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SAS:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aControllerType != StorageControllerType_LsiLogicSas)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_USB:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aControllerType != StorageControllerType_USB)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Invalid controller type %d\n", m->bd->mStorageBus));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!SUCCEEDED(rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(rc,
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync tr ("Invalid controller type %d"),
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync aControllerType);
a64bf60e92e5cb8a76aa6c8e92193932d88a906fvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mStorageControllerType = aControllerType;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getMaxDevicesPerPortCount(ULONG *aMaxDevicesPerPortCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync CheckComArgOutPointerValid(aMaxDevicesPerPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = m->pSystemProperties->GetMaxDevicesPerPortForStorageBus(m->bd->mStorageBus, aMaxDevicesPerPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getMinPortCount(ULONG *aMinPortCount)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgOutPointerValid(aMinPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = m->pSystemProperties->GetMinPortCountForStorageBus(m->bd->mStorageBus, aMinPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getMaxPortCount(ULONG *aMaxPortCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync CheckComArgOutPointerValid(aMaxPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync HRESULT rc = m->pSystemProperties->GetMaxPortCountForStorageBus(m->bd->mStorageBus, aMaxPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getPortCount(ULONG *aPortCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgOutPointerValid(aPortCount);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPortCount = m->bd->mPortCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::setPortCount(ULONG aPortCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlowThisFunc(("aPortCount=%u\n", aPortCount));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (m->bd->mStorageBus)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SATA:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* AHCI SATA supports a maximum of 30 ports. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aPortCount < 1 || aPortCount > 30)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortCount, 1, 30);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SCSI:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * SCSI does not support setting different ports.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (doesn't make sense here either).
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * The maximum and minimum is 16 and unless the callee
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * tries to set a different value we return an error.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (aPortCount != 16)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync aPortCount, 16, 16);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_IDE:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The port count is fixed to 2.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aPortCount != 2)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortCount, 2, 2);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_Floppy:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The port count is fixed to 1.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aPortCount != 1)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortCount, 1, 1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_SAS:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* SAS supports a maximum of 255 ports. */
430b3ee9393ac51b1e3670019fe3ece0a4d59f81vboxsync if (aPortCount < 1 || aPortCount > 255)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortCount, 1, 255);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case StorageBus_USB:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The port count is fixed to 8.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (aPortCount != 8)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port count: %lu (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortCount, 8, 8);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Invalid controller type %d\n", m->bd->mStorageBus));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the machine needs to be mutable */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoMutableStateDependency adep(m->pParent);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync if (FAILED(adep.rc())) return adep.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd->mPortCount != aPortCount)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.backup();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortCount = aPortCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
f5395a2af3050ddd694b0ad505975f7b717ab4f1vboxsync alock.release();
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); // m->pParent is const, needs no locking
a44cdd0b29504e3de7b8aa87f839ad62b6e66f51vboxsync m->pParent->i_setModified(Machine::IsModified_Storage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mlock.release();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->pParent->i_onStorageControllerChange();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncHRESULT StorageController::getInstance(ULONG *aInstance)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* The machine doesn't need to be mutable. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aInstance = m->bd->mInstance;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::setInstance(ULONG aInstance)
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* The machine doesn't need to be mutable. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mInstance = aInstance;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getUseHostIOCache(BOOL *fUseHostIOCache)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* The machine doesn't need to be mutable. */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *fUseHostIOCache = m->bd->fUseHostIOCache;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncHRESULT StorageController::setUseHostIOCache(BOOL fUseHostIOCache)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the machine needs to be mutable */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoMutableStateDependency adep(m->pParent);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (FAILED(adep.rc())) return adep.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd->fUseHostIOCache != !!fUseHostIOCache)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.backup();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->fUseHostIOCache = !!fUseHostIOCache;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync alock.release();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); // m->pParent is const, needs no locking
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync m->pParent->i_setModified(Machine::IsModified_Storage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mlock.release();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->pParent->i_onStorageControllerChange();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::getBootable(BOOL *fBootable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* The machine doesn't need to be mutable. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *fBootable = m->bd->fBootable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// public methods only for internal purposes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::i_getIDEEmulationPort(LONG DevicePosition, LONG *aPortNumber)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CheckComArgOutPointerValid(aPortNumber);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd->mStorageControllerType != StorageControllerType_IntelAhci)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_NOTIMPL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid controller type"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (DevicePosition)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 0:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPortNumber = m->bd->mPortIde0Master;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 1:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPortNumber = m->bd->mPortIde0Slave;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 2:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync *aPortNumber = m->bd->mPortIde1Master;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 3:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *aPortNumber = m->bd->mPortIde1Slave;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncHRESULT StorageController::i_setIDEEmulationPort(LONG DevicePosition, LONG aPortNumber)
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* the machine needs to be mutable */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoMutableStateDependency adep(m->pParent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(adep.rc())) return adep.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd->mStorageControllerType != StorageControllerType_IntelAhci)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_NOTIMPL,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid controller type"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync if (aPortNumber < 0 || aPortNumber >= 30)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("Invalid port number: %ld (must be in range [%lu, %lu])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync aPortNumber, 0, 29);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync switch (DevicePosition)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 0:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortIde0Master = aPortNumber;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 1:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortIde0Slave = aPortNumber;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 2:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortIde1Master = aPortNumber;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case 3:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd->mPortIde1Slave = aPortNumber;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync default:
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync return E_INVALIDARG;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncconst Utf8Str& StorageController::i_getName() const
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m->bd->strName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncStorageControllerType_T StorageController::i_getControllerType() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return m->bd->mStorageControllerType;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncStorageBus_T StorageController::i_getStorageBus() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m->bd->mStorageBus;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncULONG StorageController::i_getInstance() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m->bd->mInstance;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncbool StorageController::i_getBootable() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return !!m->bd->fBootable;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns S_OK if the given port and device numbers are within the range supported
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * by this controller. If not, it sets an error and returns E_INVALIDARG.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ulPort
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param ulDevice
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT StorageController::i_checkPortAndDeviceValid(LONG aControllerPort,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LONG aDevice)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG portCount = m->bd->mPortCount;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG devicesPerPort;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT rc = m->pSystemProperties->GetMaxDevicesPerPortForStorageBus(m->bd->mStorageBus, &devicesPerPort);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(rc)) return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ( aControllerPort < 0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || aControllerPort >= (LONG)portCount
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync || aDevice < 0
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync || aDevice >= (LONG)devicesPerPort
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync )
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync return setError(E_INVALIDARG,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync tr("The port and/or device parameter are out of range: port=%d (must be in range [0, %d]), device=%d (must be in range [0, %d])"),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync (int)aControllerPort, (int)portCount-1, (int)aDevice, (int)devicesPerPort-1);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return S_OK;
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @note Locks objects for writing! */
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsyncvoid StorageController::i_setBootable(BOOL fBootable)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturnVoid(autoCaller.rc());
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.backup();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync m->bd->fBootable = fBootable;
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @note Locks objects for writing! */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid StorageController::i_rollback()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturnVoid(autoCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.rollback();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync * @note Locks this object for writing, together with the peer object (also
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * for writing) if there is one.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsyncvoid StorageController::i_commit()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* sanity */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
61283d6341bac43f73cf33c9ec754a59f674fa19vboxsync AssertComRCReturnVoid (autoCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* sanity too */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller peerCaller (m->pPeer);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertComRCReturnVoid (peerCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* lock both for writing since we modify both (m->pPeer is "master" so locked
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * first) */
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd.isBackedUp())
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.commit();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->pPeer)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync // attach new data to the peer and reshare it
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->pPeer->m->bd.attach (m->bd);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Cancels sharing (if any) by making an independent copy of data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This operation also resets this object's peer to NULL.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @note Locks this object for writing, together with the peer object
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * represented by @a aThat (locked for reading).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncvoid StorageController::i_unshare()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* sanity */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller autoCaller(this);
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync AssertComRCReturnVoid (autoCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync /* sanity too */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoCaller peerCaller (m->pPeer);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AssertComRCReturnVoid (peerCaller.rc());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* peer is not modified, lock it for reading (m->pPeer is "master" so locked
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * first) */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AutoReadLock rl(m->pPeer COMMA_LOCKVAL_SRC_POS);
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (m->bd.isShared())
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!m->bd.isBackedUp())
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync m->bd.backup();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m->bd.commit();
dd8efff5286a99cf8d9b3a5e8dd62340973f3cc1vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync unconst(m->pPeer) = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncMachine* StorageController::i_getMachine()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m->pParent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncComObjPtr<StorageController> StorageController::i_getPeer()
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m->pPeer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
8dee1778d3770cdc584752c84acf4899d8bfc9f9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// private methods
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* vi: set tabstop=4 shiftwidth=4 expandtab: */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync