/* $Id: DrvHostBase.h 44528 2013-02-04 14:27:54Z vboxsync $ */ /** @file * DrvHostBase - Host base drive access driver. */ /* * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ #ifndef __HostDrvBase_h__ #define __HostDrvBase_h__ #include RT_C_DECLS_BEGIN /** Pointer to host base drive access driver instance data. */ typedef struct DRVHOSTBASE *PDRVHOSTBASE; /** * Host base drive access driver instance data. * * @implements PDMIMOUNT * @implements PDMIBLOCKBIOS * @implements PDMIBLOCK */ typedef struct DRVHOSTBASE { /** Critical section used to serialize access to the handle and other * members of this struct. */ RTCRITSECT CritSect; /** Pointer driver instance. */ PPDMDRVINS pDrvIns; /** Drive type. */ PDMBLOCKTYPE enmType; /** Visible to the BIOS. */ bool fBiosVisible; /** The configuration readonly value. */ bool fReadOnlyConfig; /** The current readonly status. */ bool fReadOnly; /** Flag whether failure to attach is an error or not. */ bool fAttachFailError; /** Flag whether to keep instance working (as unmounted though). */ bool fKeepInstance; /** Device name (MMHeap). */ char *pszDevice; /** Device name to open (RTStrFree). */ char *pszDeviceOpen; #ifdef RT_OS_SOLARIS /** Device name of raw device (RTStrFree). */ char *pszRawDeviceOpen; #endif /** Uuid of the drive. */ RTUUID Uuid; /** Pointer to the block port interface above us. */ PPDMIBLOCKPORT pDrvBlockPort; /** Pointer to the mount notify interface above us. */ PPDMIMOUNTNOTIFY pDrvMountNotify; /** Our block interface. */ PDMIBLOCK IBlock; /** Our block interface. */ PDMIBLOCKBIOS IBlockBios; /** Our mountable interface. */ PDMIMOUNT IMount; /** Media present indicator. */ bool volatile fMediaPresent; /** Locked indicator. */ bool fLocked; /** The size of the media currently in the drive. * This is invalid if no drive is in the drive. */ uint64_t volatile cbSize; #if !defined(RT_OS_DARWIN) /** The filehandle of the device. */ RTFILE hFileDevice; #endif #ifdef RT_OS_SOLARIS /** The raw filehandle of the device. */ RTFILE hFileRawDevice; #endif /** Handle of the poller thread. */ RTTHREAD ThreadPoller; #ifndef RT_OS_WINDOWS /** Event semaphore the thread will wait on. */ RTSEMEVENT EventPoller; #endif /** The poller interval. */ RTMSINTERVAL cMilliesPoller; /** The shutdown indicator. */ bool volatile fShutdownPoller; /** BIOS PCHS geometry. */ PDMMEDIAGEOMETRY PCHSGeometry; /** BIOS LCHS geometry. */ PDMMEDIAGEOMETRY LCHSGeometry; /** The number of errors that could go into the release log. (flood gate) */ uint32_t cLogRelErrors; #ifdef RT_OS_DARWIN /** The master port. */ mach_port_t MasterPort; /** The MMC-2 Device Interface. (This is only used to get the scsi task interface.) */ MMCDeviceInterface **ppMMCDI; /** The SCSI Task Device Interface. */ SCSITaskDeviceInterface **ppScsiTaskDI; /** The block size. Set when querying the media size. */ uint32_t cbBlock; /** The disk arbitration session reference. NULL if we didn't have to claim & unmount the device. */ DASessionRef pDASession; /** The disk arbitration disk reference. NULL if we didn't have to claim & unmount the device. */ DADiskRef pDADisk; #endif #ifdef RT_OS_WINDOWS /** Handle to the window we use to catch the device change broadcast messages. */ volatile HWND hwndDeviceChange; /** The unit mask. */ DWORD fUnitMask; #endif #ifdef RT_OS_LINUX /** Double buffer required for ioctl with the Linux kernel as long as we use * remap_pfn_range() instead of vm_insert_page(). */ uint8_t *pbDoubleBuffer; #endif #ifdef RT_OS_FREEBSD /** The block size. Set when querying the media size. */ uint32_t cbBlock; /** SCSI bus number. */ path_id_t ScsiBus; /** target ID of the passthrough device. */ target_id_t ScsiTargetID; /** LUN of the passthrough device. */ lun_id_t ScsiLunID; #endif /** * Performs the locking / unlocking of the device. * * This callback pointer should be set to NULL if the device doesn't support this action. * * @returns VBox status code. * @param pThis Pointer to the instance data. * @param fLock Set if locking, clear if unlocking. */ DECLCALLBACKMEMBER(int, pfnDoLock)(PDRVHOSTBASE pThis, bool fLock); /** * Queries the media size. * Can also be used to perform actions on media change. * * This callback pointer should be set to NULL if the default action is fine for this device. * * @returns VBox status code. * @param pThis Pointer to the instance data. * @param pcb Where to store the media size in bytes. */ DECLCALLBACKMEMBER(int, pfnGetMediaSize)(PDRVHOSTBASE pThis, uint64_t *pcb); /*** * Performs the polling operation. * * @returns VBox status code. (Failure means retry.) * @param pThis Pointer to the instance data. */ DECLCALLBACKMEMBER(int, pfnPoll)(PDRVHOSTBASE pThis); } DRVHOSTBASE; int DRVHostBaseInitData(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, PDMBLOCKTYPE enmType); int DRVHostBaseInitFinish(PDRVHOSTBASE pThis); int DRVHostBaseMediaPresent(PDRVHOSTBASE pThis); void DRVHostBaseMediaNotPresent(PDRVHOSTBASE pThis); DECLCALLBACK(void) DRVHostBaseDestruct(PPDMDRVINS pDrvIns); #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, size_t cbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf, uint8_t *pbSense, size_t cbSense, uint32_t cTimeoutMillies); #endif /** Makes a PDRVHOSTBASE out of a PPDMIMOUNT. */ #define PDMIMOUNT_2_DRVHOSTBASE(pInterface) ( (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IMount)) ) /** Makes a PDRVHOSTBASE out of a PPDMIBLOCK. */ #define PDMIBLOCK_2_DRVHOSTBASE(pInterface) ( (PDRVHOSTBASE)((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IBlock)) ) RT_C_DECLS_END #endif