VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp@ 77329

Last change on this file since 77329 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: VSCSIIoReq.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * Virtual SCSI driver: I/O request handling.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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#define LOG_GROUP LOG_GROUP_VSCSI
18#include <VBox/log.h>
19#include <iprt/errcore.h>
20#include <VBox/types.h>
21#include <VBox/vscsi.h>
22#include <iprt/assert.h>
23#include <iprt/mem.h>
24#include <iprt/asm.h>
25
26#include "VSCSIInternal.h"
27
28int vscsiIoReqInit(PVSCSILUNINT pVScsiLun)
29{
30 return vscsiLunReqAllocSizeSet(pVScsiLun, sizeof(VSCSIIOREQINT));
31}
32
33int vscsiIoReqFlushEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
34{
35 int rc = VINF_SUCCESS;
36 PVSCSIIOREQINT pVScsiIoReq = NULL;
37
38 rc = vscsiLunReqAlloc(pVScsiLun, (uintptr_t)pVScsiReq, &pVScsiIoReq);
39 if (RT_SUCCESS(rc))
40 {
41 pVScsiIoReq->pVScsiReq = pVScsiReq;
42 pVScsiIoReq->pVScsiLun = pVScsiLun;
43 pVScsiIoReq->enmTxDir = VSCSIIOREQTXDIR_FLUSH;
44
45 ASMAtomicIncU32(&pVScsiLun->IoReq.cReqOutstanding);
46
47 rc = vscsiLunReqTransferEnqueue(pVScsiLun, pVScsiIoReq);
48 if (RT_FAILURE(rc))
49 {
50 ASMAtomicDecU32(&pVScsiLun->IoReq.cReqOutstanding);
51 vscsiLunReqFree(pVScsiLun, pVScsiIoReq);
52 }
53 }
54
55 return rc;
56}
57
58
59int vscsiIoReqTransferEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
60 VSCSIIOREQTXDIR enmTxDir, uint64_t uOffset,
61 size_t cbTransfer)
62{
63 int rc = VINF_SUCCESS;
64 PVSCSIIOREQINT pVScsiIoReq = NULL;
65
66 LogFlowFunc(("pVScsiLun=%#p pVScsiReq=%#p enmTxDir=%u uOffset=%llu cbTransfer=%u\n",
67 pVScsiLun, pVScsiReq, enmTxDir, uOffset, cbTransfer));
68
69 rc = vscsiLunReqAlloc(pVScsiLun, (uintptr_t)pVScsiReq, &pVScsiIoReq);
70 if (RT_SUCCESS(rc))
71 {
72 pVScsiIoReq->pVScsiReq = pVScsiReq;
73 pVScsiIoReq->pVScsiLun = pVScsiLun;
74 pVScsiIoReq->enmTxDir = enmTxDir;
75 pVScsiIoReq->u.Io.uOffset = uOffset;
76 pVScsiIoReq->u.Io.cbTransfer = cbTransfer;
77 pVScsiIoReq->u.Io.paSeg = pVScsiReq->SgBuf.paSegs;
78 pVScsiIoReq->u.Io.cSeg = pVScsiReq->SgBuf.cSegs;
79
80 ASMAtomicIncU32(&pVScsiLun->IoReq.cReqOutstanding);
81
82 rc = vscsiLunReqTransferEnqueue(pVScsiLun, pVScsiIoReq);
83 if (RT_FAILURE(rc))
84 {
85 ASMAtomicDecU32(&pVScsiLun->IoReq.cReqOutstanding);
86 vscsiLunReqFree(pVScsiLun, pVScsiIoReq);
87 }
88 }
89
90 return rc;
91}
92
93
94int vscsiIoReqTransferEnqueueEx(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
95 VSCSIIOREQTXDIR enmTxDir, uint64_t uOffset,
96 PCRTSGSEG paSegs, unsigned cSegs, size_t cbTransfer)
97{
98 int rc = VINF_SUCCESS;
99 PVSCSIIOREQINT pVScsiIoReq = NULL;
100
101 LogFlowFunc(("pVScsiLun=%#p pVScsiReq=%#p enmTxDir=%u uOffset=%llu cbTransfer=%u\n",
102 pVScsiLun, pVScsiReq, enmTxDir, uOffset, cbTransfer));
103
104 rc = vscsiLunReqAlloc(pVScsiLun, (uintptr_t)pVScsiReq, &pVScsiIoReq);
105 if (RT_SUCCESS(rc))
106 {
107 pVScsiIoReq->pVScsiReq = pVScsiReq;
108 pVScsiIoReq->pVScsiLun = pVScsiLun;
109 pVScsiIoReq->enmTxDir = enmTxDir;
110 pVScsiIoReq->u.Io.uOffset = uOffset;
111 pVScsiIoReq->u.Io.cbTransfer = cbTransfer;
112 pVScsiIoReq->u.Io.paSeg = paSegs;
113 pVScsiIoReq->u.Io.cSeg = cSegs;
114
115 ASMAtomicIncU32(&pVScsiLun->IoReq.cReqOutstanding);
116
117 rc = vscsiLunReqTransferEnqueue(pVScsiLun, pVScsiIoReq);
118 if (RT_FAILURE(rc))
119 {
120 ASMAtomicDecU32(&pVScsiLun->IoReq.cReqOutstanding);
121 vscsiLunReqFree(pVScsiLun, pVScsiIoReq);
122 }
123 }
124
125 return rc;
126}
127
128
129int vscsiIoReqUnmapEnqueue(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq,
130 PRTRANGE paRanges, unsigned cRanges)
131{
132 int rc = VINF_SUCCESS;
133 PVSCSIIOREQINT pVScsiIoReq = NULL;
134
135 LogFlowFunc(("pVScsiLun=%#p pVScsiReq=%#p paRanges=%#p cRanges=%u\n",
136 pVScsiLun, pVScsiReq, paRanges, cRanges));
137
138 rc = vscsiLunReqAlloc(pVScsiLun, (uintptr_t)pVScsiReq, &pVScsiIoReq);
139 if (RT_SUCCESS(rc))
140 {
141 pVScsiIoReq->pVScsiReq = pVScsiReq;
142 pVScsiIoReq->pVScsiLun = pVScsiLun;
143 pVScsiIoReq->enmTxDir = VSCSIIOREQTXDIR_UNMAP;
144 pVScsiIoReq->u.Unmap.paRanges = paRanges;
145 pVScsiIoReq->u.Unmap.cRanges = cRanges;
146
147 ASMAtomicIncU32(&pVScsiLun->IoReq.cReqOutstanding);
148
149 rc = vscsiLunReqTransferEnqueue(pVScsiLun, pVScsiIoReq);
150 if (RT_FAILURE(rc))
151 {
152 ASMAtomicDecU32(&pVScsiLun->IoReq.cReqOutstanding);
153 vscsiLunReqFree(pVScsiLun, pVScsiIoReq);
154 }
155 }
156
157 return rc;
158}
159
160
161uint32_t vscsiIoReqOutstandingCountGet(PVSCSILUNINT pVScsiLun)
162{
163 return ASMAtomicReadU32(&pVScsiLun->IoReq.cReqOutstanding);
164}
165
166
167VBOXDDU_DECL(int) VSCSIIoReqCompleted(VSCSIIOREQ hVScsiIoReq, int rcIoReq, bool fRedoPossible)
168{
169 PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq;
170 PVSCSILUNINT pVScsiLun;
171 PVSCSIREQINT pVScsiReq;
172 int rcReq = SCSI_STATUS_OK;
173
174 AssertPtrReturn(pVScsiIoReq, VERR_INVALID_HANDLE);
175
176 LogFlowFunc(("hVScsiIoReq=%#p rcIoReq=%Rrc\n", hVScsiIoReq, rcIoReq));
177
178 pVScsiLun = pVScsiIoReq->pVScsiLun;
179 pVScsiReq = pVScsiIoReq->pVScsiReq;
180
181 AssertMsg(pVScsiLun->IoReq.cReqOutstanding > 0,
182 ("Unregistered I/O request completed\n"));
183
184 ASMAtomicDecU32(&pVScsiLun->IoReq.cReqOutstanding);
185
186 if (RT_SUCCESS(rcIoReq))
187 rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
188 else if (!fRedoPossible)
189 {
190 /** @todo Not 100% correct for the write case as the 0x00 ASCQ for write errors
191 * is not used for SBC devices. */
192 rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_MEDIUM_ERROR,
193 pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_READ
194 ? SCSI_ASC_READ_ERROR
195 : SCSI_ASC_WRITE_ERROR,
196 0x00);
197 }
198 else
199 rcReq = SCSI_STATUS_CHECK_CONDITION;
200
201 if (pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_UNMAP)
202 RTMemFree(pVScsiIoReq->u.Unmap.paRanges);
203
204 /* Free the I/O request */
205 vscsiLunReqFree(pVScsiLun, pVScsiIoReq);
206
207 /* Notify completion of the SCSI request. */
208 vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, fRedoPossible, rcIoReq);
209
210 return VINF_SUCCESS;
211}
212
213
214VBOXDDU_DECL(VSCSIIOREQTXDIR) VSCSIIoReqTxDirGet(VSCSIIOREQ hVScsiIoReq)
215{
216 PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq;
217
218 AssertPtrReturn(pVScsiIoReq, VSCSIIOREQTXDIR_INVALID);
219
220 return pVScsiIoReq->enmTxDir;
221}
222
223
224VBOXDDU_DECL(int) VSCSIIoReqParamsGet(VSCSIIOREQ hVScsiIoReq, uint64_t *puOffset,
225 size_t *pcbTransfer, unsigned *pcSeg,
226 size_t *pcbSeg, PCRTSGSEG *ppaSeg)
227{
228 PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq;
229
230 AssertPtrReturn(pVScsiIoReq, VERR_INVALID_HANDLE);
231 AssertReturn( pVScsiIoReq->enmTxDir != VSCSIIOREQTXDIR_FLUSH
232 && pVScsiIoReq->enmTxDir != VSCSIIOREQTXDIR_UNMAP,
233 VERR_NOT_SUPPORTED);
234
235 *puOffset = pVScsiIoReq->u.Io.uOffset;
236 *pcbTransfer = pVScsiIoReq->u.Io.cbTransfer;
237 *pcSeg = pVScsiIoReq->u.Io.cSeg;
238 *pcbSeg = pVScsiIoReq->u.Io.cbSeg;
239 *ppaSeg = pVScsiIoReq->u.Io.paSeg;
240
241 return VINF_SUCCESS;
242}
243
244VBOXDDU_DECL(int) VSCSIIoReqUnmapParamsGet(VSCSIIOREQ hVScsiIoReq, PCRTRANGE *ppaRanges,
245 unsigned *pcRanges)
246{
247 PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq;
248
249 AssertPtrReturn(pVScsiIoReq, VERR_INVALID_HANDLE);
250 AssertReturn(pVScsiIoReq->enmTxDir == VSCSIIOREQTXDIR_UNMAP, VERR_NOT_SUPPORTED);
251
252 *ppaRanges = pVScsiIoReq->u.Unmap.paRanges;
253 *pcRanges = pVScsiIoReq->u.Unmap.cRanges;
254
255 return VINF_SUCCESS;
256}
257
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