1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
|
/* $Id: vscsi.h $ */
/** @file
* VBox storage drivers - Virtual SCSI driver
*/
/*
* Copyright (C) 2006-2024 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses>.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
* in the VirtualBox distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
*/
#ifndef VBOX_INCLUDED_vscsi_h
#define VBOX_INCLUDED_vscsi_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <VBox/cdefs.h>
#include <VBox/types.h>
#include <VBox/vdmedia.h>
#include <iprt/sg.h>
RT_C_DECLS_BEGIN
#ifdef IN_RING0
# error "There are no VBox VSCSI APIs available in Ring-0 Host Context!"
#endif
/** @defgroup grp_drv_vscsi Virtual VSCSI Driver
* @ingroup grp_devdrv
* @{
*/
/** @todo figure better grouping. */
/** A virtual SCSI device handle */
typedef struct VSCSIDEVICEINT *VSCSIDEVICE;
/** A pointer to a virtual SCSI device handle. */
typedef VSCSIDEVICE *PVSCSIDEVICE;
/** A virtual SCSI LUN handle. */
typedef struct VSCSILUNINT *VSCSILUN;
/** A pointer to a virtual SCSI LUN handle. */
typedef VSCSILUN *PVSCSILUN;
/** A virtual SCSI request handle. */
typedef struct VSCSIREQINT *VSCSIREQ;
/** A pointer to a virtual SCSI request handle. */
typedef VSCSIREQ *PVSCSIREQ;
/** A SCSI I/O request handle. */
typedef struct VSCSIIOREQINT *VSCSIIOREQ;
/** A pointer to a SCSI I/O request handle. */
typedef VSCSIIOREQ *PVSCSIIOREQ;
/**
* Virtual SCSI I/O request transfer direction.
*/
typedef enum VSCSIIOREQTXDIR
{
/** Invalid direction */
VSCSIIOREQTXDIR_INVALID = 0,
/** Read */
VSCSIIOREQTXDIR_READ,
/** Write */
VSCSIIOREQTXDIR_WRITE,
/** Flush */
VSCSIIOREQTXDIR_FLUSH,
/** Unmap */
VSCSIIOREQTXDIR_UNMAP,
/** 32bit hack */
VSCSIIOREQTXDIR_32BIT_HACK = 0x7fffffff
} VSCSIIOREQTXDIR;
/** Pointer to a SCSI LUN type */
typedef VSCSIIOREQTXDIR *PVSCSIIOREQTXDIR;
/**
* Virtual SCSI transfer direction as seen from the initiator.
*/
typedef enum VSCSIXFERDIR
{
/** Invalid data direction. */
PVSCSIXFERDIR_INVALID = 0,
/** Direction is unknown. */
VSCSIXFERDIR_UNKNOWN,
/** Direction is from target to initiator (aka a read). */
VSCSIXFERDIR_T2I,
/** Direction is from initiator to device (aka a write). */
VSCSIXFERDIR_I2T,
/** No data transfer associated with this request. */
VSCSIXFERDIR_NONE,
/** 32bit hack. */
VSCSIXFERDIR_32BIT_HACK = 0x7fffffff
} VSCSIXFERDIR;
/**
* LUN types we support
*/
typedef enum VSCSILUNTYPE
{
/** Invalid type */
VSCSILUNTYPE_INVALID = 0,
/** Hard disk (SBC) */
VSCSILUNTYPE_SBC,
/** CD/DVD drive (MMC) */
VSCSILUNTYPE_MMC,
/** Tape drive (SSC) */
VSCSILUNTYPE_SSC,
/** Last value to indicate an invalid device */
VSCSILUNTYPE_LAST,
/** 32bit hack */
VSCSILUNTYPE_32BIT_HACK = 0x7fffffff
} VSCSILUNTYPE;
/** Pointer to a SCSI LUN type */
typedef VSCSILUNTYPE *PVSCSILUNTYPE;
/** The LUN can handle the UNMAP command. */
#define VSCSI_LUN_FEATURE_UNMAP RT_BIT(0)
/** The LUN has a non rotational medium. */
#define VSCSI_LUN_FEATURE_NON_ROTATIONAL RT_BIT(1)
/** The medium of the LUN is readonly. */
#define VSCSI_LUN_FEATURE_READONLY RT_BIT(2)
/**
* Virtual SCSI LUN I/O Callback table.
*/
typedef struct VSCSILUNIOCALLBACKS
{
/**
* Sets the size of the allocator specific memory for a I/O request.
*
* @returns VBox status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param cbVScsiIoReqAlloc The size of the allocator specific memory in bytes.
* @thread EMT.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqAllocSizeSet, (VSCSILUN hVScsiLun, void *pvScsiLunUser,
size_t cbVScsiIoReqAlloc));
/**
* Allocates a new I/O request.
*
* @returns VBox status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param u64Tag A tag to assign to the request handle for identification later on.
* @param phVScsiIoReq Where to store the handle to the allocated I/O request on success.
* @thread Any thread.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqAlloc, (VSCSILUN hVScsiLun, void *pvScsiLunUser,
uint64_t u64Tag, PVSCSIIOREQ phVScsiIoReq));
/**
* Frees a given I/O request.
*
* @returns VBox status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param hVScsiIoReq The VSCSI I/O request to free.
* @thread Any thread.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqFree, (VSCSILUN hVScsiLun, void *pvScsiLunUser, VSCSIIOREQ hVScsiIoReq));
/**
* Returns the number of regions for the medium.
*
* @returns Number of regions.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
*/
DECLR3CALLBACKMEMBER(uint32_t, pfnVScsiLunMediumGetRegionCount,(VSCSILUN hVScsiLun, void *pvScsiLunUser));
/**
* Queries the properties for the given region.
*
* @returns VBox status code.
* @retval VERR_NOT_FOUND if the region index is not known.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param uRegion The region index to query the properties of.
* @param pu64LbaStart Where to store the starting LBA for the region on success.
* @param pcBlocks Where to store the number of blocks for the region on success.
* @param pcbBlock Where to store the size of one block in bytes on success.
* @param penmDataForm WHere to store the data form for the region on success.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumQueryRegionProperties,(VSCSILUN hVScsiLun, void *pvScsiLunUser,
uint32_t uRegion, uint64_t *pu64LbaStart,
uint64_t *pcBlocks, uint64_t *pcbBlock,
PVDREGIONDATAFORM penmDataForm));
/**
* Queries the properties for the region covering the given LBA.
*
* @returns VBox status code.
* @retval VERR_NOT_FOUND if the region index is not known.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param u64LbaStart Where to store the starting LBA for the region on success.
* @param puRegion Where to store the region number on success.
* @param pcBlocks Where to store the number of blocks left in this region starting from the given LBA.
* @param pcbBlock Where to store the size of one block in bytes on success.
* @param penmDataForm WHere to store the data form for the region on success.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumQueryRegionPropertiesForLba,(VSCSILUN hVScsiLun, void *pvScsiLunUser,
uint64_t u64LbaStart, uint32_t *puRegion,
uint64_t *pcBlocks, uint64_t *pcbBlock,
PVDREGIONDATAFORM penmDataForm));
/**
* Set the lock state of the underlying medium.
*
* @returns VBox status status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param fLocked New lock state (locked/unlocked).
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumSetLock,(VSCSILUN hVScsiLun, void *pvScsiLunUser, bool fLocked));
/**
* Eject the attached medium.
*
* @returns VBox status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumEject, (VSCSILUN hVScsiLun, void *pvScsiLunUser));
/**
* Enqueue a read or write request from the medium.
*
* @returns VBox status status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param hVScsiIoReq Virtual SCSI I/O request handle.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqTransferEnqueue,(VSCSILUN hVScsiLun, void *pvScsiLunUser, VSCSIIOREQ hVScsiIoReq));
/**
* Returns flags of supported features.
*
* @returns VBox status status code.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param pfFeatures Where to return the queried features.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunGetFeatureFlags,(VSCSILUN hVScsiLun, void *pvScsiLunUser, uint64_t *pfFeatures));
/**
* Queries the vendor and product ID and revision to report for INQUIRY commands of the given LUN.
*
* @returns VBox status status code.
* @retval VERR_NOT_FOUND if the data is not available and some defaults should be sued instead.
* @param hVScsiLun Virtual SCSI LUN handle.
* @param pvScsiLunUser Opaque user data which may be used to identify the
* medium.
* @param ppszVendorId Where to store the pointer to the vendor ID string to report.
* @param ppszProductId Where to store the pointer to the product ID string to report.
* @param ppszProductLevel Where to store the pointer to the product level string to report.
*/
DECLR3CALLBACKMEMBER(int, pfnVScsiLunQueryInqStrings, (VSCSILUN hVScsiLun, void *pvScsiLunUser, const char **ppszVendorId,
const char **ppszProductId, const char **ppszProductLevel));
} VSCSILUNIOCALLBACKS;
/** Pointer to a virtual SCSI LUN I/O callback table. */
typedef VSCSILUNIOCALLBACKS *PVSCSILUNIOCALLBACKS;
/**
* The virtual SCSI request completed callback.
*/
typedef DECLCALLBACKTYPE(void, FNVSCSIREQCOMPLETED,(VSCSIDEVICE hVScsiDevice,
void *pvVScsiDeviceUser,
void *pvVScsiReqUser,
int rcScsiCode,
bool fRedoPossible,
int rcReq,
size_t cbXfer,
VSCSIXFERDIR enmXferDir,
size_t cbSense));
/** Pointer to a virtual SCSI request completed callback. */
typedef FNVSCSIREQCOMPLETED *PFNVSCSIREQCOMPLETED;
/**
* Create a new empty SCSI device instance.
*
* @returns VBox status code.
* @param phVScsiDevice Where to store the SCSI device handle.
* @param pfnVScsiReqCompleted The method call after a request completed.
* @param pvVScsiDeviceUser Opaque user data given in the completion callback.
*/
VBOXDDU_DECL(int) VSCSIDeviceCreate(PVSCSIDEVICE phVScsiDevice,
PFNVSCSIREQCOMPLETED pfnVScsiReqCompleted,
void *pvVScsiDeviceUser);
/**
* Destroy a SCSI device instance.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle to destroy.
*/
VBOXDDU_DECL(int) VSCSIDeviceDestroy(VSCSIDEVICE hVScsiDevice);
/**
* Attach a LUN to the SCSI device.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle to add the LUN to.
* @param hVScsiLun The LUN handle to add.
* @param iLun The LUN number.
*/
VBOXDDU_DECL(int) VSCSIDeviceLunAttach(VSCSIDEVICE hVScsiDevice, VSCSILUN hVScsiLun, uint32_t iLun);
/**
* Detach a LUN from the SCSI device.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle to add the LUN to.
* @param iLun The LUN number to remove.
* @param phVScsiLun Where to store the detached LUN handle.
*/
VBOXDDU_DECL(int) VSCSIDeviceLunDetach(VSCSIDEVICE hVScsiDevice, uint32_t iLun,
PVSCSILUN phVScsiLun);
/**
* Query the SCSI LUN type.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle.
* @param iLun The LUN number to get.
* @param pEnmLunType Where to store the LUN type.
*/
VBOXDDU_DECL(int) VSCSIDeviceLunQueryType(VSCSIDEVICE hVScsiDevice, uint32_t iLun,
PVSCSILUNTYPE pEnmLunType);
/**
* Enqueue a request to the SCSI device.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle.
* @param hVScsiReq The SCSI request handle to enqueue.
*/
VBOXDDU_DECL(int) VSCSIDeviceReqEnqueue(VSCSIDEVICE hVScsiDevice, VSCSIREQ hVScsiReq);
/**
* Allocate a new request handle.
*
* @returns VBox status code.
* @param hVScsiDevice The SCSI device handle.
* @param phVScsiReq Where to SCSI request handle.
* @param iLun The LUN the request is for.
* @param pbCDB The CDB for the request.
* @param cbCDB The size of the CDB in bytes.
* @param cbSGList Number of bytes the S/G list describes.
* @param cSGListEntries Number of S/G list entries.
* @param paSGList Pointer to the S/G list.
* @param pbSense Pointer to the sense buffer.
* @param cbSense Size of the sense buffer.
* @param pvVScsiReqUser Opqaue user data returned when the request completes.
*/
VBOXDDU_DECL(int) VSCSIDeviceReqCreate(VSCSIDEVICE hVScsiDevice, PVSCSIREQ phVScsiReq,
uint32_t iLun, uint8_t *pbCDB, size_t cbCDB,
size_t cbSGList, unsigned cSGListEntries,
PCRTSGSEG paSGList, uint8_t *pbSense,
size_t cbSense, void *pvVScsiReqUser);
/**
* Create a new LUN.
*
* @returns VBox status code.
* @param phVScsiLun Where to store the SCSI LUN handle.
* @param enmLunType The Lun type.
* @param pVScsiLunIoCallbacks Pointer to the I/O callbacks to use for his LUN.
* @param pvVScsiLunUser Opaque user argument which
* is returned in the pvScsiLunUser parameter
* when the request completion callback is called.
*/
VBOXDDU_DECL(int) VSCSILunCreate(PVSCSILUN phVScsiLun, VSCSILUNTYPE enmLunType,
PVSCSILUNIOCALLBACKS pVScsiLunIoCallbacks,
void *pvVScsiLunUser);
/**
* Destroy virtual SCSI LUN.
*
* @returns VBox status code.
* @param hVScsiLun The virtual SCSI LUN handle to destroy.
*/
VBOXDDU_DECL(int) VSCSILunDestroy(VSCSILUN hVScsiLun);
/**
* Notify virtual SCSI LUN of medium being mounted.
*
* @returns VBox status code.
* @param hVScsiLun The virtual SCSI LUN handle to destroy.
*/
VBOXDDU_DECL(int) VSCSILunMountNotify(VSCSILUN hVScsiLun);
/**
* Notify virtual SCSI LUN of medium being unmounted.
*
* @returns VBox status code.
* @param hVScsiLun The virtual SCSI LUN handle to destroy.
*/
VBOXDDU_DECL(int) VSCSILunUnmountNotify(VSCSILUN hVScsiLun);
/**
* Notify a that a I/O request completed.
*
* @returns VBox status code.
* @param hVScsiIoReq The I/O request handle that completed.
* This is given when a I/O callback for
* the LUN is called by the virtual SCSI layer.
* @param rcIoReq The status code the I/O request completed with.
* @param fRedoPossible Flag whether it is possible to redo the request.
* If true setting any sense code will be omitted
* in case of an error to not alter the device state.
*/
VBOXDDU_DECL(int) VSCSIIoReqCompleted(VSCSIIOREQ hVScsiIoReq, int rcIoReq, bool fRedoPossible);
/**
* Query the transfer direction of the I/O request.
*
* @returns Transfer direction.of the given I/O request
* @param hVScsiIoReq The SCSI I/O request handle.
*/
VBOXDDU_DECL(VSCSIIOREQTXDIR) VSCSIIoReqTxDirGet(VSCSIIOREQ hVScsiIoReq);
/**
* Query I/O parameters.
*
* @returns VBox status code.
* @param hVScsiIoReq The SCSI I/O request handle.
* @param puOffset Where to store the start offset.
* @param pcbTransfer Where to store the amount of bytes to transfer.
* @param pcSeg Where to store the number of segments in the S/G list.
* @param pcbSeg Where to store the number of bytes the S/G list describes.
* @param ppaSeg Where to store the pointer to the S/G list.
*/
VBOXDDU_DECL(int) VSCSIIoReqParamsGet(VSCSIIOREQ hVScsiIoReq, uint64_t *puOffset,
size_t *pcbTransfer, unsigned *pcSeg,
size_t *pcbSeg, PCRTSGSEG *ppaSeg);
/**
* Query unmap parameters.
*
* @returns VBox status code.
* @param hVScsiIoReq The SCSI I/O request handle.
* @param ppaRanges Where to store the pointer to the range array on success.
* @param pcRanges Where to store the number of ranges on success.
*/
VBOXDDU_DECL(int) VSCSIIoReqUnmapParamsGet(VSCSIIOREQ hVScsiIoReq, PCRTRANGE *ppaRanges,
unsigned *pcRanges);
/** @} */
RT_C_DECLS_END
#endif /* !VBOX_INCLUDED_vscsi_h */
|