ReactOS 0.4.15-dev-7934-g1dc8d80
storahci.c File Reference
#include "storahci.h"
Include dependency graph for storahci.c:

Go to the source code of this file.

Functions

AhciPortInitialize

@implemented

Initialize port by setting up PxCLB & PxFB Registers

Parameters
PortExtension
Returns
Return true if intialization was successful
BOOLEAN NTAPI AhciPortInitialize (__in PVOID DeviceExtension)
 
AhciAllocateResourceForAdapter

@implemented

Allocate memory from poll for required pointers

Parameters
AdapterExtension
ConfigInfo
Returns
return TRUE if allocation was successful
BOOLEAN AhciAllocateResourceForAdapter (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PPORT_CONFIGURATION_INFORMATION ConfigInfo)
 
AhciStartPort

@implemented

Try to start the port device

Parameters
AdapterExtension
PortExtension
BOOLEAN AhciStartPort (__in PAHCI_PORT_EXTENSION PortExtension)
 
AhciCommandCompletionDpcRoutine

@implemented

Handles Completed Commands

Parameters
Dpc
AdapterExtension
SystemArgument1
SystemArgument2
VOID AhciCommandCompletionDpcRoutine (__in PSTOR_DPC Dpc, __in PVOID HwDeviceExtension, __in PVOID SystemArgument1, __in PVOID SystemArgument2)
 
AhciHwPassiveInitialize

@implemented

initializes the HBA and finds all devices that are of interest to the miniport driver. (at PASSIVE LEVEL)

Parameters
adapterExtension
Returns
return TRUE if intialization was successful
BOOLEAN AhciHwPassiveInitialize (__in PVOID DeviceExtension)
 
AhciHwInitialize

@implemented

initializes the HBA and finds all devices that are of interest to the miniport driver.

Parameters
adapterExtension
Returns
return TRUE if intialization was successful
BOOLEAN NTAPI AhciHwInitialize (__in PVOID DeviceExtension)
 
AhciCompleteIssuedSrb

@implemented

Complete issued Srbs

Parameters
PortExtension
VOID AhciCompleteIssuedSrb (__in PAHCI_PORT_EXTENSION PortExtension, __in ULONG CommandsToComplete)
 
AhciInterruptHandler

@not_implemented

Interrupt Handler for PortExtension

Parameters
PortExtension
VOID AhciInterruptHandler (__in PAHCI_PORT_EXTENSION PortExtension)
 
AhciHwInterrupt

@implemented

The Storport driver calls the HwStorInterrupt routine after the HBA generates an interrupt request.

Parameters
AdapterExtension
Returns
return TRUE Indicates that an interrupt was pending on adapter. return FALSE Indicates the interrupt was not ours.
BOOLEAN NTAPI AhciHwInterrupt (__in PVOID DeviceExtension)
 
AhciHwStartIo

@not_implemented

The Storport driver calls the HwStorStartIo routine one time for each incoming I/O request.

Parameters
adapterExtension
Srb
Returns
return TRUE if the request was accepted return FALSE if the request must be submitted later
BOOLEAN NTAPI AhciHwStartIo (__in PVOID DeviceExtension, __in PSCSI_REQUEST_BLOCK Srb)
 
AhciHwResetBus

@not_implemented

The HwStorResetBus routine is called by the port driver to clear error conditions.

Parameters
adapterExtension
PathId
Returns
return TRUE if bus was successfully reset
BOOLEAN NTAPI AhciHwResetBus (__in PVOID AdapterExtension, __in ULONG PathId)
 
AhciHwFindAdapter

@implemented

The HwStorFindAdapter routine uses the supplied configuration to determine whether a specific HBA is supported and, if it is, to return configuration information about that adapter.

10.1 Platform Communication http://www.intel.in/content/dam/www/public/us/en/documents/technical-specifications/serial-ata-ahci-spec-rev1_2.pdf

Parameters
DeviceExtension
HwContext
BusInformation
ArgumentString
ConfigInfo
Reserved3
Returns
SP_RETURN_FOUND Indicates that a supported HBA was found and that the HBA-relevant configuration information was successfully determined and set in the PORT_CONFIGURATION_INFORMATION structure.

SP_RETURN_ERROR Indicates that an HBA was found but there was an error obtaining the configuration information. If possible, such an error should be logged with StorPortLogError.

SP_RETURN_BAD_CONFIG Indicates that the supplied configuration information was invalid for the adapter.

SP_RETURN_NOT_FOUND Indicates that no supported HBA was found for the supplied configuration information.

Remarks
Called by Storport.
ULONG NTAPI AhciHwFindAdapter (__in PVOID DeviceExtension, __in PVOID HwContext, __in PVOID BusInformation, __in PCHAR ArgumentString, __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo, __in PBOOLEAN Reserved3)
 
DriverEntry

@implemented

Initial Entrypoint for storahci miniport driver

Parameters
DriverObject
RegistryPath
Returns
NT_STATUS in case of driver loaded successfully.
ULONG NTAPI DriverEntry (__in PVOID DriverObject, __in PVOID RegistryPath)
 
AhciATA_CFIS

@implemented

create ATA CFIS from Srb

