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