VSCSILun.cpp revision a4ba1fc5788b1fb4c078587d5f55936e1b83098d
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/* $Id$ */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** @file
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Virtual SCSI driver: LUN handling
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/*
aae8a6a38fd27661046ab1d06cb2cb5c096c40edvboxsync * Copyright (C) 2006-2010 Sun Microsystems, Inc.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * available from http://www.virtualbox.org. This file is free software;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * General Public License (GPL) as published by the Free Software
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * additional information or have any questions.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#define LOG_GROUP LOG_GROUP_VSCSI
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include <VBox/log.h>
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include <VBox/err.h>
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include <VBox/types.h>
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include <VBox/vscsi.h>
5067a9619d7131c54d4ebb371d9dac91abdd34f6vboxsync#include <iprt/assert.h>
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include <iprt/mem.h>
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync#include "VSCSIInternal.h"
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** SBC descriptor */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncextern VSCSILUNDESC g_VScsiLunTypeSbc;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/** MMC descriptor */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync//extern PVSCSILUNDESC g_pVScsiLunTypeMmc;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/**
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Array of supported SCSI LUN types.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncstatic PVSCSILUNDESC g_aVScsiLunTypesSupported[] =
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync{
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync &g_VScsiLunTypeSbc
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync};
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncVBOXDDU_DECL(int) VSCSILunCreate(PVSCSILUN phVScsiLun, VSCSILUNTYPE enmLunType,
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PVSCSILUNIOCALLBACKS pVScsiLunIoCallbacks,
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync void *pvVScsiLunUser)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync{
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PVSCSILUNINT pVScsiLun = NULL;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PVSCSILUNDESC pVScsiLunDesc = NULL;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertPtrReturn(phVScsiLun, VERR_INVALID_POINTER);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertReturn( enmLunType > VSCSILUNTYPE_INVALID
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync && enmLunType < VSCSILUNTYPE_LAST, VERR_INVALID_PARAMETER);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertPtrReturn(pVScsiLunIoCallbacks, VERR_INVALID_PARAMETER);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync for (unsigned idxLunType = 0; idxLunType < RT_ELEMENTS(g_aVScsiLunTypesSupported); idxLunType++)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync {
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync if (g_aVScsiLunTypesSupported[idxLunType]->enmLunType == enmLunType)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync {
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync pVScsiLunDesc = g_aVScsiLunTypesSupported[idxLunType];
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync break;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync }
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync }
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync if (!pVScsiLunDesc)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return VERR_VSCSI_LUN_TYPE_NOT_SUPPORTED;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun = (PVSCSILUNINT)RTMemAllocZ(pVScsiLunDesc->cbLun);
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync if (!pVScsiLun)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return VERR_NO_MEMORY;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pVScsiDevice = NULL;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pvVScsiLunUser = pvVScsiLunUser;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pVScsiLunIoCallbacks = pVScsiLunIoCallbacks;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pVScsiLunDesc = pVScsiLunDesc;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync int rc = pVScsiLunDesc->pfnVScsiLunInit(pVScsiLun);
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync if (RT_SUCCESS(rc))
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync {
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /** @todo Init other stuff */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync *phVScsiLun = pVScsiLun;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return VINF_SUCCESS;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync }
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
728b52f802ac19865bd4aa8e9ade8f506a9e6c10vboxsync RTMemFree(pVScsiLun);
728b52f802ac19865bd4aa8e9ade8f506a9e6c10vboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return rc;
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync}
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync/**
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * Destroy virtual SCSI LUN.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync *
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @returns VBox status code.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync * @param hVScsiLun The virtal SCSI LUN handle to destroy.
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsyncVBOXDDU_DECL(int) VSCSILunDestroy(VSCSILUN hVScsiLun)
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync{
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync PVSCSILUNINT pVScsiLun = (PVSCSILUNINT)hVScsiLun;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertPtrReturn(pVScsiLun, VERR_INVALID_HANDLE);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync AssertReturn(!pVScsiLun->pVScsiDevice, VERR_VSCSI_LUN_ATTACHED_TO_DEVICE);
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync AssertReturn(vscsiIoReqOutstandingCountGet(pVScsiLun) != 0, VERR_VSCSI_LUN_BUSY);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
728b52f802ac19865bd4aa8e9ade8f506a9e6c10vboxsync int rc = pVScsiLun->pVScsiLunDesc->pfnVScsiLunDestroy(pVScsiLun);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync if (RT_FAILURE(rc))
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return rc;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync /* Make LUN invalid */
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pvVScsiLunUser = NULL;
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync pVScsiLun->pVScsiLunIoCallbacks = NULL;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync pVScsiLun->pVScsiLunDesc = NULL;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync RTMemFree(pVScsiLun);
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync return VINF_SUCCESS;
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync}
41d680dd6eb0287afc200adc5b0d61b07a32b72dvboxsync
ad4f6ac2063d9b48efd9c3193442136a8c7c890avboxsync