mirror of
https://github.com/reactos/reactos.git
synced 2024-08-27 21:58:49 +00:00
![Victor Perevertkin](/assets/img/avatar_default.png)
The source code is licensed under MS-PL license, taken from Windows Driver Samples repository (https://github.com/microsoft/Windows-driver-samples/tree/master/storage/class/classpnp/) Synched with commit 88541f70c4273ecd30c8c7c72135bc038a00fd88 The driver is written for Windows 8+, so we compile it with ntoskrnl_vista statically linked and with NTDDI_WIN8 defined CORE-17129
147 lines
4.2 KiB
C
147 lines
4.2 KiB
C
/*++
|
|
|
|
|
|
Copyright (C) Microsoft Corporation, 1991 - 1999
|
|
|
|
Module Name:
|
|
|
|
history.c
|
|
|
|
Abstract:
|
|
|
|
Packet history routines for CLASSPNP
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "classp.h"
|
|
#include "debug.h"
|
|
|
|
#ifdef DEBUG_USE_WPP
|
|
#include "history.tmh"
|
|
#endif
|
|
|
|
//#ifdef ALLOC_PRAGMA
|
|
// #pragma alloc_text(PAGE, InitializeTransferPackets)
|
|
//#endif
|
|
|
|
VOID HistoryInitializeRetryLogs(_Out_ PSRB_HISTORY History, ULONG HistoryCount) {
|
|
ULONG tmpSize = HistoryCount * sizeof(SRB_HISTORY_ITEM);
|
|
tmpSize += sizeof(SRB_HISTORY) - sizeof(SRB_HISTORY_ITEM);
|
|
RtlZeroMemory(History, tmpSize);
|
|
History->TotalHistoryCount = HistoryCount;
|
|
return;
|
|
}
|
|
|
|
|
|
VOID HistoryLogSendPacket(TRANSFER_PACKET * Pkt) {
|
|
|
|
PSRB_HISTORY history;
|
|
PSRB_HISTORY_ITEM item;
|
|
|
|
NT_ASSERT( Pkt->RetryHistory != NULL );
|
|
history = Pkt->RetryHistory;
|
|
// sending a packet implies a new history unit is to be used.
|
|
NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount );
|
|
|
|
// if already all used up, request class driver to remove at least one history unit
|
|
if (history->UsedHistoryCount == history->TotalHistoryCount )
|
|
{
|
|
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Pkt->Fdo->DeviceExtension;
|
|
PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
|
|
NT_ASSERT( fdoData->InterpretSenseInfo != NULL );
|
|
NT_ASSERT( fdoData->InterpretSenseInfo->Compress != NULL );
|
|
fdoData->InterpretSenseInfo->Compress( fdoExtension->DeviceObject, history );
|
|
NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
|
|
}
|
|
|
|
// thus, since we are about to increment the count, it must now be less...
|
|
NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount );
|
|
|
|
// increment the number of history units in use
|
|
history->UsedHistoryCount++;
|
|
|
|
// determine index to use
|
|
item = &( history->History[ history->UsedHistoryCount-1 ] );
|
|
|
|
// zero out the history item
|
|
RtlZeroMemory(item, sizeof(SRB_HISTORY_ITEM));
|
|
|
|
// Query the tick count and store in the history
|
|
KeQueryTickCount(&item->TickCountSent);
|
|
return;
|
|
}
|
|
|
|
VOID HistoryLogReturnedPacket(TRANSFER_PACKET *Pkt) {
|
|
|
|
PSRB_HISTORY history;
|
|
PSRB_HISTORY_ITEM item;
|
|
UCHAR senseSize;
|
|
PVOID senseInfoBuffer;
|
|
UCHAR senseInfoBufferLength;
|
|
SENSE_DATA convertedSenseBuffer = {0};
|
|
BOOLEAN validSense = TRUE;
|
|
|
|
NT_ASSERT( Pkt->RetryHistory != NULL );
|
|
history = Pkt->RetryHistory;
|
|
NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount );
|
|
item = &( history->History[ history->UsedHistoryCount-1 ] );
|
|
|
|
// Query the tick count and store in the history
|
|
KeQueryTickCount(&item->TickCountCompleted);
|
|
|
|
// Copy the SRB Status...
|
|
item->SrbStatus = Pkt->Srb->SrbStatus;
|
|
|
|
//
|
|
// Process sense data
|
|
//
|
|
|
|
senseInfoBuffer = ClasspTransferPacketGetSenseInfoBuffer(Pkt);
|
|
senseInfoBufferLength = ClasspTransferPacketGetSenseInfoBufferLength(Pkt);
|
|
|
|
if (IsDescriptorSenseDataFormat(senseInfoBuffer)) {
|
|
|
|
validSense = ScsiConvertToFixedSenseFormat(senseInfoBuffer,
|
|
senseInfoBufferLength,
|
|
(PVOID)&convertedSenseBuffer,
|
|
sizeof(convertedSenseBuffer));
|
|
|
|
if (validSense) {
|
|
senseInfoBuffer = (PVOID)&convertedSenseBuffer;
|
|
senseInfoBufferLength = sizeof(convertedSenseBuffer);
|
|
}
|
|
}
|
|
|
|
RtlZeroMemory(&(item->NormalizedSenseData), sizeof(item->NormalizedSenseData));
|
|
|
|
if (validSense) {
|
|
|
|
// Determine the amount of valid sense data
|
|
|
|
if (!ScsiGetTotalSenseByteCountIndicated(senseInfoBuffer,
|
|
senseInfoBufferLength,
|
|
&senseSize)) {
|
|
senseSize = senseInfoBufferLength;
|
|
}
|
|
|
|
// Normalize the sense data copy in the history
|
|
senseSize = min(senseSize, sizeof(item->NormalizedSenseData));
|
|
RtlCopyMemory(&(item->NormalizedSenseData),
|
|
senseInfoBuffer,
|
|
senseSize
|
|
);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|