VirtualBox

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

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

VSCSI: Add method to eject media from the guest and make use of it in DrvSCSI, also add callbacks for attaching and detaching drivers below DrvSCSI which will be required to avoid destroying/recreating the driver every time the medium is changed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1/* $Id: VSCSIInternal.h 64132 2016-10-03 16:23:11Z 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 /**
211 * Informs about a medium being inserted - optional.
212 *
213 * @returns VBox status code.
214 * @param pVScsiLun The SCSI LUN instance.
215 */
216 DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumInserted, (PVSCSILUNINT pVScsiLun));
217
218 /**
219 * Informs about a medium being removed - optional.
220 *
221 * @returns VBox status code.
222 * @param pVScsiLun The SCSI LUN instance.
223 */
224 DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumRemoved, (PVSCSILUNINT pVScsiLun));
225
226} VSCSILUNDESC;
227
228/** Maximum number of LUNs a device can have. */
229#define VSCSI_DEVICE_LUN_MAX 128
230
231/**
232 * Completes a SCSI request and calls the completion handler.
233 *
234 * @returns nothing.
235 * @param pVScsiDevice The virtual SCSI device.
236 * @param pVScsiReq The request which completed.
237 * @param rcScsiCode The status code
238 * One of the SCSI_STATUS_* #defines.
239 * @param fRedoPossible Flag whether redo is possible.
240 * @param rcReq Informational return code of the request.
241 */
242void vscsiDeviceReqComplete(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVScsiReq,
243 int rcScsiCode, bool fRedoPossible, int rcReq);
244
245/**
246 * Init the sense data state.
247 *
248 * @returns nothing.
249 * @param pVScsiSense The SCSI sense data state to init.
250 */
251void vscsiSenseInit(PVSCSISENSE pVScsiSense);
252
253/**
254 * Sets a ok sense code.
255 *
256 * @returns SCSI status code.
257 * @param pVScsiSense The SCSI sense state to use.
258 * @param pVScsiReq The SCSI request.
259 */
260int vscsiReqSenseOkSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
261
262/**
263 * Sets an error sense code.
264 *
265 * @returns SCSI status code.
266 * @param pVScsiSense The SCSI sense state to use.
267 * @param pVScsiReq The SCSI request.
268 * @param uSCSISenseKey The SCSI sense key to set.
269 * @param uSCSIASC The ASC value.
270 * @param uSCSIASC The ASCQ value.
271 */
272int vscsiReqSenseErrorSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey,
273 uint8_t uSCSIASC, uint8_t uSCSIASCQ);
274
275/**
276 * Sets an error sense code with additional information.
277 *
278 * @returns SCSI status code.
279 * @param pVScsiSense The SCSI sense state to use.
280 * @param pVScsiReq The SCSI request.
281 * @param uSCSISenseKey The SCSI sense key to set.
282 * @param uSCSIASC The ASC value.
283 * @param uSCSIASC The ASCQ value.
284 * @param uInfo The 32-bit sense information.
285 */
286int vscsiReqSenseErrorInfoSet(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey,
287 uint8_t uSCSIASC, uint8_t uSCSIASCQ, uint32_t uInfo);
288
289/**
290 * Process a request sense command.
291 *
292 * @returns SCSI status code.
293 * @param pVScsiSense The SCSI sense state to use.
294 * @param pVScsiReq The SCSI request.
295 */
296int vscsiReqSenseCmd(PVSCSISENSE pVScsiSense, PVSCSIREQINT pVScsiReq);
297
298/**
299 * Inits the VPD page pool.
300 *
301 * @returns VBox status code.
302 * @param pVScsiVpdPool The VPD page pool to initialize.
303 */
304int vscsiVpdPagePoolInit(PVSCSIVPDPOOL pVScsiVpdPool);
305
306/**
307 * Destroys the given VPD page pool freeing all pages in it.
308 *
309 * @returns nothing.
310 * @param pVScsiVpdPool The VPD page pool to destroy.
311 */
312void vscsiVpdPagePoolDestroy(PVSCSIVPDPOOL pVScsiVpdPool);
313
314/**
315 * Allocates a new page in the VPD page pool with the given number.
316 *
317 * @returns VBox status code.
318 * @retval VERR_ALREADY_EXIST if the page number is in use.
319 * @param pVScsiVpdPool The VPD page pool the page will belong to.
320 * @param uPage The page number, must be unique.
321 * @param cbPage Size of the page in bytes.
322 * @param ppbPage Where to store the pointer to the raw page data on success.
323 */
324int vscsiVpdPagePoolAllocNewPage(PVSCSIVPDPOOL pVScsiVpdPool, uint8_t uPage, size_t cbPage, uint8_t **ppbPage);
325
326/**
327 * Queries the given page from the pool and cpies it to the buffer given
328 * by the SCSI request.
329 *
330 * @returns VBox status code.
331 * @retval VERR_NOT_FOUND if the page is not in the pool.
332 * @param pVScsiVpdPool The VPD page pool to use.
333 * @param pVScsiReq The SCSI request.
334 * @param uPage Page to query.
335 */
336int vscsiVpdPagePoolQueryPage(PVSCSIVPDPOOL pVScsiVpdPool, PVSCSIREQINT pVScsiReq, uint8_t uPage);
337
338/**
339 * Inits the I/O request related state for the LUN.
340 *
341 * @returns VBox status code.
342 * @param pVScsiLun The LUN instance.
343 */
344int vscsiIoReqInit(PVSCSILUNINT pVScsiLun);
345
346/**
347 * Enqueues a new flush request
348 *
349 * @returns VBox status code.
350 * @param pVScsiLun The LUN instance which issued the request.
351 * @param pVScsiReq The virtual SCSI request associated with the flush.
352 */
353int vscsiIoReqFlushEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq);
354
355/**
356 * Enqueue a new data transfer request.
357 *
358 * @returns VBox status code.
359 * @param pVScsiLun The LUN instance which issued the request.
360 * @param pVScsiReq The virtual SCSI request associated with the transfer.
361 * @param enmTxDir Transfer direction.
362 * @param uOffset Start offset of the transfer.
363 * @param cbTransfer Number of bytes to transfer.
364 */
365int vscsiIoReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
366 VSCSIIOREQTXDIR enmTxDir, uint64_t uOffset,
367 size_t cbTransfer);
368
369/**
370 * Enqueue a new unmap request.
371 *
372 * @returns VBox status code.
373 * @param pVScsiLun The LUN instance which issued the request.
374 * @param pVScsiReq The virtual SCSI request associated with the transfer.
375 * @param paRanges The array of ranges to unmap.
376 * @param cRanges Number of ranges in the array.
377 */
378int vscsiIoReqUnmapEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
379 PRTRANGE paRanges, unsigned cRanges);
380
381/**
382 * Returns the current number of outstanding tasks on the given LUN.
383 *
384 * @returns Number of outstanding tasks.
385 * @param pVScsiLun The LUN to check.
386 */
387uint32_t vscsiIoReqOutstandingCountGet(PVSCSILUNINT pVScsiLun);
388
389/**
390 * Wrapper for the set I/O request allocation size I/O callback.
391 *
392 * @returns VBox status code.
393 * @param pVScsiLun The LUN.
394 * @param cbVScsiIoReqAlloc The additional size for the request to allocate.
395 */
396DECLINLINE(int) vscsiLunReqAllocSizeSet(PVSCSILUNINT pVScsiLun, size_t cbVScsiIoReqAlloc)
397{
398 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqAllocSizeSet(pVScsiLun,
399 pVScsiLun->pvVScsiLunUser,
400 cbVScsiIoReqAlloc);
401}
402
403/**
404 * Wrapper for the allocate I/O request I/O callback.
405 *
406 * @returns VBox status code.
407 * @param pVScsiLun The LUN.
408 * @param u64Tag A unique tag to assign to the request.
409 * @param ppVScsiIoReq Where to store the pointer to the request on success.
410 */
411DECLINLINE(int) vscsiLunReqAlloc(PVSCSILUNINT pVScsiLun, uint64_t u64Tag, PVSCSIIOREQINT *ppVScsiIoReq)
412{
413 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqAlloc(pVScsiLun,
414 pVScsiLun->pvVScsiLunUser,
415 u64Tag, ppVScsiIoReq);
416}
417
418/**
419 * Wrapper for the free I/O request I/O callback.
420 *
421 * @returns VBox status code.
422 * @param pVScsiLun The LUN.
423 * @param pVScsiIoReq The request to free.
424 */
425DECLINLINE(int) vscsiLunReqFree(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
426{
427 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqFree(pVScsiLun,
428 pVScsiLun->pvVScsiLunUser,
429 pVScsiIoReq);
430}
431
432/**
433 * Wrapper for the get medium size I/O callback.
434 *
435 * @returns VBox status code.
436 * @param pVScsiLun The LUN.
437 * @param pcbSize Where to store the size on success.
438 */
439DECLINLINE(int) vscsiLunMediumGetSize(PVSCSILUNINT pVScsiLun, uint64_t *pcbSize)
440{
441 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSize(pVScsiLun,
442 pVScsiLun->pvVScsiLunUser,
443 pcbSize);
444}
445
446/**
447 * Wrapper for the get medium sector size I/O callback.
448 *
449 * @returns VBox status code.
450 * @param pVScsiLun The LUN.
451 * @param pcbSectorSize Where to store the sector size on success.
452 */
453DECLINLINE(int) vscsiLunMediumGetSectorSize(PVSCSILUNINT pVScsiLun, uint32_t *pcbSectorSize)
454{
455 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSectorSize(pVScsiLun,
456 pVScsiLun->pvVScsiLunUser,
457 pcbSectorSize);
458}
459
460/**
461 * Wrapper for the get medium lock/unlock I/O callback.
462 *
463 * @returns VBox status code.
464 * @param pVScsiLun The LUN.
465 * @param bool The new medium lock state.
466 */
467DECLINLINE(int) vscsiLunMediumSetLock(PVSCSILUNINT pVScsiLun, bool fLocked)
468{
469 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumSetLock(pVScsiLun,
470 pVScsiLun->pvVScsiLunUser,
471 fLocked);
472}
473
474/**
475 * Wrapper for the eject medium I/O callback.
476 *
477 * @returns VBox status code.
478 * @param pVScsiLun The LUN.
479 */
480DECLINLINE(int) vscsiLunMediumEject(PVSCSILUNINT pVScsiLun)
481{
482 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumEject(pVScsiLun,
483 pVScsiLun->pvVScsiLunUser);
484}
485
486/**
487 * Wrapper for the I/O request enqueue I/O callback.
488 *
489 * @returns VBox status code.
490 * @param pVScsiLun The LUN.
491 * @param pVScsiIoReq The I/O request to enqueue.
492 */
493DECLINLINE(int) vscsiLunReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
494{
495 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqTransferEnqueue(pVScsiLun,
496 pVScsiLun->pvVScsiLunUser,
497 pVScsiIoReq);
498}
499
500/**
501 * Wrapper for the get feature flags I/O callback.
502 *
503 * @returns VBox status code.
504 * @param pVScsiLun The LUN.
505 * @param pVScsiIoReq The I/O request to enqueue.
506 */
507DECLINLINE(int) vscsiLunGetFeatureFlags(PVSCSILUNINT pVScsiLun, uint64_t *pfFeatures)
508{
509 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunGetFeatureFlags(pVScsiLun,
510 pVScsiLun->pvVScsiLunUser,
511 pfFeatures);
512}
513
514/**
515 * Wrapper around vscsiReqSenseOkSet()
516 */
517DECLINLINE(int) vscsiLunReqSenseOkSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
518{
519 return vscsiReqSenseOkSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq);
520}
521
522/**
523 * Wrapper around vscsiReqSenseErrorSet()
524 */
525DECLINLINE(int) vscsiLunReqSenseErrorSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ)
526{
527 return vscsiReqSenseErrorSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ);
528}
529
530/**
531 * Wrapper around vscsiReqSenseErrorInfoSet()
532 */
533DECLINLINE(int) vscsiLunReqSenseErrorInfoSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ, uint32_t uInfo)
534{
535 return vscsiReqSenseErrorInfoSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ, uInfo);
536}
537
538#endif /* ___VSCSIInternal_h */
539
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