Parameters
PortExtension
Srb
Returns
Number of CFIS fields used in DWORD
ULONG AhciATA_CFIS (__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
 
AhciATAPI_CFIS

@not_implemented

create ATAPI CFIS from Srb

Parameters
PortExtension
Srb
Returns
Number of CFIS fields used in DWORD
ULONG AhciATAPI_CFIS (__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
 
AhciBuild_PRDT

@implemented

Build PRDT for data transfer

Parameters
PortExtension
Srb
Returns
Return number of entries in PRDT.
ULONG AhciBuild_PRDT (__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
 
AhciProcessSrb

@implemented

Prepare Srb for IO processing

Parameters
PortExtension
Srb
SlotIndex
VOID AhciProcessSrb (__in PAHCI_PORT_EXTENSION PortExtension, __in PSCSI_REQUEST_BLOCK Srb, __in ULONG SlotIndex)
 
AhciActivatePort

@implemented

Program Port and populate command list

Parameters
PortExtension
VOID AhciActivatePort (__in PAHCI_PORT_EXTENSION PortExtension)
 
AhciProcessIO

@implemented

Acquire Exclusive lock to port, populate pending commands to command List program controller's port to process new commands in command list.

Parameters
AdapterExtension
PathId
Srb
VOID AhciProcessIO (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in UCHAR PathId, __in PSCSI_REQUEST_BLOCK Srb)
 
AtapiInquiryCompletion

@implemented

AtapiInquiryCompletion routine should be called after device signals for device inquiry request is completed (through interrupt) – ATAPI Device only

Parameters
PortExtension
Srb
VOID AtapiInquiryCompletion (__in PVOID _Extension, __in PVOID _Srb)
 
InquiryCompletion

@implemented

InquiryCompletion routine should be called after device signals for device inquiry request is completed (through interrupt)

Parameters
PortExtension
Srb
VOID InquiryCompletion (__in PVOID _Extension, __in PVOID _Srb)
 
AhciATAPICommand

@implemented

Handles ATAPI Requests commands

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for AhciATAPICommand
UCHAR AhciATAPICommand (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceRequestSense

@implemented

Handle SCSIOP_MODE_SENSE OperationCode

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceRequestSense
UCHAR DeviceRequestSense (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceRequestReadWrite

@implemented

Handle SCSIOP_READ SCSIOP_WRITE OperationCode

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceRequestReadWrite
UCHAR DeviceRequestReadWrite (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceRequestCapacity

@implemented

Handle SCSIOP_READ_CAPACITY OperationCode

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceRequestCapacity
UCHAR DeviceRequestCapacity (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceRequestComplete

@implemented

Handle UnHandled Requests

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceRequestComplete
UCHAR DeviceRequestComplete (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceReportLuns

@implemented

Handle SCSIOP_REPORT_LUNS OperationCode

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceReportLuns
UCHAR DeviceReportLuns (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
DeviceInquiryRequest

@implemented

Tells wheather given port is implemented or not

Parameters
AdapterExtension
Srb
Cdb
Returns
return STOR status for DeviceInquiryRequest
Remarks
http://www.seagate.com/staticfiles/support/disc/manuals/Interface%20manuals/100293068c.pdf
UCHAR DeviceInquiryRequest (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
 
AhciAdapterReset

@implemented

10.4.3 HBA Reset If the HBA becomes unusable for multiple ports, and a software reset or port reset does not correct the problem, software may reset the entire HBA by setting GHC.HR to ‘1’. When software sets the GHC.HR bit to ‘1’, the HBA shall perform an internal reset action. The bit shall be cleared to ‘0’ by the HBA when the reset is complete. A software write of ‘0’ to GHC.HR shall have no effect. To perform the HBA reset, software sets GHC.HR to ‘1’ and may poll until this bit is read to be ‘0’, at which point software knows that the HBA reset has completed. If the HBA has not cleared GHC.HR to ‘0’ within 1 second of software setting GHC.HR to ‘1’, the HBA is in a hung or locked state.

Parameters
AdapterExtension
Returns
TRUE in case AHCI Controller RESTARTED successfully. i.e GHC.HR == 0
BOOLEAN AhciAdapterReset (__in PAHCI_ADAPTER_EXTENSION AdapterExtension)
 
AhciZeroMemory

@implemented

Clear buffer by filling zeros

Parameters
Buffer
BufferSize
FORCEINLINE VOID AhciZeroMemory (__out PCHAR Buffer, __in ULONG BufferSize)
 
IsPortValid

@implemented

Tells wheather given port is implemented or not

Parameters
AdapterExtension
PathId
Returns
return TRUE if provided port is valid (implemented) or not
FORCEINLINE BOOLEAN IsPortValid (__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in ULONG pathId)
 
AddQueue

@implemented

Add Srb to Queue

Parameters
Queue
Srb
Returns
return TRUE if Srb is successfully added to Queue
FORCEINLINE BOOLEAN AddQueue (__inout PAHCI_QUEUE Queue, __in PVOID Srb)
 
RemoveQueue

@implemented

Remove and return Srb from Queue

Parameters
Queue
Returns
return Srb
FORCEINLINE PVOID RemoveQueue (__inout PAHCI_QUEUE Queue)
 
GetSrbExtension

@implemented

GetSrbExtension from Srb make sure It is properly aligned

Parameters
Srb
Returns
return SrbExtension
FORCEINLINE PAHCI_SRB_EXTENSION GetSrbExtension (__in PSCSI_REQUEST_BLOCK Srb)
 
AhciGetLba

@implemented

Find the logical address of demand block from Cdb

Parameters
Srb
Returns
return Logical Address of the block
FORCEINLINE ULONG64 AhciGetLba (__in PCDB Cdb, __in ULONG CdbLength)
 

Function Documentation

◆ AddQueue()

FORCEINLINE BOOLEAN AddQueue ( __inout PAHCI_QUEUE  Queue,
__in PVOID  Srb 
)

Definition at line 2501 of file storahci.c.

2505{
2508
2509 if (Queue->Tail == ((Queue->Head + 1) % MAXIMUM_QUEUE_BUFFER_SIZE))
2510 return FALSE;
2511
2512 Queue->Buffer[Queue->Head++] = Srb;
2514
2515 return TRUE;
2516}// -- AddQueue();
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAXIMUM_QUEUE_BUFFER_SIZE
Definition: storahci.h:24
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by AhciCompleteIssuedSrb(), and AhciProcessIO().

◆ AhciActivatePort()

VOID AhciActivatePort ( __in PAHCI_PORT_EXTENSION  PortExtension)

Definition at line 1490 of file storahci.c.

1493{
1495 ULONG QueueSlots, slotToActivate, tmp;
1496 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1497
1498 AhciDebugPrint("AhciActivatePort()\n");
1499
1500 AdapterExtension = PortExtension->AdapterExtension;
1501 QueueSlots = PortExtension->QueueSlots;
1502
1503 if (QueueSlots == 0)
1504 {
1505 return;
1506 }
1507
1508 // section 3.3.14
1509 // Bits in this field shall only be set to ‘1’ by software when PxCMD.ST is set to ‘1’
1510 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
1511
1512 if (cmd.ST == 0) // PxCMD.ST == 0
1513 {
1514 return;
1515 }
1516
1517 // get the lowest set bit
1518 tmp = QueueSlots & (QueueSlots - 1);
1519
1520 if (tmp == 0)
1521 slotToActivate = QueueSlots;
1522 else
1523 slotToActivate = (QueueSlots & (~tmp));
1524
1525 // mark that bit off in QueueSlots
1526 // so we can know we it is really needed to activate port or not
1527 PortExtension->QueueSlots &= ~slotToActivate;
1528 // mark this CommandIssuedSlots
1529 // to validate in completeIssuedCommand
1530 PortExtension->CommandIssuedSlots |= slotToActivate;
1531
1532 // tell the HBA to issue this Command Slot to the given port
1533 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CI, slotToActivate);
1534
1535 return;
1536}// -- AhciActivatePort();
STORPORT_API ULONG NTAPI StorPortReadRegisterUlong(_In_ PVOID HwDeviceExtension, _In_ PULONG Register)
Definition: stubs.c:143
STORPORT_API VOID NTAPI StorPortWriteRegisterUlong(_In_ PVOID HwDeviceExtension, _In_ PULONG Register, _In_ ULONG Value)
Definition: stubs.c:291
#define AhciDebugPrint(format,...)
Definition: storahci.h:85
Definition: ftp_var.h:139
uint32_t ULONG
Definition: typedefs.h:59

Referenced by AhciProcessIO().

◆ AhciAdapterReset()

BOOLEAN AhciAdapterReset ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension)

Definition at line 2393 of file storahci.c.

2396{
2397 ULONG ticks;
2398 AHCI_GHC ghc;
2400
2401 AhciDebugPrint("AhciAdapterReset()\n");
2402
2403 abar = AdapterExtension->ABAR_Address;
2404 if (abar == NULL) // basic sanity
2405 {
2406 return FALSE;
2407 }
2408
2409 // HR -- Very first bit (lowest significant)
2410 ghc.HR = 1;
2411 StorPortWriteRegisterUlong(AdapterExtension, &abar->GHC, ghc.Status);
2412
2413 for (ticks = 0; ticks < 50; ++ticks)
2414 {
2415 ghc.Status = StorPortReadRegisterUlong(AdapterExtension, &abar->GHC);
2416 if (ghc.HR == 0)
2417 {
2418 break;
2419 }
2421 }
2422
2423 if (ticks == 50)// 1 second
2424 {
2425 AhciDebugPrint("\tDevice Timeout\n");
2426 return FALSE;
2427 }
2428
2429 return TRUE;
2430}// -- AhciAdapterReset();
#define NULL
Definition: types.h:112
STORPORT_API VOID NTAPI StorPortStallExecution(_In_ ULONG Delay)
Definition: storport.c:1417
ULONG Status
Definition: storahci.h:261
ULONG HR
Definition: storahci.h:254

Referenced by AhciHwFindAdapter().

◆ AhciAllocateResourceForAdapter()

BOOLEAN AhciAllocateResourceForAdapter ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PPORT_CONFIGURATION_INFORMATION  ConfigInfo 
)

Definition at line 145 of file storahci.c.

149{
150 PCHAR nonCachedExtension, tmp;
151 ULONG index, NCS, AlignedNCS;
152 ULONG portCount, portImplemented, nonCachedExtensionSize;
153 PAHCI_PORT_EXTENSION PortExtension;
154
155 AhciDebugPrint("AhciAllocateResourceForAdapter()\n");
156
157 NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP);
158 AlignedNCS = ROUND_UP(NCS, 8);
159
160 // get port count -- Number of set bits in `AdapterExtension->PortImplemented`
161 portCount = 0;
162 portImplemented = AdapterExtension->PortImplemented;
163
164 NT_ASSERT(portImplemented != 0);
165 for (index = MAXIMUM_AHCI_PORT_COUNT - 1; index > 0; index--)
166 if ((portImplemented & (1 << index)) != 0)
167 break;
168
169 portCount = index + 1;
170 AhciDebugPrint("\tPort Count: %d\n", portCount);
171
172 AdapterExtension->PortCount = portCount;
173 nonCachedExtensionSize = sizeof(AHCI_COMMAND_HEADER) * AlignedNCS + //should be 1K aligned
174 sizeof(AHCI_RECEIVED_FIS) +
175 sizeof(IDENTIFY_DEVICE_DATA);
176
177 // align nonCachedExtensionSize to 1024
178 nonCachedExtensionSize = ROUND_UP(nonCachedExtensionSize, 1024);
179
180 AdapterExtension->NonCachedExtension = StorPortGetUncachedExtension(AdapterExtension,
181 ConfigInfo,
182 nonCachedExtensionSize * portCount);
183
184 if (AdapterExtension->NonCachedExtension == NULL)
185 {
186 AhciDebugPrint("\tadapterExtension->NonCachedExtension == NULL\n");
187 return FALSE;
188 }
189
190 nonCachedExtension = AdapterExtension->NonCachedExtension;
191 AhciZeroMemory(nonCachedExtension, nonCachedExtensionSize * portCount);
192
193 for (index = 0; index < portCount; index++)
194 {
195 PortExtension = &AdapterExtension->PortExtension[index];
196
197 PortExtension->DeviceParams.IsActive = FALSE;
198 if ((AdapterExtension->PortImplemented & (1 << index)) != 0)
199 {
200 PortExtension->PortNumber = index;
201 PortExtension->DeviceParams.IsActive = TRUE;
202 PortExtension->AdapterExtension = AdapterExtension;
203 PortExtension->CommandList = (PAHCI_COMMAND_HEADER)nonCachedExtension;
204
205 tmp = (PCHAR)(nonCachedExtension + sizeof(AHCI_COMMAND_HEADER) * AlignedNCS);
206
207 PortExtension->ReceivedFIS = (PAHCI_RECEIVED_FIS)tmp;
208 PortExtension->IdentifyDeviceData = (PIDENTIFY_DEVICE_DATA)(tmp + sizeof(AHCI_RECEIVED_FIS));
209 PortExtension->MaxPortQueueDepth = NCS;
210 nonCachedExtension += nonCachedExtensionSize;
211 }
212 }
213
214 return TRUE;
215}// -- AhciAllocateResourceForAdapter();
struct _IDENTIFY_DEVICE_DATA * PIDENTIFY_DEVICE_DATA
struct _IDENTIFY_DEVICE_DATA IDENTIFY_DEVICE_DATA
#define index(s, c)
Definition: various.h:29
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
GLuint index
Definition: glext.h:6031
#define PCHAR
Definition: match.c:90
FORCEINLINE VOID AhciZeroMemory(__out PCHAR Buffer, __in ULONG BufferSize)
Definition: storahci.c:2443
#define MAXIMUM_AHCI_PORT_COUNT
Definition: storahci.h:21
#define AHCI_Global_Port_CAP_NCS(x)
Definition: storahci.h:81
struct _AHCI_COMMAND_HEADER * PAHCI_COMMAND_HEADER
struct _AHCI_RECEIVED_FIS * PAHCI_RECEIVED_FIS
struct _AHCI_COMMAND_HEADER AHCI_COMMAND_HEADER
STORPORT_API PVOID NTAPI StorPortGetUncachedExtension(_In_ PVOID HwDeviceExtension, _In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo, _In_ ULONG NumberOfBytes)
Definition: storport.c:880
struct _AHCI_PORT_EXTENSION::@1344 DeviceParams
struct _AHCI_ADAPTER_EXTENSION * AdapterExtension
Definition: storahci.h:494
PIDENTIFY_DEVICE_DATA IdentifyDeviceData
Definition: storahci.h:492
PAHCI_RECEIVED_FIS ReceivedFIS
Definition: storahci.h:489
PAHCI_COMMAND_HEADER CommandList
Definition: storahci.h:490
char * PCHAR
Definition: typedefs.h:51

Referenced by AhciHwFindAdapter().

◆ AhciATA_CFIS()

ULONG AhciATA_CFIS ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in PAHCI_SRB_EXTENSION  SrbExtension 
)

Definition at line 1219 of file storahci.c.

1223{
1224 PAHCI_COMMAND_TABLE cmdTable;
1225
1226 UNREFERENCED_PARAMETER(PortExtension);
1227
1228 AhciDebugPrint("AhciATA_CFIS()\n");
1229
1230 cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
1231
1232 AhciZeroMemory((PCHAR)cmdTable->CFIS, sizeof(cmdTable->CFIS));
1233
1234 cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = FIS_TYPE_REG_H2D; // FIS Type
1235 cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C
1236 cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg;
1237
1238 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow;
1239 cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0;
1240 cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1;
1241 cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2;
1242 cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device;
1243 cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3;
1244 cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4;
1245 cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5;
1246 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh;
1247 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow;
1248 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh;
1249
1250 return 5;
1251}// -- AhciATA_CFIS();
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define AHCI_ATA_CFIS_Device
Definition: storahci.h:53
struct _AHCI_COMMAND_TABLE * PAHCI_COMMAND_TABLE
#define AHCI_ATA_CFIS_FeaturesLow
Definition: storahci.h:49
#define FIS_TYPE_REG_H2D
Definition: storahci.h:38
#define AHCI_ATA_CFIS_LBA1
Definition: storahci.h:51
#define AHCI_ATA_CFIS_LBA2
Definition: storahci.h:52
#define AHCI_ATA_CFIS_LBA4
Definition: storahci.h:55
#define AHCI_ATA_CFIS_CommandReg
Definition: storahci.h:48
#define AHCI_ATA_CFIS_LBA3
Definition: storahci.h:54
#define AHCI_ATA_CFIS_FisType
Definition: storahci.h:46
#define AHCI_ATA_CFIS_SectorCountHigh
Definition: storahci.h:59
#define AHCI_ATA_CFIS_PMPort_C
Definition: storahci.h:47
#define AHCI_ATA_CFIS_SectorCountLow
Definition: storahci.h:58
#define AHCI_ATA_CFIS_LBA5
Definition: storahci.h:56
#define AHCI_ATA_CFIS_FeaturesHigh
Definition: storahci.h:57
#define AHCI_ATA_CFIS_LBA0
Definition: storahci.h:50
UCHAR CFIS[64]
Definition: storahci.h:360

Referenced by AhciProcessSrb().

◆ AhciATAPI_CFIS()

ULONG AhciATAPI_CFIS ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in PAHCI_SRB_EXTENSION  SrbExtension 
)

Definition at line 1266 of file storahci.c.

1270{
1271 PAHCI_COMMAND_TABLE cmdTable;
1272 UNREFERENCED_PARAMETER(PortExtension);
1273
1274 AhciDebugPrint("AhciATAPI_CFIS()\n");
1275
1276 cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
1277
1278 NT_ASSERT(SrbExtension->CommandReg == IDE_COMMAND_ATAPI_PACKET);
1279
1280 AhciZeroMemory((PCHAR)cmdTable->CFIS, sizeof(cmdTable->CFIS));
1281
1282 cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = FIS_TYPE_REG_H2D; // FIS Type
1283 cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C
1284 cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg;
1285
1286 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow;
1287 cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0;
1288 cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1;
1289 cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2;
1290 cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device;
1291 cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3;
1292 cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4;
1293 cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5;
1294 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh;
1295 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow;
1296 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh;
1297
1298 return 5;
1299}// -- AhciATAPI_CFIS();
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109

Referenced by AhciProcessSrb().

◆ AhciATAPICommand()

UCHAR AhciATAPICommand ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 1843 of file storahci.c.

1848{
1849 ULONG SrbFlags, DataBufferLength;
1850 PAHCI_SRB_EXTENSION SrbExtension;
1851 PAHCI_PORT_EXTENSION PortExtension;
1852
1853 AhciDebugPrint("AhciATAPICommand()\n");
1854
1855 SrbFlags = Srb->SrbFlags;
1856 SrbExtension = GetSrbExtension(Srb);
1858 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
1859
1860 NT_ASSERT(PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI);
1861
1862 NT_ASSERT(SrbExtension != NULL);
1863
1865 SrbExtension->Flags = 0;
1866
1867 if (SrbFlags & SRB_FLAGS_DATA_IN)
1868 {
1869 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
1870 }
1871
1872 if (SrbFlags & SRB_FLAGS_DATA_OUT)
1873 {
1874 SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
1875 }
1876
1877 SrbExtension->FeaturesLow = 0;
1878
1879 SrbExtension->CompletionRoutine = NULL;
1880
1881 NT_ASSERT(Cdb != NULL);
1882 switch(Cdb->CDB10.OperationCode)
1883 {
1884 case SCSIOP_INQUIRY:
1885 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
1887 break;
1888 case SCSIOP_READ:
1889 SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
1890 SrbExtension->FeaturesLow = 0x5;
1891 break;
1892 case SCSIOP_WRITE:
1893 SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
1894 SrbExtension->FeaturesLow = 0x1;
1895 break;
1896 }
1897
1898 SrbExtension->CommandReg = IDE_COMMAND_ATAPI_PACKET;
1899
1900 SrbExtension->LBA0 = 0;
1901 SrbExtension->LBA1 = (UCHAR)(DataBufferLength >> 0);
1902 SrbExtension->LBA2 = (UCHAR)(DataBufferLength >> 8);
1903 SrbExtension->Device = 0;
1904 SrbExtension->LBA3 = 0;
1905 SrbExtension->LBA4 = 0;
1906 SrbExtension->LBA5 = 0;
1907 SrbExtension->FeaturesHigh = 0;
1908 SrbExtension->SectorCountLow = 0;
1909 SrbExtension->SectorCountHigh = 0;
1910
1911 if ((SrbExtension->Flags & ATA_FLAGS_DATA_IN) || (SrbExtension->Flags & ATA_FLAGS_DATA_OUT))
1912 {
1913 SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
1914 }
1915
1916 return SRB_STATUS_PENDING;
1917}// -- AhciATAPICommand();
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_STATUS_PENDING
Definition: srb.h:340
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_opt_ GUID _In_ USHORT DataBufferLength
Definition: fltkernel.h:1270
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
FORCEINLINE PAHCI_SRB_EXTENSION GetSrbExtension(__in PSCSI_REQUEST_BLOCK Srb)
Definition: storahci.c:2564
VOID AtapiInquiryCompletion(__in PVOID _Extension, __in PVOID _Srb)
Definition: storahci.c:1638
#define ATA_FUNCTION_ATAPI_COMMAND
Definition: storahci.h:67
struct _LOCAL_SCATTER_GATHER_LIST * PLOCAL_SCATTER_GATHER_LIST
#define AHCI_DEVICE_TYPE_ATAPI
Definition: storahci.h:31
STORPORT_API PSTOR_SCATTER_GATHER_LIST NTAPI StorPortGetScatterGatherList(_In_ PVOID DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: storport.c:846
PAHCI_COMPLETION_ROUTINE CompletionRoutine
Definition: storahci.h:561
PLOCAL_SCATTER_GATHER_LIST pSgl
Definition: storahci.h:560
UCHAR PathId
Definition: srb.h:253
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
#define ATA_FLAGS_USE_DMA
Definition: uata_ctl.h:226
#define ATA_FLAGS_DATA_OUT
Definition: uata_ctl.h:221
#define ATA_FLAGS_DATA_IN
Definition: uata_ctl.h:222
struct _CDB::_CDB10 CDB10
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DeviceInquiryRequest(), DeviceReportLuns(), DeviceRequestCapacity(), DeviceRequestReadWrite(), and DeviceRequestSense().

◆ AhciBuild_PRDT()

ULONG AhciBuild_PRDT ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in PAHCI_SRB_EXTENSION  SrbExtension 
)

Definition at line 1314 of file storahci.c.

1318{
1319 ULONG index;
1320 PAHCI_COMMAND_TABLE cmdTable;
1322 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1323
1324 AhciDebugPrint("AhciBuild_PRDT()\n");
1325
1326 sgl = SrbExtension->pSgl;
1327 cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
1328 AdapterExtension = PortExtension->AdapterExtension;
1329
1330 NT_ASSERT(sgl != NULL);
1332
1333 for (index = 0; index < sgl->NumberOfElements; index++)
1334 {
1336
1337 cmdTable->PRDT[index].DBA = sgl->List[index].PhysicalAddress.LowPart;
1338 if (IsAdapterCAPS64(AdapterExtension->CAP))
1339 {
1340 cmdTable->PRDT[index].DBAU = sgl->List[index].PhysicalAddress.HighPart;
1341 }
1342
1343 // Data Byte Count (DBC): A ‘0’ based value that Indicates the length, in bytes, of the data block.
1344 // A maximum of length of 4MB may exist for any entry. Bit ‘0’ of this field must always be ‘1’ to
1345 // indicate an even byte count. A value of ‘1’ indicates 2 bytes, ‘3’ indicates 4 bytes, etc.
1346 cmdTable->PRDT[index].DBC = sgl->List[index].Length - 1;
1347 }
1348
1349 return sgl->NumberOfElements;
1350}// -- AhciBuild_PRDT();
#define IsAdapterCAPS64(CAP)
Definition: storahci.h:78
#define MAXIMUM_TRANSFER_LENGTH
Definition: storahci.h:25
#define MAXIMUM_AHCI_PRDT_ENTRIES
Definition: storahci.h:22
AHCI_PRDT PRDT[MAXIMUM_AHCI_PRDT_ENTRIES]
Definition: storahci.h:363
ULONG DBA
Definition: storahci.h:346
ULONG DBAU
Definition: storahci.h:347
ULONG DBC
Definition: storahci.h:350
STOR_SCATTER_GATHER_ELEMENT List[MAXIMUM_AHCI_PRDT_ENTRIES]
Definition: storahci.h:535
STOR_PHYSICAL_ADDRESS PhysicalAddress
Definition: storport.h:2092
ULONG LowPart
Definition: typedefs.h:106

Referenced by AhciProcessSrb().

◆ AhciCommandCompletionDpcRoutine()

VOID AhciCommandCompletionDpcRoutine ( __in PSTOR_DPC  Dpc,
__in PVOID  HwDeviceExtension,
__in PVOID  SystemArgument1,
__in PVOID  SystemArgument2 
)

Definition at line 421 of file storahci.c.

427{
429 PAHCI_SRB_EXTENSION SrbExtension;
430 STOR_LOCK_HANDLE lockhandle = {0};
432 PAHCI_ADAPTER_EXTENSION AdapterExtension;
433 PAHCI_PORT_EXTENSION PortExtension;
434
437
438 AhciDebugPrint("AhciCommandCompletionDpcRoutine()\n");
439
440 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)HwDeviceExtension;
441 PortExtension = (PAHCI_PORT_EXTENSION)SystemArgument1;
442
443 StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
444 Srb = RemoveQueue(&PortExtension->CompletionQueue);
445 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
446
447 NT_ASSERT(Srb != NULL);
448
450 {
452 }
453 else
454 {
455 return;
456 }
457
458 SrbExtension = GetSrbExtension(Srb);
459
460 CompletionRoutine = SrbExtension->CompletionRoutine;
462
463 // now it's completion routine responsibility to set SrbStatus
464 CompletionRoutine(PortExtension, Srb);
465
466 StorPortNotification(RequestComplete, AdapterExtension, Srb);
467
468 return;
469}// -- AhciCommandCompletionDpcRoutine();
@ RequestComplete
Definition: srb.h:531
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
FORCEINLINE PVOID RemoveQueue(__inout PAHCI_QUEUE Queue)
Definition: storahci.c:2532
struct _AHCI_PORT_EXTENSION * PAHCI_PORT_EXTENSION
VOID(* PAHCI_COMPLETION_ROUTINE)(__in PVOID PortExtension, __in PVOID Srb)
Definition: storahci.h:89
struct _AHCI_ADAPTER_EXTENSION * PAHCI_ADAPTER_EXTENSION
STORPORT_API VOID StorPortNotification(_In_ SCSI_NOTIFICATION_TYPE NotificationType, _In_ PVOID HwDeviceExtension,...)
Definition: storport.c:1093
FORCEINLINE VOID StorPortReleaseSpinLock(_In_ PVOID DeviceExtension, _Inout_ PSTOR_LOCK_HANDLE LockHandle)
Definition: storport.h:2965
FORCEINLINE VOID StorPortAcquireSpinLock(_In_ PVOID DeviceExtension, _In_ STOR_SPINLOCK SpinLock, _In_ PVOID LockContext, _Inout_ PSTOR_LOCK_HANDLE LockHandle)
Definition: storport.h:2950
@ InterruptLock
Definition: storport.h:487
AHCI_QUEUE CompletionQueue
Definition: storahci.h:487
UCHAR SrbStatus
Definition: srb.h:251
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

Referenced by AhciHwPassiveInitialize().

◆ AhciCompleteIssuedSrb()

VOID AhciCompleteIssuedSrb ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in ULONG  CommandsToComplete 
)

Definition at line 561 of file storahci.c.

565{
566 ULONG NCS, i;
568 PAHCI_SRB_EXTENSION SrbExtension;
569 PAHCI_ADAPTER_EXTENSION AdapterExtension;
570
571 AhciDebugPrint("AhciCompleteIssuedSrb()\n");
572
573 NT_ASSERT(CommandsToComplete != 0);
574
575 AhciDebugPrint("\tCompleted Commands: %d\n", CommandsToComplete);
576
577 AdapterExtension = PortExtension->AdapterExtension;
578 NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP);
579
580 for (i = 0; i < NCS; i++)
581 {
582 if (((1 << i) & CommandsToComplete) != 0)
583 {
584 Srb = PortExtension->Slot[i];
585
586 if (Srb == NULL)
587 {
588 continue;
589 }
590
591 SrbExtension = GetSrbExtension(Srb);
592 NT_ASSERT(SrbExtension != NULL);
593
594 if (SrbExtension->CompletionRoutine != NULL)
595 {
596 AddQueue(&PortExtension->CompletionQueue, Srb);
597 StorPortIssueDpc(AdapterExtension, &PortExtension->CommandCompletion, PortExtension, Srb);
598 }
599 else
600 {
603 StorPortNotification(RequestComplete, AdapterExtension, Srb);
604 }
605 }
606 }
607
608 return;
609}// -- AhciCompleteIssuedSrb();
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FORCEINLINE BOOLEAN AddQueue(__inout PAHCI_QUEUE Queue, __in PVOID Srb)
Definition: storahci.c:2501
FORCEINLINE BOOLEAN StorPortIssueDpc(_In_ PVOID DeviceExtension, _In_ PSTOR_DPC Dpc, _In_ PVOID SystemArgument1, _In_ PVOID SystemArgument2)
Definition: storport.h:2931

Referenced by AhciInterruptHandler().

◆ AhciGetLba()

FORCEINLINE ULONG64 AhciGetLba ( __in PCDB  Cdb,
__in ULONG  CdbLength 
)

Definition at line 2595 of file storahci.c.

2599{
2600 ULONG64 lba = 0;
2601
2602 NT_ASSERT(Cdb != NULL);
2603 NT_ASSERT(CdbLength != 0);
2604
2605 if (CdbLength == 0x10)
2606 {
2607 REVERSE_BYTES_QUAD(&lba, Cdb->CDB16.LogicalBlock);
2608 }
2609 else
2610 {
2611 lba |= Cdb->CDB10.LogicalBlockByte3 << 0;
2612 lba |= Cdb->CDB10.LogicalBlockByte2 << 8;
2613 lba |= Cdb->CDB10.LogicalBlockByte1 << 16;
2614 lba |= Cdb->CDB10.LogicalBlockByte0 << 24;
2615 }
2616
2617 return lba;
2618}// -- AhciGetLba();
unsigned __int64 ULONG64
Definition: imports.h:198
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3452
#define lba
struct _CDB::_CDB16 CDB16

Referenced by DeviceRequestReadWrite().

◆ AhciHwFindAdapter()

ULONG NTAPI AhciHwFindAdapter ( __in PVOID  DeviceExtension,
__in PVOID  HwContext,
__in PVOID  BusInformation,
__in PCHAR  ArgumentString,
__inout PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
__in PBOOLEAN  Reserved3 
)

Definition at line 990 of file storahci.c.

998{
999 AHCI_GHC ghc;
1000 ULONG index, pci_cfg_len;
1001 PACCESS_RANGE accessRange;
1002 UCHAR pci_cfg_buf[sizeof(PCI_COMMON_CONFIG)];
1003
1005 PPCI_COMMON_CONFIG pciConfigData;
1006 PAHCI_ADAPTER_EXTENSION adapterExtension;
1007
1008 AhciDebugPrint("AhciHwFindAdapter()\n");
1009
1012 UNREFERENCED_PARAMETER(ArgumentString);
1014
1015 adapterExtension = DeviceExtension;
1016 adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
1017 adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
1018
1019 // get PCI configuration header
1020 pci_cfg_len = StorPortGetBusData(
1021 adapterExtension,
1023 adapterExtension->SystemIoBusNumber,
1024 adapterExtension->SlotNumber,
1025 pci_cfg_buf,
1026 sizeof(PCI_COMMON_CONFIG));
1027
1028 if (pci_cfg_len != sizeof(PCI_COMMON_CONFIG))
1029 {
1030 AhciDebugPrint("\tpci_cfg_len != %d :: %d", sizeof(PCI_COMMON_CONFIG), pci_cfg_len);
1031 return SP_RETURN_ERROR;//Not a valid device at the given bus number
1032 }
1033
1034 pciConfigData = (PPCI_COMMON_CONFIG)pci_cfg_buf;
1035 adapterExtension->VendorID = pciConfigData->VendorID;
1036 adapterExtension->DeviceID = pciConfigData->DeviceID;
1037 adapterExtension->RevisionID = pciConfigData->RevisionID;
1038 // The last PCI base address register (BAR[5], header offset 0x24) points to the AHCI base memory, it’s called ABAR (AHCI Base Memory Register).
1039 adapterExtension->AhciBaseAddress = pciConfigData->u.type0.BaseAddresses[5] & (0xFFFFFFF0);
1040
1041 AhciDebugPrint("\tVendorID: %04x DeviceID: %04x RevisionID: %02x\n",
1042 adapterExtension->VendorID,
1043 adapterExtension->DeviceID,
1044 adapterExtension->RevisionID);
1045
1046 // 2.1.11
1047 abar = NULL;
1048 if (ConfigInfo->NumberOfAccessRanges > 0)
1049 {
1050 accessRange = *(ConfigInfo->AccessRanges);
1051 for (index = 0; index < ConfigInfo->NumberOfAccessRanges; index++)
1052 {
1053 if (accessRange[index].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
1054 {
1055 abar = StorPortGetDeviceBase(adapterExtension,
1056 ConfigInfo->AdapterInterfaceType,
1057 ConfigInfo->SystemIoBusNumber,
1058 accessRange[index].RangeStart,
1059 accessRange[index].RangeLength,
1060 !accessRange[index].RangeInMemory);
1061 break;
1062 }
1063 }
1064 }
1065
1066 if (abar == NULL)
1067 {
1068 AhciDebugPrint("\tabar == NULL\n");
1069 return SP_RETURN_ERROR; // corrupted information supplied
1070 }
1071
1072 adapterExtension->ABAR_Address = abar;
1073 adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
1074 adapterExtension->CAP2 = StorPortReadRegisterUlong(adapterExtension, &abar->CAP2);
1075 adapterExtension->Version = StorPortReadRegisterUlong(adapterExtension, &abar->VS);
1076 adapterExtension->LastInterruptPort = (ULONG)-1;
1077
1078 // 10.1.2
1079 // 1. Indicate that system software is AHCI aware by setting GHC.AE to ‘1’.
1080 // 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
1081 ghc.Status = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
1082 // AE := Highest Significant bit of GHC
1083 if (ghc.AE != 0)// Hmm, controller was already in power state
1084 {
1085 // reset controller to have it in known state
1086 AhciDebugPrint("\tAE Already set, Reset()\n");
1087 if (!AhciAdapterReset(adapterExtension))
1088 {
1089 AhciDebugPrint("\tReset Failed!\n");
1090 return SP_RETURN_ERROR;// reset failed
1091 }
1092 }
1093
1094 ghc.Status = 0;
1095 ghc.AE = 1;// only AE=1
1096 // tell the controller that we know about AHCI
1097 StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc.Status);
1098
1099 adapterExtension->IS = &abar->IS;
1100 adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
1101
1102 if (adapterExtension->PortImplemented == 0)
1103 {
1104 AhciDebugPrint("\tadapterExtension->PortImplemented == 0\n");
1105 return SP_RETURN_ERROR;
1106 }
1107
1108 ConfigInfo->Master = TRUE;
1109 ConfigInfo->AlignmentMask = 0x3;
1110 ConfigInfo->ScatterGather = TRUE;
1111 ConfigInfo->DmaWidth = Width32Bits;
1112 ConfigInfo->WmiDataProvider = FALSE;
1113 ConfigInfo->Dma32BitAddresses = TRUE;
1114
1115 if (IsAdapterCAPS64(adapterExtension->CAP))
1116 {
1117 ConfigInfo->Dma64BitAddresses = TRUE;
1118 }
1119
1120 ConfigInfo->MaximumNumberOfTargets = 1;
1121 ConfigInfo->ResetTargetSupported = TRUE;
1122 ConfigInfo->NumberOfPhysicalBreaks = 0x21;
1123 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
1124 ConfigInfo->NumberOfBuses = MAXIMUM_AHCI_PORT_COUNT;
1125 ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_LENGTH;
1126 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
1127
1128 // Turn IE -- Interrupt Enabled
1129 ghc.Status = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
1130 ghc.IE = 1;
1131 StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc.Status);
1132
1133 // allocate necessary resource for each port
1134 if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
1135 {
1137 return SP_RETURN_ERROR;
1138 }
1139
1140 for (index = 0; index < adapterExtension->PortCount; index++)
1141 {
1142 if ((adapterExtension->PortImplemented & (0x1 << index)) != 0)
1143 AhciPortInitialize(&adapterExtension->PortExtension[index]);
1144 }
1145
1146 return SP_RETURN_FOUND;
1147}// -- AhciHwFindAdapter();
#define SP_RETURN_ERROR
Definition: srb.h:523
#define SP_RETURN_FOUND
Definition: srb.h:522
@ Reserved3
Definition: sacdrv.h:1471
@ Width32Bits
Definition: miniport.h:107
@ PCIConfiguration
Definition: miniport.h:93
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA _In_ PVOID HwContext
Definition: srb.h:907
BOOLEAN AhciAdapterReset(__in PAHCI_ADAPTER_EXTENSION AdapterExtension)
Definition: storahci.c:2393
BOOLEAN NTAPI AhciPortInitialize(__in PVOID DeviceExtension)
Definition: storahci.c:23
BOOLEAN AhciAllocateResourceForAdapter(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PPORT_CONFIGURATION_INFORMATION ConfigInfo)
Definition: storahci.c:145
STORPORT_API ULONG NTAPI StorPortGetBusData(_In_ PVOID DeviceExtension, _In_ ULONG BusDataType, _In_ ULONG SystemIoBusNumber, _In_ ULONG SlotNumber, _Out_ _When_(Length !=0, _Out_writes_bytes_(Length)) PVOID Buffer, _In_ ULONG Length)
Definition: storport.c:657
STORPORT_API PVOID NTAPI StorPortGetDeviceBase(_In_ PVOID HwDeviceExtension, _In_ INTERFACE_TYPE BusType, _In_ ULONG SystemIoBusNumber, _In_ STOR_PHYSICAL_ADDRESS IoAddress, _In_ ULONG NumberOfBytes, _In_ BOOLEAN InIoSpace)
Definition: storport.c:701
@ StorSynchronizeFullDuplex
Definition: storport.h:472
PAHCI_MEMORY_REGISTERS ABAR_Address
Definition: storahci.h:527
AHCI_PORT_EXTENSION PortExtension[MAXIMUM_AHCI_PORT_COUNT]
Definition: storahci.h:528
ULONG IE
Definition: storahci.h:255
ULONG AE
Definition: storahci.h:258
_In_ WDFDEVICE _In_ PPNP_BUS_INFORMATION BusInformation
Definition: wdfdevice.h:3915
struct _PCI_COMMON_CONFIG * PPCI_COMMON_CONFIG
struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG

