1 /*++ 2 3 4 Copyright (C) Microsoft Corporation, 1991 - 1999 5 6 Module Name: 7 8 history.c 9 10 Abstract: 11 12 Packet history routines for CLASSPNP 13 14 Environment: 15 16 kernel mode only 17 18 Notes: 19 20 21 Revision History: 22 23 --*/ 24 25 #include "classp.h" 26 #include "debug.h" 27 28 #ifdef DEBUG_USE_WPP 29 #include "history.tmh" 30 #endif 31 32 //#ifdef ALLOC_PRAGMA 33 // #pragma alloc_text(PAGE, InitializeTransferPackets) 34 //#endif 35 36 VOID HistoryInitializeRetryLogs(_Out_ PSRB_HISTORY History, ULONG HistoryCount) { 37 ULONG tmpSize = HistoryCount * sizeof(SRB_HISTORY_ITEM); 38 tmpSize += sizeof(SRB_HISTORY) - sizeof(SRB_HISTORY_ITEM); 39 RtlZeroMemory(History, tmpSize); 40 History->TotalHistoryCount = HistoryCount; 41 return; 42 } 43 44 45 VOID HistoryLogSendPacket(TRANSFER_PACKET * Pkt) { 46 47 PSRB_HISTORY history; 48 PSRB_HISTORY_ITEM item; 49 50 NT_ASSERT( Pkt->RetryHistory != NULL ); 51 history = Pkt->RetryHistory; 52 // sending a packet implies a new history unit is to be used. 53 NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount ); 54 55 // if already all used up, request class driver to remove at least one history unit 56 if (history->UsedHistoryCount == history->TotalHistoryCount ) 57 { 58 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Pkt->Fdo->DeviceExtension; 59 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData; 60 NT_ASSERT( fdoData->InterpretSenseInfo != NULL ); 61 NT_ASSERT( fdoData->InterpretSenseInfo->Compress != NULL ); 62 fdoData->InterpretSenseInfo->Compress( fdoExtension->DeviceObject, history ); 63 NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount ); 64 } 65 66 // thus, since we are about to increment the count, it must now be less... 67 NT_ASSERT( history->UsedHistoryCount < history->TotalHistoryCount ); 68 69 // increment the number of history units in use 70 history->UsedHistoryCount++; 71 72 // determine index to use 73 item = &( history->History[ history->UsedHistoryCount-1 ] ); 74 75 // zero out the history item 76 RtlZeroMemory(item, sizeof(SRB_HISTORY_ITEM)); 77 78 // Query the tick count and store in the history 79 KeQueryTickCount(&item->TickCountSent); 80 return; 81 } 82 83 VOID HistoryLogReturnedPacket(TRANSFER_PACKET *Pkt) { 84 85 PSRB_HISTORY history; 86 PSRB_HISTORY_ITEM item; 87 UCHAR senseSize; 88 PVOID senseInfoBuffer; 89 UCHAR senseInfoBufferLength; 90 SENSE_DATA convertedSenseBuffer = {0}; 91 BOOLEAN validSense = TRUE; 92 93 NT_ASSERT( Pkt->RetryHistory != NULL ); 94 history = Pkt->RetryHistory; 95 NT_ASSERT( history->UsedHistoryCount <= history->TotalHistoryCount ); 96 item = &( history->History[ history->UsedHistoryCount-1 ] ); 97 98 // Query the tick count and store in the history 99 KeQueryTickCount(&item->TickCountCompleted); 100 101 // Copy the SRB Status... 102 item->SrbStatus = Pkt->Srb->SrbStatus; 103 104 // 105 // Process sense data 106 // 107 108 senseInfoBuffer = ClasspTransferPacketGetSenseInfoBuffer(Pkt); 109 senseInfoBufferLength = ClasspTransferPacketGetSenseInfoBufferLength(Pkt); 110 111 if (IsDescriptorSenseDataFormat(senseInfoBuffer)) { 112 113 validSense = ScsiConvertToFixedSenseFormat(senseInfoBuffer, 114 senseInfoBufferLength, 115 (PVOID)&convertedSenseBuffer, 116 sizeof(convertedSenseBuffer)); 117 118 if (validSense) { 119 senseInfoBuffer = (PVOID)&convertedSenseBuffer; 120 senseInfoBufferLength = sizeof(convertedSenseBuffer); 121 } 122 } 123 124 RtlZeroMemory(&(item->NormalizedSenseData), sizeof(item->NormalizedSenseData)); 125 126 if (validSense) { 127 128 // Determine the amount of valid sense data 129 130 if (!ScsiGetTotalSenseByteCountIndicated(senseInfoBuffer, 131 senseInfoBufferLength, 132 &senseSize)) { 133 senseSize = senseInfoBufferLength; 134 } 135 136 // Normalize the sense data copy in the history 137 senseSize = min(senseSize, sizeof(item->NormalizedSenseData)); 138 RtlCopyMemory(&(item->NormalizedSenseData), 139 senseInfoBuffer, 140 senseSize 141 ); 142 } 143 144 return; 145 } 146 147