void AHCIPort::ScsiUnmap(scsi_ccb* request, scsi_unmap_parameter_list* unmapBlocks) { // Determine how many ranges we'll need // We assume that the SCSI unmap ranges cannot be merged together uint32 scsiRangeCount = B_BENDIAN_TO_HOST_INT16( unmapBlocks->block_data_length) / sizeof(scsi_unmap_block_descriptor); uint32 lbaRangeCount = 0; for (uint32 i = 0; i < scsiRangeCount; i++) { lbaRangeCount += ((uint32)B_BENDIAN_TO_HOST_INT32( unmapBlocks->blocks[i].block_count) + 65534) / 65535; } uint32 lbaRangesSize = lbaRangeCount * sizeof(uint64); uint64* lbaRanges = (uint64*)malloc(lbaRangesSize); if (lbaRanges == NULL) { TRACE("out of memory when allocating %" B_PRIu32 " unmap ranges\n", lbaRangeCount); request->subsys_status = SCSI_REQ_ABORTED; gSCSI->finished(request, 1); return; } MemoryDeleter deleter(lbaRanges); for (uint32 i = 0, scsiIndex = 0; scsiIndex < scsiRangeCount; scsiIndex++) { uint64 lba = (uint64)B_BENDIAN_TO_HOST_INT64( unmapBlocks->blocks[scsiIndex].lba); uint64 blocksLeft = (uint32)B_BENDIAN_TO_HOST_INT32( unmapBlocks->blocks[scsiIndex].block_count); while (blocksLeft > 0) { uint16 blocks = blocksLeft > 65535 ? 65535 : (uint16)blocksLeft; lbaRanges[i++] = B_HOST_TO_LENDIAN_INT64( ((uint64)blocks << 48) | lba); lba += blocks; blocksLeft -= blocks; } } sata_request sreq; sreq.SetATA48Command(ATA_COMMAND_DATA_SET_MANAGEMENT, 0, (lbaRangesSize + 511) / 512); sreq.SetFeature(1); sreq.SetData(lbaRanges, lbaRangesSize); ExecuteSataRequest(&sreq); sreq.WaitForCompletion(); if ((sreq.CompletionStatus() & ATA_ERR) != 0) { TRACE("trim failed (%" B_PRIu32 " ranges)!\n", lbaRangeCount); request->subsys_status = SCSI_REQ_CMP_ERR; } else request->subsys_status = SCSI_REQ_CMP; request->data_resid = 0; request->device_status = SCSI_STATUS_GOOD; gSCSI->finished(request, 1); }
void MemoryView::_HandleContextMenu(BPoint point) { int32 offset = _GetOffsetAt(point); if (offset < fSelectionStart || offset > fSelectionEnd) return; BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options"); if (menu == NULL) return; ObjectDeleter<BPopUpMenu> menuDeleter(menu); ObjectDeleter<BMenuItem> itemDeleter; ObjectDeleter<BMessage> messageDeleter; BMessage* message = NULL; BMenuItem* item = NULL; if (fSelectionEnd - fSelectionStart == fTargetAddressSize / 2) { BMessage* message = new(std::nothrow) BMessage(MSG_INSPECT_ADDRESS); if (message == NULL) return; target_addr_t address; if (fTargetAddressSize == 8) address = *((uint32*)(fTargetBlock->Data() + fSelectionStart)); else address = *((uint64*)(fTargetBlock->Data() + fSelectionStart)); if (fCurrentEndianMode == EndianModeBigEndian) address = B_HOST_TO_BENDIAN_INT64(address); else address = B_HOST_TO_LENDIAN_INT64(address); messageDeleter.SetTo(message); message->AddUInt64("address", address); BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message); if (item == NULL) return; messageDeleter.Detach(); itemDeleter.SetTo(item); if (!menu->AddItem(item)) return; item->SetTarget(Looper()); itemDeleter.Detach(); } message = new(std::nothrow) BMessage(B_COPY); if (message == NULL) return; messageDeleter.SetTo(message); item = new(std::nothrow) BMenuItem("Copy", message); if (item == NULL) return; messageDeleter.Detach(); itemDeleter.SetTo(item); if (!menu->AddItem(item)) return; item->SetTarget(this); itemDeleter.Detach(); menuDeleter.Detach(); BPoint screenWhere(point); ConvertToScreen(&screenWhere); BRect mouseRect(screenWhere, screenWhere); mouseRect.InsetBy(-4.0, -4.0); menu->Go(screenWhere, true, false, mouseRect, true); }
void MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, const char* address) { switch(fHexMode) { case HexMode8BitInt: { snprintf(buffer, bufferSize, "%02" B_PRIx8, *((const uint8*)address)); break; } case HexMode16BitInt: { uint16 data = *((const uint16*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT16(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT16(data); } break; } snprintf(buffer, bufferSize, "%04" B_PRIx16, data); break; } case HexMode32BitInt: { uint32 data = *((const uint32*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT32(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT32(data); } break; } snprintf(buffer, bufferSize, "%08" B_PRIx32, data); break; } case HexMode64BitInt: { uint64 data = *((const uint64*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT64(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT64(data); } break; } snprintf(buffer, bufferSize, "%0*" B_PRIx64, 16, data); break; } } }
void XTSMode::EncryptBlock(ThreadContext& context, uint8 *data, size_t length, uint64 blockIndex) { uint8 whiteningValue[BYTES_PER_XTS_BLOCK]; uint8 byteBufUnitNo[BYTES_PER_XTS_BLOCK]; uint64* bufPtr = (uint64*)data; uint32 startBlock = 0; uint32 endBlock, block; uint64 blockCount, dataUnitNo; uint8 finalCarry; // Convert the 64-bit data unit number into a little-endian 16-byte array. dataUnitNo = blockIndex; *((uint64*)byteBufUnitNo) = B_HOST_TO_LENDIAN_INT64(dataUnitNo); *((uint64*)byteBufUnitNo + 1) = 0; //ASSERT((length % BYTES_PER_XTS_BLOCK) == 0); blockCount = length / BYTES_PER_XTS_BLOCK; // Process all blocks in the buffer while (blockCount > 0) { if (blockCount < BLOCKS_PER_XTS_DATA_UNIT) endBlock = startBlock + (uint32)blockCount; else endBlock = BLOCKS_PER_XTS_DATA_UNIT; uint64* whiteningValuePtr64 = (uint64*)whiteningValue; // Encrypt the data unit number using the secondary key (in order to // generate the first whitening value for this data unit) *whiteningValuePtr64 = *((uint64*)byteBufUnitNo); *(whiteningValuePtr64 + 1) = 0; fSecondaryAlgorithm->Encrypt(context, (uint8*)whiteningValue, BYTES_PER_XTS_BLOCK); // Generate (and apply) subsequent whitening values for blocks in this // data unit and encrypt all relevant blocks in this data unit for (block = 0; block < endBlock; block++) { if (block >= startBlock) { // Pre-whitening *bufPtr++ ^= *whiteningValuePtr64++; *bufPtr-- ^= *whiteningValuePtr64--; // Actual encryption fAlgorithm->Encrypt(context, (uint8*)bufPtr, BYTES_PER_XTS_BLOCK); // Post-whitening *bufPtr++ ^= *whiteningValuePtr64++; *bufPtr++ ^= *whiteningValuePtr64; } else whiteningValuePtr64++; // Derive the next whitening value #if BYTE_ORDER == LITTLE_ENDIAN // Little-endian platforms finalCarry = (*whiteningValuePtr64 & 0x8000000000000000ULL) ? 135 : 0; *whiteningValuePtr64-- <<= 1; if (*whiteningValuePtr64 & 0x8000000000000000ULL) *(whiteningValuePtr64 + 1) |= 1; *whiteningValuePtr64 <<= 1; #else // Big-endian platforms finalCarry = (*whiteningValuePtr64 & 0x80) ? 135 : 0; *whiteningValuePtr64 = B_HOST_TO_LENDIAN_INT64( B_HOST_TO_LENDIAN_INT64(*whiteningValuePtr64) << 1); whiteningValuePtr64--; if (*whiteningValuePtr64 & 0x80) *(whiteningValuePtr64 + 1) |= 0x0100000000000000ULL; *whiteningValuePtr64 = B_HOST_TO_LENDIAN_INT64( B_HOST_TO_LENDIAN_INT64(*whiteningValuePtr64) << 1); #endif whiteningValue[0] ^= finalCarry; } blockCount -= endBlock - startBlock; startBlock = 0; dataUnitNo++; *((uint64*)byteBufUnitNo) = B_HOST_TO_LENDIAN_INT64(dataUnitNo); } memset(whiteningValue, 0, sizeof(whiteningValue)); }