Referenced by DriverEntry().

◆ AhciHwInitialize()

BOOLEAN NTAPI AhciHwInitialize ( __in PVOID  DeviceExtension)

Definition at line 521 of file storahci.c.

524{
525 PAHCI_ADAPTER_EXTENSION AdapterExtension;
526 AHCI_GHC ghc;
527
528 AhciDebugPrint("AhciHwInitialize()\n");
529
530 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
531 AdapterExtension->StateFlags.MessagePerPort = FALSE;
532
533 // First check what type of interrupt/synchronization device is using
534 ghc.Status = StorPortReadRegisterUlong(AdapterExtension, &AdapterExtension->ABAR_Address->GHC);
535
536 // When set to ‘1’ by hardware, indicates that the HBA requested more than one MSI vector
537 // but has reverted to using the first vector only. When this bit is cleared to ‘0’,
538 // the HBA has not reverted to single MSI mode (i.e. hardware is already in single MSI mode,
539 // software has allocated the number of messages requested
540 if (ghc.MRSM == 0)
541 {
542 AdapterExtension->StateFlags.MessagePerPort = TRUE;
543 AhciDebugPrint("\tMultiple MSI based message not supported\n");
544 }
545
547
548 return TRUE;
549}// -- AhciHwInitialize();
BOOLEAN AhciHwPassiveInitialize(__in PVOID DeviceExtension)
Definition: storahci.c:483
FORCEINLINE BOOLEAN StorPortEnablePassiveInitialization(_In_ PVOID DeviceExtension, _In_ PHW_PASSIVE_INITIALIZE_ROUTINE HwPassiveInitializeRoutine)
Definition: storport.h:2903
struct _AHCI_ADAPTER_EXTENSION::@1345 StateFlags
ULONG MRSM
Definition: storahci.h:256

