Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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;
		}
	}
}
Exemple #4
0
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));
}