992
* Maps the data buffer into R3.
984
* Allocate data buffer.
994
986
* @returns VBox status code.
995
987
* @param pTaskState Pointer to the task state.
996
* @param fReadonly Flag whether the mappings should be readonly.
998
static int buslogicMapGCDataBufIntoR3(PBUSLOGICTASKSTATE pTaskState, bool fReadonly)
989
static int buslogicDataBufferAlloc(PBUSLOGICTASKSTATE pTaskState)
1000
int rc = VINF_SUCCESS;
1001
uint32_t cScatterGatherEntriesR3 = 0;
1002
991
PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
1005
* @todo: Check following assumption and what residual means.
1007
* The BusLogic adapter can handle two different data buffer formats.
1008
* The first one is that the data pointer entry in the CCB points to
1009
* the buffer directly. In second mode the data pointer points to a
1010
* scatter gather list which describes the buffer.
1012
if ( (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
1013
|| (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
993
if ( (pTaskState->CommandControlBlockGuest.uDataDirection != BUSLOGIC_CCB_DIRECTION_NO_DATA)
994
&& (pTaskState->CommandControlBlockGuest.cbData > 0))
1015
uint32_t cScatterGatherGCRead;
1016
uint32_t iScatterGatherEntry;
1017
ScatterGatherEntry aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
1018
uint32_t cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
1019
RTGCPHYS GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1021
/* First pass - count needed R3 scatter gather list entries. */
1024
cScatterGatherGCRead = (cScatterGatherGCLeft < RT_ELEMENTS(aScatterGatherReadGC))
1025
? cScatterGatherGCLeft
1026
: RT_ELEMENTS(aScatterGatherReadGC);
1027
cScatterGatherGCLeft -= cScatterGatherGCRead;
1029
/* Read the SG entries. */
1030
PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
1031
cScatterGatherGCRead * sizeof(ScatterGatherEntry));
1033
for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
1035
RTGCPHYS GCPhysAddrDataBase;
1036
size_t cbDataToTransfer;
1038
Log(("%s: iScatterGatherEntry=%u\n", __FUNCTION__, iScatterGatherEntry));
1040
GCPhysAddrDataBase = (RTGCPHYS)aScatterGatherReadGC[iScatterGatherEntry].u32PhysAddrSegmentBase;
1041
cbDataToTransfer = aScatterGatherReadGC[iScatterGatherEntry].cbSegment;
1043
Log(("%s: GCPhysAddrDataBase=%RGp cbDataToTransfer=%u\n", __FUNCTION__, GCPhysAddrDataBase, cbDataToTransfer));
1046
* Check if the physical address is page aligned.
1048
if (GCPhysAddrDataBase & PAGE_OFFSET_MASK)
1050
RTGCPHYS GCPhysAddrDataNextPage = PAGE_ADDRESS(GCPhysAddrDataBase) + PAGE_SIZE;
1051
uint32_t u32GCPhysAddrDiff = GCPhysAddrDataNextPage - GCPhysAddrDataBase;
1053
Log(("%s: Align page: GCPhysAddrDataBase=%RGp GCPhysAddrDataNextPage=%RGp\n",
1054
__FUNCTION__, GCPhysAddrDataBase, GCPhysAddrDataNextPage));
1056
cScatterGatherEntriesR3++;
1057
/* Subtract size of the buffer in the actual page. */
1058
if (cbDataToTransfer < u32GCPhysAddrDiff)
1059
cbDataToTransfer = 0;
1061
cbDataToTransfer -= u32GCPhysAddrDiff;
1064
/* The address is now page aligned. */
1065
while (cbDataToTransfer)
1067
Log(("%s: GCPhysAddrDataBase=%RGp cbDataToTransfer=%u cScatterGatherEntriesR3=%u\n",
1068
__FUNCTION__, GCPhysAddrDataBase, cbDataToTransfer, cScatterGatherEntriesR3));
1070
cScatterGatherEntriesR3++;
1072
/* Check if this is the last page the buffer is in. */
1073
if (cbDataToTransfer < PAGE_SIZE)
1074
cbDataToTransfer = 0;
1076
cbDataToTransfer -= PAGE_SIZE;
1080
/* Set address to the next entries to read. */
1081
GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
1082
} while (cScatterGatherGCLeft);
1084
Log(("%s: cScatterGatherEntriesR3=%u\n", __FUNCTION__, cScatterGatherEntriesR3));
1087
* Allocate page map lock and scatter gather array.
1088
* @todo: Optimize with caching.
997
* @todo: Check following assumption and what residual means.
999
* The BusLogic adapter can handle two different data buffer formats.
1000
* The first one is that the data pointer entry in the CCB points to
1001
* the buffer directly. In second mode the data pointer points to a
1002
* scatter gather list which describes the buffer.
1090
AssertMsg(!pTaskState->paPageLock && !pTaskState->paScatterGather, ("paPageLock or/and paScatterGather are not NULL\n"));
1091
pTaskState->cScatterGather = cScatterGatherEntriesR3;
1092
pTaskState->cbScatterGather = 0;
1093
pTaskState->paPageLock = (PPGMPAGEMAPLOCK)RTMemAllocZ(cScatterGatherEntriesR3 * sizeof(PGMPAGEMAPLOCK));
1094
AssertMsgReturn(pTaskState->paPageLock, ("Allocating page lock array failed\n"), VERR_NO_MEMORY);
1095
pTaskState->paScatterGather = (PPDMDATASEG)RTMemAllocZ(cScatterGatherEntriesR3 * sizeof(PDMDATASEG));
1096
AssertMsgReturn(pTaskState->paScatterGather, ("Allocating page lock array failed\n"), VERR_NO_MEMORY);
1098
/* Second pass - map the elements into R3. **/
1099
cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
1100
GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1101
PPGMPAGEMAPLOCK pPageLockCurrent = pTaskState->paPageLock;
1102
PPDMDATASEG pScatterGatherCurrent = pTaskState->paScatterGather;
1004
if ( (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
1005
|| (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
1106
cScatterGatherGCRead = (cScatterGatherGCLeft < RT_ELEMENTS(aScatterGatherReadGC)) ? cScatterGatherGCLeft : RT_ELEMENTS(aScatterGatherReadGC);
1107
cScatterGatherGCLeft -= cScatterGatherGCRead;
1109
/* Read the SG entries. */
1110
PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0], cScatterGatherGCRead * sizeof(ScatterGatherEntry));
1112
for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
1114
RTGCPHYS GCPhysAddrDataBase;
1115
uint32_t cbDataToTransfer;
1117
GCPhysAddrDataBase = (RTGCPHYS)aScatterGatherReadGC[iScatterGatherEntry].u32PhysAddrSegmentBase;
1118
cbDataToTransfer = aScatterGatherReadGC[iScatterGatherEntry].cbSegment;
1119
pTaskState->cbScatterGather += cbDataToTransfer;
1122
* Check if the physical address is page aligned.
1124
if (GCPhysAddrDataBase & PAGE_OFFSET_MASK)
1126
RTGCPHYS GCPhysAddrDataNextPage = PAGE_ADDRESS(GCPhysAddrDataBase) + PAGE_SIZE;
1127
uint32_t u32GCPhysAddrDiff = GCPhysAddrDataNextPage - GCPhysAddrDataBase; /* Difference from the buffer start to the next page boundary. */
1129
/* Check if the mapping ends at the page boundary and set segment size accordingly. */
1130
pScatterGatherCurrent->cbSeg = (cbDataToTransfer < u32GCPhysAddrDiff) ? cbDataToTransfer : u32GCPhysAddrDiff;
1132
/* Create the mapping. */
1134
rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, PAGE_ADDRESS(GCPhysAddrDataBase), 0, (const void **)&pScatterGatherCurrent->pvSeg, pPageLockCurrent); /** @todo r=bird: PAGE_ADDRESS is the wrong macro here as well... */
1136
rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, PAGE_ADDRESS(GCPhysAddrDataBase), 0, &pScatterGatherCurrent->pvSeg, pPageLockCurrent);
1139
AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc));
1141
/* Let pvBuf point to the start of the buffer in the page. */
1142
pScatterGatherCurrent->pvSeg = ((uint8_t *)pScatterGatherCurrent->pvSeg) + (GCPhysAddrDataBase - PAGE_ADDRESS(GCPhysAddrDataBase));
1144
/* Subtract size of the buffer in the actual page. */
1145
cbDataToTransfer -= (uint32_t)pScatterGatherCurrent->cbSeg;
1147
pScatterGatherCurrent++;
1148
/* Let physical address point to the next page in the buffer. */
1149
GCPhysAddrDataBase = GCPhysAddrDataNextPage;
1152
/* The address is now page aligned. */
1153
while (cbDataToTransfer)
1155
/* Check if this is the last page the buffer is in. */
1156
if (cbDataToTransfer < PAGE_SIZE)
1158
pScatterGatherCurrent->cbSeg = cbDataToTransfer;
1159
cbDataToTransfer = 0;
1163
cbDataToTransfer -= PAGE_SIZE;
1164
pScatterGatherCurrent->cbSeg = PAGE_SIZE;
1167
/* Create the mapping. */
1169
rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhysAddrDataBase, 0, (const void **)&pScatterGatherCurrent->pvSeg, pPageLockCurrent);
1171
rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, GCPhysAddrDataBase, 0, &pScatterGatherCurrent->pvSeg, pPageLockCurrent);
1174
AssertMsgFailed(("Creating mapping failed rc=%Rrc\n", rc));
1176
/* Go to the next page. */
1177
GCPhysAddrDataBase += PAGE_SIZE;
1179
pScatterGatherCurrent++;
1007
uint32_t cScatterGatherGCRead;
1008
uint32_t iScatterGatherEntry;
1009
ScatterGatherEntry aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
1010
uint32_t cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
1011
RTGCPHYS GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1012
size_t cbDataToTransfer = 0;
1014
/* Count number of bytes to transfer. */
1017
cScatterGatherGCRead = (cScatterGatherGCLeft < RT_ELEMENTS(aScatterGatherReadGC))
1018
? cScatterGatherGCLeft
1019
: RT_ELEMENTS(aScatterGatherReadGC);
1020
cScatterGatherGCLeft -= cScatterGatherGCRead;
1022
/* Read the SG entries. */
1023
PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
1024
cScatterGatherGCRead * sizeof(ScatterGatherEntry));
1026
for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
1028
RTGCPHYS GCPhysAddrDataBase;
1030
Log(("%s: iScatterGatherEntry=%u\n", __FUNCTION__, iScatterGatherEntry));
1032
GCPhysAddrDataBase = (RTGCPHYS)aScatterGatherReadGC[iScatterGatherEntry].u32PhysAddrSegmentBase;
1033
cbDataToTransfer += aScatterGatherReadGC[iScatterGatherEntry].cbSegment;
1035
Log(("%s: GCPhysAddrDataBase=%RGp cbDataToTransfer=%u\n",
1036
__FUNCTION__, GCPhysAddrDataBase,
1037
aScatterGatherReadGC[iScatterGatherEntry].cbSegment));
1040
/* Set address to the next entries to read. */
1041
GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
1042
} while (cScatterGatherGCLeft > 0);
1044
Log((": cbDataToTransfer=%d\n", cbDataToTransfer));
1046
/* Allocate buffer */
1047
pTaskState->DataSeg.cbSeg = cbDataToTransfer;
1048
pTaskState->DataSeg.pvSeg = RTMemAlloc(pTaskState->DataSeg.cbSeg);
1049
if (!pTaskState->DataSeg.pvSeg)
1050
return VERR_NO_MEMORY;
1052
/* Copy the data if needed */
1053
if (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_OUT)
1055
cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
1056
GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1057
uint8_t *pbData = (uint8_t *)pTaskState->DataSeg.pvSeg;
1061
cScatterGatherGCRead = (cScatterGatherGCLeft < RT_ELEMENTS(aScatterGatherReadGC))
1062
? cScatterGatherGCLeft
1063
: RT_ELEMENTS(aScatterGatherReadGC);
1064
cScatterGatherGCLeft -= cScatterGatherGCRead;
1066
/* Read the SG entries. */
1067
PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
1068
cScatterGatherGCRead * sizeof(ScatterGatherEntry));
1070
for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
1072
RTGCPHYS GCPhysAddrDataBase;
1074
Log(("%s: iScatterGatherEntry=%u\n", __FUNCTION__, iScatterGatherEntry));
1076
GCPhysAddrDataBase = (RTGCPHYS)aScatterGatherReadGC[iScatterGatherEntry].u32PhysAddrSegmentBase;
1077
cbDataToTransfer = aScatterGatherReadGC[iScatterGatherEntry].cbSegment;
1079
Log(("%s: GCPhysAddrDataBase=%RGp cbDataToTransfer=%u\n", __FUNCTION__, GCPhysAddrDataBase, cbDataToTransfer));
1081
PDMDevHlpPhysRead(pDevIns, GCPhysAddrDataBase, pbData, cbDataToTransfer);
1082
pbData += cbDataToTransfer;
1085
/* Set address to the next entries to read. */
1086
GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
1087
} while (cScatterGatherGCLeft > 0);
1183
/* Set address to the next entries to read. */
1184
GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
1186
} while (cScatterGatherGCLeft);
1189
else if ( (pTaskState->CommandControlBlockGuest.u32PhysAddrData != 0)
1190
&& (pTaskState->CommandControlBlockGuest.cbData != 0))
1192
/* The buffer is not scattered. */
1193
RTGCPHYS GCPhysAddrDataBase = (RTGCPHYS)PAGE_ADDRESS(pTaskState->CommandControlBlockGuest.u32PhysAddrData);
1194
RTGCPHYS GCPhysAddrDataEnd = (RTGCPHYS)(pTaskState->CommandControlBlockGuest.u32PhysAddrData + pTaskState->CommandControlBlockGuest.cbData);
1195
RTGCPHYS GCPhysAddrDataEndBase = (RTGCPHYS)PAGE_ADDRESS(GCPhysAddrDataEnd);
1196
RTGCPHYS GCPhysAddrDataNext = (RTGCPHYS)PAGE_ADDRESS(GCPhysAddrDataEnd) + PAGE_SIZE;
1197
uint32_t cPages = (GCPhysAddrDataNext - GCPhysAddrDataBase) / PAGE_SIZE;
1198
uint32_t cbOffsetFirstPage = pTaskState->CommandControlBlockGuest.u32PhysAddrData & PAGE_OFFSET_MASK;
1200
Log(("Non scattered buffer:\n"));
1201
Log(("u32PhysAddrData=%#x\n", pTaskState->CommandControlBlockGuest.u32PhysAddrData));
1202
Log(("cbData=%u\n", pTaskState->CommandControlBlockGuest.cbData));
1203
Log(("GCPhysAddrDataBase=0x%RGp\n", GCPhysAddrDataBase));
1204
Log(("GCPhysAddrDataEnd=0x%RGp\n", GCPhysAddrDataEnd));
1205
Log(("GCPhysAddrDataEndBase=0x%RGp\n", GCPhysAddrDataEndBase));
1206
Log(("GCPhysAddrDataNext=0x%RGp\n", GCPhysAddrDataNext));
1207
Log(("cPages=%u\n", cPages));
1209
pTaskState->paPageLock = (PPGMPAGEMAPLOCK)RTMemAllocZ(cPages * sizeof(PGMPAGEMAPLOCK));
1210
AssertMsgReturn(pTaskState->paPageLock, ("Allocating page lock array failed\n"), VERR_NO_MEMORY);
1211
pTaskState->paScatterGather = (PPDMDATASEG)RTMemAllocZ(cPages * sizeof(PDMDATASEG));
1212
AssertMsgReturn(pTaskState->paScatterGather, ("Allocating scatter gather list failed\n"), VERR_NO_MEMORY);
1214
PPGMPAGEMAPLOCK pPageLockCurrent = pTaskState->paPageLock;
1215
PPDMDATASEG pScatterGatherCurrent = pTaskState->paScatterGather;
1217
for (uint32_t i = 0; i < cPages; i++)
1091
else if (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB)
1220
rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhysAddrDataBase, 0, (const void **)&pScatterGatherCurrent->pvSeg, pPageLockCurrent);
1222
rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, GCPhysAddrDataBase, 0, &pScatterGatherCurrent->pvSeg, pPageLockCurrent);
1224
pScatterGatherCurrent->cbSeg = PAGE_SIZE;
1227
pScatterGatherCurrent++;
1228
GCPhysAddrDataBase += PAGE_SIZE;
1093
/* The buffer is not scattered. */
1094
RTGCPHYS GCPhysAddrDataBase = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1096
AssertMsg(GCPhysAddrDataBase != 0, ("Physical address is 0\n"));
1098
pTaskState->DataSeg.cbSeg = pTaskState->CommandControlBlockGuest.cbData;
1099
pTaskState->DataSeg.pvSeg = RTMemAlloc(pTaskState->DataSeg.cbSeg);
1100
if (!pTaskState->DataSeg.pvSeg)
1101
return VERR_NO_MEMORY;
1103
Log(("Non scattered buffer:\n"));
1104
Log(("u32PhysAddrData=%#x\n", pTaskState->CommandControlBlockGuest.u32PhysAddrData));
1105
Log(("cbData=%u\n", pTaskState->CommandControlBlockGuest.cbData));
1106
Log(("GCPhysAddrDataBase=0x%RGp\n", GCPhysAddrDataBase));
1108
/* Copy the data into the buffer. */
1109
PDMDevHlpPhysRead(pDevIns, GCPhysAddrDataBase, pTaskState->DataSeg.pvSeg, pTaskState->DataSeg.cbSeg);
1231
/* Correct pointer of the first entry. */
1232
pTaskState->paScatterGather[0].pvSeg = (uint8_t *)pTaskState->paScatterGather[0].pvSeg + cbOffsetFirstPage;
1233
pTaskState->paScatterGather[0].cbSeg -= cbOffsetFirstPage;
1234
/* Correct size of the last entry. */
1235
pTaskState->paScatterGather[cPages-1].cbSeg = GCPhysAddrDataEnd - GCPhysAddrDataEndBase;
1236
pTaskState->cScatterGather = cPages;
1237
pTaskState->cbScatterGather = pTaskState->CommandControlBlockGuest.cbData;
1113
return VINF_SUCCESS;
1244
* Free mapped pages and other allocated resources used for the scatter gather list.
1117
* Free allocated resources used for the scatter gather list.
1246
1119
* @returns nothing.
1247
1120
* @param pTaskState Pointer to the task state.
1249
static void buslogicFreeGCDataBuffer(PBUSLOGICTASKSTATE pTaskState)
1122
static void buslogicDataBufferFree(PBUSLOGICTASKSTATE pTaskState)
1251
PPGMPAGEMAPLOCK pPageMapLock = pTaskState->paPageLock;
1252
PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
1124
PPDMDEVINS pDevIns = pTaskState->CTX_SUFF(pTargetDevice)->CTX_SUFF(pBusLogic)->CTX_SUFF(pDevIns);
1254
for (uint32_t iPageLockCurrent = 0; iPageLockCurrent < pTaskState->cScatterGather; iPageLockCurrent++)
1126
if ( (pTaskState->CommandControlBlockGuest.cbData > 0)
1127
&& ( (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_IN)
1128
|| (pTaskState->CommandControlBlockGuest.uDataDirection == BUSLOGIC_CCB_DIRECTION_UNKNOWN)))
1256
PDMDevHlpPhysReleasePageMappingLock(pDevIns, pPageMapLock);
1130
if ( (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_SCATTER_GATHER)
1131
|| (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB_RESIDUAL_SCATTER_GATHER))
1133
uint32_t cScatterGatherGCRead;
1134
uint32_t iScatterGatherEntry;
1135
ScatterGatherEntry aScatterGatherReadGC[32]; /* Number of scatter gather list entries read from guest memory. */
1136
uint32_t cScatterGatherGCLeft = pTaskState->CommandControlBlockGuest.cbData / sizeof(ScatterGatherEntry);
1137
RTGCPHYS GCPhysAddrScatterGatherCurrent = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1138
uint8_t *pbData = (uint8_t *)pTaskState->DataSeg.pvSeg;
1142
cScatterGatherGCRead = (cScatterGatherGCLeft < RT_ELEMENTS(aScatterGatherReadGC))
1143
? cScatterGatherGCLeft
1144
: RT_ELEMENTS(aScatterGatherReadGC);
1145
cScatterGatherGCLeft -= cScatterGatherGCRead;
1147
/* Read the SG entries. */
1148
PDMDevHlpPhysRead(pDevIns, GCPhysAddrScatterGatherCurrent, &aScatterGatherReadGC[0],
1149
cScatterGatherGCRead * sizeof(ScatterGatherEntry));
1151
for (iScatterGatherEntry = 0; iScatterGatherEntry < cScatterGatherGCRead; iScatterGatherEntry++)
1153
RTGCPHYS GCPhysAddrDataBase;
1154
size_t cbDataToTransfer;
1156
Log(("%s: iScatterGatherEntry=%u\n", __FUNCTION__, iScatterGatherEntry));
1158
GCPhysAddrDataBase = (RTGCPHYS)aScatterGatherReadGC[iScatterGatherEntry].u32PhysAddrSegmentBase;
1159
cbDataToTransfer = aScatterGatherReadGC[iScatterGatherEntry].cbSegment;
1161
Log(("%s: GCPhysAddrDataBase=%RGp cbDataToTransfer=%u\n", __FUNCTION__, GCPhysAddrDataBase, cbDataToTransfer));
1163
PDMDevHlpPhysWrite(pDevIns, GCPhysAddrDataBase, pbData, cbDataToTransfer);
1164
pbData += cbDataToTransfer;
1167
/* Set address to the next entries to read. */
1168
GCPhysAddrScatterGatherCurrent += cScatterGatherGCRead * sizeof(ScatterGatherEntry);
1169
} while (cScatterGatherGCLeft > 0);
1172
else if (pTaskState->CommandControlBlockGuest.uOpcode == BUSLOGIC_CCB_OPCODE_INITIATOR_CCB)
1174
/* The buffer is not scattered. */
1175
RTGCPHYS GCPhysAddrDataBase = (RTGCPHYS)pTaskState->CommandControlBlockGuest.u32PhysAddrData;
1177
AssertMsg(GCPhysAddrDataBase != 0, ("Physical address is 0\n"));
1179
Log(("Non scattered buffer:\n"));
1180
Log(("u32PhysAddrData=%#x\n", pTaskState->CommandControlBlockGuest.u32PhysAddrData));
1181
Log(("cbData=%u\n", pTaskState->CommandControlBlockGuest.cbData));
1182
Log(("GCPhysAddrDataBase=0x%RGp\n", GCPhysAddrDataBase));
1184
/* Copy the data into the guest memory. */
1185
PDMDevHlpPhysWrite(pDevIns, GCPhysAddrDataBase, pTaskState->DataSeg.pvSeg, pTaskState->DataSeg.cbSeg);
1260
/* @todo: optimize with caching. */
1261
RTMemFree(pTaskState->paPageLock);
1262
RTMemFree(pTaskState->paScatterGather);
1263
pTaskState->paPageLock = NULL;
1264
pTaskState->paScatterGather = NULL;
1265
pTaskState->cScatterGather = 0;
1266
pTaskState->cbScatterGather = 0;
1189
RTMemFree(pTaskState->DataSeg.pvSeg);
1190
pTaskState->DataSeg.pvSeg = NULL;
1191
pTaskState->DataSeg.cbSeg = 0;