Changeset 44256 in vbox for trunk/src/VBox
- Timestamp:
- Jan 8, 2013 3:45:57 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/ISCSI.cpp
r44252 r44256 336 336 typedef struct SCSIREQ 337 337 { 338 /** I/O context associated with this request. */ 339 PVDIOCTX pIoCtx; 338 340 /** Transfer direction. */ 339 341 SCSIXFER enmXfer; … … 349 351 /** Completion status of the command. */ 350 352 uint8_t status; 351 /** Pointer to command block. */ 352 void *pvCDB; 353 /** Pointer to sense buffer. */ 354 void *pvSense; 353 /** The CDB. */ 354 uint8_t abCDB[16]; 355 /** The sense buffer. */ 356 uint8_t abSense[96]; 357 /** Status code to return if we got sense data. */ 358 int rcSense; 355 359 /** Pointer to the Initiator2Target S/G list. */ 356 360 PRTSGSEG paI2TSegs; … … 363 367 /** S/G buffer for the target to initiator bits. */ 364 368 RTSGBUF SgBufT2I; 365 } SCSIREQ, *PSCSIREQ;366 367 /**368 * Async request structure holding all necessary data for369 * request processing.370 */371 typedef struct SCSIREQASYNC372 {373 /** I/O context associated with this request. */374 PVDIOCTX pIoCtx;375 /** Pointer to the SCSI request structure. */376 PSCSIREQ pScsiReq;377 /** The CDB. */378 uint8_t abCDB[16];379 /** The sense buffer. */380 uint8_t abSense[96];381 /** Status code to return if we got sense data. */382 int rcSense;383 369 /** Number of retries if the command completes with sense 384 370 * data before we return with an error. 385 371 */ 386 372 unsigned cSenseRetries; 387 /** The number of entries in the I2T S/G list. */388 unsigned cI2TSegs;389 /** The number of entries in the T2I S/G list. */390 unsigned cT2ISegs;391 373 /** The S/G list - variable in size. 392 374 * This array holds both the I2T and T2I segments. … … 394 376 */ 395 377 RTSGSEG aSegs[1]; 396 } SCSIREQ ASYNC, *PSCSIREQASYNC;378 } SCSIREQ, *PSCSIREQ; 397 379 398 380 typedef enum ISCSICMDTYPE … … 452 434 { 453 435 /** The SCSI request to process. */ 454 PSCSIREQ 436 PSCSIREQ pScsiReq; 455 437 } ScsiReq; 456 438 /** Call a function in the I/O thread. */ … … 458 440 { 459 441 /** The method to execute. */ 460 PFNISCSIEXEC 442 PFNISCSIEXEC pfnExec; 461 443 /** User data. */ 462 void 444 void *pvUser; 463 445 } Exec; 464 446 } CmdType; … … 1822 1804 aReqBHS[6] = RT_H2N_U32(pImage->CmdSN); 1823 1805 aReqBHS[7] = RT_H2N_U32(pImage->ExpStatSN); 1824 memcpy(aReqBHS + 8, pRequest-> pvCDB, pRequest->cbCDB);1806 memcpy(aReqBHS + 8, pRequest->abCDB, pRequest->cbCDB); 1825 1807 pImage->CmdSN++; 1826 1808 … … 1914 1896 /* Truncate sense data if it doesn't fit into the buffer. */ 1915 1897 pRequest->cbSense = RT_MIN(cbStat, pRequest->cbSense); 1916 memcpy(pRequest-> pvSense,1898 memcpy(pRequest->abSense, 1917 1899 ((const char *)aISCSIRes[1].pvSeg) + 2, 1918 1900 RT_MIN(aISCSIRes[1].cbSeg - 2, pRequest->cbSense)); … … 1920 1902 && (ssize_t)pRequest->cbSense - aISCSIRes[1].cbSeg + 2 > 0) 1921 1903 { 1922 memcpy((char *)pRequest-> pvSense + aISCSIRes[1].cbSeg - 2,1904 memcpy((char *)pRequest->abSense + aISCSIRes[1].cbSeg - 2, 1923 1905 aISCSIRes[2].pvSeg, 1924 1906 pRequest->cbSense - aISCSIRes[1].cbSeg + 2); … … 2676 2658 paReqBHS[6] = RT_H2N_U32(pImage->CmdSN); 2677 2659 paReqBHS[7] = RT_H2N_U32(pImage->ExpStatSN); 2678 memcpy(paReqBHS + 8, pScsiReq-> pvCDB, pScsiReq->cbCDB);2660 memcpy(paReqBHS + 8, pScsiReq->abCDB, pScsiReq->cbCDB); 2679 2661 2680 2662 pIScsiPDU->CmdSN = pImage->CmdSN; … … 2789 2771 /* Truncate sense data if it doesn't fit into the buffer. */ 2790 2772 pScsiReq->cbSense = RT_MIN(cbStat, pScsiReq->cbSense); 2791 memcpy(pScsiReq-> pvSense, (uint8_t *)pvSense + 2,2773 memcpy(pScsiReq->abSense, (uint8_t *)pvSense + 2, 2792 2774 RT_MIN(paRes[0].cbSeg - ISCSI_BHS_SIZE - 2, pScsiReq->cbSense)); 2793 2775 } … … 3619 3601 bool fComplete = true; 3620 3602 size_t cbTransfered = 0; 3621 PSCSIREQASYNC pReqAsync = (PSCSIREQASYNC)pvUser; 3622 PSCSIREQ pScsiReq = pReqAsync->pScsiReq; 3603 PSCSIREQ pScsiReq = (PSCSIREQ)pvUser; 3623 3604 3624 3605 if ( RT_SUCCESS(rcReq) … … 3626 3607 { 3627 3608 /* Try again if possible. */ 3628 if (p ReqAsync->cSenseRetries > 0)3629 { 3630 p ReqAsync->cSenseRetries--;3631 pScsiReq->cbSense = sizeof(p ReqAsync->abSense);3632 int rc = iscsiCommandAsync(pImage, pScsiReq, iscsiCommandAsyncComplete, p ReqAsync);3609 if (pScsiReq->cSenseRetries > 0) 3610 { 3611 pScsiReq->cSenseRetries--; 3612 pScsiReq->cbSense = sizeof(pScsiReq->abSense); 3613 int rc = iscsiCommandAsync(pImage, pScsiReq, iscsiCommandAsyncComplete, pScsiReq); 3633 3614 if (RT_SUCCESS(rc)) 3634 3615 fComplete = false; 3635 3616 else 3636 rcReq = p ReqAsync->rcSense;3617 rcReq = pScsiReq->rcSense; 3637 3618 } 3638 3619 else 3639 rcReq = p ReqAsync->rcSense;3620 rcReq = pScsiReq->rcSense; 3640 3621 } 3641 3622 … … 3651 3632 /* Continue I/O context. */ 3652 3633 pImage->pIfIo->pfnIoCtxCompleted(pImage->pIfIo->Core.pvUser, 3653 p ReqAsync->pIoCtx, rcReq,3634 pScsiReq->pIoCtx, rcReq, 3654 3635 cbTransfered); 3655 3636 3656 3637 RTMemFree(pScsiReq); 3657 RTMemFree(pReqAsync);3658 3638 } 3659 3639 } … … 4069 4049 * Inquire available LUNs - purely dummy request. 4070 4050 */ 4071 uint8_t CDB_rlun[12];4072 4051 uint8_t rlundata[16]; 4073 CDB_rlun[0] = SCSI_REPORT_LUNS; 4074 CDB_rlun[1] = 0; /* reserved */ 4075 CDB_rlun[2] = 0; /* reserved */ 4076 CDB_rlun[3] = 0; /* reserved */ 4077 CDB_rlun[4] = 0; /* reserved */ 4078 CDB_rlun[5] = 0; /* reserved */ 4079 CDB_rlun[6] = sizeof(rlundata) >> 24; 4080 CDB_rlun[7] = (sizeof(rlundata) >> 16) & 0xff; 4081 CDB_rlun[8] = (sizeof(rlundata) >> 8) & 0xff; 4082 CDB_rlun[9] = sizeof(rlundata) & 0xff; 4083 CDB_rlun[10] = 0; /* reserved */ 4084 CDB_rlun[11] = 0; /* control */ 4052 RT_ZERO(sr.abCDB); 4053 sr.abCDB[0] = SCSI_REPORT_LUNS; 4054 sr.abCDB[1] = 0; /* reserved */ 4055 sr.abCDB[2] = 0; /* reserved */ 4056 sr.abCDB[3] = 0; /* reserved */ 4057 sr.abCDB[4] = 0; /* reserved */ 4058 sr.abCDB[5] = 0; /* reserved */ 4059 sr.abCDB[6] = sizeof(rlundata) >> 24; 4060 sr.abCDB[7] = (sizeof(rlundata) >> 16) & 0xff; 4061 sr.abCDB[8] = (sizeof(rlundata) >> 8) & 0xff; 4062 sr.abCDB[9] = sizeof(rlundata) & 0xff; 4063 sr.abCDB[10] = 0; /* reserved */ 4064 sr.abCDB[11] = 0; /* control */ 4085 4065 4086 4066 DataSeg.pvSeg = rlundata; 4087 4067 DataSeg.cbSeg = sizeof(rlundata); 4088 4068 4089 sr.enmXfer = SCSIXFER_FROM_TARGET; 4090 sr.cbCDB = sizeof(CDB_rlun); 4091 sr.pvCDB = CDB_rlun; 4069 sr.enmXfer = SCSIXFER_FROM_TARGET; 4070 sr.cbCDB = 12; 4092 4071 sr.cbI2TData = 0; 4093 4072 sr.paI2TSegs = NULL; … … 4096 4075 sr.paT2ISegs = &DataSeg; 4097 4076 sr.cT2ISegs = 1; 4098 sr.cbSense = sizeof(sense); 4099 sr.pvSense = sense; 4100 4077 sr.cbSense = sizeof(sr.abSense); 4101 4078 rc = iscsiCommandSync(pImage, &sr, false, VERR_INVALID_STATE); 4102 4079 if (RT_FAILURE(rc)) … … 4109 4086 * Inquire device characteristics - no tapes, scanners etc., please. 4110 4087 */ 4111 uint8_t CDB_inq[6];4112 CDB_inq[0] = SCSI_INQUIRY;4113 CDB_inq[1] = 0; /* reserved */4114 CDB_inq[2] = 0; /* reserved */4115 CDB_inq[3] = 0; /* reserved */4116 CDB_inq[4] = sizeof(data8);4117 CDB_inq[5] = 0; /* control */4088 RT_ZERO(sr.abCDB); 4089 sr.abCDB[0] = SCSI_INQUIRY; 4090 sr.abCDB[1] = 0; /* reserved */ 4091 sr.abCDB[2] = 0; /* reserved */ 4092 sr.abCDB[3] = 0; /* reserved */ 4093 sr.abCDB[4] = sizeof(data8); 4094 sr.abCDB[5] = 0; /* control */ 4118 4095 4119 4096 DataSeg.pvSeg = data8; 4120 4097 DataSeg.cbSeg = sizeof(data8); 4121 4098 4122 sr.enmXfer = SCSIXFER_FROM_TARGET; 4123 sr.cbCDB = sizeof(CDB_inq); 4124 sr.pvCDB = CDB_inq; 4099 sr.enmXfer = SCSIXFER_FROM_TARGET; 4100 sr.cbCDB = 6; 4125 4101 sr.cbI2TData = 0; 4126 4102 sr.paI2TSegs = NULL; … … 4129 4105 sr.paT2ISegs = &DataSeg; 4130 4106 sr.cT2ISegs = 1; 4131 sr.cbSense = sizeof(sense); 4132 sr.pvSense = sense; 4133 4107 sr.cbSense = sizeof(sr.abSense); 4134 4108 rc = iscsiCommandSync(pImage, &sr, true /* fRetry */, VERR_INVALID_STATE); 4135 4109 if (RT_SUCCESS(rc)) … … 4168 4142 * mode parameter header. Refuse read/write opening of read only disks. 4169 4143 */ 4170 4171 uint8_t CDB_ms[6];4172 4144 uint8_t data4[4]; 4173 CDB_ms[0] = SCSI_MODE_SENSE_6; 4174 CDB_ms[1] = 0; /* dbd=0/reserved */ 4175 CDB_ms[2] = 0x3f; /* pc=0/page code=0x3f, ask for all pages */ 4176 CDB_ms[3] = 0; /* subpage code=0, return everything in page_0 format */ 4177 CDB_ms[4] = sizeof(data4); /* allocation length=4 */ 4178 CDB_ms[5] = 0; /* control */ 4145 RT_ZERO(sr.abCDB); 4146 sr.abCDB[0] = SCSI_MODE_SENSE_6; 4147 sr.abCDB[1] = 0; /* dbd=0/reserved */ 4148 sr.abCDB[2] = 0x3f; /* pc=0/page code=0x3f, ask for all pages */ 4149 sr.abCDB[3] = 0; /* subpage code=0, return everything in page_0 format */ 4150 sr.abCDB[4] = sizeof(data4); /* allocation length=4 */ 4151 sr.abCDB[5] = 0; /* control */ 4179 4152 4180 4153 DataSeg.pvSeg = data4; 4181 4154 DataSeg.cbSeg = sizeof(data4); 4182 4155 4183 sr.enmXfer = SCSIXFER_FROM_TARGET; 4184 sr.cbCDB = sizeof(CDB_ms); 4185 sr.pvCDB = CDB_ms; 4156 sr.enmXfer = SCSIXFER_FROM_TARGET; 4157 sr.cbCDB = 6; 4186 4158 sr.cbI2TData = 0; 4187 4159 sr.paI2TSegs = NULL; … … 4190 4162 sr.paT2ISegs = &DataSeg; 4191 4163 sr.cT2ISegs = 1; 4192 sr.cbSense = sizeof(sense); 4193 sr.pvSense = sense; 4194 4164 sr.cbSense = sizeof(sr.abSense); 4195 4165 rc = iscsiCommandSync(pImage, &sr, true /* fRetry */, VERR_INVALID_STATE); 4196 4166 if (RT_SUCCESS(rc)) … … 4211 4181 * Determine sector size and capacity of the volume immediately. 4212 4182 */ 4213 uint8_t CDB_cap[16];4214 4215 4183 RT_ZERO(data12); 4216 RT_ZERO( CDB_cap);4217 CDB_cap[0] = SCSI_SERVICE_ACTION_IN_16;4218 CDB_cap[1] = SCSI_SVC_ACTION_IN_READ_CAPACITY_16; /* subcommand */4219 CDB_cap[10+3] = sizeof(data12); /* allocation length (dword) */4184 RT_ZERO(sr.abCDB); 4185 sr.abCDB[0] = SCSI_SERVICE_ACTION_IN_16; 4186 sr.abCDB[1] = SCSI_SVC_ACTION_IN_READ_CAPACITY_16; /* subcommand */ 4187 sr.abCDB[10+3] = sizeof(data12); /* allocation length (dword) */ 4220 4188 4221 4189 DataSeg.pvSeg = data12; 4222 4190 DataSeg.cbSeg = sizeof(data12); 4223 4191 4224 sr.enmXfer = SCSIXFER_FROM_TARGET; 4225 sr.cbCDB = sizeof(CDB_cap); 4226 sr.pvCDB = CDB_cap; 4192 sr.enmXfer = SCSIXFER_FROM_TARGET; 4193 sr.cbCDB = 16; 4227 4194 sr.cbI2TData = 0; 4228 4195 sr.paI2TSegs = NULL; … … 4231 4198 sr.paT2ISegs = &DataSeg; 4232 4199 sr.cT2ISegs = 1; 4233 sr.cbSense = sizeof(sense); 4234 sr.pvSense = sense; 4200 sr.cbSense = sizeof(sr.abSense); 4235 4201 4236 4202 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4237 4203 if (RT_SUCCESS(rc)) 4238 4204 { 4239 bool b_end = false;4240 uint8_t max_counter= 10;4205 bool fEnd = false; 4206 uint8_t cMaxRetries = 10; 4241 4207 do 4242 4208 { … … 4256 4222 pImage->LUN, pImage->cVolume, pImage->cbSector); 4257 4223 } 4258 b_end = true;4224 fEnd = true; 4259 4225 break; 4260 4226 } 4261 4227 case SCSI_STATUS_CHECK_CONDITION: 4262 4228 { 4263 if((s ense[2]&0x0F)==SCSI_SENSE_UNIT_ATTENTION)4229 if((sr.abSense[2] & 0x0f) == SCSI_SENSE_UNIT_ATTENTION) 4264 4230 { 4265 if( sense[12]==SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED &&4266 sense[13]==SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED)4231 if( sr.abSense[12] == SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 4232 && sr.abSense[13] == SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED) 4267 4233 { 4268 4234 /** @todo for future: prepare and send command "REQUEST SENSE" which will … … 4270 4236 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4271 4237 if (RT_FAILURE(rc)) 4272 b_end = true;4273 --max_counter;4238 fEnd = true; 4239 cMaxRetries--; 4274 4240 break; 4275 4241 … … 4282 4248 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4283 4249 if (RT_FAILURE(rc)) 4284 b_end = true;4285 --max_counter;4250 fEnd = true; 4251 cMaxRetries--; 4286 4252 break; 4287 4253 } 4288 4254 } 4289 if ( max_counter==0)4290 b_end=true;4291 } while(!b_end);4255 if (!cMaxRetries) 4256 fEnd = true; 4257 } while(!fEnd); 4292 4258 } 4293 4259 else 4294 4260 { 4295 uint8_t CDB_capfb[10];4296 4297 4261 RT_ZERO(data8); 4298 CDB_capfb[0] = SCSI_READ_CAPACITY;4299 CDB_capfb[1] = 0; /* reserved */4300 CDB_capfb[2] = 0; /* reserved */4301 CDB_capfb[3] = 0; /* reserved */4302 CDB_capfb[4] = 0; /* reserved */4303 CDB_capfb[5] = 0; /* reserved */4304 CDB_capfb[6] = 0; /* reserved */4305 CDB_capfb[7] = 0; /* reserved */4306 CDB_capfb[8] = 0; /* reserved */4307 CDB_capfb[9] = 0; /* control */4262 sr.abCDB[0] = SCSI_READ_CAPACITY; 4263 sr.abCDB[1] = 0; /* reserved */ 4264 sr.abCDB[2] = 0; /* reserved */ 4265 sr.abCDB[3] = 0; /* reserved */ 4266 sr.abCDB[4] = 0; /* reserved */ 4267 sr.abCDB[5] = 0; /* reserved */ 4268 sr.abCDB[6] = 0; /* reserved */ 4269 sr.abCDB[7] = 0; /* reserved */ 4270 sr.abCDB[8] = 0; /* reserved */ 4271 sr.abCDB[9] = 0; /* control */ 4308 4272 4309 4273 DataSeg.pvSeg = data8; 4310 4274 DataSeg.cbSeg = sizeof(data8); 4311 4275 4312 sr.enmXfer = SCSIXFER_FROM_TARGET; 4313 sr.cbCDB = sizeof(CDB_capfb); 4314 sr.pvCDB = CDB_capfb; 4276 sr.enmXfer = SCSIXFER_FROM_TARGET; 4277 sr.cbCDB = 10; 4315 4278 sr.cbI2TData = 0; 4316 4279 sr.paI2TSegs = NULL; … … 4319 4282 sr.paT2ISegs = &DataSeg; 4320 4283 sr.cT2ISegs = 1; 4321 sr.cbSense = sizeof(sense); 4322 sr.pvSense = sense; 4323 4284 sr.cbSense = sizeof(sr.abSense); 4324 4285 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4325 4286 if (RT_SUCCESS(rc)) 4326 4287 { 4327 bool b_end = false;4328 uint8_t max_counter= 10;4288 bool fEnd = false; 4289 uint8_t cMaxRetries = 10; 4329 4290 do 4330 4291 { … … 4345 4306 } 4346 4307 4347 b_end = true;4308 fEnd = true; 4348 4309 break; 4349 4310 } 4350 4311 case SCSI_STATUS_CHECK_CONDITION: 4351 4312 { 4352 if((s ense[2]&0x0F)==SCSI_SENSE_UNIT_ATTENTION)4313 if((sr.abSense[2] & 0x0f) == SCSI_SENSE_UNIT_ATTENTION) 4353 4314 { 4354 if( sense[12]==SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED &&4355 sense[13]==SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED)4315 if( sr.abSense[12] == SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 4316 && sr.abSense[13] == SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED) 4356 4317 { 4357 4318 /** @todo for future: prepare and send command "REQUEST SENSE" which will … … 4359 4320 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4360 4321 if (RT_FAILURE(rc)) 4361 b_end = true;4362 --max_counter;4322 fEnd = true; 4323 cMaxRetries--; 4363 4324 break; 4364 4325 … … 4371 4332 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4372 4333 if (RT_FAILURE(rc)) 4373 b_end = true;4374 --max_counter;4334 fEnd = true; 4335 cMaxRetries--; 4375 4336 break; 4376 4337 } 4377 4338 } 4378 if ( max_counter==0)4379 b_end=true;4380 } while(!b_end);4339 if (!cMaxRetries) 4340 fEnd = true; 4341 } while(!fEnd); 4381 4342 } 4382 4343 else … … 4395 4356 */ 4396 4357 uint8_t aCachingModePage[32]; 4397 uint8_t aCDBModeSense6[6];4398 4358 4399 4359 memset(aCachingModePage, '\0', sizeof(aCachingModePage)); 4400 aCDBModeSense6[0] = SCSI_MODE_SENSE_6;4401 aCDBModeSense6[1] = 0;4402 aCDBModeSense6[2] = (0x00 << 6) | (0x08 & 0x3f); /* Current values and caching mode page */4403 aCDBModeSense6[3] = 0; /* Sub page code. */4404 aCDBModeSense6[4] = sizeof(aCachingModePage) & 0xff;4405 aCDBModeSense6[5] = 0;4360 sr.abCDB[0] = SCSI_MODE_SENSE_6; 4361 sr.abCDB[1] = 0; 4362 sr.abCDB[2] = (0x00 << 6) | (0x08 & 0x3f); /* Current values and caching mode page */ 4363 sr.abCDB[3] = 0; /* Sub page code. */ 4364 sr.abCDB[4] = sizeof(aCachingModePage) & 0xff; 4365 sr.abCDB[5] = 0; 4406 4366 4407 4367 DataSeg.pvSeg = aCachingModePage; 4408 4368 DataSeg.cbSeg = sizeof(aCachingModePage); 4409 4369 4410 sr.enmXfer = SCSIXFER_FROM_TARGET; 4411 sr.cbCDB = sizeof(aCDBModeSense6); 4412 sr.pvCDB = aCDBModeSense6; 4370 sr.enmXfer = SCSIXFER_FROM_TARGET; 4371 sr.cbCDB = 6; 4413 4372 sr.cbI2TData = 0; 4414 4373 sr.paI2TSegs = NULL; … … 4417 4376 sr.paT2ISegs = &DataSeg; 4418 4377 sr.cT2ISegs = 1; 4419 sr.cbSense = sizeof(sense); 4420 sr.pvSense = sense; 4378 sr.cbSense = sizeof(sr.abSense); 4421 4379 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4422 4380 if ( RT_SUCCESS(rc) … … 4443 4401 4444 4402 uint8_t aCDBCaching[6]; 4445 aCDBCaching[0] = SCSI_MODE_SELECT_6;4446 aCDBCaching[1] = 0; /* Don't write the page into NV RAM. */4447 aCDBCaching[2] = 0;4448 aCDBCaching[3] = 0;4449 aCDBCaching[4] = sizeof(aCachingModePage) & 0xff;4450 aCDBCaching[5] = 0;4403 sr.abCDB[0] = SCSI_MODE_SELECT_6; 4404 sr.abCDB[1] = 0; /* Don't write the page into NV RAM. */ 4405 sr.abCDB[2] = 0; 4406 sr.abCDB[3] = 0; 4407 sr.abCDB[4] = sizeof(aCachingModePage) & 0xff; 4408 sr.abCDB[5] = 0; 4451 4409 4452 4410 DataSeg.pvSeg = aCachingModePage; 4453 4411 DataSeg.cbSeg = sizeof(aCachingModePage); 4454 4412 4455 sr.enmXfer = SCSIXFER_TO_TARGET; 4456 sr.cbCDB = sizeof(aCDBCaching); 4457 sr.pvCDB = aCDBCaching; 4413 sr.enmXfer = SCSIXFER_TO_TARGET; 4414 sr.cbCDB = 6; 4458 4415 sr.cbI2TData = DataSeg.cbSeg; 4459 4416 sr.paI2TSegs = &DataSeg; … … 4462 4419 sr.paT2ISegs = NULL; 4463 4420 sr.cT2ISegs = 0; 4464 sr.cbSense = sizeof(sense); 4465 sr.pvSense = sense; 4466 sr.status = 0; 4421 sr.cbSense = sizeof(sr.abSense); 4422 sr.status = 0; 4467 4423 rc = iscsiCommandSync(pImage, &sr, false /* fRetry */, VINF_SUCCESS); 4468 4424 if ( RT_SUCCESS(rc) … … 4604 4560 } 4605 4561 4606 static int iscsiReadSync(void *pBackendData, uint64_t uOffset, void *pvBuf, 4607 size_t cbToRead, size_t *pcbActuallyRead) 4608 { 4609 /** @todo reinstate logging of the target everywhere - dropped temporarily */ 4610 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead)); 4562 /** @copydoc VBOXHDDBACKEND::pfnRead */ 4563 static int iscsiRead(void *pBackendData, uint64_t uOffset, size_t cbToRead, 4564 PVDIOCTX pIoCtx, size_t *pcbActuallyRead) 4565 { 4611 4566 PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData; 4612 uint64_t lba; 4613 uint16_t tls; 4614 int rc; 4615 4616 Assert(pImage); 4617 Assert(uOffset % 512 == 0); 4618 Assert(cbToRead % 512 == 0); 4619 4620 Assert(pImage->cbSector); 4621 AssertPtr(pvBuf); 4567 int rc = VINF_SUCCESS; 4568 4569 LogFlowFunc(("pBackendData=%p uOffset=%#llx pIoCtx=%#p cbToRead=%u pcbActuallyRead=%p\n", 4570 pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead)); 4622 4571 4623 4572 if ( uOffset + cbToRead > pImage->cbSize 4624 4573 || cbToRead == 0) 4625 { 4626 rc = VERR_INVALID_PARAMETER; 4627 goto out; 4628 } 4574 return VERR_INVALID_PARAMETER; 4629 4575 4630 4576 /* … … 4633 4579 cbToRead = RT_MIN(cbToRead, pImage->cbRecvDataLength); 4634 4580 4635 lba = uOffset / pImage->cbSector;4636 tls = (uint16_t)(cbToRead / pImage->cbSector);4637 SCSIREQ sr;4638 RTSGSEG T2ISeg;4639 size_t cbCDB;4640 uint8_t abCDB[16];4641 uint8_t sense[96];4642 4643 if (pImage->cVolume < _4G)4644 {4645 cbCDB = 10;4646 abCDB[0] = SCSI_READ_10;4647 abCDB[1] = 0; /* reserved */4648 abCDB[2] = (lba >> 24) & 0xff;4649 abCDB[3] = (lba >> 16) & 0xff;4650 abCDB[4] = (lba >> 8) & 0xff;4651 abCDB[5] = lba & 0xff;4652 abCDB[6] = 0; /* reserved */4653 abCDB[7] = (tls >> 8) & 0xff;4654 abCDB[8] = tls & 0xff;4655 abCDB[9] = 0; /* control */4656 }4657 else4658 {4659 cbCDB = 16;4660 abCDB[0] = SCSI_READ_16;4661 abCDB[1] = 0; /* reserved */4662 abCDB[2] = (lba >> 56) & 0xff;4663 abCDB[3] = (lba >> 48) & 0xff;4664 abCDB[4] = (lba >> 40) & 0xff;4665 abCDB[5] = (lba >> 32) & 0xff;4666 abCDB[6] = (lba >> 24) & 0xff;4667 abCDB[7] = (lba >> 16) & 0xff;4668 abCDB[8] = (lba >> 8) & 0xff;4669 abCDB[9] = lba & 0xff;4670 abCDB[10] = 0; /* tls unused */4671 abCDB[11] = 0; /* tls unused */4672 abCDB[12] = (tls >> 8) & 0xff;4673 abCDB[13] = tls & 0xff;4674 abCDB[14] = 0; /* reserved */4675 abCDB[15] = 0; /* reserved */4676 }4677 4678 T2ISeg.pvSeg = pvBuf;4679 T2ISeg.cbSeg = cbToRead;4680 4681 sr.enmXfer = SCSIXFER_FROM_TARGET;4682 sr.cbCDB = cbCDB;4683 sr.pvCDB = abCDB;4684 sr.cbI2TData = 0;4685 sr.paI2TSegs = NULL;4686 sr.cI2TSegs = 0;4687 sr.cbT2IData = cbToRead;4688 sr.paT2ISegs = &T2ISeg;4689 sr.cT2ISegs = 1;4690 sr.cbSense = sizeof(sense);4691 sr.pvSense = sense;4692 4693 rc = iscsiCommandSync(pImage, &sr, true, VERR_READ_ERROR);4694 if (RT_FAILURE(rc))4695 {4696 LogFlow(("iscsiCommandSync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc));4697 *pcbActuallyRead = 0;4698 }4699 else4700 *pcbActuallyRead = sr.cbT2IData;4701 4702 out:4703 LogFlowFunc(("returns %Rrc\n", rc));4704 return rc;4705 }4706 4707 static int iscsiWriteSync(void *pBackendData, uint64_t uOffset, const void *pvBuf,4708 size_t cbToWrite, size_t *pcbWriteProcess,4709 size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)4710 {4711 LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n", pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead));4712 PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;4713 uint64_t lba;4714 uint16_t tls;4715 int rc;4716 4717 Assert(pImage);4718 Assert(uOffset % 512 == 0);4719 Assert(cbToWrite % 512 == 0);4720 4721 Assert(pImage->cbSector);4722 Assert(pvBuf);4723 4724 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)4725 {4726 rc = VERR_VD_IMAGE_READ_ONLY;4727 goto out;4728 }4729 4730 *pcbPreRead = 0;4731 *pcbPostRead = 0;4732 4733 /*4734 * Clip write size to a value which is supported by the target.4735 */4736 cbToWrite = RT_MIN(cbToWrite, pImage->cbSendDataLength);4737 4738 lba = uOffset / pImage->cbSector;4739 tls = (uint16_t)(cbToWrite / pImage->cbSector);4740 SCSIREQ sr;4741 RTSGSEG I2TSeg;4742 size_t cbCDB;4743 uint8_t abCDB[16];4744 uint8_t sense[96];4745 4746 if (pImage->cVolume < _4G)4747 {4748 cbCDB = 10;4749 abCDB[0] = SCSI_WRITE_10;4750 abCDB[1] = 0; /* reserved */4751 abCDB[2] = (lba >> 24) & 0xff;4752 abCDB[3] = (lba >> 16) & 0xff;4753 abCDB[4] = (lba >> 8) & 0xff;4754 abCDB[5] = lba & 0xff;4755 abCDB[6] = 0; /* reserved */4756 abCDB[7] = (tls >> 8) & 0xff;4757 abCDB[8] = tls & 0xff;4758 abCDB[9] = 0; /* control */4759 }4760 else4761 {4762 cbCDB = 16;4763 abCDB[0] = SCSI_WRITE_16;4764 abCDB[1] = 0; /* reserved */4765 abCDB[2] = (lba >> 56) & 0xff;4766 abCDB[3] = (lba >> 48) & 0xff;4767 abCDB[4] = (lba >> 40) & 0xff;4768 abCDB[5] = (lba >> 32) & 0xff;4769 abCDB[6] = (lba >> 24) & 0xff;4770 abCDB[7] = (lba >> 16) & 0xff;4771 abCDB[8] = (lba >> 8) & 0xff;4772 abCDB[9] = lba & 0xff;4773 abCDB[10] = 0; /* tls unused */4774 abCDB[11] = 0; /* tls unused */4775 abCDB[12] = (tls >> 8) & 0xff;4776 abCDB[13] = tls & 0xff;4777 abCDB[14] = 0; /* reserved */4778 abCDB[15] = 0; /* reserved */4779 }4780 4781 I2TSeg.pvSeg = (void *)pvBuf;4782 I2TSeg.cbSeg = cbToWrite;4783 4784 sr.enmXfer = SCSIXFER_TO_TARGET;4785 sr.cbCDB = cbCDB;4786 sr.pvCDB = abCDB;4787 sr.cbI2TData = cbToWrite;4788 sr.paI2TSegs = &I2TSeg;4789 sr.cI2TSegs = 1;4790 sr.cbT2IData = 0;4791 sr.paT2ISegs = NULL;4792 sr.cT2ISegs = 0;4793 sr.cbSense = sizeof(sense);4794 sr.pvSense = sense;4795 4796 rc = iscsiCommandSync(pImage, &sr, true, VERR_WRITE_ERROR);4797 if (RT_FAILURE(rc))4798 {4799 LogFlow(("iscsiCommandSync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc));4800 *pcbWriteProcess = 0;4801 }4802 else4803 *pcbWriteProcess = cbToWrite;4804 4805 out:4806 LogFlowFunc(("returns %Rrc\n", rc));4807 return rc;4808 }4809 4810 static int iscsiFlushSync(void *pBackendData)4811 {4812 LogFlowFunc(("pBackendData=%#p\n", pBackendData));4813 PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;4814 int rc;4815 4816 Assert(pImage);4817 4818 SCSIREQ sr;4819 uint8_t abCDB[10];4820 uint8_t sense[96];4821 4822 abCDB[0] = SCSI_SYNCHRONIZE_CACHE;4823 abCDB[1] = 0; /* reserved */4824 abCDB[2] = 0; /* LBA 0 */4825 abCDB[3] = 0; /* LBA 0 */4826 abCDB[4] = 0; /* LBA 0 */4827 abCDB[5] = 0; /* LBA 0 */4828 abCDB[6] = 0; /* reserved */4829 abCDB[7] = 0; /* transfer everything to disk */4830 abCDB[8] = 0; /* transfer everything to disk */4831 abCDB[9] = 0; /* control */4832 4833 sr.enmXfer = SCSIXFER_NONE;4834 sr.cbCDB = sizeof(abCDB);4835 sr.pvCDB = abCDB;4836 sr.cbI2TData = 0;4837 sr.paI2TSegs = NULL;4838 sr.cI2TSegs = 0;4839 sr.cbT2IData = 0;4840 sr.paT2ISegs = NULL;4841 sr.cT2ISegs = 0;4842 sr.cbSense = sizeof(sense);4843 sr.pvSense = sense;4844 4845 rc = iscsiCommandSync(pImage, &sr, false, VINF_SUCCESS);4846 if (RT_FAILURE(rc))4847 AssertMsgFailed(("iscsiCommand(%s) -> %Rrc\n", pImage->pszTargetName, rc));4848 LogFlowFunc(("returns %Rrc\n", rc));4849 return rc;4850 }4851 4852 /** @copydoc VBOXHDDBACKEND::pfnRead */4853 static int iscsiRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,4854 PVDIOCTX pIoCtx, size_t *pcbActuallyRead)4855 {4856 PISCSIIMAGE pImage = (PISCSIIMAGE)pBackendData;4857 int rc = VINF_SUCCESS;4858 4859 LogFlowFunc(("pBackendData=%p uOffset=%#llx pIoCtx=%#p cbToRead=%u pcbActuallyRead=%p\n",4860 pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead));4861 4862 if ( uOffset + cbToRead > pImage->cbSize4863 || cbToRead == 0)4864 return VERR_INVALID_PARAMETER;4865 4866 /*4867 * Clip read size to a value which is supported by the target.4868 */4869 cbToRead = RT_MIN(cbToRead, pImage->cbRecvDataLength);4870 4871 /** @todo: Remove iscsiRead and integrate properly. */4872 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx))4873 {4874 RTSGSEG Segment;4875 unsigned cSegments = 1;4876 size_t cbSegs;4877 4878 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx,4879 &Segment, &cSegments, cbToRead);4880 Assert(cbSegs == cbToRead);4881 4882 return iscsiReadSync(pBackendData, uOffset, Segment.pvSeg, cbToRead, pcbActuallyRead);4883 }4884 4885 4581 unsigned cT2ISegs = 0; 4886 4582 size_t cbSegs = 0; … … 4891 4587 Assert(cbSegs == cbToRead); 4892 4588 4893 PSCSIREQASYNC pReqAsync = (PSCSIREQASYNC)RTMemAllocZ(RT_OFFSETOF(SCSIREQASYNC, aSegs[cT2ISegs])); 4894 if (RT_LIKELY(pReqAsync)) 4895 { 4896 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(sizeof(SCSIREQ)); 4897 if (pReq) 4898 { 4899 uint64_t lba; 4900 uint16_t tls; 4901 uint8_t *pbCDB = &pReqAsync->abCDB[0]; 4902 size_t cbCDB; 4903 4904 lba = uOffset / pImage->cbSector; 4905 tls = (uint16_t)(cbToRead / pImage->cbSector); 4906 4907 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx, 4908 &pReqAsync->aSegs[0], 4909 &cT2ISegs, cbToRead); 4910 Assert(cbSegs == cbToRead); 4911 pReqAsync->cT2ISegs = cT2ISegs; 4912 pReqAsync->pIoCtx = pIoCtx; 4913 pReqAsync->pScsiReq = pReq; 4914 pReqAsync->cSenseRetries = 10; 4915 pReqAsync->rcSense = VERR_READ_ERROR; 4916 4917 if (pImage->cVolume < _4G) 4589 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(RT_OFFSETOF(SCSIREQ, aSegs[cT2ISegs])); 4590 if (RT_LIKELY(pReq)) 4591 { 4592 uint64_t lba; 4593 uint16_t tls; 4594 uint8_t *pbCDB = &pReq->abCDB[0]; 4595 size_t cbCDB; 4596 4597 lba = uOffset / pImage->cbSector; 4598 tls = (uint16_t)(cbToRead / pImage->cbSector); 4599 4600 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx, 4601 &pReq->aSegs[0], 4602 &cT2ISegs, cbToRead); 4603 Assert(cbSegs == cbToRead); 4604 4605 if (pImage->cVolume < _4G) 4606 { 4607 cbCDB = 10; 4608 pbCDB[0] = SCSI_READ_10; 4609 pbCDB[1] = 0; /* reserved */ 4610 pbCDB[2] = (lba >> 24) & 0xff; 4611 pbCDB[3] = (lba >> 16) & 0xff; 4612 pbCDB[4] = (lba >> 8) & 0xff; 4613 pbCDB[5] = lba & 0xff; 4614 pbCDB[6] = 0; /* reserved */ 4615 pbCDB[7] = (tls >> 8) & 0xff; 4616 pbCDB[8] = tls & 0xff; 4617 pbCDB[9] = 0; /* control */ 4618 } 4619 else 4620 { 4621 cbCDB = 16; 4622 pbCDB[0] = SCSI_READ_16; 4623 pbCDB[1] = 0; /* reserved */ 4624 pbCDB[2] = (lba >> 56) & 0xff; 4625 pbCDB[3] = (lba >> 48) & 0xff; 4626 pbCDB[4] = (lba >> 40) & 0xff; 4627 pbCDB[5] = (lba >> 32) & 0xff; 4628 pbCDB[6] = (lba >> 24) & 0xff; 4629 pbCDB[7] = (lba >> 16) & 0xff; 4630 pbCDB[8] = (lba >> 8) & 0xff; 4631 pbCDB[9] = lba & 0xff; 4632 pbCDB[10] = 0; /* tls unused */ 4633 pbCDB[11] = 0; /* tls unused */ 4634 pbCDB[12] = (tls >> 8) & 0xff; 4635 pbCDB[13] = tls & 0xff; 4636 pbCDB[14] = 0; /* reserved */ 4637 pbCDB[15] = 0; /* reserved */ 4638 } 4639 4640 pReq->enmXfer = SCSIXFER_FROM_TARGET; 4641 pReq->cbCDB = cbCDB; 4642 pReq->cbI2TData = 0; 4643 pReq->paI2TSegs = NULL; 4644 pReq->cI2TSegs = 0; 4645 pReq->cbT2IData = cbToRead; 4646 pReq->paT2ISegs = &pReq->aSegs[pReq->cI2TSegs]; 4647 pReq->cT2ISegs = pReq->cT2ISegs; 4648 pReq->cbSense = sizeof(pReq->abSense); 4649 pReq->cT2ISegs = cT2ISegs; 4650 pReq->pIoCtx = pIoCtx; 4651 pReq->cSenseRetries = 10; 4652 pReq->rcSense = VERR_READ_ERROR; 4653 4654 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx)) 4655 { 4656 rc = iscsiCommandSync(pImage, pReq, true, VERR_READ_ERROR); 4657 if (RT_FAILURE(rc)) 4918 4658 { 4919 cbCDB = 10; 4920 pbCDB[0] = SCSI_READ_10; 4921 pbCDB[1] = 0; /* reserved */ 4922 pbCDB[2] = (lba >> 24) & 0xff; 4923 pbCDB[3] = (lba >> 16) & 0xff; 4924 pbCDB[4] = (lba >> 8) & 0xff; 4925 pbCDB[5] = lba & 0xff; 4926 pbCDB[6] = 0; /* reserved */ 4927 pbCDB[7] = (tls >> 8) & 0xff; 4928 pbCDB[8] = tls & 0xff; 4929 pbCDB[9] = 0; /* control */ 4659 LogFlow(("iscsiCommandSync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc)); 4660 *pcbActuallyRead = 0; 4930 4661 } 4931 4662 else 4932 { 4933 cbCDB = 16; 4934 pbCDB[0] = SCSI_READ_16; 4935 pbCDB[1] = 0; /* reserved */ 4936 pbCDB[2] = (lba >> 56) & 0xff; 4937 pbCDB[3] = (lba >> 48) & 0xff; 4938 pbCDB[4] = (lba >> 40) & 0xff; 4939 pbCDB[5] = (lba >> 32) & 0xff; 4940 pbCDB[6] = (lba >> 24) & 0xff; 4941 pbCDB[7] = (lba >> 16) & 0xff; 4942 pbCDB[8] = (lba >> 8) & 0xff; 4943 pbCDB[9] = lba & 0xff; 4944 pbCDB[10] = 0; /* tls unused */ 4945 pbCDB[11] = 0; /* tls unused */ 4946 pbCDB[12] = (tls >> 8) & 0xff; 4947 pbCDB[13] = tls & 0xff; 4948 pbCDB[14] = 0; /* reserved */ 4949 pbCDB[15] = 0; /* reserved */ 4950 } 4951 4952 pReq->enmXfer = SCSIXFER_FROM_TARGET; 4953 pReq->cbCDB = cbCDB; 4954 pReq->pvCDB = pReqAsync->abCDB; 4955 pReq->cbI2TData = 0; 4956 pReq->paI2TSegs = NULL; 4957 pReq->cI2TSegs = 0; 4958 pReq->cbT2IData = cbToRead; 4959 pReq->paT2ISegs = &pReqAsync->aSegs[pReqAsync->cI2TSegs]; 4960 pReq->cT2ISegs = pReqAsync->cT2ISegs; 4961 pReq->cbSense = sizeof(pReqAsync->abSense); 4962 pReq->pvSense = pReqAsync->abSense; 4963 4964 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReqAsync); 4663 *pcbActuallyRead = pReq->cbT2IData; 4664 } 4665 else 4666 { 4667 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReq); 4965 4668 if (RT_FAILURE(rc)) 4966 AssertMsgFailed(("iscsiCommand (%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc));4669 AssertMsgFailed(("iscsiCommandAsync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc)); 4967 4670 else 4968 4671 { … … 4970 4673 return VERR_VD_IOCTX_HALT; /* Halt the I/O context until further notification from the I/O thread. */ 4971 4674 } 4972 4973 RTMemFree(pReq); 4974 } 4975 else 4976 rc = VERR_NO_MEMORY; 4977 4978 RTMemFree(pReqAsync); 4675 } 4676 4677 RTMemFree(pReq); 4979 4678 } 4980 4679 else … … 4985 4684 } 4986 4685 4987 /** @copydoc VBOXHDDBACKEND::pfn AsyncWrite */4686 /** @copydoc VBOXHDDBACKEND::pfnWrite */ 4988 4687 static int iscsiWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite, 4989 4688 PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead, … … 5007 4706 cbToWrite = RT_MIN(cbToWrite, pImage->cbSendDataLength); 5008 4707 5009 /** @todo: Remove iscsiWriteSync and integrate properly. */5010 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx))5011 {5012 RTSGSEG Segment;5013 unsigned cSegments = 1;5014 size_t cbSegs;5015 5016 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx,5017 &Segment, &cSegments, cbToWrite);5018 Assert(cbSegs == cbToWrite);5019 5020 return iscsiWriteSync(pBackendData, uOffset, Segment.pvSeg, cbToWrite,5021 pcbWriteProcess, pcbPreRead, pcbPostRead, fWrite);5022 }5023 5024 4708 unsigned cI2TSegs = 0; 5025 4709 size_t cbSegs = 0; … … 5030 4714 Assert(cbSegs == cbToWrite); 5031 4715 5032 PSCSIREQASYNC pReqAsync = (PSCSIREQASYNC)RTMemAllocZ(RT_OFFSETOF(SCSIREQASYNC, aSegs[cI2TSegs])); 5033 if (RT_LIKELY(pReqAsync)) 5034 { 5035 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(sizeof(SCSIREQ)); 5036 if (pReq) 5037 { 5038 uint64_t lba; 5039 uint16_t tls; 5040 uint8_t *pbCDB = &pReqAsync->abCDB[0]; 5041 size_t cbCDB; 5042 5043 lba = uOffset / pImage->cbSector; 5044 tls = (uint16_t)(cbToWrite / pImage->cbSector); 5045 5046 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx, 5047 &pReqAsync->aSegs[0], 5048 &cI2TSegs, cbToWrite); 5049 Assert(cbSegs == cbToWrite); 5050 pReqAsync->cI2TSegs = cI2TSegs; 5051 pReqAsync->pIoCtx = pIoCtx; 5052 pReqAsync->pScsiReq = pReq; 5053 pReqAsync->cSenseRetries = 10; 5054 pReqAsync->rcSense = VERR_WRITE_ERROR; 5055 5056 if (pImage->cVolume < _4G) 4716 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(RT_OFFSETOF(SCSIREQ, aSegs[cI2TSegs])); 4717 if (RT_LIKELY(pReq)) 4718 { 4719 uint64_t lba; 4720 uint16_t tls; 4721 uint8_t *pbCDB = &pReq->abCDB[0]; 4722 size_t cbCDB; 4723 4724 lba = uOffset / pImage->cbSector; 4725 tls = (uint16_t)(cbToWrite / pImage->cbSector); 4726 4727 cbSegs = pImage->pIfIo->pfnIoCtxSegArrayCreate(pImage->pIfIo->Core.pvUser, pIoCtx, 4728 &pReq->aSegs[0], 4729 &cI2TSegs, cbToWrite); 4730 Assert(cbSegs == cbToWrite); 4731 4732 if (pImage->cVolume < _4G) 4733 { 4734 cbCDB = 10; 4735 pbCDB[0] = SCSI_WRITE_10; 4736 pbCDB[1] = 0; /* reserved */ 4737 pbCDB[2] = (lba >> 24) & 0xff; 4738 pbCDB[3] = (lba >> 16) & 0xff; 4739 pbCDB[4] = (lba >> 8) & 0xff; 4740 pbCDB[5] = lba & 0xff; 4741 pbCDB[6] = 0; /* reserved */ 4742 pbCDB[7] = (tls >> 8) & 0xff; 4743 pbCDB[8] = tls & 0xff; 4744 pbCDB[9] = 0; /* control */ 4745 } 4746 else 4747 { 4748 cbCDB = 16; 4749 pbCDB[0] = SCSI_WRITE_16; 4750 pbCDB[1] = 0; /* reserved */ 4751 pbCDB[2] = (lba >> 56) & 0xff; 4752 pbCDB[3] = (lba >> 48) & 0xff; 4753 pbCDB[4] = (lba >> 40) & 0xff; 4754 pbCDB[5] = (lba >> 32) & 0xff; 4755 pbCDB[6] = (lba >> 24) & 0xff; 4756 pbCDB[7] = (lba >> 16) & 0xff; 4757 pbCDB[8] = (lba >> 8) & 0xff; 4758 pbCDB[9] = lba & 0xff; 4759 pbCDB[10] = 0; /* tls unused */ 4760 pbCDB[11] = 0; /* tls unused */ 4761 pbCDB[12] = (tls >> 8) & 0xff; 4762 pbCDB[13] = tls & 0xff; 4763 pbCDB[14] = 0; /* reserved */ 4764 pbCDB[15] = 0; /* reserved */ 4765 } 4766 4767 pReq->enmXfer = SCSIXFER_TO_TARGET; 4768 pReq->cbCDB = cbCDB; 4769 pReq->cbI2TData = cbToWrite; 4770 pReq->paI2TSegs = &pReq->aSegs[0]; 4771 pReq->cI2TSegs = cI2TSegs; 4772 pReq->cbT2IData = 0; 4773 pReq->paT2ISegs = NULL; 4774 pReq->cT2ISegs = 0; 4775 pReq->cbSense = sizeof(pReq->abSense); 4776 pReq->pIoCtx = pIoCtx; 4777 pReq->cSenseRetries = 10; 4778 pReq->rcSense = VERR_WRITE_ERROR; 4779 4780 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx)) 4781 { 4782 rc = iscsiCommandSync(pImage, pReq, true, VERR_WRITE_ERROR); 4783 if (RT_FAILURE(rc)) 5057 4784 { 5058 cbCDB = 10; 5059 pbCDB[0] = SCSI_WRITE_10; 5060 pbCDB[1] = 0; /* reserved */ 5061 pbCDB[2] = (lba >> 24) & 0xff; 5062 pbCDB[3] = (lba >> 16) & 0xff; 5063 pbCDB[4] = (lba >> 8) & 0xff; 5064 pbCDB[5] = lba & 0xff; 5065 pbCDB[6] = 0; /* reserved */ 5066 pbCDB[7] = (tls >> 8) & 0xff; 5067 pbCDB[8] = tls & 0xff; 5068 pbCDB[9] = 0; /* control */ 4785 LogFlow(("iscsiCommandSync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc)); 4786 *pcbWriteProcess = 0; 5069 4787 } 5070 4788 else 5071 { 5072 cbCDB = 16; 5073 pbCDB[0] = SCSI_WRITE_16; 5074 pbCDB[1] = 0; /* reserved */ 5075 pbCDB[2] = (lba >> 56) & 0xff; 5076 pbCDB[3] = (lba >> 48) & 0xff; 5077 pbCDB[4] = (lba >> 40) & 0xff; 5078 pbCDB[5] = (lba >> 32) & 0xff; 5079 pbCDB[6] = (lba >> 24) & 0xff; 5080 pbCDB[7] = (lba >> 16) & 0xff; 5081 pbCDB[8] = (lba >> 8) & 0xff; 5082 pbCDB[9] = lba & 0xff; 5083 pbCDB[10] = 0; /* tls unused */ 5084 pbCDB[11] = 0; /* tls unused */ 5085 pbCDB[12] = (tls >> 8) & 0xff; 5086 pbCDB[13] = tls & 0xff; 5087 pbCDB[14] = 0; /* reserved */ 5088 pbCDB[15] = 0; /* reserved */ 5089 } 5090 5091 pReq->enmXfer = SCSIXFER_TO_TARGET; 5092 pReq->cbCDB = cbCDB; 5093 pReq->pvCDB = pReqAsync->abCDB; 5094 pReq->cbI2TData = cbToWrite; 5095 pReq->paI2TSegs = &pReqAsync->aSegs[0]; 5096 pReq->cI2TSegs = pReqAsync->cI2TSegs; 5097 pReq->cbT2IData = 0; 5098 pReq->paT2ISegs = NULL; 5099 pReq->cT2ISegs = 0; 5100 pReq->cbSense = sizeof(pReqAsync->abSense); 5101 pReq->pvSense = pReqAsync->abSense; 5102 5103 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReqAsync); 4789 *pcbWriteProcess = cbToWrite; 4790 } 4791 else 4792 { 4793 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReq); 5104 4794 if (RT_FAILURE(rc)) 5105 AssertMsgFailed(("iscsiCommand (%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc));4795 AssertMsgFailed(("iscsiCommandAsync(%s, %#llx) -> %Rrc\n", pImage->pszTargetName, uOffset, rc)); 5106 4796 else 5107 4797 { … … 5109 4799 return VERR_VD_IOCTX_HALT; /* Halt the I/O context until further notification from the I/O thread. */ 5110 4800 } 5111 5112 RTMemFree(pReq); 5113 } 5114 else 5115 rc = VERR_NO_MEMORY; 5116 5117 RTMemFree(pReqAsync); 4801 } 4802 4803 RTMemFree(pReq); 5118 4804 } 5119 4805 else … … 5131 4817 int rc = VINF_SUCCESS; 5132 4818 5133 /** @todo: Remove iscsiFlushSync and integrate properly. */ 5134 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx)) 5135 return iscsiFlushSync(pBackendData); 5136 5137 PSCSIREQASYNC pReqAsync = (PSCSIREQASYNC)RTMemAllocZ(sizeof(SCSIREQASYNC)); 5138 if (RT_LIKELY(pReqAsync)) 5139 { 5140 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(sizeof(SCSIREQ)); 5141 if (pReq) 5142 { 5143 uint8_t *pbCDB = &pReqAsync->abCDB[0]; 5144 5145 pReqAsync->pIoCtx = pIoCtx; 5146 pReqAsync->pScsiReq = pReq; 5147 pReqAsync->cSenseRetries = 0; 5148 pReqAsync->rcSense = VINF_SUCCESS; 5149 5150 pbCDB[0] = SCSI_SYNCHRONIZE_CACHE; 5151 pbCDB[1] = 0; /* reserved */ 5152 pbCDB[2] = 0; /* reserved */ 5153 pbCDB[3] = 0; /* reserved */ 5154 pbCDB[4] = 0; /* reserved */ 5155 pbCDB[5] = 0; /* reserved */ 5156 pbCDB[6] = 0; /* reserved */ 5157 pbCDB[7] = 0; /* reserved */ 5158 pbCDB[8] = 0; /* reserved */ 5159 pbCDB[9] = 0; /* control */ 5160 5161 pReq->enmXfer = SCSIXFER_NONE; 5162 pReq->cbCDB = 10; 5163 pReq->pvCDB = pReqAsync->abCDB; 5164 pReq->cbI2TData = 0; 5165 pReq->paI2TSegs = NULL; 5166 pReq->cI2TSegs = 0; 5167 pReq->cbT2IData = 0; 5168 pReq->paT2ISegs = NULL; 5169 pReq->cT2ISegs = 0; 5170 pReq->cbSense = sizeof(pReqAsync->abSense); 5171 pReq->pvSense = pReqAsync->abSense; 5172 5173 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReqAsync); 4819 PSCSIREQ pReq = (PSCSIREQ)RTMemAllocZ(sizeof(SCSIREQ)); 4820 if (RT_LIKELY(pReq)) 4821 { 4822 uint8_t *pbCDB = &pReq->abCDB[0]; 4823 4824 pbCDB[0] = SCSI_SYNCHRONIZE_CACHE; 4825 pbCDB[1] = 0; /* reserved */ 4826 pbCDB[2] = 0; /* reserved */ 4827 pbCDB[3] = 0; /* reserved */ 4828 pbCDB[4] = 0; /* reserved */ 4829 pbCDB[5] = 0; /* reserved */ 4830 pbCDB[6] = 0; /* reserved */ 4831 pbCDB[7] = 0; /* reserved */ 4832 pbCDB[8] = 0; /* reserved */ 4833 pbCDB[9] = 0; /* control */ 4834 4835 pReq->enmXfer = SCSIXFER_NONE; 4836 pReq->cbCDB = 10; 4837 pReq->cbI2TData = 0; 4838 pReq->paI2TSegs = NULL; 4839 pReq->cI2TSegs = 0; 4840 pReq->cbT2IData = 0; 4841 pReq->paT2ISegs = NULL; 4842 pReq->cT2ISegs = 0; 4843 pReq->cbSense = sizeof(pReq->abSense); 4844 pReq->pIoCtx = pIoCtx; 4845 pReq->cSenseRetries = 0; 4846 pReq->rcSense = VINF_SUCCESS; 4847 4848 if (vdIfIoIntIoCtxIsSynchronous(pImage->pIfIo, pIoCtx)) 4849 { 4850 rc = iscsiCommandSync(pImage, pReq, false, VINF_SUCCESS); 4851 if (RT_FAILURE(rc)) 4852 AssertMsgFailed(("iscsiCommand(%s) -> %Rrc\n", pImage->pszTargetName, rc)); 4853 } 4854 else 4855 { 4856 rc = iscsiCommandAsync(pImage, pReq, iscsiCommandAsyncComplete, pReq); 5174 4857 if (RT_FAILURE(rc)) 5175 4858 AssertMsgFailed(("iscsiCommand(%s) -> %Rrc\n", pImage->pszTargetName, rc)); 5176 4859 else 5177 4860 return VERR_VD_IOCTX_HALT; /* Halt the I/O context until further notification from the I/O thread. */ 5178 5179 RTMemFree(pReq); 5180 } 5181 else 5182 rc = VERR_NO_MEMORY; 5183 5184 RTMemFree(pReqAsync); 4861 } 4862 4863 RTMemFree(pReq); 5185 4864 } 5186 4865 else
Note:
See TracChangeset
for help on using the changeset viewer.