Referenced by DriverEntry().

◆ AhciHwInterrupt()

BOOLEAN NTAPI AhciHwInterrupt ( __in PVOID  DeviceExtension)

Definition at line 719 of file storahci.c.

722{
723 PAHCI_ADAPTER_EXTENSION AdapterExtension;
724 ULONG portPending, nextPort, i, portCount;
725
726 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
727
728 if (AdapterExtension->StateFlags.Removed)
729 {
730 return FALSE;
731 }
732
733 portPending = StorPortReadRegisterUlong(AdapterExtension, AdapterExtension->IS);
734
735 // we process interrupt for implemented ports only
736 portCount = AdapterExtension->PortCount;
737 portPending = portPending & AdapterExtension->PortImplemented;
738
739 if (portPending == 0)
740 {
741 return FALSE;
742 }
743
744 for (i = 1; i <= portCount; i++)
745 {
746 nextPort = (AdapterExtension->LastInterruptPort + i) % portCount;
747 if ((portPending & (0x1 << nextPort)) == 0)
748 continue;
749
750 NT_ASSERT(IsPortValid(AdapterExtension, nextPort));
751
752 if (AdapterExtension->PortExtension[nextPort].DeviceParams.IsActive == FALSE)
753 {
754 continue;
755 }
756
757 // we can assign this interrupt to this port
758 AdapterExtension->LastInterruptPort = nextPort;
759 AhciInterruptHandler(&AdapterExtension->PortExtension[nextPort]);
760
761 portPending &= ~(1 << nextPort);
762
763 // interrupt belongs to this device
764 // should always return TRUE
765 return TRUE;
766 }
767
768 AhciDebugPrint("\tSomething went wrong");
769 return FALSE;
770}// -- AhciHwInterrupt();
VOID AhciInterruptHandler(__in PAHCI_PORT_EXTENSION PortExtension)
Definition: storahci.c:621
FORCEINLINE BOOLEAN IsPortValid(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in ULONG pathId)
Definition: storahci.c:2471

Referenced by DriverEntry().

◆ AhciHwPassiveInitialize()

BOOLEAN AhciHwPassiveInitialize ( __in PVOID  DeviceExtension)

Definition at line 483 of file storahci.c.

486{
487 ULONG index;
488 PAHCI_ADAPTER_EXTENSION AdapterExtension;
489 PAHCI_PORT_EXTENSION PortExtension;
490
491 AhciDebugPrint("AhciHwPassiveInitialize()\n");
492
493 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
494
495 for (index = 0; index < AdapterExtension->PortCount; index++)
496 {
497 if ((AdapterExtension->PortImplemented & (0x1 << index)) != 0)
498 {
499 PortExtension = &AdapterExtension->PortExtension[index];
500 PortExtension->DeviceParams.IsActive = AhciStartPort(PortExtension);
502 }
503 }
504
505 return TRUE;
506}// -- AhciHwPassiveInitialize();
VOID AhciCommandCompletionDpcRoutine(__in PSTOR_DPC Dpc, __in PVOID HwDeviceExtension, __in PVOID SystemArgument1, __in PVOID SystemArgument2)
Definition: storahci.c:421
BOOLEAN AhciStartPort(__in PAHCI_PORT_EXTENSION PortExtension)
Definition: storahci.c:228
FORCEINLINE VOID StorPortInitializeDpc(_In_ PVOID DeviceExtension, _Out_ PSTOR_DPC Dpc, _In_ PHW_DPC_ROUTINE HwDpcRoutine)
Definition: storport.h:2918
STOR_DPC CommandCompletion
Definition: storahci.h:484

Referenced by AhciHwInitialize().

◆ AhciHwResetBus()

BOOLEAN NTAPI AhciHwResetBus ( __in PVOID  AdapterExtension,
__in ULONG  PathId 
)

Definition at line 930 of file storahci.c.

934{
935 STOR_LOCK_HANDLE lockhandle = {0};
936// PAHCI_ADAPTER_EXTENSION adapterExtension;
937
938 AhciDebugPrint("AhciHwResetBus()\n");
939
940// adapterExtension = AdapterExtension;
941
942 if (IsPortValid(AdapterExtension, PathId))
943 {
944 // Acquire Lock
945 StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
946
947 // TODO: Perform port reset
948
949 // Release lock
950 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
951 }
952
953 return FALSE;
954}// -- AhciHwResetBus();
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1313

Referenced by DriverEntry().

◆ AhciHwStartIo()

BOOLEAN NTAPI AhciHwStartIo ( __in PVOID  DeviceExtension,
__in PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 787 of file storahci.c.

791{
792 PAHCI_ADAPTER_EXTENSION AdapterExtension;
793
794 AhciDebugPrint("AhciHwStartIo()\n");
795
796 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
797
798 if (!IsPortValid(AdapterExtension, Srb->PathId))
799 {
801 StorPortNotification(RequestComplete, AdapterExtension, Srb);
802 return TRUE;
803 }
804
805 switch(Srb->Function)
806 {
807 case SRB_FUNCTION_PNP:
808 {
809 // https://msdn.microsoft.com/windows/hardware/drivers/storage/handling-srb-function-pnp
810 // If the function member of an SRB is set to SRB_FUNCTION_PNP,
811 // the SRB is a structure of type SCSI_PNP_REQUEST_BLOCK.
812
813 PSCSI_PNP_REQUEST_BLOCK pnpRequest;
814 pnpRequest = (PSCSI_PNP_REQUEST_BLOCK)Srb;
815 if ((pnpRequest->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST) != 0)
816 {
817 switch(pnpRequest->PnPAction)
818 {
819 case StorRemoveDevice:
821 {
823 AdapterExtension->StateFlags.Removed = 1;
824 AhciDebugPrint("\tAdapter removed\n");
825 }
826 break;
827 case StorStopDevice:
828 {
830 AhciDebugPrint("\tRequested to Stop the adapter\n");
831 }
832 break;
833 default:
835 break;
836 }
837 }
838 else
839 {
841 }
842 }
843 break;
845 {
846 // https://msdn.microsoft.com/en-us/windows/hardware/drivers/storage/handling-srb-function-execute-scsi
847 // On receipt of an SRB_FUNCTION_EXECUTE_SCSI request, a miniport driver's HwScsiStartIo
848 // routine does the following:
849 //
850 // - Gets and/or sets up whatever context the miniport driver maintains in its device,
851 // logical unit, and/or SRB extensions
852 // For example, a miniport driver might set up a logical unit extension with pointers
853 // to the SRB itself and the SRB DataBuffer pointer, the SRB DataTransferLength value,
854 // and a driver-defined value (or CDB SCSIOP_XXX value) indicating the operation to be
855 // carried out on the HBA.
856 //
857 // - Calls an internal routine to program the HBA, as partially directed by the SrbFlags,
858 // for the requested operation
859 // For a device I/O operation, such an internal routine generally selects the target device
860 // and sends the CDB over the bus to the target logical unit.
861 PCDB cdb = (PCDB)&Srb->Cdb;
862 if (Srb->CdbLength == 0)
863 {
864 AhciDebugPrint("\tOperationCode: %d\n", cdb->CDB10.OperationCode);
866 break;
867 }
868
869 NT_ASSERT(cdb != NULL);
870
871 switch(cdb->CDB10.OperationCode)
872 {
873 case SCSIOP_INQUIRY:
874 Srb->SrbStatus = DeviceInquiryRequest(AdapterExtension, Srb, cdb);
875 break;
877 Srb->SrbStatus = DeviceReportLuns(AdapterExtension, Srb, cdb);
878 break;
880 Srb->SrbStatus = DeviceRequestCapacity(AdapterExtension, Srb, cdb);
881 break;
883 Srb->SrbStatus = DeviceRequestComplete(AdapterExtension, Srb, cdb);
884 break;
886 Srb->SrbStatus = DeviceRequestSense(AdapterExtension, Srb, cdb);
887 break;
888 case SCSIOP_READ:
889 case SCSIOP_WRITE:
890 Srb->SrbStatus = DeviceRequestReadWrite(AdapterExtension, Srb, cdb);
891 break;
892 default:
893 AhciDebugPrint("\tOperationCode: %d\n", cdb->CDB10.OperationCode);
895 break;
896 }
897 }
898 break;
899 default:
900 AhciDebugPrint("\tUnknown function code recieved: %x\n", Srb->Function);
902 break;
903 }
904
906 {
907 StorPortNotification(RequestComplete, AdapterExtension, Srb);
908 }
909 else
910 {
911 AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
912 }
913 return TRUE;
914}// -- AhciHwStartIo();
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
union _CDB * PCDB
#define SCSIOP_REPORT_LUNS
Definition: scsi.h:921
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_BAD_FUNCTION
Definition: srb.h:364
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:348
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:346
if(dx< 0)
Definition: linetemp.h:194
struct _SCSI_PNP_REQUEST_BLOCK * PSCSI_PNP_REQUEST_BLOCK
@ StorRemoveDevice
Definition: srb.h:401
@ StorStopDevice
Definition: srb.h:402
@ StorSurpriseRemoval
Definition: srb.h:406
#define SRB_PNP_FLAGS_ADAPTER_REQUEST
Definition: srb.h:188
#define SRB_FUNCTION_PNP
Definition: srb.h:105
UCHAR DeviceReportLuns(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:2196
UCHAR DeviceInquiryRequest(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:2250
UCHAR DeviceRequestSense(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:1933
UCHAR DeviceRequestReadWrite(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:1988
VOID AhciProcessIO(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in UCHAR PathId, __in PSCSI_REQUEST_BLOCK Srb)
Definition: storahci.c:1555
UCHAR DeviceRequestCapacity(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:2098
@ DeviceRequestComplete
Definition: strmini.h:330
STOR_PNP_ACTION PnPAction
Definition: srb.h:431
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
UCHAR Function
Definition: srb.h:250
Definition: cdrw_hw.h:28

Referenced by DriverEntry().

◆ AhciInterruptHandler()

VOID AhciInterruptHandler ( __in PAHCI_PORT_EXTENSION  PortExtension)

Definition at line 621 of file storahci.c.

624{
625 ULONG is, ci, sact, outstanding;
627 AHCI_INTERRUPT_STATUS PxISMasked;
628 PAHCI_ADAPTER_EXTENSION AdapterExtension;
629
630 AhciDebugPrint("AhciInterruptHandler()\n");
631 AhciDebugPrint("\tPort Number: %d\n", PortExtension->PortNumber);
632
633 AdapterExtension = PortExtension->AdapterExtension;
634 NT_ASSERT(IsPortValid(AdapterExtension, PortExtension->PortNumber));
635
636 // 5.5.3
637 // 1. Software determines the cause of the interrupt by reading the PxIS register.
638 // It is possible for multiple bits to be set
639 // 2. Software clears appropriate bits in the PxIS register corresponding to the cause of the interrupt.
640 // 3. Software clears the interrupt bit in IS.IPS corresponding to the port.
641 // 4. If executing non-queued commands, software reads the PxCI register, and compares the current value to
642 // the list of commands previously issued by software that are still outstanding.
643 // If executing native queued commands, software reads the PxSACT register and compares the current
644 // value to the list of commands previously issued by software.
645 // Software completes with success any outstanding command whose corresponding bit has been cleared in
646 // the respective register. PxCI and PxSACT are volatile registers; software should only use their values
647 // to determine commands that have completed, not to determine which commands have previously been issued.
648 // 5. If there were errors, noted in the PxIS register, software performs error recovery actions (see section 6.2.2).
649 PxISMasked.Status = 0;
650 PxIS.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->IS);
651
652 // 6.2.2
653 // Fatal Error
654 // signified by the setting of PxIS.HBFS, PxIS.HBDS, PxIS.IFS, or PxIS.TFES
655 if (PxIS.HBFS || PxIS.HBDS || PxIS.IFS || PxIS.TFES)
656 {
657 // In this state, the HBA shall not issue any new commands nor acknowledge DMA Setup FISes to process
658 // any native command queuing commands. To recover, the port must be restarted
659 // To detect an error that requires software recovery actions to be performed,
660 // software should check whether any of the following status bits are set on an interrupt:
661 // PxIS.HBFS, PxIS.HBDS, PxIS.IFS, and PxIS.TFES. If any of these bits are set,
662 // software should perform the appropriate error recovery actions based on whether
663 // non-queued commands were being issued or native command queuing commands were being issued.
664
665 AhciDebugPrint("\tFatal Error: %x\n", PxIS.Status);
666 }
667
668 // Normal Command Completion
669 // 3.3.5
670 // A D2H Register FIS has been received with the ‘I’ bit set, and has been copied into system memory.
671 PxISMasked.DHRS = PxIS.DHRS;
672 // A PIO Setup FIS has been received with the ‘I’ bit set, it has been copied into system memory.
673 PxISMasked.PSS = PxIS.PSS;
674 // A DMA Setup FIS has been received with the ‘I’ bit set and has been copied into system memory.
675 PxISMasked.DSS = PxIS.DSS;
676 // A Set Device Bits FIS has been received with the ‘I’ bit set and has been copied into system memory/
677 PxISMasked.SDBS = PxIS.SDBS;
678 // A PRD with the ‘I’ bit set has transferred all of its data.
679 PxISMasked.DPS = PxIS.DPS;
680
681 if (PxISMasked.Status != 0)
682 {
683 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->IS, PxISMasked.Status);
684 }
685
686 // 10.7.1.1
687 // Clear port interrupt
688 // It is set by the level of the virtual interrupt line being a set, and cleared by a write of ‘1’ from the software.
689 is = (1 << PortExtension->PortNumber);
690 StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, is);
691
692 ci = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CI);
693 sact = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SACT);
694
695 outstanding = ci | sact; // NOTE: Including both non-NCQ and NCQ based commands
696 if ((PortExtension->CommandIssuedSlots & (~outstanding)) != 0)
697 {
698 AhciCompleteIssuedSrb(PortExtension, (PortExtension->CommandIssuedSlots & (~outstanding)));
699 PortExtension->CommandIssuedSlots &= outstanding;
700 }
701
702 return;
703}// -- AhciInterruptHandler();
struct outstanding_list outstanding
Definition: adh-query.c:36
VOID AhciCompleteIssuedSrb(__in PAHCI_PORT_EXTENSION PortExtension, __in ULONG CommandsToComplete)
Definition: storahci.c:561

Referenced by AhciHwInterrupt().

◆ AhciPortInitialize()

BOOLEAN NTAPI AhciPortInitialize ( __in PVOID  DeviceExtension)

Definition at line 23 of file storahci.c.

26{
27 PAHCI_PORT_EXTENSION PortExtension;
30 ULONG mappedLength, portNumber, ticks;
31 PAHCI_ADAPTER_EXTENSION adapterExtension;
32 STOR_PHYSICAL_ADDRESS commandListPhysical, receivedFISPhysical;
33
34 AhciDebugPrint("AhciPortInitialize()\n");
35
36 PortExtension = (PAHCI_PORT_EXTENSION)DeviceExtension;
37 adapterExtension = PortExtension->AdapterExtension;
38 abar = adapterExtension->ABAR_Address;
39 portNumber = PortExtension->PortNumber;
40
41 NT_ASSERT(abar != NULL);
42 NT_ASSERT(portNumber < adapterExtension->PortCount);
43
44 PortExtension->Port = &abar->PortList[portNumber];
45
46 commandListPhysical = StorPortGetPhysicalAddress(adapterExtension,
47 NULL,
48 PortExtension->CommandList,
49 &mappedLength);
50
51 if ((mappedLength == 0) || ((commandListPhysical.LowPart % 1024) != 0))
52 {
53 AhciDebugPrint("\tcommandListPhysical mappedLength:%d\n", mappedLength);
54 return FALSE;
55 }
56
57 receivedFISPhysical = StorPortGetPhysicalAddress(adapterExtension,
58 NULL,
59 PortExtension->ReceivedFIS,
60 &mappedLength);
61
62 if ((mappedLength == 0) || ((receivedFISPhysical.LowPart % 256) != 0))
63 {
64 AhciDebugPrint("\treceivedFISPhysical mappedLength:%d\n", mappedLength);
65 return FALSE;
66 }
67
68 // Ensure that the controller is not in the running state by reading and examining each
69 // implemented port’s PxCMD register. If PxCMD.ST, PxCMD.CR, PxCMD.FRE and
70 // PxCMD.FR are all cleared, the port is in an idle state. Otherwise, the port is not idle and
71 // should be placed in the idle state prior to manipulating HBA and port specific registers.
72 // System software places a port into the idle state by clearing PxCMD.ST and waiting for
73 // PxCMD.CR to return ‘0’ when read. Software should wait at least 500 milliseconds for
74 // this to occur. If PxCMD.FRE is set to ‘1’, software should clear it to ‘0’ and wait at least
75 // 500 milliseconds for PxCMD.FR to return ‘0’ when read. If PxCMD.CR or PxCMD.FR do
76 // not clear to ‘0’ correctly, then software may attempt a port reset or a full HBA reset to recove
77
78 // TODO: Check if port is in idle state or not, if not then restart port
79 cmd.Status = StorPortReadRegisterUlong(adapterExtension, &PortExtension->Port->CMD);
80 if ((cmd.FR != 0) || (cmd.CR != 0) || (cmd.FRE != 0) || (cmd.ST != 0))
81 {
82 cmd.ST = 0;
83 cmd.FRE = 0;
84
85 ticks = 3;
86 do
87 {
89 cmd.Status = StorPortReadRegisterUlong(adapterExtension, &PortExtension->Port->CMD);
90 if (ticks == 0)
91 {
92 AhciDebugPrint("\tAttempt to reset port failed: %x\n", cmd);
93 return FALSE;
94 }
95 ticks--;
96 }
97 while(cmd.CR != 0 || cmd.FR != 0);
98 }
99
100 // 10.1.2 For each implemented port, system software shall allocate memory for and program:
101 // ? PxCLB and PxCLBU (if CAP.S64A is set to ‘1’)
102 // ? PxFB and PxFBU (if CAP.S64A is set to ‘1’)
103 // Note: Assuming 32bit support only
104 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->CLB, commandListPhysical.LowPart);
105 if (IsAdapterCAPS64(adapterExtension->CAP))
106 {
107 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->CLBU, commandListPhysical.HighPart);
108 }
109
110 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->FB, receivedFISPhysical.LowPart);
111 if (IsAdapterCAPS64(adapterExtension->CAP))
112 {
113 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->FBU, receivedFISPhysical.HighPart);
114 }
115
116 PortExtension->IdentifyDeviceDataPhysicalAddress = StorPortGetPhysicalAddress(adapterExtension,
117 NULL,
118 PortExtension->IdentifyDeviceData,
119 &mappedLength);
120
121 // set device power state flag to D0
122 PortExtension->DevicePowerState = StorPowerDeviceD0;
123
124 // clear pending interrupts
125 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->SERR, (ULONG)~0);
126 StorPortWriteRegisterUlong(adapterExtension, &PortExtension->Port->IS, (ULONG)~0);
127 StorPortWriteRegisterUlong(adapterExtension, adapterExtension->IS, (1 << PortExtension->PortNumber));
128
129 return TRUE;
130}// -- AhciPortInitialize();
@ StorPowerDeviceD0
Definition: srb.h:357
STORPORT_API STOR_PHYSICAL_ADDRESS NTAPI StorPortGetPhysicalAddress(_In_ PVOID HwDeviceExtension, _In_opt_ PSCSI_REQUEST_BLOCK Srb, _In_ PVOID VirtualAddress, _Out_ ULONG *Length)
Definition: storport.c:791
AHCI_PORT PortList[MAXIMUM_AHCI_PORT_COUNT]
Definition: storahci.h:458
PAHCI_PORT Port
Definition: storahci.h:485
STOR_PHYSICAL_ADDRESS IdentifyDeviceDataPhysicalAddress
Definition: storahci.h:493
STOR_DEVICE_POWER_STATE DevicePowerState
Definition: storahci.h:491
ULONG CLB
Definition: storahci.h:393
ULONG IS
Definition: storahci.h:397
ULONG FB
Definition: storahci.h:395
ULONG FBU
Definition: storahci.h:396
ULONG CMD
Definition: storahci.h:399
ULONG SERR
Definition: storahci.h:405
ULONG CLBU
Definition: storahci.h:394

Referenced by AhciHwFindAdapter().

◆ AhciProcessIO()

VOID AhciProcessIO ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in UCHAR  PathId,
__in PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 1555 of file storahci.c.

1560{
1561 PSCSI_REQUEST_BLOCK tmpSrb;
1562 STOR_LOCK_HANDLE lockhandle = {0};
1563 PAHCI_PORT_EXTENSION PortExtension;
1564 ULONG commandSlotMask, occupiedSlots, slotIndex, NCS;
1565
1566 AhciDebugPrint("AhciProcessIO()\n");
1567 AhciDebugPrint("\tPathId: %d\n", PathId);
1568
1569 PortExtension = &AdapterExtension->PortExtension[PathId];
1570
1571 NT_ASSERT(PathId < AdapterExtension->PortCount);
1572
1573 // Acquire Lock
1574 StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
1575
1576 // add Srb to queue
1577 AddQueue(&PortExtension->SrbQueue, Srb);
1578
1579 if (PortExtension->DeviceParams.IsActive == FALSE)
1580 {
1581 // Release Lock
1582 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
1583 return; // we should wait for device to get active
1584 }
1585
1586 occupiedSlots = (PortExtension->QueueSlots | PortExtension->CommandIssuedSlots); // Busy command slots for given port
1587 NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP);
1588 commandSlotMask = (1 << NCS) - 1; // available slots mask
1589
1590 commandSlotMask = (commandSlotMask & ~occupiedSlots);
1591 if(commandSlotMask != 0)
1592 {
1593 // iterate over HBA port slots
1594 for (slotIndex = 0; slotIndex < NCS; slotIndex++)
1595 {
1596 // find first free slot
1597 if ((commandSlotMask & (1 << slotIndex)) != 0)
1598 {
1599 tmpSrb = RemoveQueue(&PortExtension->SrbQueue);
1600 if (tmpSrb != NULL)
1601 {
1602 NT_ASSERT(tmpSrb->PathId == PathId);
1603 AhciProcessSrb(PortExtension, tmpSrb, slotIndex);
1604 }
1605 else
1606 {
1607 break;
1608 }
1609 }
1610 else
1611 {
1612 break;
1613 }
1614 }
1615 }
1616
1617 // program HBA port
1618 AhciActivatePort(PortExtension);
1619
1620 // Release Lock
1621 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
1622
1623 return;
1624}// -- AhciProcessIO();
VOID AhciProcessSrb(__in PAHCI_PORT_EXTENSION PortExtension, __in PSCSI_REQUEST_BLOCK Srb, __in ULONG SlotIndex)
Definition: storahci.c:1364
VOID AhciActivatePort(__in PAHCI_PORT_EXTENSION PortExtension)
Definition: storahci.c:1490
ULONG CommandIssuedSlots
Definition: storahci.h:466
AHCI_QUEUE SrbQueue
Definition: storahci.h:486

Referenced by AhciHwStartIo().

◆ AhciProcessSrb()

VOID AhciProcessSrb ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in ULONG  SlotIndex 
)

Definition at line 1364 of file storahci.c.

1369{
1370 ULONG prdtlen, sig, length, cfl;
1371 PAHCI_SRB_EXTENSION SrbExtension;
1372 PAHCI_COMMAND_HEADER CommandHeader;
1373 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1374 STOR_PHYSICAL_ADDRESS CommandTablePhysicalAddress;
1375
1376 AhciDebugPrint("AhciProcessSrb()\n");
1377
1378 NT_ASSERT(Srb->PathId == PortExtension->PortNumber);
1379
1380 SrbExtension = GetSrbExtension(Srb);
1381 AdapterExtension = PortExtension->AdapterExtension;
1382
1383 NT_ASSERT(SrbExtension != NULL);
1384 NT_ASSERT(SrbExtension->AtaFunction != 0);
1385
1386 if ((SrbExtension->AtaFunction == ATA_FUNCTION_ATA_IDENTIFY) &&
1387 (SrbExtension->CommandReg == IDE_COMMAND_NOT_VALID))
1388 {
1389 // Here we are safe to check SIG register
1390 sig = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SIG);
1391 if (sig == 0x101)
1392 {
1393 AhciDebugPrint("\tATA Device Found!\n");
1394 SrbExtension->CommandReg = IDE_COMMAND_IDENTIFY;
1395 }
1396 else
1397 {
1398 AhciDebugPrint("\tATAPI Device Found!\n");
1399 SrbExtension->CommandReg = IDE_COMMAND_ATAPI_IDENTIFY;
1400 }
1401 }
1402
1403 NT_ASSERT(SlotIndex < AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
1404 SrbExtension->SlotIndex = SlotIndex;
1405
1406 // program the CFIS in the CommandTable
1407 CommandHeader = &PortExtension->CommandList[SlotIndex];
1408
1409 cfl = 0;
1410 if (IsAtapiCommand(SrbExtension->AtaFunction))
1411 {
1412 cfl = AhciATAPI_CFIS(PortExtension, SrbExtension);
1413 }
1414 else if (IsAtaCommand(SrbExtension->AtaFunction))
1415 {
1416 cfl = AhciATA_CFIS(PortExtension, SrbExtension);
1417 }
1418 else
1419 {
1421 }
1422
1423 prdtlen = 0;
1424 if (IsDataTransferNeeded(SrbExtension))
1425 {
1426 prdtlen = AhciBuild_PRDT(PortExtension, SrbExtension);
1427 NT_ASSERT(prdtlen != -1);
1428 }
1429
1430 // Program the command header
1431 CommandHeader->DI.PRDTL = prdtlen; // number of entries in PRD table
1432 CommandHeader->DI.CFL = cfl;
1433 CommandHeader->DI.A = (SrbExtension->AtaFunction & ATA_FUNCTION_ATAPI_COMMAND) ? 1 : 0;
1434 CommandHeader->DI.W = (SrbExtension->Flags & ATA_FLAGS_DATA_OUT) ? 1 : 0;
1435 CommandHeader->DI.P = 0; // ATA Specifications says so
1436 CommandHeader->DI.PMP = 0; // Port Multiplier
1437
1438 // Reset -- Manual Configuation
1439 CommandHeader->DI.R = 0;
1440 CommandHeader->DI.B = 0;
1441 CommandHeader->DI.C = 0;
1442
1443 CommandHeader->PRDBC = 0;
1444
1445 CommandHeader->Reserved[0] = 0;
1446 CommandHeader->Reserved[1] = 0;
1447 CommandHeader->Reserved[2] = 0;
1448 CommandHeader->Reserved[3] = 0;
1449
1450 // set CommandHeader CTBA
1451 CommandTablePhysicalAddress = StorPortGetPhysicalAddress(AdapterExtension,
1452 NULL,
1453 SrbExtension,
1454 &length);
1455
1456 NT_ASSERT(length != 0);
1457
1458 // command table alignment
1459 NT_ASSERT((CommandTablePhysicalAddress.LowPart % 128) == 0);
1460
1461 CommandHeader->CTBA = CommandTablePhysicalAddress.LowPart;
1462
1463 if (IsAdapterCAPS64(AdapterExtension->CAP))
1464 {
1465 CommandHeader->CTBA_U = CommandTablePhysicalAddress.HighPart;
1466 }
1467
1468 // mark this slot
1469 PortExtension->Slot[SlotIndex] = Srb;
1470 PortExtension->QueueSlots |= 1 << SlotIndex;
1471 return;
1472}// -- AhciProcessSrb();
#define IDE_COMMAND_NOT_VALID
Definition: ata.h:299
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
ULONG AhciBuild_PRDT(__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
Definition: storahci.c:1314
ULONG AhciATAPI_CFIS(__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
Definition: storahci.c:1266
ULONG AhciATA_CFIS(__in PAHCI_PORT_EXTENSION PortExtension, __in PAHCI_SRB_EXTENSION SrbExtension)
Definition: storahci.c:1219
#define IsAtapiCommand(AtaFunction)
Definition: storahci.h:76
#define IsAtaCommand(AtaFunction)
Definition: storahci.h:75
#define IsDataTransferNeeded(SrbExtension)
Definition: storahci.h:77
#define ATA_FUNCTION_ATA_IDENTIFY
Definition: storahci.h:63
AHCI_COMMAND_HEADER_DESCRIPTION DI
Definition: storahci.h:369

Referenced by AhciProcessIO().

◆ AhciStartPort()

BOOLEAN AhciStartPort ( __in PAHCI_PORT_EXTENSION  PortExtension)

Definition at line 228 of file storahci.c.

231{
232 ULONG index;
238 PAHCI_ADAPTER_EXTENSION AdapterExtension;
239
240 AhciDebugPrint("AhciStartPort()\n");
241
242 AdapterExtension = PortExtension->AdapterExtension;
243 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
244
245 if ((cmd.FR == 1) && (cmd.CR == 1) && (cmd.FRE == 1) && (cmd.ST == 1))
246 {
247 // Already Running
248 return TRUE;
249 }
250
251 cmd.SUD = 1;
252 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CMD, cmd.Status);
253
254 if (((cmd.FR == 1) && (cmd.FRE == 0)) ||
255 ((cmd.CR == 1) && (cmd.ST == 0)))
256 {
257 AhciDebugPrint("\tCOMRESET\n");
258 // perform COMRESET
259 // section 10.4.2
260
261 // Software causes a port reset (COMRESET) by writing 1h to the PxSCTL.DET field to invoke a
262 // COMRESET on the interface and start a re-establishment of Phy layer communications. Software shall
263 // wait at least 1 millisecond before clearing PxSCTL.DET to 0h; this ensures that at least one COMRESET
264 // signal is sent over the interface. After clearing PxSCTL.DET to 0h, software should wait for
265 // communication to be re-established as indicated by PxSSTS.DET being set to 3h. Then software should
266 // write all 1s to the PxSERR register to clear any bits that were set as part of the port reset.
267
268 sctl.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SCTL);
269 sctl.DET = 1;
270 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->SCTL, sctl.Status);
271
273
274 sctl.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SCTL);
275 sctl.DET = 0;
276 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->SCTL, sctl.Status);
277
278 // Poll DET to verify if a device is attached to the port
279 index = 0;
280 do
281 {
283 ssts.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SSTS);
284
285 index++;
286 if (ssts.DET != 0)
287 {
288 break;
289 }
290 }
291 while(index < 30);
292 }
293
294 ssts.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->SSTS);
295 switch (ssts.DET)
296 {
297 case 0x3:
298 {
299 NT_ASSERT(cmd.ST == 0);
300
301 // make sure FIS Recieve is enabled (cmd.FRE)
302 index = 0;
303 do
304 {
306 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
307 cmd.FRE = 1;
308 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CMD, cmd.Status);
309 index++;
310 }
311 while((cmd.FR != 1) && (index < 3));
312
313 if (cmd.FR != 1)
314 {
315 // failed to start FIS DMA engine
316 // it can crash the driver later
317 // so better to turn this port off
318 return FALSE;
319 }
320
321 // start port channel
322 // set cmd.ST
323
324 NT_ASSERT(cmd.FRE == 1);
325 NT_ASSERT(cmd.CR == 0);
326
327 // why assert? well If we face such condition on DET = 0x3
328 // then we don't have port in idle state and hence before executing this part of code
329 // we must have restarted it.
330 tfd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->TFD);
331
332 if ((tfd.STS.BSY) || (tfd.STS.DRQ))
333 {
334 AhciDebugPrint("\tUnhandled Case BSY-DRQ\n");
335 }
336
337 // clear pending interrupts
338 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->SERR, (ULONG)~0);
339 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->IS, (ULONG)~0);
340 StorPortWriteRegisterUlong(AdapterExtension, AdapterExtension->IS, (1 << PortExtension->PortNumber));
341
342 // set IE
343 ie.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->IE);
344 /* Device to Host Register FIS Interrupt Enable */
345 ie.DHRE = 1;
346 /* PIO Setup FIS Interrupt Enable */
347 ie.PSE = 1;
348 /* DMA Setup FIS Interrupt Enable */
349 ie.DSE = 1;
350 /* Set Device Bits FIS Interrupt Enable */
351 ie.SDBE = 1;
352 /* Unknown FIS Interrupt Enable */
353 ie.UFE = 0;
354 /* Descriptor Processed Interrupt Enable */
355 ie.DPE = 0;
356 /* Port Change Interrupt Enable */
357 ie.PCE = 1;
358 /* Device Mechanical Presence Enable */
359 ie.DMPE = 0;
360 /* PhyRdy Change Interrupt Enable */
361 ie.PRCE = 1;
362 /* Incorrect Port Multiplier Enable */
363 ie.IPME = 0;
364 /* Overflow Enable */
365 ie.OFE = 1;
366 /* Interface Non-fatal Error Enable */
367 ie.INFE = 1;
368 /* Interface Fatal Error Enable */
369 ie.IFE = 1;
370 /* Host Bus Data Error Enable */
371 ie.HBDE = 1;
372 /* Host Bus Fatal Error Enable */
373 ie.HBFE = 1;
374 /* Task File Error Enable */
375 ie.TFEE = 1;
376
377 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
378 /* Cold Presence Detect Enable */
379 if (cmd.CPD) // does it support CPD?
380 {
381 // disable it for now
382 ie.CPDE = 0;
383 }
384
385 // should I replace this to single line?
386 // by directly setting ie.Status?
387
388 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->IE, ie.Status);
389
390 cmd.ST = 1;
391 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CMD, cmd.Status);
392 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
393
394 if (cmd.ST != 1)
395 {
396 AhciDebugPrint("\tFailed to start Port\n");
397 return FALSE;
398 }
399
400 return TRUE;
401 }
402 default:
403 // unhandled case
404 AhciDebugPrint("\tDET == %x Unsupported\n", ssts.DET);
405 return FALSE;
406 }
407}// -- AhciStartPort();
struct _AHCI_TASK_FILE_DATA::@1340::_STS STS

Referenced by AhciHwPassiveInitialize().

◆ AhciZeroMemory()

FORCEINLINE VOID AhciZeroMemory ( __out PCHAR  Buffer,
__in ULONG  BufferSize 
)

Definition at line 2443 of file storahci.c.

2447{
2448 ULONG i;
2449 for (i = 0; i < BufferSize; i++)
2450 {
2451 Buffer[i] = 0;
2452 }
2453
2454 return;
2455}// -- AhciZeroMemory();
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75

Referenced by AhciAllocateResourceForAdapter(), AhciATA_CFIS(), AhciATAPI_CFIS(), DeviceInquiryRequest(), DeviceReportLuns(), and DeviceRequestSense().

◆ AtapiInquiryCompletion()

VOID AtapiInquiryCompletion ( __in PVOID  _Extension,
__in PVOID  _Srb 
)

Definition at line 1638 of file storahci.c.

1642{
1643 PAHCI_PORT_EXTENSION PortExtension;
1644 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1647
1648 AhciDebugPrint("AtapiInquiryCompletion()\n");
1649
1650 PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
1651 Srb = (PSCSI_REQUEST_BLOCK)_Srb;
1652
1653 NT_ASSERT(Srb != NULL);
1654 NT_ASSERT(PortExtension != NULL);
1655
1656 AdapterExtension = PortExtension->AdapterExtension;
1657
1658 // send queue depth
1660 Srb->PathId,
1661 Srb->TargetId,
1662 Srb->Lun,
1663 AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
1664
1665 NT_ASSERT(status == TRUE);
1666 return;
1667}// -- AtapiInquiryCompletion();
unsigned char BOOLEAN
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
STORPORT_API BOOLEAN NTAPI StorPortSetDeviceQueueDepth(_In_ PVOID HwDeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun, _In_ ULONG Depth)
Definition: storport.c:1398
UCHAR TargetId
Definition: srb.h:254
Definition: ps.c:97

Referenced by AhciATAPICommand().

◆ DeviceInquiryRequest()

UCHAR DeviceInquiryRequest ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 2250 of file storahci.c.

2255{
2256 PVOID DataBuffer;
2257 PAHCI_SRB_EXTENSION SrbExtension;
2258 PAHCI_PORT_EXTENSION PortExtension;
2259 PVPD_SUPPORTED_PAGES_PAGE VpdOutputBuffer;
2260 ULONG DataBufferLength, RequiredDataBufferLength;
2261
2262 AhciDebugPrint("DeviceInquiryRequest()\n");
2263
2264 NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_INQUIRY);
2265 NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
2266
2267 SrbExtension = GetSrbExtension(Srb);
2268 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
2269
2270 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
2271 {
2272 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
2273 }
2274
2275 if (Srb->Lun != 0)
2276 {
2278 }
2279 else if (Cdb->CDB6INQUIRY3.EnableVitalProductData == 0)
2280 {
2281 // 3.6.1
2282 // If the EVPD bit is set to zero, the device server shall return the standard INQUIRY data
2283 AhciDebugPrint("\tEVPD Inquired\n");
2284 NT_ASSERT(SrbExtension != NULL);
2285
2286 SrbExtension->AtaFunction = ATA_FUNCTION_ATA_IDENTIFY;
2287 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
2288 SrbExtension->CompletionRoutine = InquiryCompletion;
2289 SrbExtension->CommandReg = IDE_COMMAND_NOT_VALID;
2290
2291 // TODO: Should use AhciZeroMemory
2292 SrbExtension->FeaturesLow = 0;
2293 SrbExtension->LBA0 = 0;
2294 SrbExtension->LBA1 = 0;
2295 SrbExtension->LBA2 = 0;
2296 SrbExtension->Device = 0xA0;
2297 SrbExtension->LBA3 = 0;
2298 SrbExtension->LBA4 = 0;
2299 SrbExtension->LBA5 = 0;
2300 SrbExtension->FeaturesHigh = 0;
2301 SrbExtension->SectorCountLow = 0;
2302 SrbExtension->SectorCountHigh = 0;
2303
2304 SrbExtension->Sgl.NumberOfElements = 1;
2305 SrbExtension->Sgl.List[0].PhysicalAddress.LowPart = PortExtension->IdentifyDeviceDataPhysicalAddress.LowPart;
2307 SrbExtension->Sgl.List[0].Length = sizeof(IDENTIFY_DEVICE_DATA);
2308
2309 SrbExtension->pSgl = &SrbExtension->Sgl;
2310 return SRB_STATUS_PENDING;
2311 }
2312 else
2313 {
2314 AhciDebugPrint("\tVPD Inquired\n");
2315
2316 DataBuffer = Srb->DataBuffer;
2318 RequiredDataBufferLength = DataBufferLength; // make the compiler happy :p
2319
2320 if (DataBuffer == NULL)
2321 {
2323 }
2324
2325 AhciZeroMemory(DataBuffer, DataBufferLength);
2326
2327 switch(Cdb->CDB6INQUIRY3.PageCode)
2328 {
2330 {
2331 AhciDebugPrint("\tVPD_SUPPORTED_PAGES\n");
2332 RequiredDataBufferLength = sizeof(VPD_SUPPORTED_PAGES_PAGE) + 1;
2333
2334 if (DataBufferLength < RequiredDataBufferLength)
2335 {
2336 AhciDebugPrint("\tDataBufferLength: %d Required: %d\n", DataBufferLength, RequiredDataBufferLength);
2338 }
2339
2340 VpdOutputBuffer = (PVPD_SUPPORTED_PAGES_PAGE)DataBuffer;
2341
2342 VpdOutputBuffer->DeviceType = PortExtension->DeviceParams.AccessType;
2343 VpdOutputBuffer->DeviceTypeQualifier = 0;
2344 VpdOutputBuffer->PageCode = VPD_SUPPORTED_PAGES;
2345 VpdOutputBuffer->PageLength = 1;
2346 VpdOutputBuffer->SupportedPageList[0] = VPD_SUPPORTED_PAGES;
2347 //VpdOutputBuffer->SupportedPageList[1] = VPD_SERIAL_NUMBER;
2348 //VpdOutputBuffer->SupportedPageList[2] = VPD_DEVICE_IDENTIFIERS;
2349
2350 NT_ASSERT(VpdOutputBuffer->DeviceType == DIRECT_ACCESS_DEVICE);
2351 }
2352 break;
2353 case VPD_SERIAL_NUMBER:
2354 {
2355 AhciDebugPrint("\tVPD_SERIAL_NUMBER\n");
2356 }
2357 break;
2359 {
2360 AhciDebugPrint("\tVPD_DEVICE_IDENTIFIERS\n");
2361 }
2362 break;
2363 default:
2364 AhciDebugPrint("\tPageCode: %x\n", Cdb->CDB6INQUIRY3.PageCode);
2366 }
2367
2368 Srb->DataTransferLength = RequiredDataBufferLength;
2369 return SRB_STATUS_SUCCESS;
2370 }
2371}// -- DeviceInquiryRequest();
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:350
struct _VPD_SUPPORTED_PAGES_PAGE VPD_SUPPORTED_PAGES_PAGE
struct _VPD_SUPPORTED_PAGES_PAGE * PVPD_SUPPORTED_PAGES_PAGE
#define VPD_SUPPORTED_PAGES
Definition: scsi.h:2404
#define VPD_SERIAL_NUMBER
Definition: scsi.h:2405
#define VPD_DEVICE_IDENTIFIERS
Definition: scsi.h:2406
UCHAR AhciATAPICommand(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:1843
VOID InquiryCompletion(__in PVOID _Extension, __in PVOID _Srb)
Definition: storahci.c:1681
LOCAL_SCATTER_GATHER_LIST Sgl
Definition: storahci.h:559
PVOID DataBuffer
Definition: srb.h:263
UCHAR SupportedPageList[0]
Definition: scsi.h:2633
struct _CDB::_CDB6INQUIRY3 CDB6INQUIRY3

Referenced by AhciHwStartIo().

◆ DeviceReportLuns()

UCHAR DeviceReportLuns ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 2196 of file storahci.c.

2201{
2202 PLUN_LIST LunList;
2203 PAHCI_PORT_EXTENSION PortExtension;
2204
2205 AhciDebugPrint("DeviceReportLuns()\n");
2206
2208
2209 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
2210
2212 NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_REPORT_LUNS);
2213
2214 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
2215 {
2216 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
2217 }
2218
2219 LunList = (PLUN_LIST)Srb->DataBuffer;
2220
2221 NT_ASSERT(LunList != NULL);
2222
2223 AhciZeroMemory((PCHAR)LunList, sizeof(LUN_LIST));
2224
2225 LunList->LunListLength[3] = 8;
2226
2228 Srb->DataTransferLength = sizeof(LUN_LIST);
2229
2230 return SRB_STATUS_SUCCESS;
2231}// -- DeviceReportLuns();
#define SCSISTAT_GOOD
Definition: cdrw_hw.h:1078
struct _LUN_LIST LUN_LIST
struct _LUN_LIST * PLUN_LIST
UCHAR ScsiStatus
Definition: srb.h:252

Referenced by AhciHwStartIo().

◆ DeviceRequestCapacity()

UCHAR DeviceRequestCapacity ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 2098 of file storahci.c.

2103{
2104 ULONG MaxLba, BytesPerLogicalSector;
2105 PREAD_CAPACITY_DATA ReadCapacity;
2106 PAHCI_PORT_EXTENSION PortExtension;
2107
2108 AhciDebugPrint("DeviceRequestCapacity()\n");
2109
2110 UNREFERENCED_PARAMETER(AdapterExtension);
2112
2114 NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
2115
2116
2117 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
2118
2119 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
2120 {
2121 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
2122 }
2123
2124 if (Cdb->CDB10.OperationCode == SCSIOP_READ_CAPACITY)
2125 {
2126 ReadCapacity = (PREAD_CAPACITY_DATA)Srb->DataBuffer;
2127
2128 BytesPerLogicalSector = PortExtension->DeviceParams.BytesPerLogicalSector;
2129 MaxLba = (ULONG)PortExtension->DeviceParams.MaxLba.QuadPart - 1;
2130
2131 // I trust you windows :D
2133
2134 // I trust you user :D
2135 NT_ASSERT(PortExtension->DeviceParams.MaxLba.QuadPart < (ULONG)-1);
2136
2137 // Actually I don't trust anyone :p
2139
2140 REVERSE_BYTES(&ReadCapacity->BytesPerBlock, &BytesPerLogicalSector);
2141 REVERSE_BYTES(&ReadCapacity->LogicalBlockAddress, &MaxLba);
2142 }
2143 else
2144 {
2145 AhciDebugPrint("\tSCSIOP_READ_CAPACITY16 not supported\n");
2147 }
2148
2149 return SRB_STATUS_SUCCESS;
2150}// -- DeviceRequestCapacity();
struct _READ_CAPACITY_DATA * PREAD_CAPACITY_DATA
struct _READ_CAPACITY_DATA READ_CAPACITY_DATA
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471

Referenced by AhciHwStartIo().

◆ DeviceRequestComplete()

UCHAR DeviceRequestComplete ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 2166 of file storahci.c.

2171{
2172 AhciDebugPrint("DeviceRequestComplete()\n");
2173
2174 UNREFERENCED_PARAMETER(AdapterExtension);
2176
2178
2179 return SRB_STATUS_SUCCESS;
2180}// -- DeviceRequestComplete();

◆ DeviceRequestReadWrite()

UCHAR DeviceRequestReadWrite ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 1988 of file storahci.c.

1993{
1994 BOOLEAN IsReading;
1995 ULONG64 StartOffset;
1996 PAHCI_SRB_EXTENSION SrbExtension;
1997 PAHCI_PORT_EXTENSION PortExtension;
1998 ULONG DataTransferLength, BytesPerSector, SectorCount;
1999
2000 AhciDebugPrint("DeviceRequestReadWrite()\n");
2001
2002 NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
2003 NT_ASSERT((Cdb->CDB10.OperationCode == SCSIOP_READ) || (Cdb->CDB10.OperationCode == SCSIOP_WRITE));
2004
2005 SrbExtension = GetSrbExtension(Srb);
2006 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
2007
2008 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
2009 {
2010 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
2011 }
2012
2013 DataTransferLength = Srb->DataTransferLength;
2014 BytesPerSector = PortExtension->DeviceParams.BytesPerLogicalSector;
2015
2016 NT_ASSERT(BytesPerSector > 0);
2017
2018 //ROUND_UP(DataTransferLength, BytesPerSector);
2019
2020 SectorCount = DataTransferLength / BytesPerSector;
2021
2022 Srb->DataTransferLength = SectorCount * BytesPerSector;
2023
2024 StartOffset = AhciGetLba(Cdb, Srb->CdbLength);
2025 IsReading = (Cdb->CDB10.OperationCode == SCSIOP_READ);
2026
2028
2029 SrbExtension->AtaFunction = ATA_FUNCTION_ATA_READ;
2030 SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
2031 SrbExtension->CompletionRoutine = NULL;
2032
2033 if (IsReading)
2034 {
2035 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
2036 SrbExtension->CommandReg = IDE_COMMAND_READ_DMA;
2037 }
2038 else
2039 {
2040 SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
2041 SrbExtension->CommandReg = IDE_COMMAND_WRITE_DMA;
2042 }
2043
2044 SrbExtension->FeaturesLow = 0;
2045 SrbExtension->LBA0 = (StartOffset >> 0) & 0xFF;
2046 SrbExtension->LBA1 = (StartOffset >> 8) & 0xFF;
2047 SrbExtension->LBA2 = (StartOffset >> 16) & 0xFF;
2048
2049 SrbExtension->Device = (0xA0 | IDE_LBA_MODE);
2050
2051 if (PortExtension->DeviceParams.Lba48BitMode)
2052 {
2053 SrbExtension->Flags |= ATA_FLAGS_48BIT_COMMAND;
2054
2055 if (IsReading)
2056 {
2057 SrbExtension->CommandReg = IDE_COMMAND_READ_DMA_EXT;
2058 }
2059 else
2060 {
2061 SrbExtension->CommandReg = IDE_COMMAND_WRITE_DMA_EXT;
2062 }
2063
2064 SrbExtension->LBA3 = (StartOffset >> 24) & 0xFF;
2065 SrbExtension->LBA4 = (StartOffset >> 32) & 0xFF;
2066 SrbExtension->LBA5 = (StartOffset >> 40) & 0xFF;
2067 }
2068 else
2069 {
2071 }
2072
2073 SrbExtension->FeaturesHigh = 0;
2074 SrbExtension->SectorCountLow = (SectorCount >> 0) & 0xFF;
2075 SrbExtension->SectorCountHigh = (SectorCount >> 8) & 0xFF;
2076
2077 NT_ASSERT(SectorCount < 0x100);
2078
2079 SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
2080
2081 return SRB_STATUS_PENDING;
2082}// -- DeviceRequestReadWrite();
#define IDE_COMMAND_READ_DMA_EXT
Definition: ata.h:262
#define IDE_LBA_MODE
Definition: ata.h:255
#define IDE_COMMAND_WRITE_DMA_EXT
Definition: ata.h:267
#define IDE_COMMAND_WRITE_DMA
Definition: atapi.h:115
#define IDE_COMMAND_READ_DMA
Definition: atapi.h:114
ULONG SectorCount
Definition: part_xbox.c:31
FORCEINLINE ULONG64 AhciGetLba(__in PCDB Cdb, __in ULONG CdbLength)
Definition: storahci.c:2595
#define ATA_FUNCTION_ATA_READ
Definition: storahci.h:64
#define ATA_FLAGS_48BIT_COMMAND
Definition: uata_ctl.h:223

Referenced by AhciHwStartIo().

◆ DeviceRequestSense()

UCHAR DeviceRequestSense ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in PSCSI_REQUEST_BLOCK  Srb,
__in PCDB  Cdb 
)

Definition at line 1933 of file storahci.c.

1938{
1939 PMODE_PARAMETER_HEADER ModeHeader;
1940 PAHCI_PORT_EXTENSION PortExtension;
1941
1942 AhciDebugPrint("DeviceRequestSense()\n");
1943
1944 NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
1945 NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_MODE_SENSE);
1946
1947 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
1948
1949 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
1950 {
1951 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
1952 }
1953
1954 ModeHeader = (PMODE_PARAMETER_HEADER)Srb->DataBuffer;
1955
1956 NT_ASSERT(ModeHeader != NULL);
1957
1959
1960 ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER);
1961 ModeHeader->MediumType = 0;
1962 ModeHeader->DeviceSpecificParameter = 0;
1963 ModeHeader->BlockDescriptorLength = 0;
1964
1965 if (Cdb->MODE_SENSE.PageCode == MODE_SENSE_CURRENT_VALUES)
1966 {
1967 ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_PARAMETER_BLOCK);
1968 ModeHeader->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
1969 }
1970
1971 return SRB_STATUS_SUCCESS;
1972}// -- DeviceRequestSense();
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
#define MODE_SENSE_CURRENT_VALUES
Definition: cdrw_hw.h:859
struct _MODE_PARAMETER_BLOCK MODE_PARAMETER_BLOCK
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
struct _CDB::_MODE_SENSE MODE_SENSE

Referenced by AhciHwStartIo().

◆ DriverEntry()

ULONG NTAPI DriverEntry ( __in PVOID  DriverObject,
__in PVOID  RegistryPath 
)

Definition at line 1163 of file storahci.c.

1167{
1168 ULONG status;
1169 // initialize the hardware data structure
1170 HW_INITIALIZATION_DATA hwInitializationData = {0};
1171
1172 // set size of hardware initialization structure
1173 hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
1174
1175 // identity required miniport entry point routines
1176 hwInitializationData.HwStartIo = AhciHwStartIo;
1177 hwInitializationData.HwResetBus = AhciHwResetBus;
1178 hwInitializationData.HwInterrupt = AhciHwInterrupt;
1179 hwInitializationData.HwInitialize = AhciHwInitialize;
1180 hwInitializationData.HwFindAdapter = AhciHwFindAdapter;
1181
1182 // adapter specific information
1183 hwInitializationData.TaggedQueuing = TRUE;
1184 hwInitializationData.AutoRequestSense = TRUE;
1185 hwInitializationData.MultipleRequestPerLu = TRUE;
1186 hwInitializationData.NeedPhysicalAddresses = TRUE;
1187
1188 hwInitializationData.NumberOfAccessRanges = 6;
1189 hwInitializationData.AdapterInterfaceType = PCIBus;
1190 hwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1191
1192 // set required extension sizes
1193 hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
1194 hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
1195
1196 // register our hw init data
1199 &hwInitializationData,
1200 NULL);
1201
1203 return status;
1204}// -- DriverEntry();
struct _HW_INITIALIZATION_DATA HW_INITIALIZATION_DATA
@ PCIBus
Definition: hwresource.cpp:142
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN NTAPI AhciHwInterrupt(__in PVOID DeviceExtension)
Definition: storahci.c:719
BOOLEAN NTAPI AhciHwStartIo(__in PVOID DeviceExtension, __in PSCSI_REQUEST_BLOCK Srb)
Definition: storahci.c:787
BOOLEAN NTAPI AhciHwResetBus(__in PVOID AdapterExtension, __in ULONG PathId)
Definition: storahci.c:930
BOOLEAN NTAPI AhciHwInitialize(__in PVOID DeviceExtension)
Definition: storahci.c:521
ULONG NTAPI AhciHwFindAdapter(__in PVOID DeviceExtension, __in PVOID HwContext, __in PVOID BusInformation, __in PCHAR ArgumentString, __inout PPORT_CONFIGURATION_INFORMATION ConfigInfo, __in PBOOLEAN Reserved3)
Definition: storahci.c:990
struct _AHCI_SRB_EXTENSION AHCI_SRB_EXTENSION
struct _AHCI_ADAPTER_EXTENSION AHCI_ADAPTER_EXTENSION
STORPORT_API ULONG NTAPI StorPortInitialize(_In_ PVOID Argument1, _In_ PVOID Argument2, _In_ struct _HW_INITIALIZATION_DATA *HwInitializationData, _In_opt_ PVOID HwContext)
Definition: storport.c:949
#define STOR_MAP_NON_READ_WRITE_BUFFERS
Definition: storport.h:440
PHW_INTERRUPT HwInterrupt
Definition: srb.h:569
BOOLEAN TaggedQueuing
Definition: srb.h:582
BOOLEAN AutoRequestSense
Definition: srb.h:583
PHW_RESET_BUS HwResetBus
Definition: srb.h:571
PHW_STARTIO HwStartIo
Definition: srb.h:568
BOOLEAN MultipleRequestPerLu
Definition: srb.h:584
BOOLEAN NeedPhysicalAddresses
Definition: srb.h:581
ULONG SrbExtensionSize
Definition: srb.h:576
ULONG HwInitializationDataSize
Definition: srb.h:550
PHW_INITIALIZE HwInitialize
Definition: srb.h:567
ULONG DeviceExtensionSize
Definition: srb.h:574
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:565
PHW_FIND_ADAPTER HwFindAdapter
Definition: srb.h:570
BOOLEAN MapBuffers
Definition: srb.h:580
ULONG NumberOfAccessRanges
Definition: srb.h:577
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

◆ GetSrbExtension()

Definition at line 2564 of file storahci.c.

2567{
2568 ULONG Offset;
2569 ULONG_PTR SrbExtension;
2570
2571 SrbExtension = (ULONG_PTR)Srb->SrbExtension;
2572 Offset = SrbExtension % 128;
2573
2574 // CommandTable should be 128 byte aligned
2575 if (Offset != 0)
2576 Offset = 128 - Offset;
2577
2578 return (PAHCI_SRB_EXTENSION)(SrbExtension + Offset);
2579}// -- PAHCI_SRB_EXTENSION();
#define ULONG_PTR
Definition: config.h:101
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PVOID SrbExtension
Definition: srb.h:267
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by AhciATAPICommand(), AhciCommandCompletionDpcRoutine(), AhciCompleteIssuedSrb(), AhciProcessSrb(), DeviceInquiryRequest(), DeviceRequestReadWrite(), and InquiryCompletion().

◆ InquiryCompletion()

VOID InquiryCompletion ( __in PVOID  _Extension,
__in PVOID  _Srb 
)

Definition at line 1681 of file storahci.c.

1685{
1686 PAHCI_PORT_EXTENSION PortExtension;
1688
1689// PCDB cdb;
1691 PINQUIRYDATA InquiryData;
1692 PAHCI_SRB_EXTENSION SrbExtension;
1693 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1694 PIDENTIFY_DEVICE_DATA IdentifyDeviceData;
1695
1696 AhciDebugPrint("InquiryCompletion()\n");
1697
1698 PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
1699 Srb = (PSCSI_REQUEST_BLOCK)_Srb;
1700
1701 NT_ASSERT(Srb != NULL);
1702 NT_ASSERT(PortExtension != NULL);
1703
1704// cdb = (PCDB)&Srb->Cdb;
1705 InquiryData = Srb->DataBuffer;
1706 SrbExtension = GetSrbExtension(Srb);
1707 AdapterExtension = PortExtension->AdapterExtension;
1708 IdentifyDeviceData = PortExtension->IdentifyDeviceData;
1709
1711 {
1713 {
1714 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_NODEVICE;
1715 }
1716 return;
1717 }
1718
1719 NT_ASSERT(InquiryData != NULL);
1721
1722 // Device specific data
1723 PortExtension->DeviceParams.MaxLba.QuadPart = 0;
1724
1725 if (SrbExtension->CommandReg == IDE_COMMAND_IDENTIFY)
1726 {
1727 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATA;
1728 if (IdentifyDeviceData->GeneralConfiguration.RemovableMedia)
1729 {
1730 PortExtension->DeviceParams.RemovableDevice = 1;
1731 }
1732
1733 if ((IdentifyDeviceData->CommandSetSupport.BigLba) && (IdentifyDeviceData->CommandSetActive.BigLba))
1734 {
1735 PortExtension->DeviceParams.Lba48BitMode = 1;
1736 }
1737
1738 PortExtension->DeviceParams.AccessType = DIRECT_ACCESS_DEVICE;
1739
1740 /* Device max address lba */
1741 if (PortExtension->DeviceParams.Lba48BitMode)
1742 {
1743 PortExtension->DeviceParams.MaxLba.LowPart = IdentifyDeviceData->Max48BitLBA[0];
1744 PortExtension->DeviceParams.MaxLba.HighPart = IdentifyDeviceData->Max48BitLBA[1];
1745 }
1746 else
1747 {
1748 PortExtension->DeviceParams.MaxLba.LowPart = IdentifyDeviceData->UserAddressableSectors;
1749 }
1750
1751 /* Bytes Per Logical Sector */
1752 if (IdentifyDeviceData->PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words)
1753 {
1754 AhciDebugPrint("\tBytesPerLogicalSector != DEVICE_ATA_BLOCK_SIZE\n");
1756 }
1757
1758 PortExtension->DeviceParams.BytesPerLogicalSector = DEVICE_ATA_BLOCK_SIZE;
1759
1760 /* Bytes Per Physical Sector */
1761 if (IdentifyDeviceData->PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector)
1762 {
1763 AhciDebugPrint("\tBytesPerPhysicalSector != DEVICE_ATA_BLOCK_SIZE\n");
1765 }
1766
1767 PortExtension->DeviceParams.BytesPerPhysicalSector = DEVICE_ATA_BLOCK_SIZE;
1768
1769 // last byte should be NULL
1770 StorPortCopyMemory(PortExtension->DeviceParams.VendorId, IdentifyDeviceData->ModelNumber, sizeof(PortExtension->DeviceParams.VendorId) - 1);
1771 StorPortCopyMemory(PortExtension->DeviceParams.RevisionID, IdentifyDeviceData->FirmwareRevision, sizeof(PortExtension->DeviceParams.RevisionID) - 1);
1772 StorPortCopyMemory(PortExtension->DeviceParams.SerialNumber, IdentifyDeviceData->SerialNumber, sizeof(PortExtension->DeviceParams.SerialNumber) - 1);
1773
1774 PortExtension->DeviceParams.VendorId[sizeof(PortExtension->DeviceParams.VendorId) - 1] = '\0';
1775 PortExtension->DeviceParams.RevisionID[sizeof(PortExtension->DeviceParams.RevisionID) - 1] = '\0';
1776 PortExtension->DeviceParams.SerialNumber[sizeof(PortExtension->DeviceParams.SerialNumber) - 1] = '\0';
1777
1778 // TODO: Add other device params
1779 AhciDebugPrint("\tATA Device\n");
1780 }
1781 else
1782 {
1783 AhciDebugPrint("\tATAPI Device\n");
1784 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATAPI;
1785 PortExtension->DeviceParams.AccessType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1786 }
1787
1788 // INQUIRYDATABUFFERSIZE = 36 ; Defined in storport.h
1790 {
1791 AhciDebugPrint("\tDataBufferLength < sizeof(INQUIRYDATA), Could crash the driver.\n");
1793 }
1794
1795 // update data transfer length
1797
1798 // prepare data to send
1799 InquiryData->Versions = 2;
1800 InquiryData->Wide32Bit = 1;
1801 InquiryData->CommandQueue = 0; // NCQ not supported
1802 InquiryData->ResponseDataFormat = 0x2;
1803 InquiryData->DeviceTypeModifier = 0;
1805 InquiryData->AdditionalLength = INQUIRYDATABUFFERSIZE - 5;
1806 InquiryData->DeviceType = PortExtension->DeviceParams.AccessType;
1807 InquiryData->RemovableMedia = PortExtension->DeviceParams.RemovableDevice;
1808
1809 // Fill VendorID, Product Revision Level and other string fields
1810 StorPortCopyMemory(InquiryData->VendorId, PortExtension->DeviceParams.VendorId, sizeof(InquiryData->VendorId) - 1);
1811 StorPortCopyMemory(InquiryData->ProductId, PortExtension->DeviceParams.RevisionID, sizeof(PortExtension->DeviceParams.RevisionID));
1812 StorPortCopyMemory(InquiryData->ProductRevisionLevel, PortExtension->DeviceParams.SerialNumber, sizeof(InquiryData->ProductRevisionLevel) - 1);
1813
1814 InquiryData->VendorId[sizeof(InquiryData->VendorId) - 1] = '\0';
1815 InquiryData->ProductId[sizeof(InquiryData->ProductId) - 1] = '\0';
1816 InquiryData->ProductRevisionLevel[sizeof(InquiryData->ProductRevisionLevel) - 1] = '\0';
1817
1818 // send queue depth
1820 Srb->PathId,
1821 Srb->TargetId,
1822 Srb->Lun,
1823 AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
1824
1825 NT_ASSERT(status == TRUE);
1826 return;
1827}// -- InquiryCompletion();
#define DEVICE_CONNECTED
Definition: cdrw_hw.h:1159
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
#define DEVICE_ATA_BLOCK_SIZE
Definition: storahci.h:27
#define AHCI_DEVICE_TYPE_NODEVICE
Definition: storahci.h:32
#define AHCI_DEVICE_TYPE_ATA
Definition: storahci.h:30
#define StorPortCopyMemory(Destination, Source, Length)
Definition: storport.h:2401
UCHAR FirmwareRevision[8]
Definition: ata.h:25
struct _IDENTIFY_DEVICE_DATA::@1894 CommandSetActive
struct _IDENTIFY_DEVICE_DATA::@1891 GeneralConfiguration
ULONG Max48BitLBA[2]
Definition: ata.h:168
struct _IDENTIFY_DEVICE_DATA::@1893 CommandSetSupport
UCHAR ModelNumber[40]
Definition: ata.h:26
UCHAR SerialNumber[20]
Definition: ata.h:22
ULONG UserAddressableSectors
Definition: ata.h:51
struct _IDENTIFY_DEVICE_DATA::@1895 PhysicalLogicalSectorSize
UCHAR Versions
Definition: cdrw_hw.h:1120
UCHAR CommandQueue
Definition: cdrw_hw.h:1125
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
UCHAR DeviceTypeModifier
Definition: cdrw_hw.h:1118
UCHAR Wide32Bit
Definition: cdrw_hw.h:1130
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
UCHAR ResponseDataFormat
Definition: cdrw_hw.h:1121
UCHAR DeviceType
Definition: cdrw_hw.h:1116
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
UCHAR AdditionalLength
Definition: cdrw_hw.h:1122

Referenced by DeviceInquiryRequest().

◆ IsPortValid()

FORCEINLINE BOOLEAN IsPortValid ( __in PAHCI_ADAPTER_EXTENSION  AdapterExtension,
__in ULONG  pathId 
)

Definition at line 2471 of file storahci.c.

2475{
2477
2478 if (pathId >= AdapterExtension->PortCount)
2479 {
2480 return FALSE;
2481 }
2482
2483 return AdapterExtension->PortExtension[pathId].DeviceParams.IsActive;
2484}// -- IsPortValid()

Referenced by AhciHwInterrupt(), AhciHwResetBus(), AhciHwStartIo(), AhciInterruptHandler(), DeviceInquiryRequest(), DeviceRequestCapacity(), DeviceRequestReadWrite(), and DeviceRequestSense().

◆ RemoveQueue()

FORCEINLINE PVOID RemoveQueue ( __inout PAHCI_QUEUE  Queue)

Definition at line 2532 of file storahci.c.

2535{
2536 PVOID Srb;
2537
2540
2541 if (Queue->Head == Queue->Tail)
2542 return NULL;
2543
2544 Srb = Queue->Buffer[Queue->Tail++];
2546
2547 return Srb;
2548}// -- RemoveQueue();

Referenced by AhciCommandCompletionDpcRoutine(), and AhciProcessIO().