VirtualBox

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

Last change on this file since 61541 was 56292, checked in by vboxsync, 10 years ago

Devices: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1/* $Id: VSCSIInternal.h 56292 2015-06-09 14:20:46Z vboxsync $ */
2/** @file
3 * Virtual SCSI driver: Internal defines
4 */
5
6/*
7 * Copyright (C) 2006-2015 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 * Enqueues a new flush request
324 *
325 * @returns VBox status code.
326 * @param pVScsiLun The LUN instance which issued the request.
327 * @param pVScsiReq The virtual SCSI request associated with the flush.
328 */
329int vscsiIoReqFlushEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq);
330
331/**
332 * Enqueue a new data transfer request.
333 *
334 * @returns VBox status code.
335 * @param pVScsiLun The LUN instance which issued the request.
336 * @param pVScsiReq The virtual SCSI request associated with the transfer.
337 * @param enmTxDir Transfer direction.
338 * @param uOffset Start offset of the transfer.
339 * @param cbTransfer Number of bytes to transfer.
340 */
341int vscsiIoReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
342 VSCSIIOREQTXDIR enmTxDir, uint64_t uOffset,
343 size_t cbTransfer);
344
345/**
346 * Enqueue a new unmap request.
347 *
348 * @returns VBox status code.
349 * @param pVScsiLun The LUN instance which issued the request.
350 * @param pVScsiReq The virtual SCSI request associated with the transfer.
351 * @param paRanges The array of ranges to unmap.
352 * @param cRanges Number of ranges in the array.
353 */
354int vscsiIoReqUnmapEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
355 PRTRANGE paRanges, unsigned cRanges);
356
357/**
358 * Returns the current number of outstanding tasks on the given LUN.
359 *
360 * @returns Number of outstanding tasks.
361 * @param pVScsiLun The LUN to check.
362 */
363uint32_t vscsiIoReqOutstandingCountGet(PVSCSILUNINT pVScsiLun);
364
365/**
366 * Wrapper for the get medium size I/O callback.
367 *
368 * @returns VBox status code.
369 * @param pVScsiLun The LUN.
370 * @param pcbSize Where to store the size on success.
371 */
372DECLINLINE(int) vscsiLunMediumGetSize(PVSCSILUNINT pVScsiLun, uint64_t *pcbSize)
373{
374 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSize(pVScsiLun,
375 pVScsiLun->pvVScsiLunUser,
376 pcbSize);
377}
378
379/**
380 * Wrapper for the get medium sector size I/O callback.
381 *
382 * @returns VBox status code.
383 * @param pVScsiLun The LUN.
384 * @param pcbSectorSize Where to store the sector size on success.
385 */
386DECLINLINE(int) vscsiLunMediumGetSectorSize(PVSCSILUNINT pVScsiLun, uint32_t *pcbSectorSize)
387{
388 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumGetSectorSize(pVScsiLun,
389 pVScsiLun->pvVScsiLunUser,
390 pcbSectorSize);
391}
392
393/**
394 * Wrapper for the get medium lock/unlock I/O callback.
395 *
396 * @returns VBox status code.
397 * @param pVScsiLun The LUN.
398 * @param bool The new medium lock state.
399 */
400DECLINLINE(int) vscsiLunMediumSetLock(PVSCSILUNINT pVScsiLun, bool fLocked)
401{
402 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunMediumSetLock(pVScsiLun,
403 pVScsiLun->pvVScsiLunUser,
404 fLocked);
405}
406
407/**
408 * Wrapper for the I/O request enqueue I/O callback.
409 *
410 * @returns VBox status code.
411 * @param pVScsiLun The LUN.
412 * @param pVScsiIoReq The I/O request to enqueue.
413 */
414DECLINLINE(int) vscsiLunReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIIOREQINT pVScsiIoReq)
415{
416 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunReqTransferEnqueue(pVScsiLun,
417 pVScsiLun->pvVScsiLunUser,
418 pVScsiIoReq);
419}
420
421/**
422 * Wrapper for the get feature flags I/O callback.
423 *
424 * @returns VBox status code.
425 * @param pVScsiLun The LUN.
426 * @param pVScsiIoReq The I/O request to enqueue.
427 */
428DECLINLINE(int) vscsiLunGetFeatureFlags(PVSCSILUNINT pVScsiLun, uint64_t *pfFeatures)
429{
430 return pVScsiLun->pVScsiLunIoCallbacks->pfnVScsiLunGetFeatureFlags(pVScsiLun,
431 pVScsiLun->pvVScsiLunUser,
432 pfFeatures);
433}
434
435/**
436 * Wrapper around vscsiReqSenseOkSet()
437 */
438DECLINLINE(int) vscsiLunReqSenseOkSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
439{
440 return vscsiReqSenseOkSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq);
441}
442
443/**
444 * Wrapper around vscsiReqSenseErrorSet()
445 */
446DECLINLINE(int) vscsiLunReqSenseErrorSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ)
447{
448 return vscsiReqSenseErrorSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ);
449}
450
451/**
452 * Wrapper around vscsiReqSenseErrorInfoSet()
453 */
454DECLINLINE(int) vscsiLunReqSenseErrorInfoSet(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint8_t uSCSISenseKey, uint8_t uSCSIASC, uint8_t uSCSIASCQ, uint32_t uInfo)
455{
456 return vscsiReqSenseErrorInfoSet(&pVScsiLun->pVScsiDevice->VScsiSense, pVScsiReq, uSCSISenseKey, uSCSIASC, uSCSIASCQ, uInfo);
457}
458
459#endif /* ___VSCSIInternal_h */
460
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