VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h@ 63992

Last change on this file since 63992 was 63992, checked in by vboxsync, 8 years ago

VSCSI,DrvSCSI: Switch to PDMIMEDIAEX instead of using PDMIMEDIAASYNC

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1/* $Id: VSCSIInternal.h 63992 2016-09-25 17:58:56Z vboxsync $ */
2/** @file
3 * Virtual SCSI driver: Internal defines
4 */
5
6/*
7 * Copyright (C) 2006-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#ifndef ___VSCSIInternal_h
18#define ___VSCSIInternal_h
19
20#include <VBox/vscsi.h>
21#include <VBox/scsi.h>
22#include <iprt/memcache.h>
23#include <iprt/sg.h>
24#include <iprt/list.h>
25
26#include "VSCSIInline.h"
27#include "VSCSIVpdPages.h"
28
29/** Pointer to an internal virtual SCSI device. */
30typedef VSCSIDEVICEINT *PVSCSIDEVICEINT;
31/** Pointer to an internal virtual SCSI device LUN. */
32typedef VSCSILUNINT *PVSCSILUNINT;
33/** Pointer to an internal virtual SCSI device LUN pointer. */
34typedef PVSCSILUNINT *PPVSCSILUNINT;
35/** Pointer to a virtual SCSI LUN descriptor. */
36typedef struct VSCSILUNDESC *PVSCSILUNDESC;
37/** Pointer to a virtual SCSI request. */
38typedef VSCSIREQINT *PVSCSIREQINT;
39/** Pointer to a virtual SCSI I/O request. */
40typedef VSCSIIOREQINT *PVSCSIIOREQINT;
41/** Pointer to virtual SCSI sense data state. */
42typedef struct VSCSISENSE *PVSCSISENSE;
43
44/**
45 * Virtual SCSI sense data handling.
46 */
47typedef struct VSCSISENSE
48{
49 /** Buffer holding the sense data. */
50 uint8_t abSenseBuf[32];
51} VSCSISENSE;
52
53/**
54 * Virtual SCSI device.
55 */
56typedef struct VSCSIDEVICEINT
57{
58 /** Request completion callback */
59 PFNVSCSIREQCOMPLETED pfnVScsiReqCompleted;
60 /** Opaque user data. */
61 void *pvVScsiDeviceUser;
62 /** Number of LUNs currently attached. */
63 uint32_t cLunsAttached;
64 /** How many LUNs are fitting in the array. */
65 uint32_t cLunsMax;
66 /** Request cache */
67 RTMEMCACHE hCacheReq;
68 /** Sense data handling. */
69 VSCSISENSE VScsiSense;
70 /** Pointer to the array of LUN handles.
71 * The index is the LUN id. */
72 PPVSCSILUNINT papVScsiLun;
73} VSCSIDEVICEINT;
74
75/**
76 * Virtual SCSI device LUN.
77 */
78typedef struct VSCSILUNINT
79{
80 /** Pointer to the parent SCSI device. */
81 PVSCSIDEVICEINT pVScsiDevice;
82 /** Opaque user data */
83 void *pvVScsiLunUser;
84 /** I/O callback table */
85 PVSCSILUNIOCALLBACKS pVScsiLunIoCallbacks;
86 /** Pointer to the LUN type descriptor. */
87 PVSCSILUNDESC pVScsiLunDesc;
88 /** Flag indicating whether LUN is ready. */
89 bool fReady;
90 /** Flag indicating media presence in LUN. */
91 bool fMediaPresent;
92 /** Flags of supported features. */
93 uint64_t fFeatures;
94 /** I/O request processing data */
95 struct
96 {
97 /** Number of outstanding tasks on this LUN. */
98 volatile uint32_t cReqOutstanding;
99 } IoReq;
100} VSCSILUNINT;
101
102/**
103 * Virtual SCSI request.
104 */
105typedef struct VSCSIREQINT
106{
107 /** The LUN the request is for. */
108 uint32_t iLun;
109 /** The CDB */
110 uint8_t *pbCDB;
111 /** Size of the CDB */
112 size_t cbCDB;
113 /** S/G buffer. */
114 RTSGBUF SgBuf;
115 /** Pointer to the sense buffer. */
116 uint8_t *pbSense;
117 /** Size of the sense buffer */
118 size_t cbSense;
119 /** Opaque user data associated with this request */
120 void *pvVScsiReqUser;
121} VSCSIREQINT;
122
123/**
124 * Virtual SCSI I/O request.
125 */
126typedef struct VSCSIIOREQINT
127{
128 /** The associated request. */
129 PVSCSIREQINT pVScsiReq;
130 /** Lun for this I/O request. */
131 PVSCSILUNINT pVScsiLun;
132 /** Transfer direction */
133 VSCSIIOREQTXDIR enmTxDir;
134 /** Direction dependent data. */
135 union
136 {
137 /** Read/Write request. */
138 struct
139 {
140 /** Start offset */
141 uint64_t uOffset;
142 /** Number of bytes to transfer */
143 size_t cbTransfer;
144 /** Number of bytes the S/G list holds */
145 size_t cbSeg;
146 /** Number of segments. */
147 unsigned cSeg;
148 /** Segment array. */
149 PCRTSGSEG paSeg;
150 } Io;
151 /** Unmape request. */
152 struct
153 {
154 /** Array of ranges to unmap. */
155 PRTRANGE paRanges;
156 /** Number of ranges. */
157 unsigned cRanges;
158 } Unmap;
159 } u;
160} VSCSIIOREQINT;
161
162/**
163 * VPD page pool.
164 */
165typedef struct VSCSIVPDPOOL
166{
167 /** List of registered pages (VSCSIVPDPAGE). */
168 RTLISTANCHOR ListPages;
169} VSCSIVPDPOOL;
170/** Pointer to the VSCSI VPD page pool. */
171typedef VSCSIVPDPOOL *PVSCSIVPDPOOL;
172
173/**
174 * Virtual SCSI LUN descriptor.
175 */
176typedef struct VSCSILUNDESC
177{
178 /** Device type this descriptor emulates. */
179 VSCSILUNTYPE enmLunType;
180 /** Descriptor name */
181 const char *pcszDescName;
182 /** LUN type size */
183 size_t cbLun;
184
185 /**
186 * Initialise a Lun instance.
187 *
188 * @returns VBox status code.
189 * @param pVScsiLun The SCSI LUN instance.
190 */
191 DECLR3CALLBACKMEMBER(int, pfnVScsiLunInit, (PVSCSILUNINT pVScsiLun));
192
193 /**
194 * Destroy a Lun instance.
195 *
196 * @returns VBox status code.
197 * @param pVScsiLun The SCSI LUN instance.
198 */
199 DECLR3CALLBACKMEMBER(int, pfnVScsiLunDestroy, (PVSCSILUNINT pVScsiLun));
200
201 /**
202 * Processes a SCSI request.
203 *
204 * @returns VBox status code.
205 * @param pVScsiLun The SCSI LUN instance.
206 * @param pVScsiReq The SCSi request to process.
207 */
208 DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqProcess, (PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq));
209
210} VSCSILUNDESC;
211
212/** Maximum number of LUNs a device can have. */
213#define VSCSI_DEVICE_LUN_MAX 128
214
215/**
216 * Completes a SCSI request and calls the completion handler.
217 *
218 * @returns nothing.
219 * @param pVScsiDevice The virtual SCSI device.
220 * @param pVScsiReq The request which completed.
221 * @param rcScsiCode The status code
222 * One of the SCSI_STATUS_* #defines.
223 * @param fRedoPossible Flag whether redo is possible.
224 * @param rcReq Informational return code of the request.
225 */
226void vscsiDeviceReqComplete(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVScsiReq,
227 int rcScsiCode, bool fRedoPossible, int rcReq);
228
229/**
230 * Init the sense data state.
231 *
232 * @returns nothing.
233 * @param pVScsiSense The SCSI sense data state to init.
234 */
235void vscsiSenseInit(PVSCSISENSE pVScsiSense);
236
237/**
238 * Sets a ok sense code.
239 *
240 * @returns SCSI status code.
241 * @param pVScsiSense The SCSI sense state to use.
242 * @param pVScsiReq The SCSI request.
243 */
244int vscsiReqSenseOkSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
245
246/**
247 * Sets an error sense code.
248 *
249 * @returns SCSI status code.
250 * @param pVScsiSense The SCSI sense state to use.
251 * @param pVScsiReq The SCSI request.
252 * @param uSCSISenseKey The SCSI sense key to set.
253 * @param uSCSIASC The ASC value.
254 * @param uSCSIASC The ASCQ value.
255 */
256int vscsiReqSenseErrorSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey,
257 uint8_t uSCSIASC, uint8_t uSCSIASCQ);
258
259/**
260 * Sets an error sense code with additional information.
261 *
262 * @returns SCSI status code.
263 * @param pVScsiSense The SCSI sense state to use.
264 * @param pVScsiReq The SCSI request.
265 * @param uSCSISenseKey The SCSI sense key to set.
266 * @param uSCSIASC The ASC value.
267 * @param uSCSIASC The ASCQ value.
268 * @param uInfo The 32-bit sense information.
269 */
270int vscsiReqSenseErrorInfoSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey,
271 uint8_t uSCSIASC, uint8_t uSCSIASCQ, uint32_t uInfo);
272
273/**
274 * Process a request sense command.
275 *
276 * @returns SCSI status code.
277 * @param pVScsiSense The SCSI sense state to use.
278 * @param pVScsiReq The SCSI request.
279 */
280int vscsiReqSenseCmd(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
281
282/**
283 * Inits the VPD page pool.
284 *
285 * @returns VBox status code.
286 * @param pVScsiVpdPool The VPD page pool to initialize.
287 */
288int vscsiVpdPagePoolInit(PVSCSIVPDPOOL pVScsiVpdPool);
289
290/**
291 * Destroys the given VPD page pool freeing all pages in it.
292 *
293 * @returns nothing.
294 * @param pVScsiVpdPool The VPD page pool to destroy.
295 */
296void vscsiVpdPagePoolDestroy(PVSCSIVPDPOOL pVScsiVpdPool);
297
298/**
299 * Allocates a new page in the VPD page pool with the given number.
300 *
301 * @returns VBox status code.
302 * @retval VERR_ALREADY_EXIST if the page number is in use.
303 * @param pVScsiVpdPool The VPD page pool the page will belong to.
304 * @param uPage The page number, must be unique.
305 * @param cbPage Size of the page in bytes.
306 * @param ppbPage Where to store the pointer to the raw page data on success.
307 */
308int vscsiVpdPagePoolAllocNewPage(PVSCSIVPDPOOL pVScsiVpdPool, uint8_t uPage, size_t cbPage, uint8_t **ppbPage);
309
310/**
311 * Queries the given page from the pool and cpies it to the buffer given
312 * by the SCSI request.
313 *
314 * @returns VBox status code.
315 * @retval VERR_NOT_FOUND if the page is not in the pool.
316 * @param pVScsiVpdPool The VPD page pool to use.
317 * @param pVScsiReq The SCSI request.
318 * @param uPage Page to query.
319 */
320int vscsiVpdPagePoolQueryPage(PVSCSIVPDPOOL pVScsiVpdPool, PVSCSIREQINT pVScsiReq, uint8_t uPage);
321
322/**
323 * Inits the I/O request related state for the LUN.
324 *
325 * @returns VBox status code.
326 * @param pVScsiLun The LUN instance.
327 */
328int vscsiIoReqInit(PVSCSILUNINT pVScsiLun);
329
330/**
331 * Enqueues a new flush request
332 *
333 * @returns VBox status code.
334 * @param pVScsiLun The LUN instance which issued the request.
335 * @param pVScsiReq The virtual SCSI request associated with the flush.
336 */
337int vscsiIoReqFlushEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq);
338
339/**
340 * Enqueue a new data transfer request.
341 *
342 * @returns VBox status code.
343 * @param pVScsiLun The LUN instance which issued the request.
344 * @param pVScsiReq The virtual SCSI request associated with the transfer.
345 * @param enmTxDir Transfer direction.
346 * @param uOffset Start offset of the transfer.
347 * @param cbTransfer Number of bytes to transfer.
348 */
349int vscsiIoReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
350 VSCSIIOREQTXDIR enmTxDir, uint64_t uOffset,
351 size_t cbTransfer);
352
353/**
354 * Enqueue a new unmap request.
355 *
356 * @returns VBox status code.
357 * @param pVScsiLun The LUN instance which issued the request.
358 * @param pVScsiReq The virtual SCSI request associated with the transfer.
359 * @param paRanges The array of ranges to unmap.
360 * @param cRanges Number of ranges in the array.
361 */
362int vscsiIoReqUnmapEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
363 PRTRANGE paRanges, unsigned cRanges);
364
365/**
366 * Returns the current number of outstanding tasks on the given LUN.
367 *
368 * @returns Number of outstanding tasks.
369 * @param pVScsiLun The LUN to check.
370 */
371uint32_t vscsiIoReqOutstandingCountGet(PVSCSILUNINT pVScsiLun);
372
373/**
374 * Wrapper for the set I/O request allocation size I/O callback.
375 *
376 * @returns VBox status code.
377 * @param pVScsiLun The LUN.
378 * @param cbVScsiIoReqAlloc The additional size for the request to allocate.
379 */
380DECLINLINE(int) vscsiLunReqAllocSizeSet(PVSCSILUNINT pVScsiLun, size_t cbVScsiIoReqAlloc)
381{
382 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqAllocSizeSet(pVScsiLun,
383 pVScsiLun->pvVScsiLunUser,
384 cbVScsiIoReqAlloc);
385}
386
387/**
388 * Wrapper for the allocate I/O request I/O callback.
389 *
390 * @returns VBox status code.
391 * @param pVScsiLun The LUN.
392 * @param u64Tag A unique tag to assign to the request.
393 * @param ppVScsiIoReq Where to store the pointer to the request on success.
394 */
395DECLINLINE(int) vscsiLunReqAlloc(PVSCSILUNINT pVScsiLun, uint64_t u64Tag, PVSCSIIOREQINT *ppVScsiIoReq)
396{
397 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqAlloc(pVScsiLun,
398 pVScsiLun->pvVScsiLunUser,
399 u64Tag, ppVScsiIoReq);
400}
401
402/**
403 * Wrapper for the free I/O request I/O callback.
404 *
405 * @returns VBox status code.
406 * @param pVScsiLun The LUN.
407 * @param pVScsiIoReq The request to free.
408 */
409DECLINLINE(int) vscsiLunReqFree(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
410{
411 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqFree(pVScsiLun,
412 pVScsiLun->pvVScsiLunUser,
413 pVScsiIoReq);
414}
415
416/**
417 * Wrapper for the get medium size I/O callback.
418 *
419 * @returns VBox status code.
420 * @param pVScsiLun The LUN.
421 * @param pcbSize Where to store the size on success.
422 */
423DECLINLINE(int) vscsiLunMediumGetSize(PVSCSILUNINT pVScsiLun, uint64_t *pcbSize)
424{
425 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSize(pVScsiLun,
426 pVScsiLun->pvVScsiLunUser,
427 pcbSize);
428}
429
430/**
431 * Wrapper for the get medium sector size I/O callback.
432 *
433 * @returns VBox status code.
434 * @param pVScsiLun The LUN.
435 * @param pcbSectorSize Where to store the sector size on success.
436 */
437DECLINLINE(int) vscsiLunMediumGetSectorSize(PVSCSILUNINT pVScsiLun, uint32_t *pcbSectorSize)
438{
439 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSectorSize(pVScsiLun,
440 pVScsiLun->pvVScsiLunUser,
441 pcbSectorSize);
442}
443
444/**
445 * Wrapper for the get medium lock/unlock I/O callback.
446 *
447 * @returns VBox status code.
448 * @param pVScsiLun The LUN.
449 * @param bool The new medium lock state.
450 */
451DECLINLINE(int) vscsiLunMediumSetLock(PVSCSILUNINT pVScsiLun, bool fLocked)
452{
453 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumSetLock(pVScsiLun,
454 pVScsiLun->pvVScsiLunUser,
455 fLocked);
456}
457
458/**
459 * Wrapper for the I/O request enqueue I/O callback.
460 *
461 * @returns VBox status code.
462 * @param pVScsiLun The LUN.
463 * @param pVScsiIoReq The I/O request to enqueue.
464 */
465DECLINLINE(int) vscsiLunReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
466{
467 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqTransferEnqueue(pVScsiLun,
468 pVScsiLun->pvVScsiLunUser,
469 pVScsiIoReq);
470}
471
472/**
473 * Wrapper for the get feature flags I/O callback.
474 *
475 * @returns VBox status code.
476 * @param pVScsiLun The LUN.
477 * @param pVScsiIoReq The I/O request to enqueue.
478 */
479DECLINLINE(int) vscsiLunGetFeatureFlags(PVSCSILUNINT pVScsiLun, uint64_t *pfFeatures)
480{
481 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunGetFeatureFlags(pVScsiLun,
482 pVScsiLun->pvVScsiLunUser,
483 pfFeatures);
484}
485
486/**
487 * Wrapper around vscsiReqSenseOkSet()
488 */
489DECLINLINE(int) vscsiLunReqSenseOkSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
490{
491 return vscsiReqSenseOkSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq);
492}
493
494/**
495 * Wrapper around vscsiReqSenseErrorSet()
496 */
497DECLINLINE(int) vscsiLunReqSenseErrorSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ)
498{
499 return vscsiReqSenseErrorSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ);
500}
501
502/**
503 * Wrapper around vscsiReqSenseErrorInfoSet()
504 */
505DECLINLINE(int) vscsiLunReqSenseErrorInfoSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ, uint32_t uInfo)
506{
507 return vscsiReqSenseErrorInfoSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ, uInfo);
508}
509
510#endif /* ___VSCSIInternal_h */
511
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette